From 264ac4c09baef1951eedc3aa96d058d40c8b58f6 Mon Sep 17 00:00:00 2001 From: Arturas-Alfredas Lapinskas Date: Wed, 3 Jul 2024 13:09:23 +0300 Subject: [PATCH] 1.4.4: disable iNetwork interface by default --- README.md | 2 +- dist/index.es6.js | 17 +++-- dist/index.es6.js.map | 2 +- dist/index.es6.min.js | 2 +- docs/templates/custom/tmpl/layout.tmpl | 3 +- examples/main.js | 5 +- examples/primitives/primitives.js | 98 ++++++++++++++++++++++++++ examples/startPage.js | 22 +++++- history/history-roadmap.txt | 3 + package.json | 2 +- src/base/IExtension.js | 2 +- src/base/INetwork.js | 3 + src/base/ISystem.js | 6 +- src/base/System.js | 2 +- src/configs.js | 4 +- 15 files changed, 152 insertions(+), 21 deletions(-) create mode 100644 examples/primitives/primitives.js diff --git a/README.md b/README.md index ae249c3..a607562 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Javascript Game Engine +# Javascript Game Engine This engine was designed to simplify creating javascript 2d game applications. diff --git a/dist/index.es6.js b/dist/index.es6.js index 3f0d096..9ecfaf3 100644 --- a/dist/index.es6.js +++ b/dist/index.es6.js @@ -3013,7 +3013,7 @@ class IExtension { * Register render method for class. * @param {string} objectClassName - object name registered to DrawObjectFactory * @param {function(renderObject, gl, pageData, program, vars):Promise} objectRenderMethod - should be promise based returns vertices number and draw program - * @param {string=} objectWebGlDrawProgram - a webgl program name previously registered with iExtension.registerAndCompileWebGlProgram() + * @param {string} objectWebGlDrawProgram - a webgl program name previously registered with iExtension.registerAndCompileWebGlProgram() */ registerObjectRender(objectClassName, objectRenderMethod, objectWebGlDrawProgram) { this.#systemReference.iRender._registerObjectRender(objectClassName, objectRenderMethod, objectWebGlDrawProgram); @@ -3043,6 +3043,9 @@ __webpack_require__.r(__webpack_exports__); /** * Represents Socket connection + * + * From 1.4.4 disabled by default, + * to enable, set settings.network.enabled to true */ class INetwork extends EventTarget { #systemSettings; @@ -3876,7 +3879,7 @@ class ISystem { */ #iExtension; /** - * @type {INetwork} + * @type {INetwork | null} */ #systemServerConnection; /** @@ -3915,7 +3918,7 @@ class ISystem { this.#systemSettings = systemSettings; this.#systemAudioInterface = new _ISystemAudio_js__WEBPACK_IMPORTED_MODULE_3__.ISystemAudio(this.iLoader); - this.#systemServerConnection = new _INetwork_js__WEBPACK_IMPORTED_MODULE_2__.INetwork(systemSettings); + this.#systemServerConnection = systemSettings.network.enabled ? new _INetwork_js__WEBPACK_IMPORTED_MODULE_2__.INetwork(systemSettings) : null; this.#iRender = new _IRender_js__WEBPACK_IMPORTED_MODULE_8__.IRender(this.systemSettings, this.iLoader, canvasContainer); this.#iExtension = new _IExtension_js__WEBPACK_IMPORTED_MODULE_9__.IExtension(this, this.#iRender); this.#registeredStagesReference = registeredStages; @@ -3956,7 +3959,7 @@ class ISystem { }; /** - * @type { INetwork } + * @type { INetwork | null } */ get iNetwork () { return this.#systemServerConnection; @@ -4369,7 +4372,7 @@ class System { * A main factory method for create GameStage instances,
* register them in a System and call GameStage.register() stage * @param {string} screenPageName - * @param {typeof GameStage} stage + * @param {GameStage} stage */ registerStage(screenPageName, stage) { if (screenPageName && typeof screenPageName === "string" && screenPageName.trim().length > 0) { @@ -6203,7 +6206,7 @@ class SystemSettings { // no other variants only WEBGL for now library: _constants_js__WEBPACK_IMPORTED_MODULE_0__.CONST.LIBRARY.WEBGL, optimization: _constants_js__WEBPACK_IMPORTED_MODULE_0__.CONST.OPTIMIZATION.NATIVE_JS.OPTIMIZED, - optimizationWASMUrl: "/src/wa/calculateBufferDataWat.wasm", + optimizationWASMUrl: "./src/wa/calculateBufferDataWat.wasm", optimizationAssemblyUrl: "/src/wa/calculateBufferDataAssembly.wasm", loadingScreen: { backgroundColor: "rgba(128, 128, 128, 0.6)", @@ -6238,6 +6241,8 @@ class SystemSettings { static network = { + // disable INetwork by default + enabled: false, address: "https://gameserver.reslc.ru:9009", gatherRoomsInfoInterval: 5000 }; diff --git a/dist/index.es6.js.map b/dist/index.es6.js.map index c943e13..21e5ffb 100644 --- a/dist/index.es6.js.map +++ b/dist/index.es6.js.map @@ -1 +1 @@ -{"version":3,"file":"index.es6.js","mappings":";;;;;;;;;;;;AAAA,2BAA2B,oGAAoG,iBAAiB,63BAA63B,aAAa,GAAG,GAAG,WAAW,WAAW,iBAAiB,+BAA+B,oBAAoB,yDAAyD,6DAA6D,+BAA+B,wHAAwH,GAAG,QAAQ,iBAAiB,MAAM,kBAAkB,4BAA4B,oBAAoB,mBAAmB,eAAe,mBAAmB,eAAe,iBAAiB,6GAA6G,iCAAiC,2BAA0C,oBAAoB,KAAK,mBAAmB,WAAW,KAAK,cAAc,ySAAyS,4BAA4B,QAAQ,2EAA2E,iDAAiD,2BAA2B,yBAAyB,wFAAwF,wCAAwC,kBAAkB,UAAU,2CAA2C,qBAAqB,cAAc,cAAc,KAAK,GAAG,GAAG,QAAQ,2BAA2B,4DAA4D,gBAAgB,kDAAkD,4EAA4E,kBAAkB,GAAG,KAAK,4BAA4B,SAAS,0CAA0C,kDAAkD,2EAA2E,UAAU,GAAG,mCAAmC,kBAAkB,0BAA0B,iBAAiB,kEAAkE,MAAM,GAAG,GAAG,2BAA2B,uIAAuI,8BAA8B,sCAAsC,wIAAwI,iGAAiG,MAAM,mBAAmB,kEAAkE,yDAAyD,sCAAsC,IAAI,4DAA4D,oFAAoF,8BAA8B,WAAW,SAAS,qDAAqD,gBAAgB,iNAAiN,kDAAkD,+BAA+B,aAAa,mCAAmC,mBAAmB,aAAa,0CAA0C,mBAAmB,GAAG,gBAAgB,+DAA+D,mBAAmB,SAAS,GAAG,mFAAmF,MAAM,2DAA2D,GAAG,iGAAiG,eAAe,2DAA2D,wCAAwC,IAAI,qCAAqC,4EAA4E,mBAAmB,4CAA4C,WAAW,mCAAmC,MAAM,oBAAoB,qFAAqF,UAAU,4BAA4B,YAAY,WAAW,KAAK,aAAa,qBAAqB,0BAA0B,GAAG,0BAA0B,6IAA6I,mCAAmC,qBAAqB,sCAAsC,eAAe,oCAAoC,yDAAyD,mBAAmB,GAAG,GAAG,uDAAuD,UAAU,KAAK,kBAAkB,8BAA8B,qBAAqB,+BAA+B,YAAY,eAAe,GAAG,gBAAgB,yDAAyD,mBAAmB,UAAU,GAAG,MAAM,6EAA6E,MAAM,sGAAsG,MAAM,sGAAsG,MAAM,sYAAsY,MAAM,oCAAoC,kOAAkO,oBAAoB,uBAAuB,4FAA4F,mBAAmB,uBAAuB,gCAAgC,iDAAiD,aAAa,uBAAuB,0BAA0B,iDAAiD,UAAU,kDAAkD,oGAAoG,KAAK,iCAAiC,uEAAuE,QAAQ,GAAG,KAAK,mEAAmE,KAAK,mCAAmC,iFAAiF,2CAA2C,GAAG,MAAM,oGAAoG,QAAQ,IAAI,sBAAsB,mBAAmB,oBAAoB;;;;;;;;;;;;;;ACAlmQ;AACP;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;;;;;;;;;;;;;;;AC9FwC;AACe;;AAEvD;AACA;AACA;AACA,SAAS,yBAAyB;AAClC;AACO,+BAA+B,gEAAe;AACrD;AACA,cAAc;AACd;AACA;;AAEA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,iEAAsB;AACpC;AACA;AACA;;AAEA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AC9CwC;AACe;;AAEvD;AACA;AACA;AACA,SAAS,yBAAyB;AAClC;AACO,8BAA8B,gEAAe;AACpD;AACA,cAAc;AACd;AACA;;AAEA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,gEAAqB;AACnC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;AC5EqD;AACA;AACE;AACI;AACP;AACpD;AACA;AACA;AACA,SAAS,yBAAyB;AAClC;AACO,8BAA8B,gEAAe;AACpD;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,gEAAqB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,GAAG;AAClB,eAAe,GAAG;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,GAAG;AAClB,eAAe,GAAG;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,SAAS;AACzB,gBAAgB,uBAAuB,2BAA2B,IAAI;AACtE,gBAAgB,UAAU;AAC1B;AACA;AACA;AACA,YAAY,wDAAS,CAAC,8EAAmC,4EAA4E,2BAA2B;AAChK;AACA,mCAAmC,8DAAc;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACrSwC;AACe;;AAEvD;AACA;AACA;AACA,SAAS,yBAAyB;AAClC;AACO,6BAA6B,gEAAe;AACnD;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,+DAAoB;AAClC;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;AChCqD;AACA;AACE;AACA;AACF;AACM;AACF;AACJ;AACE;AACJ;AACR;AACG;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,iBAAiB;AAC1B;AACO;AACP;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,GAAG;AAClB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA,iCAAiC,8DAAc;AAC/C;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA,iCAAiC,8DAAc;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB;AACjB;AACA;AACA,iCAAiC,gEAAe;AAChD;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA,iCAAiC,kEAAgB;AACjD;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,OAAO,mBAAmB,KAAK,SAAS,GAAG;AAC1D,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,YAAY,yDAAS,CAAC,0EAA8B;AACpD;AACA;AACA,iCAAiC,gEAAe;AAChD;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,eAAe;AAC9B,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA,iCAAiC,8DAAc;AAC/C;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO,mBAAmB,GAAG;AAC5C,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA,iCAAiC,oEAAiB;AAClD;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,UAAU;AACzB,eAAe,kBAAkB;AACjC,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,8DAAc;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,UAAU;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,UAAU;AACzB,eAAe,YAAY;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,eAAe;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AC7MwC;AACe;;AAEvD;AACA;AACA,SAAS,yBAAyB;AAClC;AACO,gCAAgC,gEAAe;AACtD;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,kEAAuB;AACrC;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AC/BwC;AACe;;AAEvD;AACA;AACA,SAAS,yBAAyB;AAClC;AACO,6BAA6B,gEAAe;AACnD;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,oEAAyB;AACvC;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AC1DwC;AACJ;;AAEpC;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA,cAAc;AACd,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA,UAAU,2DAAoB;AAC9B;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,cAAc;AACd,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,iBAAiB;AAChC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA,wBAAwB,YAAY;AACpC;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA,wBAAwB,YAAY;AACpC;AACA;;AAEA;AACA;;AAEA;AACA;;;AAGA;AACA,eAAe,8BAA8B,mBAAmB,GAAG;AACnE,iBAAiB;AACjB;AACA;AACA;AACA;AACA,mBAAmB,wEAAiC;AACpD,UAAU;AACV;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;AC1QuD;AACX;AACS;AACV;AACgB;;AAE3D;AACA;AACA,SAAS,yBAAyB;AAClC;AACO,6BAA6B,gEAAe;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,+DAAoB;AAClC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,mBAAmB,qDAAS;AAC5B;;AAEA;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,2DAA2D,0BAA0B,GAAG;AACxF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAU;AACV,YAAY,wDAAS,CAAC,0EAA+B;AACrD;AACA;AACA;;;;;;;;;;;;;;;;;AC9NqD;AACE;AACI;AAC3D;AACA;AACA,SAAS,yBAAyB;AAClC;AACO;AACP;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,iBAAiB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,GAAG;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,8DAAc;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO,+BAA+B,GAAG;AACxD,iBAAiB,OAAO,2BAA2B;AACnD;AACA;AACA,mDAAmD,4DAA4D;AAC/G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACjRwD;AACZ;;AAErC;AACP;AACA;AACA;AACA;AACA,YAAY,wDAAS,CAAC,4EAAiC;AACvD;AACA;AACA;;AAEA;AACA,6BAA6B,+EAAoC;AACjE;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACpBO;AACP;AACA;;AAEO;AACP;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACNoE;AACjB;AACC;AACkB;AACX;AACF;AACF;AACA;AACF;AACM;AACN;AACA;AACd;AACU;AACF;AACwK;AAC9K;AACzC;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,cAAc;AACvB;AACA;AACO;AACP;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,8BAA8B,4DAAa;AAC3C;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA,YAAY,sDAAO,CAAC,gFAAqC;AACzD,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,GAAG;AAClB,eAAe,IAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,GAAG;AAClB,eAAe,IAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,mBAAmB;AAClC,eAAe,aAAa;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,iBAAiB;AAChC,kBAAkB,8BAA8B;AAChD;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,+DAAoB;AACjC,aAAa,oEAAyB;AACtC,aAAa,gEAAqB;AAClC,aAAa,gEAAqB;AAClC;AACA;AACA,cAAc;AACd;AACA;AACA,aAAa,iEAAsB;AACnC,YAAY,sDAAO,CAAC,qFAA0C;AAC9D;AACA,aAAa,+DAAoB;AACjC,YAAY,sDAAO,CAAC,qFAA0C;AAC9D;AACA;AACA,YAAY,sDAAO,CAAC,kFAAuC;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,iBAAiB;AAChC,eAAe,wBAAwB;AACvC,kBAAkB,8BAA8B,WAAW;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,+DAAoB;AACjC,aAAa,oEAAyB;AACtC,aAAa,gEAAqB;AAClC,aAAa,gEAAqB;AAClC;AACA;AACA,cAAc;AACd;AACA;AACA,aAAa,iEAAsB;AACnC,YAAY,sDAAO,CAAC,qFAA0C;AAC9D;AACA,aAAa,+DAAoB;AACjC,YAAY,sDAAO,CAAC,qFAA0C;AAC9D;AACA;AACA,YAAY,sDAAO,CAAC,kFAAuC;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,+DAAoB;AACrC,iBAAiB,oEAAyB;AAC1C,iBAAiB,gEAAqB;AACtC,iBAAiB,gEAAqB;AACtC;AACA;AACA,iBAAiB,iEAAsB;AACvC;AACA;AACA,iBAAiB,+DAAoB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,+DAAoB;AACrC,iBAAiB,oEAAyB;AAC1C,iBAAiB,gEAAqB;AACtC,iBAAiB,gEAAqB;AACtC;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,iBAAiB,iEAAsB;AACvC;AACA;AACA,iBAAiB,+DAAoB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,4BAA4B,iEAAqB;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,mDAAM;AAC9B;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,4BAA4B,kEAAsB;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,mDAAM;AACjC,0BAA0B,yDAAa;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,kBAAkB,8BAA8B;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,4BAA4B,iEAAqB;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,UAAU;AACtC;AACA,gCAAgC,oEAAwB,WAAW,gCAAgC;AACnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,UAAU;AACtC;AACA;AACA;AACA,gCAAgC,kEAAsB,UAAU,gCAAgC;AAChG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,sBAAsB;AACrC,eAAe,QAAQ;AACvB,kBAAkB,8BAA8B;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,4BAA4B,kEAAsB;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,UAAU;AACtC;AACA,gCAAgC,qEAAyB;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,UAAU;AACtC;AACA;AACA;AACA,gCAAgC,mEAAuB;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AC3oBgD;AACP;AACzC;AACA;AACA;AACA,SAAS,iBAAiB;AAC1B;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,gBAAgB,2CAA2C;AAC3D;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,sBAAsB;AACrC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,sDAAO,CAAC,iFAAsC;AAC1D;AACA,6BAA6B,iCAAiC;AAC9D,6BAA6B,6CAA6C;AAC1E,6BAA6B,6CAA6C;AAC1E,6BAA6B,iCAAiC;AAC9D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,sDAAO,CAAC,iFAAsC;AAC1D;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,sBAAsB;AACrC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACxYuC;;AAEvC;AACA;AACA;AACA;AACO;AACP;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,UAAU;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,eAAe;AAC9B,eAAe,eAAe;AAC9B,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,0BAA0B;AACzC,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,oEAAoE;AACnF,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;AC1DqD;AACV;AACN;AACiB;;AAEtD;AACA;AACA;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,wDAAS,CAAC,4EAAiC;AACvD;AACA;AACA;;AAEA;AACA,QAAQ,mOAA0B;AAClC,4EAA4E,sBAAsB;AAClG;AACA;AACA,SAAS;AACT;;AAEA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,0BAA0B,kGAAuD;AACjF;;AAEA;AACA,0BAA0B,8FAAmD;AAC7E;;AAEA;AACA,0BAA0B,8FAAmD;AAC7E;;AAEA;AACA,QAAQ,oDAAY;AACpB,qCAAqC,yGAA8D;AACnG;;AAEA;AACA,QAAQ,oDAAY;AACpB,qCAAqC,yGAA8D;AACnG;;AAEA;AACA;AACA;;AAEA;AACA,QAAQ,oDAAY;AACpB,+BAA+B,+DAAW,CAAC,8FAAmD;AAC9F;;AAEA;AACA,QAAQ,oDAAY;AACpB,+BAA+B,+DAAW,CAAC,0FAA+C;AAC1F;;AAEA;AACA,QAAQ,oDAAY;AACpB,+BAA+B,+DAAW,CAAC,uFAA4C,GAAG,UAAU;AACpG;;AAEA;AACA,QAAQ,oDAAY;AACpB,+BAA+B,+DAAW,CAAC,oFAAyC,GAAG,KAAK;AAC5F;;AAEA;AACA,QAAQ,oDAAY;AACpB,+BAA+B,+DAAW,CAAC,sFAA2C,GAAG,UAAU;AACnG;;AAEA;AACA,+BAA+B,+DAAW,CAAC,4FAAiD,GAAG,SAAS;AACxG;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACrIqD;AACD;AACS;AACR;AACN;AACI;AACmB;AACtE,WAAW,sBAAsB;AACO;AACe;AACE;AACF;AACF;AACM;AACN;AACA;AACyD;AACgC;AAC1G;AACpC;AACA;AACA;AACA;AACA,SAAS,iBAAiB;AAC1B;AACA;AACO;AACP;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,8DAA8D,cAAc;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,8DAAW;AAC3C,6DAA6D,qFAA0C;AACvG,6DAA6D,0FAA+C;AAC5G;AACA;AACA;AACA;AACA;AACA,uDAAuD,2EAAgC,EAAE,yEAAe,EAAE,2EAAiB,EAAE,qEAAW,EAAE,uEAAa;AACvJ;AACA;AACA,uDAAuD,+EAAoC,EAAE,oFAAsB,EAAE,sFAAwB,EAAE,gFAAkB,EAAE,kFAAoB;AACvL;AACA;AACA;AACA,mCAAmC,oEAAmB,+BAA+B,2EAAgC;AACrH,mCAAmC,oEAAmB,qCAAqC,+EAAoC;AAC/H,mCAAmC,0EAAsB,qCAAqC,+EAAoC;AAClI,mCAAmC,uEAAqB,gCAAgC,+EAAoC;AAC5H,mCAAmC,qEAAoB,gCAAgC,+EAAoC;AAC3H,mCAAmC,mEAAmB,qCAAqC,2EAAgC;AAC3H,mCAAmC,oEAAmB,+BAA+B,+EAAoC;AACzH;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,GAAG;AAClB,eAAe,IAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,GAAG;AAClB,eAAe,IAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,eAAe;AAC9B,eAAe,eAAe;AAC9B,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,0BAA0B;AACzC,iBAAiB;AACjB;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,oEAAoE;AACnF,eAAe,SAAS;AACxB;AACA;AACA,4DAA4D,qEAAqE;AACjI;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,0BAA0B;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA;AACA,0BAA0B,mBAAmB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,gBAAgB;AAC/B,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,yCAAyC;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,sDAAO,CAAC,kEAAuB;AACnD;AACA;AACA;AACA,gCAAgC,qBAAqB;AACrD;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,sDAAO,CAAC,8EAAmC;AACnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,iBAAiB;AACvD,0CAA0C,iBAAiB;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,eAAe,8IAA8I;AAC7J,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,UAAU;AACV;AACA,sCAAsC,gEAAqB;AAC3D,6DAA6D,2EAAgC;AAC7F,oEAAoE,2EAAgC;AACpG;AACA;AACA;AACA;AACA,wBAAwB,wDAAS,CAAC,yEAA8B;AAChE,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA,qBAAqB;AACrB,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,SAAS;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,sEAA8B;AACjE,oDAAoD,8CAA8C;AAClG;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,eAAe;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,8DAAmB;AAChC;AACA;AACA;AACA;AACA;AACA,wDAAwD,sFAA2C;AACnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,sDAAO,CAAC,6EAAkC;AAClE;AACA;AACA,iBAAiB;AACjB;AACA,aAAa;AACb,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,2GAA2G,qFAA0C;AACrJ;AACA,kBAAkB,2EAAgC;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,yEAA8B;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,oBAAoB,sDAAO,CAAC,6EAAkC;AAC9D,iBAAiB;AACjB,cAAc;AACd,gBAAgB,sDAAO,CAAC,6EAAkC;AAC1D;AACA;AACA,SAAS;AACT;AACA;;;;;;;;;;;;;;;;;;;;;;;;AC9mBoE;AAChB;AACX;AACQ;AACF;AACuB;AACX;AAChB;AACJ;AACM;;AAE7C;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,cAAc;AACvB,SAAS,iBAAiB;AAC1B;AACO;AACP;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA,mBAAmB,4EAAa;AAChC;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA,6BAA6B,oEAAiB;AAC9C;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,wDAAS,CAAC,4EAAiC;AACvD;AACA;AACA;AACA,yCAAyC,0DAAY;AACrD,2CAA2C,kDAAQ;AACnD,4BAA4B,gDAAO;AACnC,+BAA+B,sDAAU;AACzC;AACA;AACA,uCAAuC,2EAAgC,kBAAkB,2EAAgC;AACzH,uCAAuC,yEAA8B,kBAAkB,yEAA8B;AACrH;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,GAAG;AAClB,eAAe,IAAI;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,GAAG;AAClB,eAAe,IAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;;AAEA;AACA,eAAe;AACf;AACA;AACA;AACA;;AAEA;AACA,eAAe;AACf;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,gBAAgB,QAAQ;AACxB,iBAAiB;AACjB;AACA;AACA;AACA;AACA,YAAY,sDAAO,CAAC,iFAAsC;AAC1D;AACA,UAAU;AACV;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,yEAA8B;AACpD;AACA,UAAU;AACV,YAAY,wDAAS,CAAC,qEAA0B;AAChD;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA,sBAAsB,wEAA6B;AACnD;AACA;AACA;AACA,UAAU;AACV,YAAY,wDAAS,CAAC,qEAA0B;AAChD;AACA;AACA;;;;;;;;;;;;;;;;;ACvNuE;AACvB;AACP;;AAEzC;AACA;AACA;AACA;AACA;AACA,SAAS,iBAAiB;AAC1B;AACA;AACO;AACP;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;AACA,YAAY,sDAAO,CAAC,yEAA8B;AAClD;AACA;AACA;AACA;AACA,UAAU;AACV,YAAY,sDAAO,CAAC,6EAAkC;AACtD;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;AACA,YAAY,sDAAO,CAAC,yEAA8B;AAClD;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,YAAY,sDAAO,CAAC,6EAAkC;AACtD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AC7F+C;AACP;;AAEjC;AACP;AACA,YAAY,4DAAmB,KAAK,2DAAgB;AACpD;AACA;AACA;;;;;;;;;;;;;;;;ACRA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;AC7E8C;AACH;AACA;AACJ;AACQ;;AAEU;;AAEzD;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,eAAe,gBAAgB;AAC/B,eAAe,oBAAoB;AACnC;AACA;AACA;AACA,YAAY,wDAAS,CAAC,4EAAiC;AACvD;AACA;;AAEA;AACA;AACA;AACA;;AAEA,4BAA4B,gDAAO;;AAEnC,4CAA4C,iEAAY;;AAExD;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,kBAAkB;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,YAAY,wDAAS,CAAC,4EAAiC;AACvD;AACA;;AAEA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;;AAEA;AACA,uDAAuD,mBAAmB;AAC1E;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;AC9FA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;;;;;;;;;;;;;;;;;;AC/DA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACxEA;AACA;AACA;AACO;AACP;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;ACxCuE;AACzB;AACO;AACD;AACC;AACrD;AACO;AACP;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,YAAY,wDAAS,CAAC,8EAAmC;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,uDAAuD,qFAA0C;AACjG;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,2CAA2C;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,cAAc;AACd;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,eAAe;AAC9B,eAAe,eAAe;AAC9B,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,gBAAgB,wDAAS,CAAC,kEAAuB;AACjD;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,gBAAgB,wDAAS,CAAC,kEAAuB;AACjD;AACA;AACA;AACA;AACA;AACA,gBAAgB,wDAAS,CAAC,kEAAuB,0CAA0C,KAAK;AAChG;AACA,UAAU;AACV,YAAY,wDAAS,CAAC,kEAAuB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,cAAc;AAC7B,eAAe,eAAe;AAC9B,eAAe,eAAe;AAC9B,iBAAiB,+CAA+C;AAChE;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,wDAAS,CAAC,kEAAuB;AACjD;AACA,UAAU;AACV,YAAY,wDAAS,CAAC,kEAAuB,qBAAqB,WAAW;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,oEAAyB;AACtC;AACA;AACA;AACA,aAAa,+DAAoB;AACjC;AACA,aAAa,iEAAsB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,kEAAuB;AACpC;AACA;AACA;AACA;AACA,gBAAgB,sDAAO,CAAC,qFAA0C,cAAc,gBAAgB;AAChG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA,uCAAuC;AACvC;AACA,eAAe,kCAAkC;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,8DAAc;AAC/C;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,8DAAc;AAC/C;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA,uCAAuC;AACvC;AACA;AACA;AACA;AACA,aAAa,qFAA0C;AACvD;AACA;AACA,aAAa,0FAA+C;AAC5D,aAAa,qFAA0C;AACvD;AACA;AACA,aAAa,iFAAsC;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,4BAA4B;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,uBAAuB;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,8DAAc;AACvD;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,+EAAoC;AAC5E,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,8BAA8B,+EAAoC;AAChF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,sDAAO,CAAC,qFAA0C;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,+EAAoC;AAC5E,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,8BAA8B,+EAAoC;AAChF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,gBAAgB;AAC/B,eAAe,eAAe;AAC9B,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,yCAAyC;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,sDAAO,CAAC,kEAAuB;AAC/C;AACA;AACA;AACA,4BAA4B,qBAAqB;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAiE;AACjE;AACA;AACA,oBAAoB,sDAAO,CAAC,8EAAmC;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,kBAAkB;AACpD;AACA;AACA,sCAAsC,kBAAkB;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,sDAAO;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0DAA0D;AAC1D;AACA;AACA;AACA;AACA,qDAAqD;AACrD,8CAA8C;AAC9C;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,yCAAyC;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,sDAAO,CAAC,kEAAuB;AAC/C;AACA;AACA,4BAA4B,0BAA0B;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,sDAAO,CAAC,8EAAmC;AAC/D;AACA;AACA,kCAAkC,iBAAiB;AACnD,sCAAsC,iBAAiB;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,eAAe,gBAAgB;AAC/B,eAAe,eAAe;AAC9B,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,yCAAyC;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,sDAAO,CAAC,kEAAuB;AAC/C;AACA;AACA;AACA,4BAA4B,qBAAqB;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,sDAAO,CAAC,8EAAmC;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA,2FAA2F,QAAQ;AACnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,sBAAsB;AACrC,eAAe,eAAe;AAC9B,iBAAiB;AACjB;AACA;AACA;AACA,qCAAqC,uDAAY,EAAE,8BAA8B,GAAG,8BAA8B;AAClH;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,oBAAoB,sDAAO,CAAC,0EAA+B;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACh/CuC;AACvC;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,2DAAgB;;AAElC;AACA;AACA,iBAAiB,8DAAmB;AACpC,sBAAsB,iFAAsC;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,uBAAuB,sFAA2C;AAClE;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;;;;;;;;;;;;;;;ACtEO;AACP;AACA;AACA;AACA,KAAK;AACL,eAAe;AACf,aAAa;AACb;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,KAAK;AACL,oBAAoB;AACpB;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;AC7HiD;;AAE1C,2BAA2B,yDAAS;AAC3C;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,mBAAmB,wBAAwB;AAC3C;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC1C0C;AACM;AACY;AACN;AACH;AACL;AACP;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACPU;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,uDAAM;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,6CAA6C;AACzD,YAAY,6CAA6C;AACzD,cAAc,8BAA8B;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB;AACnB;AACA;AACA;AACA,gBAAgB;AAChB,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,uDAAM;AACrB;AACA;AACA;AACA,gBAAgB,uDAAM,wDAAwD,uDAAM;AACpF;AACA;AACA;AACA,sBAAsB,uDAAM;AAC5B,uBAAuB,uDAAM,kDAAkD,uDAAM;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,sBAAsB;AACjC,YAAY,6CAA6C;AACzD,cAAc,8BAA8B;AAC5C;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,IAAI,GAAG,+DAA+D;AACxG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,YAAY,+BAA+B;AAC3C,aAAa;AACb;AACA;AACA;AACA,iCAAiC,uDAAM;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,mBAAmB;AACnC,gBAAgB,mBAAmB;AACnC,gBAAgB,qBAAqB;AACrC,gBAAgB,qBAAqB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,yBAAyB;AACzB;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,eAAe;AAC1B,WAAW,sBAAsB;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,sBAAsB;AAClD,4BAA4B,sBAAsB;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,sCAAsC;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,eAAe;AAC1B,YAAY,+BAA+B;AAC3C,cAAc,8BAA8B;AAC5C;AACA;AACA;AACA;AACA,gCAAgC,gDAAgD;AAChF;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,eAAe;AAC1B,WAAW,sBAAsB;AACjC,aAAa;AACb;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa;AACb;AACA;AACA;AACA;AACA,oBAAoB,YAAY;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;SC1aA;SACA;;SAEA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;;SAEA;SACA;;SAEA;SACA;SACA;;SAEA;SACA;;;;;UCzBA;UACA;UACA;UACA;UACA,yCAAyC,wCAAwC;UACjF;UACA;UACA;;;;;UCPA;UACA;UACA;UACA;UACA;UACA;UACA;UACA,EAAE;UACF;;;;;UCRA;UACA;UACA;UACA;UACA;;;;;UCJA;;;;;UCAA;UACA;UACA;UACA;UACA,uBAAuB,4BAA4B;UACnD;UACA;UACA;UACA,iBAAiB,oBAAoB;UACrC;UACA,mGAAmG,YAAY;UAC/G;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA,mEAAmE,iCAAiC;UACpG;UACA;UACA;UACA;;;;;UCxCA;UACA;UACA;UACA,uDAAuD,iBAAiB;UACxE;UACA,gDAAgD,aAAa;UAC7D;;;;;UCNA;UACA;UACA;UACA;UACA;UACA;UACA;;;;;UCNA;;UAEA;UACA;UACA;UACA;UACA;UACA;;UAEA;UACA;UACA;UACA,iCAAiC;;UAEjC;UACA;UACA;UACA,KAAK;UACL,eAAe;UACf;UACA;UACA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA,MAAM;UACN;UACA;UACA;;UAEA;;UAEA;;UAEA;;UAEA;;UAEA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA,MAAM,qBAAqB;UAC3B;UACA;UACA;UACA;UACA;UACA;;UAEA;;UAEA;UACA;UACA;;;;;SErFA;SACA;SACA;SACA","sources":["webpack://jsge/./modules/assetsm/dist/assetsm.min.js","webpack://jsge/./src/base/AnimationEvent.js","webpack://jsge/./src/base/DrawCircleObject.js","webpack://jsge/./src/base/DrawConusObject.js","webpack://jsge/./src/base/DrawImageObject.js","webpack://jsge/./src/base/DrawLineObject.js","webpack://jsge/./src/base/DrawObjectFactory.js","webpack://jsge/./src/base/DrawPolygonObject.js","webpack://jsge/./src/base/DrawRectObject.js","webpack://jsge/./src/base/DrawShapeObject.js","webpack://jsge/./src/base/DrawTextObject.js","webpack://jsge/./src/base/DrawTiledLayer.js","webpack://jsge/./src/base/Events/SystemEvent.js","webpack://jsge/./src/base/Exception.js","webpack://jsge/./src/base/GameStage.js","webpack://jsge/./src/base/GameStageData.js","webpack://jsge/./src/base/IExtension.js","webpack://jsge/./src/base/INetwork.js","webpack://jsge/./src/base/IRender.js","webpack://jsge/./src/base/ISystem.js","webpack://jsge/./src/base/ISystemAudio.js","webpack://jsge/./src/base/Logger.js","webpack://jsge/./src/base/Primitives.js","webpack://jsge/./src/base/System.js","webpack://jsge/./src/base/WebGl/ImagesDrawProgram.js","webpack://jsge/./src/base/WebGl/PrimitivesDrawProgram.js","webpack://jsge/./src/base/WebGl/TextureStorage.js","webpack://jsge/./src/base/WebGl/WebGlEngine.js","webpack://jsge/./src/configs.js","webpack://jsge/./src/constants.js","webpack://jsge/./src/design/LoadingStage.js","webpack://jsge/./src/index.js","webpack://jsge/./src/utils.js","webpack://jsge/webpack/bootstrap","webpack://jsge/webpack/runtime/define property getters","webpack://jsge/webpack/runtime/ensure chunk","webpack://jsge/webpack/runtime/get javascript chunk filename","webpack://jsge/webpack/runtime/hasOwnProperty shorthand","webpack://jsge/webpack/runtime/load script","webpack://jsge/webpack/runtime/make namespace object","webpack://jsge/webpack/runtime/publicPath","webpack://jsge/webpack/runtime/jsonp chunk loading","webpack://jsge/webpack/before-startup","webpack://jsge/webpack/startup","webpack://jsge/webpack/after-startup"],"sourcesContent":["const PROGRESS_EVENT_TYPE={loadstart:\"loadstart\",progress:\"progress\",abort:\"abort\",error:\"error\",load:\"load\",timeout:\"timeout\"},ERROR_MESSAGES={LOADER_NOT_REGISTERED:\" loader is not registered.\",RECURSION_ERROR:\"Too much recursion. Stop iteration.\",NOT_CORRECT_METHOD_TYPE:\"uploadMethod should be instance of Promise and return upload result value\",XML_FILE_EXTENSION_INCORRECT:\" AtlasXML file extension is incorrect, only .xml file supported\",TILESET_FILE_EXTENSION_INCORRECT:\" tileset file extension is not correct, only .tsj or .json files are supported\",TILEMAP_FILE_EXTENSION_INCORRECT:\" tilemap file extension is not correct, only .tmj or .json files are supported\",INPUT_PARAMS_ARE_INCORRECT:\" fileKey and url should be provided\",ATLAS_IMAGE_LOADING_FAILED:\"Error loading atlas image \",TILESET_LOADING_FAILED:\"Error loading related tileset \",TILEMAP_LOADING_FAILED:\"Error loading tilemap \",AUDIO_LOADING_FAILED:\"Error loading audio \",IMAGE_LOADING_FAILED:\"Error loading image \",XML_FORMAT_INCORRECT:\" XML format is not correct.\"};class Loader{#e;#t;#r=new Map;#s=new Map;constructor(e,t){this.#e=e,this.#t=(e,r,...s)=>{const i=t(e,r,...s);if(i instanceof Promise)return i.then((t=>this.#i(t,e)));throw new TypeError(ERROR_MESSAGES.NOT_CORRECT_METHOD_TYPE)}}#i=(e,t)=>new Promise(((r,s)=>{e||null===e||Warning(\"AssetsManager: uploadMethod for \"+this.#e+\" returns incorrect value\"),this.#o(t,e),this.#a(t),r()}));#o(e,t){this.#s.set(e,t)}#a(e){this.#r.delete(e)}get filesWaitingForUpload(){return this.#r.size}get loadingQueue(){return this.#r}get uploadMethod(){return this.#t}_addFile=(e,t)=>{this.#r.has(e)&&Warning(\"AssetsManager: File \"+this.#e+\" with key \"+e+\" is already added\"),this.#r.set(e,t)};_isFileInQueue=e=>this.#r.has(e);_getFile=e=>this.#s.get(e)}export default class AssetsManager{#n=5;#l=new EventTarget;#d=new Map;#E=0;constructor(){this.registerLoader(\"Audio\",this._loadAudio),this.registerLoader(\"Image\",this._loadImage),this.registerLoader(\"TileMap\",this._loadTileMap),this.registerLoader(\"TileSet\",this._loadTileSet),this.registerLoader(\"AtlasImageMap\",this._loadAtlasImage),this.registerLoader(\"AtlasXML\",this._loadAtlasXml)}get filesWaitingForUpload(){let e=0;return Array.from(this.#d.values()).map((t=>e+=t.filesWaitingForUpload)),e}registerLoader=(e,t=this._defaultUploadMethod)=>{this[\"add\"+e]=(t,r,...s)=>{this.addFile(e,t,r,...s)},this[\"get\"+e]=t=>this.getFile(e,t),this[\"is\"+e+[\"InQueue\"]]=t=>this.isFileInQueue(e,t);const r=this.#d.get(e)||new Loader(e,t);this.#d.set(e,r)};preload(){return this.#h(),new Promise((async(e,t)=>{this.#u().then((()=>{this.#c(),e()})).catch((e=>{t(e)}))}))}#u(e=0){return this.#R().then((t=>{if(0===this.filesWaitingForUpload)return Promise.resolve(t);if(++e>this.#n){const e=new Error(ERROR_MESSAGES.RECURSION_ERROR);return this.#g(e),Promise.reject(new Error(ERROR_MESSAGES.RECURSION_ERROR))}return this.#u(e)}))}#R(){return new Promise(((e,t)=>{let r=[];Array.from(this.#d.values()).forEach((e=>{Array.from(e.loadingQueue.entries()).forEach((t=>{const s=new Promise(((r,s)=>e.uploadMethod(t[0],...t[1]).then((e=>r(e)))));r.push(s)}))})),Promise.allSettled(r).then((r=>{for(const s of r){if(\"rejected\"===s.status){const e=s.reason;this.#_(e)?t(e):(Warning(\"AssetsManager: \"+e.message),this.#g(e))}e(r)}}))}))}addEventListener(e,t,...r){PROGRESS_EVENT_TYPE[e]?this.#l.addEventListener(e,t,...r):Warning(\"AssetsManager: Event type should be one of the ProgressEvent.type\")}removeEventListener(e,t,...r){this.#l.removeEventListener(e,t,...r)}_loadAtlasXml=(e,t)=>(this.#m(t),fetch(t).then((e=>e.text())).then((e=>(new window.DOMParser).parseFromString(e,\"text/xml\"))).then((r=>{const s=r.documentElement||r.activeElement,i=s.attributes.getNamedItem(\"imagePath\"),o=s.children;if(i){const r=this.#p(t);return this.addAtlasImageMap(e,r+i.value,o,r),Promise.resolve(s)}{const t=new Error(e+ERROR_MESSAGES.XML_FORMAT_INCORRECT);return this.#g(t),Promise.resolve(t)}})));_loadAtlasImage=(e,t,r,s=\"anonymous\")=>new Promise(((e,i)=>{const o=new Image,a=new Map,n=document.createElement(\"canvas\"),l=n.getContext(\"2d\");o.crossOrigin=s,o.onload=()=>{const t=[];let s=[];n.width=o.width,n.height=o.height,l.drawImage(o,0,0);for(let e of r){const r=e.attributes,i=r.getNamedItem(\"name\").value,o=i.includes(\".\")?i.split(\".\")[0]:i,a=r.getNamedItem(\"x\").value,n=r.getNamedItem(\"y\").value,d=r.getNamedItem(\"width\").value,E=r.getNamedItem(\"height\").value;t.push(createImageBitmap(l.getImageData(a,n,d,E),{premultiplyAlpha:\"premultiply\"})),s.push(o)}this.#S(),Promise.all(t).then((t=>{t.forEach(((e,t)=>{const r=s[t];a.set(r,e),this.addImage(r,\"empty url\",e)})),n.remove(),e(a)}))},o.onerror=()=>{const r=new Error(ERROR_MESSAGES.ATLAS_IMAGE_LOADING_FAILED+t);this.#g(r),e(null)},o.src=t}));_loadTileSet=(e,t,r=1,s)=>(this.#I(t),fetch(s?s+t:t).then((e=>e.json())).then((e=>{const{name:t,image:i,spacing:o,margin:a,tilewidth:n,tileheight:l}=e;return t&&i&&!this.isFileInQueue(\"Image\",t)&&this.addImage(t,s?s+i:i),e.gid=r,Promise.resolve(e)})).catch((()=>{const e=new Error(ERROR_MESSAGES.TILESET_LOADING_FAILED+t);return this.#g(e),Promise.resolve(null)})));_defaultUploadMethod=(e,t)=>fetch(t);_loadTileMap=(e,t,r=!0)=>(this.#L(t),fetch(t).then((e=>e.json())).then((e=>{const s=this.#p(t);if(!0===r&&e.tilesets&&e.tilesets.length>0){const t=[];return e.tilesets.forEach(((e,r)=>{const{firstgid:i,source:o}=e,a=this._loadTileSet(\"default-\"+i,o,i,s).then((e=>(this.#S(),Promise.resolve(e))));t.push(a)})),Promise.all(t).then((t=>{for(let r=0;r(e.message.includes(\"JSON.parse:\")&&(e=new Error(ERROR_MESSAGES.TILEMAP_LOADING_FAILED+t)),this.#g(e),Promise.resolve(null)))));_loadAudio=(e,t)=>new Promise((e=>{const r=new Audio(t);r.addEventListener(\"loadeddata\",(()=>{this.#S(),e(r)})),r.addEventListener(\"error\",(()=>{const r=new Error(ERROR_MESSAGES.AUDIO_LOADING_FAILED+t);this.#g(r),e(null)}))}));_loadImage=(e,t,r,s=\"anonymous\")=>new Promise(((e,i)=>{if(r)e(r);else{const r=new Image;r.crossOrigin=s,r.onload=()=>{createImageBitmap(r,{premultiplyAlpha:\"premultiply\"}).then((t=>{this.#S(),e(t)}))},r.onerror=()=>{const r=new Error(ERROR_MESSAGES.IMAGE_LOADING_FAILED+t);this.#g(r),e(null)},r.src=t}}));#m(e){e.includes(\".xml\")||Exception(e+ERROR_MESSAGES.XML_FILE_EXTENSION_INCORRECT)}#I(e){e.includes(\".tsj\")||e.includes(\".json\")||Exception(e+ERROR_MESSAGES.TILESET_FILE_EXTENSION_INCORRECT)}#L(e){e.includes(\".tmj\")||e.includes(\".json\")||Exception(e+ERROR_MESSAGES.TILEMAP_FILE_EXTENSION_INCORRECT)}#_(e){return e.message.includes(ERROR_MESSAGES.NOT_CORRECT_METHOD_TYPE)||e.message.includes(ERROR_MESSAGES.XML_FILE_EXTENSION_INCORRECT)||e.message.includes(ERROR_MESSAGES.TILESET_FILE_EXTENSION_INCORRECT)||e.message.includes(ERROR_MESSAGES.TILEMAP_FILE_EXTENSION_INCORRECT)||e.message.includes(ERROR_MESSAGES.INPUT_PARAMS_ARE_INCORRECT)||e.message.includes(ERROR_MESSAGES.LOADER_NOT_REGISTERED)}#p(e){let t=e.split(\"/\"),r=t.length,s=\"/\";return t[r-1].includes(\".tmj\")||t[r-1].includes(\".xml\")||t[r-1].includes(\".json\")?(t.pop(),s=t.join(\"/\")+\"/\"):(t[r-2].includes(\".tmj\")||t[r-2].includes(\".xml\")||t[r-2].includes(\".json\"))&&(t.splice(r-2,2),s=t.join(\"/\")+\"/\"),s}addFile(e,t,r,...s){const i=this.#d.get(e);i?(this.#A(t,r,e),i._addFile(t,[r,...s])):Exception(e+ERROR_MESSAGES.LOADER_NOT_REGISTERED)}isFileInQueue(e,t){const r=this.#d.get(e);if(r)return r._isFileInQueue(t);Exception(\"Loader for \"+e+\" is not registered!\")}getFile(e,t){const r=this.#d.get(e);if(r)return r._getFile(t);Exception(\"Loader for \"+e+\" is not registered!\")}#A(e,t,r){const s=ERROR_MESSAGES.INPUT_PARAMS_ARE_INCORRECT;e&&0!==e.trim().length||Exception(\"add\"+r+\"()\"+s),t&&0!==t.trim().length||Exception(\"add\"+r+\"()\"+s)}#h(){let e=this.filesWaitingForUpload;this.#l.dispatchEvent(new ProgressEvent(PROGRESS_EVENT_TYPE.loadstart,{total:e}))}#c(){this.#l.dispatchEvent(new ProgressEvent(PROGRESS_EVENT_TYPE.load))}#S(){const e=this.filesWaitingForUpload;this.#E+=1,this.#l.dispatchEvent(new ProgressEvent(PROGRESS_EVENT_TYPE.progress,{lengthComputable:!0,loaded:this.#E,total:e}))}#g(e){Warning(\"AssetsManger: \"+e.message),this.#l.dispatchEvent(new ErrorEvent(PROGRESS_EVENT_TYPE.error,{error:e}))}}function Exception(e){throw new Error(e)}function Warning(e){console.warn(e)}","export class AnimationEvent {\n #eventName;\n /**\n * @type {number}\n */\n #defaultDurationTime = 100;\n /**\n * Array [sprite index, duration]\n * @type { Array> }\n */\n #animationSpriteIndexes;\n /**\n * \n * @type {number}\n */\n #currentAnimationItemIndex;\n /**\n * @type {boolean}\n */\n #isActive;\n /**\n * @type {boolean}\n */\n #isRepeated;\n #lastAnimationTimeStamp;\n \n constructor(eventName, animationSpriteIndexes, isRepeated = false, currentSpriteIndex, isActive = false) {\n this.#eventName = eventName;\n this.#animationSpriteIndexes = this.#convertToArray(animationSpriteIndexes);\n this.#currentAnimationItemIndex = currentSpriteIndex ? currentSpriteIndex : 0;\n this.#isActive = isActive;\n this.#isRepeated = isRepeated;\n }\n\n get name() {\n return this.#eventName;\n }\n\n get isActive() {\n return this.#isActive;\n }\n\n get currentSprite() {\n return this.#animationSpriteIndexes[this.#currentAnimationItemIndex][0];\n }\n\n get _isLastSprite() {\n return (this.#animationSpriteIndexes.length - 1) === this.#currentAnimationItemIndex;\n }\n\n iterateAnimationIndex() {\n const currentIndex = this.#currentAnimationItemIndex,\n currentDuration = this.#animationSpriteIndexes[currentIndex][1],\n lastIterationTime = Date.now() - this.#lastAnimationTimeStamp;\n // iterate or skip\n if (currentDuration < lastIterationTime) {\n if (!this._isLastSprite) {\n this.#currentAnimationItemIndex++;\n } else {\n if (!this.#isRepeated) {\n this.deactivateAnimation();\n } else {\n // take first element\n this.#currentAnimationItemIndex = 0;\n \n }\n }\n // reset timestamp\n this.#lastAnimationTimeStamp = Date.now();\n }\n }\n\n activateAnimation = () => {\n this.#isActive = true;\n this.#currentAnimationItemIndex = 0;\n this.#lastAnimationTimeStamp = Date.now();\n };\n\n deactivateAnimation = () => {\n this.#isActive = false;\n };\n\n #convertToArray(animationSpriteIndexes) {\n let animationArray = [];\n animationSpriteIndexes.forEach(element => {\n if (typeof element.id === \"number\" && typeof element.duration === \"number\") {\n animationArray.push([element.id, element.duration]);\n } else {\n animationArray.push([element, this.#defaultDurationTime]);\n }\n \n });\n return animationArray;\n }\n}","import { CONST } from \"../constants.js\";\nimport { DrawShapeObject } from \"./DrawShapeObject.js\";\n\n/**\n * Circle object to draw.\n * @extends DrawShapeObject\n * @see {@link DrawObjectFactory} should be created with factory method\n */\nexport class DrawCircleObject extends DrawShapeObject {\n /**\n * @type {number}\n */\n #radius;\n\n /**\n * @type {Array}\n */\n #vertices;\n\n /**\n * @hideconstructor\n */\n constructor(x, y, radius, bgColor) {\n super(CONST.DRAW_TYPE.CIRCLE, x, y, bgColor);\n this.#radius = radius;\n this.#vertices = this._interpolateConus(radius);\n }\n\n /**\n * Array of [x,y] cords.\n * @type {Array}\n */\n get vertices () {\n return this.#vertices;\n }\n\n set vertices(value) {\n this.#vertices = value;\n }\n\n /**\n * @type {number}\n */\n get radius() {\n return this.#radius;\n }\n}","import { CONST } from \"../constants.js\";\nimport { DrawShapeObject } from \"./DrawShapeObject.js\";\n\n/**\n * Conus object to draw.\n * @extends DrawShapeObject\n * @see {@link DrawObjectFactory} should be created with factory method\n */\nexport class DrawConusObject extends DrawShapeObject {\n /**\n * @type {number}\n */\n #radius;\n\n /**\n * @type {number}\n */\n #angle;\n\n /**\n * Array of [x,y] cords.\n * @type {Array}\n */\n #vertices;\n #fade_min;\n\n /**\n * @hideconstructor\n */\n constructor(x, y, radius, bgColor, angle, fade = 0) {\n super(CONST.DRAW_TYPE.CONUS, x, y, bgColor);\n this.#radius = radius;\n this.#angle = angle;\n this.#fade_min = fade;\n this.#vertices = this._interpolateConus(radius, angle);\n }\n\n /**\n * Array of [x,y] cords.\n * @type {Array}\n */\n get vertices () {\n return this.#vertices;\n }\n\n set vertices(value) {\n this.#vertices = value;\n }\n\n /**\n * @type {number}\n */\n get radius() {\n return this.#radius;\n }\n\n /**\n * @type {number}\n */\n get angle() {\n return this.#angle;\n }\n\n /**\n * @type {number}\n */\n get fade_min() {\n return this.#fade_min;\n }\n\n /**\n * @param {number} value - fade start pos in px\n */\n set fade_min(value) {\n this.#fade_min = value;\n }\n}","import { AnimationEvent } from \"./AnimationEvent.js\";\r\nimport { CONST, ERROR_CODES } from \"../constants.js\";\r\nimport { DrawShapeObject } from \"./DrawShapeObject.js\";\r\nimport { TextureStorage } from \"./WebGl/TextureStorage.js\";\r\nimport { Exception, Warning } from \"./Exception.js\";\r\n/**\r\n * Image object to draw\r\n * @extends DrawShapeObject\r\n * @see {@link DrawObjectFactory} should be created with factory method\r\n */\r\nexport class DrawImageObject extends DrawShapeObject {\r\n /**\r\n * @type {number}\r\n */\r\n #w;\r\n /**\r\n * @type {number}\r\n */\r\n #h;\r\n /**\r\n * Image sprite key\r\n * @type {string}\r\n */\r\n #key;\r\n /**\r\n * @type {ImageBitmap}\r\n */\r\n #image;\r\n /**\r\n * @type {EventTarget}\r\n */\r\n #emitter;\r\n /**\r\n * @type {Map}\r\n */\r\n #animations;\r\n /**\r\n * @type {null | string}\r\n */\r\n #activeAnimation;\r\n /**\r\n * @type {number}\r\n */\r\n #imageIndex;\r\n /**\r\n * @type {number}\r\n */\r\n #spacing = 0;\r\n /**\r\n * @type {Array>}\r\n */\r\n #vertices;\r\n /**\r\n * @type {Object | null}\r\n */\r\n #circleBoundaries;\r\n /**\r\n * @type {TextureStorage}\r\n */\r\n #textureStorage;\r\n\r\n /**\r\n * @hideconstructor\r\n */\r\n constructor(mapX, mapY, width, height, key, imageIndex = 0, boundaries, image, spacing = 0) {\r\n super(CONST.DRAW_TYPE.IMAGE, mapX, mapY);\r\n this.#key = key;\r\n this.#emitter = new EventTarget();\r\n this.#animations = new Map();\r\n this.image = image;\r\n this.#imageIndex = imageIndex;\r\n this.#spacing = spacing;\r\n this.#w = width;\r\n this.#h = height;\r\n this.#vertices = boundaries && !boundaries.r ? this._convertVerticesArray(boundaries) : boundaries && boundaries.r ? this._calculateConusBoundaries(boundaries.r) : this._calculateRectVertices(width, height);\r\n this.#circleBoundaries = boundaries && typeof boundaries.r !== \"undefined\" ? boundaries : null;\r\n }\r\n\r\n /**\r\n * @type {number}\r\n */\r\n get width() {\r\n return this.#w;\r\n }\r\n\r\n /**\r\n * @type {number}\r\n */\r\n get height() {\r\n return this.#h;\r\n }\r\n\r\n set width(w) {\r\n this.#w = w;\r\n }\r\n\r\n set height(h) {\r\n this.#h = h;\r\n }\r\n\r\n /**\r\n * A key should match an image loaded through AssetsManager\r\n * @type {string}\r\n */\r\n get key() {\r\n return this.#key;\r\n }\r\n\r\n /**\r\n * @type {ImageBitmap}\r\n */\r\n get image() {\r\n return this.#image;\r\n }\r\n\r\n set image(value) {\r\n if (this.#textureStorage) {\r\n this.#textureStorage._isTextureRecalculated = true;\r\n }\r\n\r\n this.#image = value;\r\n }\r\n\r\n /**\r\n * Current image index\r\n * @type {number}\r\n */\r\n get imageIndex() {\r\n return this.#imageIndex;\r\n }\r\n\r\n set imageIndex(value) {\r\n this.#imageIndex = value;\r\n }\r\n\r\n /**\r\n * Image spacing (for tilesets.spacing > 0)\r\n * @type {number}\r\n */\r\n get spacing() {\r\n return this.#spacing;\r\n }\r\n\r\n /**\r\n * Determines if image is animated or not\r\n * @type {boolean}\r\n */\r\n get hasAnimations() {\r\n return this.#animations.size > 0;\r\n }\r\n\r\n /**\r\n * @type {null | string}\r\n */\r\n get activeAnimation() {\r\n return this.#activeAnimation;\r\n }\r\n\r\n /**\r\n * @deprecated - use .vertices instead \r\n * @type {Array>}\r\n */\r\n get boundaries() {\r\n return this.#vertices;\r\n }\r\n\r\n get vertices() {\r\n return this.#vertices;\r\n }\r\n\r\n get circleBoundaries() {\r\n return this.#circleBoundaries;\r\n }\r\n\r\n /**\r\n * @ignore\r\n */\r\n _processActiveAnimations() {\r\n const activeAnimation = this.#activeAnimation;\r\n if (activeAnimation) {\r\n const animationEvent = this.#animations.get(activeAnimation);\r\n animationEvent.iterateAnimationIndex();\r\n this.#imageIndex = animationEvent.currentSprite;\r\n }\r\n }\r\n /**\r\n * @ignore\r\n */\r\n get _textureStorage() {\r\n return this.#textureStorage;\r\n }\r\n\r\n /**\r\n * @ignore\r\n */\r\n set _textureStorage(texture) {\r\n this.#textureStorage = texture;\r\n }\r\n\r\n /**\r\n * Emit event\r\n * @param {string} eventName \r\n * @param {...any} eventParams \r\n */\r\n emit(eventName, ...eventParams) {\r\n const event = new Event(eventName);\r\n event.data = [...eventParams];\r\n this.#emitter.dispatchEvent(event);\r\n }\r\n\r\n /**\r\n * Subscribe\r\n * @param {string} eventName \r\n * @param {*} listener \r\n * @param {*} options \r\n */\r\n addEventListener(eventName, listener, options) {\r\n this.#emitter.addEventListener(eventName, listener, options);\r\n }\r\n\r\n /**\r\n * Unsubscribe\r\n * @param {string} eventName \r\n * @param {*} listener \r\n * @param {*} options \r\n */\r\n removeEventListener(eventName, listener, options) {\r\n this.#emitter.removeEventListener(eventName, listener, options);\r\n }\r\n\r\n /**\r\n * Adds image animations\r\n * @param { string } eventName -animation name\r\n * @param { Array | Array<{duration:number, id:number}> } animationSpriteIndexes - animation image indexes\r\n * @param { boolean } [isRepeated = false] - animation is cycled or not, cycled animation could be stopped only with stopRepeatedAnimation();\r\n */\r\n addAnimation (eventName, animationSpriteIndexes, isRepeated) {\r\n if (!this.#checkAnimationParams(animationSpriteIndexes)) {\r\n Exception(ERROR_CODES.UNEXPECTED_INPUT_PARAMS, \" animationSpriteIndexes should be Array of indexes, or Array of objects {duration:number, id:number}\");\r\n }\r\n const animationEvent = new AnimationEvent(eventName, animationSpriteIndexes, isRepeated);\r\n this.#animations.set(eventName, animationEvent);\r\n this.addEventListener(eventName, this.#activateAnimation);\r\n }\r\n\r\n #checkAnimationParams (animationSpriteIndexes) {\r\n let isCorrect = true;\r\n animationSpriteIndexes.forEach(element => {\r\n if (typeof element !== \"number\") {\r\n if (typeof element.duration !== \"number\" || typeof element.id !== \"number\") {\r\n isCorrect = false;\r\n }\r\n } \r\n });\r\n return isCorrect;\r\n }\r\n #activateAnimation = (event) => {\r\n const animationName = event.type,\r\n animationEvent = this.#animations.get(animationName);\r\n // only one active animation can exist at a time\r\n if (this.#activeAnimation && this.#activeAnimation !== animationName) {\r\n this.stopRepeatedAnimation(this.#activeAnimation);\r\n }\r\n animationEvent.activateAnimation();\r\n this.#activeAnimation = animationName;\r\n this.#imageIndex = animationEvent.currentSprite;\r\n }; \r\n\r\n /**\r\n *\r\n * @param {string=} eventName - animation name, if not provided - stop current active animation event\r\n */\r\n stopRepeatedAnimation (eventName) {\r\n this.#animations.get(eventName).deactivateAnimation();\r\n this.#activeAnimation = null;\r\n }\r\n\r\n /**\r\n * Removes animations\r\n */\r\n removeAllAnimations() {\r\n for (let [eventName, animationEvent] of this.#animations.entries()) {\r\n this.removeEventListener(eventName, animationEvent.activateAnimation);\r\n animationEvent.deactivateAnimation();\r\n }\r\n this.#animations.clear();\r\n this.#animations = undefined;\r\n }\r\n\r\n destroy() {\r\n this.removeAllAnimations();\r\n super.destroy();\r\n }\r\n}","import { CONST } from \"../constants.js\";\nimport { DrawShapeObject } from \"./DrawShapeObject.js\";\n\n/**\n * Line object to draw.\n * @extends DrawShapeObject\n * @see {@link DrawObjectFactory} should be created with factory method\n */\nexport class DrawLineObject extends DrawShapeObject {\n /**\n * @type {Array>}\n */\n #vertices;\n\n /**\n * @hideconstructor\n */\n constructor(vertices, bgColor) {\n super(CONST.DRAW_TYPE.LINE, vertices[0][0], vertices[0][1], bgColor);\n this.#vertices = vertices;\n }\n\n /**\n * @type {Array>}\n */\n get vertices () {\n return this.#vertices;\n }\n\n set vertices(value) {\n this.#vertices = value;\n }\n}","import { DrawRectObject } from \"./DrawRectObject.js\";\r\nimport { DrawTextObject } from \"./DrawTextObject.js\";\r\nimport { DrawConusObject } from \"./DrawConusObject.js\";\r\nimport { DrawImageObject } from \"./DrawImageObject.js\";\r\nimport { DrawLineObject } from \"./DrawLineObject.js\";\r\nimport { DrawPolygonObject } from \"./DrawPolygonObject.js\";\r\nimport { DrawCircleObject } from \"./DrawCircleObject.js\";\r\nimport { DrawTiledLayer } from \"./DrawTiledLayer.js\";\r\nimport { DrawShapeObject } from \"./DrawShapeObject.js\";\r\nimport { GameStageData } from \"./GameStageData.js\";\r\nimport { Exception } from \"./Exception.js\";\r\nimport { ERROR_CODES } from \"../constants.js\";\r\n\r\n/**\r\n * Creates drawObjects instances.
\r\n * accessible via GameStage.draw
\r\n * Attach images for image objects and tilemaps
\r\n * Adds drawObjects to current GameStage.stageData\r\n * @see {@link GameStage} a part of GameStage\r\n */\r\nexport class DrawObjectFactory {\r\n /**\r\n * @type {AssetsManager}\r\n */\r\n #iLoader;\r\n /**\r\n * @type {GameStageData | null}\r\n */\r\n #currentPageData;\r\n /**\r\n * @hideconstructor \r\n */\r\n constructor(iLoader) {\r\n this.#iLoader = iLoader;\r\n }\r\n\r\n /**\r\n * @returns {GameStageData}\r\n */\r\n get stageData() {\r\n return this.#currentPageData;\r\n }\r\n\r\n /**\r\n * \r\n * @param {*} renderObject \r\n * @returns {Object}\r\n */\r\n #addObjectToPageData(renderObject) {\r\n this.#currentPageData._renderObject = renderObject;\r\n this.#currentPageData._sortRenderObjectsBySortIndex();\r\n return renderObject;\r\n }\r\n /**\r\n * @param {number} x \r\n * @param {number} y \r\n * @param {number} width \r\n * @param {number} height \r\n * @param {string} backgroundColor - rgba(r,g,b,a)\r\n * @returns {DrawRectObject}\r\n */\r\n rect(x, y, width, height, backgroundColor) {\r\n const renderObject = new DrawRectObject(x, y, width, height, backgroundColor);\r\n this.#addObjectToPageData(renderObject);\r\n return renderObject; \r\n }\r\n\r\n /**\r\n * @param {number} x \r\n * @param {number} y \r\n * @param {string} text \r\n * @param {string} font - size fontFamily\r\n * @param {string} color - rgba(r,g,b,a)\r\n * @returns {DrawTextObject}\r\n */\r\n text(x, y, text, font, color) {\r\n const renderObject = new DrawTextObject(x, y, text, font, color);\r\n this.#addObjectToPageData(renderObject);\r\n return renderObject;\r\n }\r\n\r\n /**\r\n * \r\n * @param {number} radius \r\n * @param {string} bgColor - rgba(r,g,b,a)\r\n * @param {number=} angle\r\n * @param {number=} [fade=0] (0 - 1)\r\n * @returns {DrawConusObject}\r\n */\r\n conus(x, y, radius, bgColor, angle, fade = 0) {\r\n const renderObject = new DrawConusObject(x, y, radius, bgColor, angle, fade);\r\n this.#addObjectToPageData(renderObject);\r\n return renderObject;\r\n }\r\n\r\n /**\r\n * \r\n * @param {number} radius \r\n * @param {string} bgColor - rgba(r,g,b,a)\r\n * @returns {DrawCircleObject}\r\n */\r\n circle(x, y, radius, bgColor) {\r\n const renderObject = new DrawCircleObject(x, y, radius, bgColor);\r\n this.#addObjectToPageData(renderObject);\r\n return renderObject;\r\n }\r\n\r\n /**\r\n * @param {number} x \r\n * @param {number} y \r\n * @param {number} width \r\n * @param {number} height \r\n * @param {string} key \r\n * @param {number} [imageIndex = 0]\r\n * @param {Array<{x:Number, y:Number}> | {r:number}=} boundaries - boundaries as polygon, or circle\r\n * @param {number} [spacing = 0] - for tilesets.spacing > 0\r\n * @returns {DrawImageObject}\r\n */\r\n image(x, y, width, height, key, imageIndex = 0, boundaries, spacing = 0) {\r\n const image = this.#iLoader.getImage(key);\r\n\r\n if (!image) {\r\n Exception(ERROR_CODES.CANT_GET_THE_IMAGE, \"iLoader can't get the image with key: \" + key);\r\n }\r\n \r\n const renderObject = new DrawImageObject(x, y, width, height, key, imageIndex, boundaries, image, spacing);\r\n \r\n this.#addObjectToPageData(renderObject);\r\n return renderObject;\r\n }\r\n\r\n /**\r\n * @param {Array} vertices \r\n * @param {string} color - rgba(r,g,b,a)\r\n * @returns {DrawLineObject}\r\n */\r\n line(vertices, color) {\r\n const renderObject = new DrawLineObject(vertices, color);\r\n this.#addObjectToPageData(renderObject);\r\n return renderObject;\r\n }\r\n\r\n /**\r\n * @param {Array<{x:number, y:number}>} vertices - should go in anticlockwise order\r\n * @param {string} bgColor - rgba(r,g,b,a)\r\n * @returns {DrawPolygonObject}\r\n */\r\n polygon(vertices, bgColor) {\r\n const renderObject = new DrawPolygonObject(vertices, bgColor);\r\n this.#addObjectToPageData(renderObject);\r\n return renderObject;\r\n }\r\n\r\n /**\r\n * \r\n * @param {string} layerKey \r\n * @param {string} tileMapKey \r\n * @param {boolean=} setBoundaries \r\n * @param {DrawShapeObject=} shapeMask \r\n * @returns {DrawTiledLayer}\r\n */\r\n tiledLayer(layerKey, tileMapKey, setBoundaries, shapeMask) {\r\n const tilemap = this.#iLoader.getTileMap(tileMapKey),\r\n tilesets = tilemap.tilesets,\r\n tilesetImages = tilesets.map((tileset) => this.#iLoader.getImage(tileset.data.name)),\r\n layerData = tilemap.layers.find((layer) => layer.name === layerKey),\r\n renderObject = new DrawTiledLayer(layerKey, tileMapKey, tilemap, tilesets, tilesetImages, layerData, setBoundaries, shapeMask);\r\n\r\n this.#addObjectToPageData(renderObject);\r\n return renderObject;\r\n }\r\n\r\n /**\r\n * @ignore\r\n * @param {string} methodKey \r\n * @param {Function} createObjectInstance\r\n */\r\n _registerNewObjectMethod = (methodKey, createObjectInstance) => {\r\n this[methodKey] = (...args) => this.#createObjectAndAddToPageData(createObjectInstance, ...args);\r\n };\r\n\r\n /**\r\n * @ignore\r\n * @param {Function} createInstance\r\n * @param {Array} args\r\n */\r\n #createObjectAndAddToPageData = (createInstance, ...args) => {\r\n const instance = createInstance(...args);\r\n this.#addObjectToPageData(instance);\r\n return instance;\r\n };\r\n\r\n /**\r\n * @ignore\r\n * @param {GameStageData} pageData;\r\n */\r\n _attachPageData = (pageData) => {\r\n this.#currentPageData = pageData;\r\n };\r\n /**\r\n * @ignore\r\n */\r\n _detachPageData = () => {\r\n this.#currentPageData = null;\r\n };\r\n}","import { CONST } from \"../constants.js\";\nimport { DrawShapeObject } from \"./DrawShapeObject.js\";\n\n/**\n * @extends DrawShapeObject\n * @see {@link DrawObjectFactory} should be created with factory method\n */\nexport class DrawPolygonObject extends DrawShapeObject {\n /**\n * @type {Array>}\n */\n #vertices;\n\n /**\n * @hideconstructor\n */\n constructor(vertices, bgColor) {\n super(CONST.DRAW_TYPE.POLYGON, vertices[0].x, vertices[0].y, bgColor);\n this.#vertices = this._convertVerticesArray(vertices);\n }\n\n /**\n * @type {Array>}\n */\n get vertices () {\n return this.#vertices;\n }\n\n set vertices(value) {\n this.#vertices = value;\n }\n}","import { CONST } from \"../constants.js\";\nimport { DrawShapeObject } from \"./DrawShapeObject.js\";\n\n/**\n * @extends DrawShapeObject\n * @see {@link DrawObjectFactory} should be created with factory method\n */\nexport class DrawRectObject extends DrawShapeObject {\n /**\n * @type {number}\n */\n #w;\n /**\n * @type {number}\n */\n #h;\n /**\n * @type {Array>}\n */\n #vertices;\n\n /**\n * @hideconstructor\n */\n constructor(x, y, w, h, bgColor) {\n super(CONST.DRAW_TYPE.RECTANGLE, x, y, bgColor);\n this.#w = w;\n this.#h = h;\n this.#vertices = this._calculateRectVertices(w,h);\n }\n\n /**\n * @type {Array>}\n */\n get vertices () {\n return this.#vertices;\n }\n /**\n * @type {number}\n */\n get width() {\n return this.#w;\n }\n\n /**\n * @type {number}\n */\n get height() {\n return this.#h;\n }\n\n set width(w) {\n this.#w = w;\n }\n\n set height(h) {\n this.#h = h;\n }\n}","import { CONST } from \"../constants.js\";\nimport { utils } from \"../index.js\";\n\n/**\n * A base draw object.\n */\nexport class DrawShapeObject {\n #x;\n #y;\n #bg;\n /**\n * @type {string}\n * @enum {CONST.DRAW_TYPE}\n */\n #type;\n /**\n * Is used for blending pixel arithmetic\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/blendFunc.\n * @type {Array}\n */\n #blendFunc;\n \n /**\n * @type {number}\n */\n #sortIndex = 0;\n /**\n * @type {number}\n */\n #rotation = 0;\n /**\n * @type {number}\n */\n #id = utils.generateUniqId();\n /**\n * @type {boolean}\n */\n #isRemoved = false;\n /**\n * @type {undefined | number | null}\n */\n #attachedMaskId;\n /**\n * @type {boolean}\n */\n #isMask;\n /**\n * @type {boolean}\n */\n #isOffsetTurnedOff = false;\n\n /**\n * @type {boolean}\n */\n #isChanged = false;\n /**\n * @hideconstructor\n */\n constructor(type, mapX, mapY, bgColor) {\n this.#x = mapX;\n this.#y = mapY;\n this.#bg = bgColor;\n this.#type = type;\n }\n\n /**\n * Background color as rgba(r,g,b,a).\n * @type {string}\n */\n get bgColor() {\n return this.#bg;\n }\n\n set bgColor(value) {\n this.#bg = value;\n }\n\n /**\n * @type {string}\n * @enum {CONST.DRAW_TYPE}\n */\n get type() {\n return this.#type;\n }\n\n /**\n * @type {number}\n */\n get x() {\n return this.#x;\n }\n\n /**\n * @type {number}\n */\n get y () {\n return this.#y;\n }\n\n set x(posX) {\n this.#x = posX;\n }\n\n set y(posY) {\n this.#y = posY;\n }\n\n /**\n * @type {number}\n */\n get sortIndex () {\n return this.#sortIndex;\n }\n\n set sortIndex(value) {\n this.#sortIndex = value;\n }\n\n get blendFunc () {\n return this.#blendFunc;\n }\n\n set blendFunc(value) {\n this.#blendFunc = value;\n }\n\n /**\n * @type {number}\n */\n get rotation() {\n return this.#rotation;\n }\n\n set rotation(value) {\n this.#rotation = value;\n }\n\n /**\n * @type {number}\n */\n get id() {\n return this.#id;\n }\n\n /**\n * @type {boolean}\n */\n get isRemoved() {\n return this.#isRemoved;\n }\n /**\n * Destroy object on next render iteration.\n */\n destroy() {\n this.#isRemoved = true;\n }\n\n get isMaskAttached() {\n return !!this.#attachedMaskId;\n }\n\n /**\n * @ignore\n */\n get _maskId() {\n return this.#attachedMaskId;\n }\n\n /**\n * \n * @param {DrawShapeObject} mask \n */\n setMask(mask) {\n mask._isMask = true;\n this.#attachedMaskId = mask.id;\n }\n\n removeMask() {\n this.#attachedMaskId = null;\n }\n\n set _isMask(isSet) {\n this.#isMask = isSet;\n }\n\n get _isMask() {\n return this.#isMask;\n }\n\n get isOffsetTurnedOff() {\n return this.#isOffsetTurnedOff;\n }\n\n /**\n * turn off offset for specific draw object\n * gameStageData.centerCameraPosition() will take no effect on such object\n * Can be used for something that should be always on screen: control buttons, overlay masks etc.\n */\n turnOffOffset() {\n this.#isOffsetTurnedOff = true;\n }\n /**\n * @ignore\n * @param {number} width \n * @param {number} height \n * @returns {Array>}\n */\n _calculateRectVertices = (width, height) => {\n const halfW = width/2,\n halfH = height/2;\n return [[-halfW, -halfH], [halfW, -halfH], [halfW, halfH], [-halfW, halfH]];\n };\n\n /**\n * @param {number} radius \n * @param {number} [angle = 2 * Math.PI]\n * @param {number} [step = Math.PI/12] \n * @returns {Array}\n * @ignore\n */\n _interpolateConus(radius, angle = 2*Math.PI, step = Math.PI/14) {\n let conusPolygonCoords = [0, 0];\n\n for (let r = 0; r <= angle; r += step) {\n let x2 = Math.cos(r) * radius,\n y2 = Math.sin(r) * radius;\n\n conusPolygonCoords.push(x2, y2);\n }\n\n return conusPolygonCoords;\n }\n\n /**\n * @param {number} radius \n * @param {number} [angle = 2 * Math.PI]\n * @param {number} [step = Math.PI/12] \n * @returns {Array>}\n * @ignore\n */\n _calculateConusBoundaries(radius, angle = 2*Math.PI, step = Math.PI/14) {\n let conusPolygonCoords = [];\n\n for (let r = 0; r <= angle; r += step) {\n let x2 = Math.cos(r) * radius,\n y2 = Math.sin(r) * radius;\n\n conusPolygonCoords.push([x2, y2]);\n }\n\n return conusPolygonCoords;\n }\n\n\n /**\n * @param {Array> | Array<{x:number, y:number}>} boundaries\n * @returns {Array>}\n * @ignore\n */\n _convertVerticesArray(boundaries) {\n if (typeof boundaries[0].x !== \"undefined\" && typeof boundaries[0].y !== \"undefined\") {\n return utils.verticesArrayToArrayNumbers(boundaries);\n } else {\n return boundaries;\n }\n }\n}","import { DrawShapeObject } from \"./DrawShapeObject.js\";\nimport { Rectangle } from \"./Primitives.js\";\nimport { CONST, ERROR_CODES } from \"../constants.js\";\nimport { Exception } from \"./Exception.js\";\nimport { TextureStorage } from \"./WebGl/TextureStorage.js\";\n\n/**\n * @extends DrawShapeObject\n * @see {@link DrawObjectFactory} should be created with factory method\n */\nexport class DrawTextObject extends DrawShapeObject {\n #font;\n #textAlign;\n #textBaseline;\n #fillStyle;\n #strokeStyle;\n #text;\n #textMetrics;\n /**\n * @type {HTMLCanvasElement}\n */\n #textureCanvas = document.createElement(\"canvas\");\n\n /**\n * @type {TextureStorage}\n */\n #textureStorage;\n\n /**\n * @hideconstructor\n */\n constructor(mapX, mapY, text, font, fillStyle) {\n super(CONST.DRAW_TYPE.TEXT, mapX, mapY);\n this.#text = text;\n this.#font = font;\n this.#fillStyle = fillStyle;\n this.#textMetrics;\n this.#calculateCanvasTextureAndMeasurements();\n }\n\n /**\n * Rectangle text box.\n * @type {Rectangle}\n */\n get boundariesBox() {\n const width = this.textMetrics ? Math.floor(this.textMetrics.width) : 300,\n height = this.textMetrics ? Math.floor(this.textMetrics.fontBoundingBoxAscent + this.textMetrics.fontBoundingBoxDescent): 30;\n return new Rectangle(this.x, this.y - height, width, height);\n }\n\n get vertices() {\n const bb = this.boundariesBox;\n return this._calculateRectVertices(bb.width, bb.height);\n }\n\n /**\n * @type {string}\n */\n get text() {\n return this.#text;\n }\n\n set text(value) {\n if (value !== this.#text) {\n this.#text = value;\n this.#calculateCanvasTextureAndMeasurements();\n }\n }\n\n /**\n * @type {string}\n */\n get font() {\n return this.#font;\n }\n\n set font(value) {\n if (value !== this.#font) {\n this.#font = value;\n this.#calculateCanvasTextureAndMeasurements();\n }\n }\n\n /**\n * @type {string}\n */\n get textAlign() {\n return this.#textAlign;\n }\n\n set textAlign(value) {\n if (value !== this.#textAlign) {\n this.#textAlign = value;\n this.#calculateCanvasTextureAndMeasurements();\n }\n }\n\n /**\n * @type {string}\n */\n get textBaseline() {\n return this.#textBaseline;\n }\n\n set textBaseline(value) {\n if (value !== this.#textBaseline) {\n this.#textBaseline = value;\n this.#calculateCanvasTextureAndMeasurements();\n }\n }\n\n /**\n * font color\n * @type {string}\n */\n get fillStyle() {\n return this.#fillStyle;\n }\n\n /**\n * font color\n */\n set fillStyle(value) {\n if (value !== this.#fillStyle) {\n this.#fillStyle = value;\n this.#calculateCanvasTextureAndMeasurements();\n }\n }\n\n /**\n * font stroke color\n * @type {string}\n */\n get strokeStyle() {\n return this.#strokeStyle;\n }\n\n /**\n * font stroke color\n */\n set strokeStyle(value) {\n if (value !== this.#strokeStyle) {\n this.#strokeStyle = value;\n this.#calculateCanvasTextureAndMeasurements();\n }\n }\n\n /**\n * @type {TextMetrics}\n */\n get textMetrics() {\n return this.#textMetrics;\n }\n\n /**\n * @ignore\n */\n set _textMetrics(value) {\n this.#textMetrics = value;\n }\n\n /**\n * @ignore\n */\n get _textureStorage() {\n return this.#textureStorage;\n }\n\n /**\n * @ignore\n */\n set _textureStorage(texture) {\n this.#textureStorage = texture;\n }\n\n /**\n * @ignore\n */\n get _textureCanvas() {\n return this.#textureCanvas;\n }\n\n /**\n * \n * @returns {void}\n */\n #calculateCanvasTextureAndMeasurements() {\n const ctx = this.#textureCanvas.getContext(\"2d\", { willReadFrequently: true }); // cpu counting instead gpu\n if (ctx) {\n //ctx.clearRect(0, 0, this.#textureCanvas.width, this.#textureCanvas.height);\n ctx.font = this.font;\n this._textMetrics = ctx.measureText(this.text);\n const boxWidth = this.boundariesBox.width, \n boxHeight = this.boundariesBox.height;\n \n ctx.canvas.width = boxWidth;\n ctx.canvas.height = boxHeight;\n // after canvas resize, have to cleanup and set the font again\n ctx.clearRect(0, 0, boxWidth, boxHeight);\n ctx.font = this.font;\n ctx.textBaseline = \"bottom\";// bottom\n if (this.fillStyle) {\n ctx.fillStyle = this.fillStyle;\n ctx.fillText(this.text, 0, boxHeight);\n } \n if (this.strokeStyle) {\n ctx.strokeStyle = this.strokeStyle;\n ctx.strokeText(this.text, 0, boxHeight);\n }\n \n if (this.#textureStorage) {\n this.#textureStorage._isTextureRecalculated = true;\n }\n\n // debug canvas\n // this.#textureCanvas.style.position = \"absolute\";\n // document.body.appendChild(this.#textureCanvas);\n \n } else {\n Exception(ERROR_CODES.UNHANDLED_EXCEPTION, \"can't getContext('2d')\");\n }\n }\n}","import { AnimationEvent } from \"./AnimationEvent.js\";\r\nimport { DrawShapeObject } from \"./DrawShapeObject.js\";\r\nimport { TextureStorage } from \"./WebGl/TextureStorage.js\";\r\n/**\r\n * A render object represents a layer from tiled editor\r\n * @see {@link DrawObjectFactory} should be created with factory method\r\n */\r\nexport class DrawTiledLayer {\r\n #layerKey;\r\n #tileMapKey;\r\n #tilemap;\r\n #tilesets;\r\n /**\r\n * @type {string}\r\n */\r\n #DELIMITER = \"-#-\";\r\n #tilesetImages;\r\n /**\r\n * @type {Array}\r\n */\r\n #textureStorages;\r\n #layerData;\r\n #setBoundaries;\r\n #drawBoundaries;\r\n #attachedMaskId;\r\n /**\r\n * @type {number}\r\n */\r\n #sortIndex = 0;\r\n /**\r\n * @type {Map}\r\n */\r\n #animations = new Map();\r\n #isOffsetTurnedOff;\r\n\r\n /**\r\n * @hideconstructor\r\n */\r\n constructor(layerKey, tileMapKey, tilemap, tilesets, tilesetImages, layerData, setBoundaries = false, shapeMask) {\r\n this.#layerKey = layerKey;\r\n this.#tileMapKey = tileMapKey;\r\n this.#tilemap = tilemap;\r\n this.#tilesets = tilesets;\r\n this.#textureStorages = [];\r\n this.#tilesetImages = tilesetImages;\r\n this.#layerData = layerData;\r\n this.#setBoundaries = setBoundaries;\r\n this.#drawBoundaries = setBoundaries ? setBoundaries : false;\r\n if (shapeMask) {\r\n this.setMask(shapeMask);\r\n }\r\n this.#processTilesets(tilesets);\r\n }\r\n\r\n /**\r\n * A layer name.\r\n * @type {string}\r\n */\r\n get layerKey() {\r\n return this.#layerKey;\r\n }\r\n\r\n /**\r\n * A tilemap layer key, should match key from the tilemap.\r\n * @type {string}\r\n */\r\n get tileMapKey() {\r\n return this.#tileMapKey;\r\n }\r\n\r\n get tilemap() {\r\n return this.#tilemap;\r\n }\r\n \r\n get tilesets() {\r\n return this.#tilesets;\r\n }\r\n\r\n get tilesetImages() {\r\n return this.#tilesetImages;\r\n }\r\n\r\n get layerData() {\r\n return this.#layerData;\r\n }\r\n /**\r\n * Should the layer borders used as boundaries, or not\r\n * Can be set in GameStage.addRenderLayer() method.\r\n * @type {boolean}\r\n */\r\n get setBoundaries() {\r\n return this.#setBoundaries;\r\n }\r\n\r\n /**\r\n * Should draw a boundaries helper, or not\r\n * Can be set in SystemSettings.\r\n * @type {boolean}\r\n */\r\n get drawBoundaries() {\r\n return this.#drawBoundaries;\r\n }\r\n\r\n set drawBoundaries(value) {\r\n this.#drawBoundaries = value;\r\n }\r\n\r\n /**\r\n * @ignore\r\n */\r\n get _maskId() {\r\n return this.#attachedMaskId;\r\n }\r\n /**\r\n * \r\n * @param {DrawShapeObject} mask \r\n */\r\n setMask(mask) {\r\n mask._isMask = true;\r\n this.#attachedMaskId = mask.id;\r\n }\r\n\r\n removeMask() {\r\n this.#attachedMaskId = null;\r\n }\r\n\r\n /**\r\n * @type {number}\r\n */\r\n get sortIndex () {\r\n return this.#sortIndex;\r\n }\r\n\r\n set sortIndex(value) {\r\n this.#sortIndex = value;\r\n }\r\n\r\n get isOffsetTurnedOff() {\r\n return this.#isOffsetTurnedOff;\r\n }\r\n turnOffOffset() {\r\n this.#isOffsetTurnedOff = true;\r\n }\r\n\r\n /**\r\n * Determines if image is animated or not\r\n * @type {boolean}\r\n */\r\n get hasAnimations() {\r\n return this.#animations.size > 0;\r\n }\r\n\r\n /**\r\n * @ignore\r\n */\r\n get _textureStorages() {\r\n return this.#textureStorages;\r\n }\r\n\r\n /**\r\n * @ignore\r\n */\r\n _setTextureStorage(index, value) {\r\n this.#textureStorages[index] = value;\r\n }\r\n\r\n /**\r\n * Tilesets has a property tiles, which could contain tile animations\r\n * or object boundaries, this is workaround for split this and add\r\n * additional properties for use in draw phase:\r\n * _hasAnimations\r\n * _animations - Map\r\n * _hasBoundaries\r\n * _boundaries - Map\r\n * @param {*} tilesets\r\n */\r\n #processTilesets(tilesets) {\r\n for (let tileset of tilesets) {\r\n const tiles = tileset.data.tiles,\r\n name = tileset.data.name;\r\n if (tiles) {\r\n for (let tile of tiles) {\r\n const animation = tile.animation,\r\n objectgroup = tile.objectgroup,\r\n id = tile.id;\r\n if (animation) {\r\n const eventName = name + this.#DELIMITER + id, \r\n animationIndexes = this.#fixAnimationsItems(animation),\r\n animationEvent = new AnimationEvent(eventName, animationIndexes, true);\r\n\r\n this.#animations.set(eventName, animationEvent);\r\n // add additional properties\r\n if (!tileset.data._hasAnimations) {\r\n tileset.data._hasAnimations = true;\r\n tileset.data._animations = new Map();\r\n //\r\n tileset.data._animations.set(id, animationIndexes[0][0]);\r\n }\r\n this.#activateAnimation(animationEvent);\r\n }\r\n if (objectgroup) {\r\n if (tileset.data._hasBoundaries) {\r\n tileset.data._boundaries.set(id, objectgroup);\r\n } else {\r\n // add additional properties\r\n tileset.data._hasBoundaries = true;\r\n tileset.data._boundaries = new Map();\r\n tileset.data._boundaries.set(id, objectgroup);\r\n }\r\n \r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * \r\n * @param {Array<{duration:number, tileid:number}>} animation \r\n * @returns {Array<{duration:number, id:number}>}\r\n */\r\n #fixAnimationsItems(animation) {\r\n return animation.map((animation_item) => ({duration:animation_item.duration, id: animation_item.tileid}));\r\n }\r\n /**\r\n * @ignore\r\n */\r\n _processActiveAnimations() {\r\n for (let animationEvent of this.#animations.values()) {\r\n if (animationEvent.isActive) {\r\n animationEvent.iterateAnimationIndex();\r\n this.#switchCurrentActiveSprite(animationEvent);\r\n }\r\n }\r\n }\r\n\r\n #activateAnimation = (animationEvent) => {\r\n animationEvent.activateAnimation();\r\n this.#switchCurrentActiveSprite(animationEvent);\r\n }; \r\n\r\n #switchCurrentActiveSprite = (animationEvent) => {\r\n const [tilesetKey, animationId] = animationEvent.name.split(this.#DELIMITER),\r\n tilesetIndex = this.#tilesets.findIndex(tileset => tileset.data.name === tilesetKey),\r\n tileset = this.#tilesets[tilesetIndex];\r\n \r\n tileset.data._animations.set(parseInt(animationId), animationEvent.currentSprite);\r\n };\r\n\r\n /**\r\n *\r\n * @param {string} eventName - animation name\r\n */\r\n stopRepeatedAnimation (eventName) {\r\n this.#animations.get(eventName).deactivateAnimation();\r\n }\r\n\r\n /**\r\n * Removes animations\r\n */\r\n removeAllAnimations() {\r\n for (let [eventName, animationEvent] of this.#animations.entries()) {\r\n this.removeEventListener(eventName, animationEvent.activateAnimation);\r\n animationEvent.deactivateAnimation();\r\n }\r\n this.#animations.clear();\r\n this.#animations = undefined;\r\n }\r\n\r\n destroy() {\r\n this.removeAllAnimations();\r\n super.destroy();\r\n }\r\n}\r\n","import { CONST, ERROR_CODES } from \"../../constants.js\";\nimport { Exception } from \"../Exception.js\";\n\nexport class SystemEvent extends Event {\n #data;\n constructor(eventValue, data){\n super(eventValue);\n if (!this.#isEventExist(eventValue)) {\n Exception(ERROR_CODES.UNEXPECTED_EVENT_NAME, \", Please check if event is exist\");\n }\n this.#data = data;\n }\n\n #isEventExist(eventValue) {\n return Object.values(CONST.EVENTS.WEBSOCKET.SERVER_CLIENT).find(eventVal => eventVal === eventValue);\n }\n\n get data () {\n return this.#data;\n }\n}","export function Exception (code, message) {\n throw new Error(code + \": \" + message);\n}\n\nexport function Warning (code, message) {\n console.warn(code, message);\n}","import { CONST, ERROR_CODES, WARNING_CODES } from \"../constants.js\";\r\nimport { GameStageData } from \"./GameStageData.js\";\r\nimport { Exception, Warning } from \"./Exception.js\";\r\nimport AssetsManager from \"../../modules/assetsm/dist/assetsm.min.js\";\r\nimport { DrawObjectFactory } from \"./DrawObjectFactory.js\";\r\nimport { DrawCircleObject } from \"./DrawCircleObject.js\";\r\nimport { DrawConusObject } from \"./DrawConusObject.js\";\r\nimport { DrawImageObject } from \"./DrawImageObject.js\";\r\nimport { DrawLineObject } from \"./DrawLineObject.js\";\r\nimport { DrawPolygonObject } from \"./DrawPolygonObject.js\";\r\nimport { DrawRectObject } from \"./DrawRectObject.js\";\r\nimport { DrawTextObject } from \"./DrawTextObject.js\";\r\nimport { ISystem } from \"./ISystem.js\";\r\nimport { ISystemAudio } from \"./ISystemAudio.js\";\r\nimport { SystemSettings } from \"../configs.js\";\r\nimport { isPointLineIntersect, isEllipseCircleIntersect, isPointCircleIntersect, isEllipsePolygonIntersect, isPolygonLineIntersect, isPointPolygonIntersect, angle_2points, isCircleLineIntersect } from \"../utils.js\";\r\nimport { Vector } from \"./Primitives.js\";\r\n\r\n/**\r\n * Represents the stage of the game,
\r\n * Contains pages logic.
\r\n * Instances should be created and registered with System.registerStage() factory method\r\n * \r\n * @see {@link System} instances of this class holds by the System class\r\n * @hideconstructor\r\n */\r\nexport class GameStage {\r\n /**\r\n * @type {string}\r\n */\r\n #name;\r\n /**\r\n * @type {boolean}\r\n */\r\n #isInitiated = false;\r\n /**\r\n * @type {boolean}\r\n */\r\n #isActive;\r\n /**\r\n * @typedef {ISystem}\r\n */\r\n #iSystemReference;\r\n /**\r\n * @type {GameStageData}\r\n */\r\n #stageData;\r\n\r\n constructor() {\r\n this.#isActive = false;\r\n this.#stageData = new GameStageData();\r\n }\r\n\r\n /**\r\n * Register stage\r\n * @param {string} name\r\n * @param {ISystem} system \r\n * @ignore\r\n */\r\n _register(name, system) {\r\n this.#name = name;\r\n this.#iSystemReference = system;\r\n this.#setWorldDimensions();\r\n this.#setCanvasSize();\r\n this.register();\r\n }\r\n\r\n /**\r\n * Initialization stage\r\n * @ignore\r\n */\r\n _init() {\r\n this.init();\r\n this.#isInitiated = true;\r\n }\r\n\r\n /**\r\n * @tutorial stages_lifecycle\r\n * Custom logic for register stage\r\n */\r\n register() {}\r\n /**\r\n * @tutorial stages_lifecycle\r\n * Custom logic for init stage\r\n */\r\n init() {}\r\n /**\r\n * Custom logic for start stage\r\n * @param {Object=} options\r\n */\r\n start(options) {}\r\n /**\r\n * @tutorial stages_lifecycle\r\n * Custom logic for stop stage\r\n */\r\n stop() {}\r\n /**\r\n * Custom logic for resize stage\r\n */\r\n resize() {}\r\n\r\n /**\r\n * @tutorial assets_manager\r\n * @type {AssetsManager}\r\n */\r\n get iLoader() {\r\n return this.#iSystemReference.iLoader;\r\n }\r\n\r\n /**\r\n * @type {DrawObjectFactory}\r\n */\r\n get draw() {\r\n return this.#iSystemReference.drawObjectFactory;\r\n }\r\n\r\n /**\r\n * Attach all canvas elements from the #views to container\r\n * @param {HTMLElement} container\r\n * @ignore\r\n */\r\n _attachCanvasToContainer(container) {\r\n this.#attachElementToContainer(this.canvasHtmlElement, container);\r\n }\r\n\r\n /**\r\n * Add render object to the stageData\r\n * @param { DrawConusObject | DrawImageObject | \r\n * DrawLineObject | DrawPolygonObject | \r\n * DrawRectObject | DrawCircleObject | \r\n * DrawTextObject } renderObject \r\n */\r\n addRenderObject = (renderObject) => {\r\n const data = this.stageData,\r\n isDataAlreadyAdded = data.renderObjects.indexOf(renderObject) !== -1;\r\n if (isDataAlreadyAdded) {\r\n Warning(WARNING_CODES.NEW_BEHAVIOR_INTRODUCED, \"stage.draw methods add objects to pageData, no need to call addRenderObject\");\r\n } else {\r\n data._renderObject = renderObject;\r\n data._sortRenderObjectsBySortIndex(); \r\n }\r\n };\r\n\r\n /**\r\n * Determines if this stage render is Active or not\r\n * @type {boolean}\r\n */\r\n get isActive() {\r\n return this.#isActive;\r\n }\r\n\r\n /**\r\n * Determines if this stage is initialized or not\r\n * @type {boolean}\r\n */\r\n get isInitiated() {\r\n return this.#isInitiated;\r\n }\r\n\r\n /**\r\n * Current stage name\r\n * @type {string}\r\n */\r\n get name () {\r\n return this.#name;\r\n }\r\n\r\n /**\r\n * @type {GameStageData}\r\n */\r\n get stageData() {\r\n return this.#stageData;\r\n }\r\n\r\n /**\r\n * @type {SystemSettings}\r\n */\r\n get systemSettings() {\r\n return this.#iSystemReference.systemSettings;\r\n }\r\n\r\n /**\r\n * @type {ISystemAudio}\r\n */\r\n get audio() {\r\n return this.#iSystemReference.audio;\r\n }\r\n\r\n /**\r\n * @type {ISystem}\r\n */\r\n get iSystem() {\r\n return this.#iSystemReference;\r\n }\r\n\r\n get canvasHtmlElement() {\r\n return document.getElementsByTagName(\"canvas\")[0];\r\n }\r\n\r\n /**\r\n * \r\n * @param {string} eventName \r\n * @param {*} listener \r\n * @param {*=} options \r\n */\r\n addEventListener = (eventName, listener, options) => {\r\n this.iSystem.addEventListener(eventName, listener, options);\r\n };\r\n\r\n /**\r\n * \r\n * @param {string} eventName \r\n * @param {*} listener \r\n * @param {*=} options \r\n */\r\n removeEventListener = (eventName, listener, options) => {\r\n this.iSystem.removeEventListener(eventName, listener, options);\r\n };\r\n\r\n /**\r\n * Start stage render\r\n * @param {Object=} options \r\n * @ignore\r\n */\r\n _start(options) {\r\n this.start(options);\r\n this.#isActive = true;\r\n window.addEventListener(\"resize\", this._resize);\r\n this._resize();\r\n }\r\n\r\n /**\r\n * Stop stage render\r\n * @ignore\r\n */\r\n _stop() {\r\n this.#isActive = false;\r\n window.removeEventListener(\"resize\", this._resize);\r\n this.stop();\r\n }\r\n\r\n /**\r\n * Resize event\r\n * @ignore\r\n */\r\n _resize = () => {\r\n this.#setCanvasSize();\r\n this.resize();\r\n };\r\n\r\n /**\r\n * \r\n * @param {HTMLCanvasElement} htmlElement \r\n * @param {HTMLElement} container \r\n */\r\n #attachElementToContainer(htmlElement, container) {\r\n container.appendChild(htmlElement);\r\n }\r\n\r\n #setWorldDimensions() {\r\n const width = this.systemSettings.worldSize ? this.systemSettings.worldSize.width : 0,\r\n height = this.systemSettings.worldSize ? this.systemSettings.worldSize.height : 0;\r\n \r\n this.stageData._setWorldDimensions(width, height);\r\n }\r\n\r\n //////////////////////////////////////////////////////\r\n //***************************************************/\r\n //****************** Collisions ********************//\r\n //**************************************************//\r\n //////////////////////////////////////////////////////\r\n\r\n /**\r\n * \r\n * @param {number} x \r\n * @param {number} y \r\n * @param {DrawImageObject} drawObject \r\n * @returns {{x:number, y:number, p:number} | boolean}\r\n */\r\n isBoundariesCollision = (x, y, drawObject) => {\r\n const drawObjectType = drawObject.type,\r\n vertices = drawObject.vertices,\r\n circleBoundaries = drawObject.circleBoundaries;\r\n switch(drawObjectType) {\r\n case CONST.DRAW_TYPE.TEXT:\r\n case CONST.DRAW_TYPE.RECTANGLE:\r\n case CONST.DRAW_TYPE.CONUS:\r\n case CONST.DRAW_TYPE.IMAGE:\r\n if (!circleBoundaries) {\r\n return this.#isPolygonToBoundariesCollision(x, y, vertices, drawObject.rotation);\r\n } else {\r\n return this.#isCircleToBoundariesCollision(x, y, drawObject.circleBoundaries.r);\r\n }\r\n case CONST.DRAW_TYPE.CIRCLE:\r\n Warning(CONST.WARNING_CODES.METHOD_NOT_IMPLEMENTED, \"isObjectCollision.circle check is not implemented yet!\");\r\n break;\r\n case CONST.DRAW_TYPE.LINE:\r\n Warning(CONST.WARNING_CODES.METHOD_NOT_IMPLEMENTED, \"isObjectCollision.line check is not implemented yet, please use .rect instead line!\");\r\n break;\r\n default:\r\n Warning(CONST.WARNING_CODES.UNKNOWN_DRAW_OBJECT, \"unknown object type!\");\r\n }\r\n return false;\r\n };\r\n\r\n /**\r\n * \r\n * @param {number} x \r\n * @param {number} y \r\n * @param {DrawImageObject} drawObject\r\n * @param {Array} objects - objects array to check\r\n * @returns {{x:number, y:number, p:number} | boolean} - the closest collision\r\n */\r\n isObjectsCollision = (x, y, drawObject, objects) => {\r\n const drawObjectType = drawObject.type,\r\n drawObjectBoundaries = drawObject.vertices,\r\n circleBoundaries = drawObject.circleBoundaries;\r\n switch(drawObjectType) {\r\n case CONST.DRAW_TYPE.TEXT:\r\n case CONST.DRAW_TYPE.RECTANGLE:\r\n case CONST.DRAW_TYPE.CONUS:\r\n case CONST.DRAW_TYPE.IMAGE:\r\n if (!circleBoundaries) {\r\n return this.#isPolygonToObjectsCollision(x, y, drawObjectBoundaries, drawObject.rotation, objects);\r\n } else {\r\n return this.#isCircleToObjectsCollision(x, y, circleBoundaries, objects);\r\n }\r\n case CONST.DRAW_TYPE.CIRCLE:\r\n Warning(CONST.WARNING_CODES.METHOD_NOT_IMPLEMENTED, \"isObjectCollision.circle check is not implemented yet!\");\r\n break;\r\n case CONST.DRAW_TYPE.LINE:\r\n Warning(CONST.WARNING_CODES.METHOD_NOT_IMPLEMENTED, \"isObjectCollision.line check is not implemented yet, please use .rect instead line!\");\r\n break;\r\n default:\r\n Warning(CONST.WARNING_CODES.UNKNOWN_DRAW_OBJECT, \"unknown object type!\");\r\n }\r\n return false;\r\n };\r\n #isPolygonToObjectsCollision(x, y, polygonVertices, polygonRotation, objects) {\r\n const len = objects.length;\r\n\r\n let collisions = [];\r\n for (let i = 0; i < len; i++) {\r\n const mapObject = objects[i],\r\n drawMapObjectType = mapObject.type;\r\n\r\n let coll;\r\n \r\n switch(drawMapObjectType) {\r\n case CONST.DRAW_TYPE.TEXT:\r\n case CONST.DRAW_TYPE.RECTANGLE:\r\n case CONST.DRAW_TYPE.CONUS:\r\n case CONST.DRAW_TYPE.IMAGE:\r\n coll = this.#isPolygonToPolygonCollision(x, y, polygonVertices, polygonRotation, mapObject);\r\n break;\r\n case CONST.DRAW_TYPE.CIRCLE:\r\n console.warn(\"isObjectCollision.circle check is not implemented yet!\");\r\n break;\r\n case CONST.DRAW_TYPE.LINE:\r\n console.warn(\"isObjectCollision.line check is not implemented, please use rect instead\");\r\n break;\r\n default:\r\n console.warn(\"unknown object type!\");\r\n }\r\n if (coll) {\r\n collisions.push(coll);\r\n }\r\n }\r\n if (collisions.length > 0) {\r\n return this.#takeTheClosestCollision(collisions);\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n #isCircleToObjectsCollision(x, y, drawObjectBoundaries, objects) {\r\n const radius = drawObjectBoundaries.r;\r\n\r\n const len = objects.length;\r\n\r\n let collisions = [];\r\n for (let i = 0; i < len; i++) {\r\n const mapObject = objects[i],\r\n drawMapObjectType = mapObject.type,\r\n circleBoundaries = mapObject.circleBoundaries;\r\n\r\n let coll;\r\n \r\n switch(drawMapObjectType) {\r\n case CONST.DRAW_TYPE.TEXT:\r\n case CONST.DRAW_TYPE.RECTANGLE:\r\n case CONST.DRAW_TYPE.CONUS:\r\n case CONST.DRAW_TYPE.IMAGE:\r\n if (!circleBoundaries) {\r\n coll = this.#isCircleToPolygonCollision(x, y, radius, mapObject);\r\n } else {\r\n coll = this.#isCircleToCircleCollision(x, y, radius, mapObject.x, mapObject.y, circleBoundaries.r);\r\n }\r\n break;\r\n case CONST.DRAW_TYPE.CIRCLE:\r\n console.warn(\"isObjectCollision.circle check is not implemented yet!\");\r\n break;\r\n case CONST.DRAW_TYPE.LINE:\r\n console.warn(\"isObjectCollision.line check is not implemented, please use rect instead\");\r\n break;\r\n default:\r\n console.warn(\"unknown object type!\");\r\n }\r\n if (coll) {\r\n collisions.push(coll);\r\n }\r\n }\r\n if (collisions.length > 0) {\r\n return this.#takeTheClosestCollision(collisions);\r\n } else {\r\n return null;\r\n }\r\n }\r\n \r\n #takeTheClosestCollision(collisions) {\r\n return collisions.sort((a,b) => a.p < b.p)[0];\r\n }\r\n\r\n #isCircleToPolygonCollision(x, y, radius, mapObject) {\r\n const [mapOffsetX, mapOffsetY] = this.stageData.worldOffset,\r\n xWithOffset = x - mapOffsetX,\r\n yWithOffset = y - mapOffsetY,\r\n mapObjXWithOffset = mapObject.x - mapOffsetX,\r\n mapObjYWithOffset = mapObject.y - mapOffsetY,\r\n mapObjVertices = mapObject.vertices, \r\n mapObjRotation = mapObject.rotation,\r\n len = mapObjVertices.length;\r\n //console.log(\"map object check:\");\r\n //console.log(mapObject);\r\n for (let i = 0; i < len; i+=1) {\r\n const mapObjFirstVertex = mapObjVertices[i];\r\n let mapObjNextVertex = mapObjVertices[i + 1];\r\n if (!mapObjNextVertex) {\r\n mapObjNextVertex = mapObjVertices[0];\r\n }\r\n const vertex = this.#calculateShiftedVertexPos(mapObjFirstVertex, mapObjXWithOffset, mapObjYWithOffset, mapObjRotation),\r\n nextVertex = this.#calculateShiftedVertexPos(mapObjNextVertex, mapObjXWithOffset, mapObjYWithOffset, mapObjRotation),\r\n edge = {\r\n x1: vertex[0],\r\n y1: vertex[1],\r\n x2: nextVertex[0],\r\n y2: nextVertex[1]\r\n },\r\n intersect = isCircleLineIntersect(xWithOffset, yWithOffset, radius, edge);\r\n if (intersect) {\r\n //console.log(\"polygon: \", polygonWithOffsetAndRotation);\r\n //console.log(\"intersect: \", intersect);\r\n return intersect;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n #isCircleToCircleCollision(circle1X, circle1Y, circle1R, circle2X, circle2Y, circle2R) {\r\n const len = new Vector(circle1X, circle1Y, circle2X, circle2Y).length;\r\n console.log(len);\r\n console.log(circle1R);\r\n console.log(circle2R);\r\n if ((len - (circle1R + circle2R)) > 0) {\r\n return false;\r\n } else {\r\n //@todo calculate point of intersect\r\n return true;\r\n }\r\n }\r\n\r\n #isPolygonToPolygonCollision(x, y, polygonVertices, polygonRotation, mapObject) {\r\n const [mapOffsetX, mapOffsetY] = this.stageData.worldOffset,\r\n xWithOffset = x - mapOffsetX,\r\n yWithOffset = y - mapOffsetY,\r\n mapObjXWithOffset = mapObject.x - mapOffsetX,\r\n mapObjYWithOffset = mapObject.y - mapOffsetY,\r\n mapObjVertices = mapObject.vertices, \r\n mapObjRotation = mapObject.rotation,\r\n polygonWithOffsetAndRotation = polygonVertices.map((vertex) => (this.#calculateShiftedVertexPos(vertex, xWithOffset, yWithOffset, polygonRotation))),\r\n len = mapObjVertices.length;\r\n //console.log(\"map object check:\");\r\n //console.log(mapObject);\r\n for (let i = 0; i < len; i+=1) {\r\n const mapObjFirstVertex = mapObjVertices[i];\r\n let mapObjNextVertex = mapObjVertices[i + 1];\r\n if (!mapObjNextVertex) {\r\n mapObjNextVertex = mapObjVertices[0];\r\n }\r\n const vertex = this.#calculateShiftedVertexPos(mapObjFirstVertex, mapObjXWithOffset, mapObjYWithOffset, mapObjRotation),\r\n nextVertex = this.#calculateShiftedVertexPos(mapObjNextVertex, mapObjXWithOffset, mapObjYWithOffset, mapObjRotation),\r\n edge = {\r\n x1: vertex[0],\r\n y1: vertex[1],\r\n x2: nextVertex[0],\r\n y2: nextVertex[1]\r\n },\r\n intersect = isPolygonLineIntersect(polygonWithOffsetAndRotation, edge);\r\n if (intersect) {\r\n //console.log(\"polygon: \", polygonWithOffsetAndRotation);\r\n //console.log(\"intersect: \", intersect);\r\n return intersect;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n #calculateShiftedVertexPos(vertex, centerX, centerY, rotation) {\r\n const vector = new Vector(0, 0, vertex[0], vertex[1]),\r\n vertexAngle = angle_2points(0, 0, vertex[0], vertex[1]),\r\n len = vector.length;\r\n \r\n const newX = centerX + (len * Math.cos(rotation + vertexAngle)),\r\n newY = centerY + (len * Math.sin(rotation + vertexAngle));\r\n return [newX, newY];\r\n }\r\n /**\r\n * \r\n * @param {number} x \r\n * @param {number} y \r\n * @param {number} r \r\n * @returns {{x:number, y:number, p:number} | boolean}\r\n */\r\n #isCircleToBoundariesCollision(x, y, r) {\r\n const mapObjects = this.stageData.getBoundaries(),\r\n ellipseB = this.stageData.getEllipseBoundaries(),\r\n pointB = this.stageData.getPointBoundaries(),\r\n [mapOffsetX, mapOffsetY] = this.stageData.worldOffset,\r\n xWithOffset = x - mapOffsetX,\r\n yWithOffset = y - mapOffsetY,\r\n len = mapObjects.length,\r\n eLen = ellipseB.length,\r\n pLen = pointB.length;\r\n\r\n for (let i = 0; i < len; i+=1) {\r\n const item = mapObjects[i];\r\n const object = {\r\n x1: item[0],\r\n y1: item[1],\r\n x2: item[2],\r\n y2: item[3]\r\n },\r\n intersect = isCircleLineIntersect(xWithOffset, yWithOffset, r, object);\r\n if (intersect) {\r\n //console.log(\"rotation: \", rotation);\r\n //console.log(\"polygon: \", polygonWithOffsetAndRotation);\r\n //console.log(\"intersect: \", intersect);\r\n return intersect;\r\n }\r\n }\r\n if (eLen > 0) {\r\n for (let i = 0; i < eLen; i+=1) {\r\n const ellipse = ellipseB[i],\r\n intersect = isEllipseCircleIntersect(ellipse, {x:xWithOffset, y:yWithOffset, r});\r\n if (intersect) {\r\n //console.log(\"rotation: \", rotation);\r\n //console.log(\"polygon: \", polygonWithOffsetAndRotation);\r\n //console.log(\"intersect: \", intersect);\r\n return intersect;\r\n }\r\n }\r\n }\r\n \r\n if (pLen > 0) {\r\n for (let i = 0; i < pLen; i+=1) {\r\n const point = pointB[i],\r\n xP = point[0],\r\n yP = point[1],\r\n intersect = isPointCircleIntersect(xP, yP, {x:xWithOffset, y:yWithOffset, r});\r\n if (intersect) {\r\n //console.log(\"rotation: \", rotation);\r\n //console.log(\"polygon: \", polygonWithOffsetAndRotation);\r\n //console.log(\"intersect: \", intersect);\r\n return intersect;\r\n }\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * @param {number} x\r\n * @param {number} y\r\n * @param {Array>} polygon\r\n * @param {number} rotation \r\n * @returns {{x:number, y:number, p:number} | boolean}\r\n */\r\n #isPolygonToBoundariesCollision(x, y, polygon, rotation) {\r\n const mapObjects = this.stageData.getBoundaries(),\r\n ellipseB = this.stageData.getEllipseBoundaries(),\r\n pointB = this.stageData.getPointBoundaries(),\r\n [mapOffsetX, mapOffsetY] = this.stageData.worldOffset,\r\n xWithOffset = x - mapOffsetX,\r\n yWithOffset = y - mapOffsetY,\r\n polygonWithOffsetAndRotation = polygon.map((vertex) => (this.#calculateShiftedVertexPos(vertex, xWithOffset, yWithOffset, rotation))),\r\n len = mapObjects.length,\r\n eLen = ellipseB.length,\r\n pLen = pointB.length;\r\n\r\n for (let i = 0; i < len; i+=1) {\r\n const item = mapObjects[i];\r\n const object = {\r\n x1: item[0],\r\n y1: item[1],\r\n x2: item[2],\r\n y2: item[3]\r\n },\r\n intersect = isPolygonLineIntersect(polygonWithOffsetAndRotation, object);\r\n if (intersect) {\r\n //console.log(\"rotation: \", rotation);\r\n //console.log(\"polygon: \", polygonWithOffsetAndRotation);\r\n //console.log(\"intersect: \", intersect);\r\n return intersect;\r\n }\r\n }\r\n if (eLen > 0) {\r\n for (let i = 0; i < eLen; i+=1) {\r\n const ellipse = ellipseB[i],\r\n intersect = isEllipsePolygonIntersect(ellipse, polygonWithOffsetAndRotation);\r\n if (intersect) {\r\n //console.log(\"rotation: \", rotation);\r\n //console.log(\"polygon: \", polygonWithOffsetAndRotation);\r\n //console.log(\"intersect: \", intersect);\r\n return intersect;\r\n }\r\n }\r\n }\r\n \r\n if (pLen > 0) {\r\n for (let i = 0; i < pLen; i+=1) {\r\n const point = pointB[i],\r\n x = point[0],\r\n y = point[1],\r\n intersect = isPointPolygonIntersect(x, y, polygonWithOffsetAndRotation);\r\n if (intersect) {\r\n //console.log(\"rotation: \", rotation);\r\n //console.log(\"polygon: \", polygonWithOffsetAndRotation);\r\n //console.log(\"intersect: \", intersect);\r\n return intersect;\r\n }\r\n }\r\n }\r\n return false;\r\n }\r\n //****************** End Collisions ****************//\r\n\r\n #setCanvasSize() {\r\n const canvasWidth = this.systemSettings.canvasMaxSize.width && (this.systemSettings.canvasMaxSize.width < window.innerWidth) ? this.systemSettings.canvasMaxSize.width : window.innerWidth,\r\n canvasHeight = this.systemSettings.canvasMaxSize.height && (this.systemSettings.canvasMaxSize.height < window.innerHeight) ? this.systemSettings.canvasMaxSize.height : window.innerHeight;\r\n this.stageData._setCanvasDimensions(canvasWidth, canvasHeight);\r\n }\r\n}","import { WARNING_CODES } from \"../constants.js\";\nimport { Warning } from \"./Exception.js\";\n/**\n * A storage for stage data, such as gameObjects,\n * boundaries, worldDimensions and offset\n * @see {@link GameStage} a part of GameStage\n * @hideconstructor\n */\nexport class GameStageData {\n #worldWidth;\n #worldHeight;\n #viewWidth;\n #viewHeight;\n #xOffset = 0;\n #yOffset = 0;\n #centerX = 0;\n #centerY = 0;\n #rotate = 0;\n /**\n * current screen boundaries, recalculated every render cycles\n * @type {Array>}\n */\n #boundaries = [];\n /**\n * ellipse boundaries\n * @type {Array>}\n */\n #ellipseBoundaries = [];\n /**\n * point boundaries\n * @type {Array>}\n */\n #pointBoundaries = [];\n /**\n * whole world boundaries, calculated once on prepare stage\n * @type {Array>}\n */\n #wholeWorldBoundaries = [];\n /**\n * @type {Array}\n */\n #renderObjects = [];\n \n /**\n * @type {boolean}\n */\n #isOffsetTurnedOff;\n /**\n * @deprecated\n * @type {boolean}\n */\n #isWorldBoundariesEnabled = false;\n\n /**\n * \n * @returns {boolean}\n */\n isOffsetTurnedOff() {\n return this.#isOffsetTurnedOff;\n }\n set mapRotate(value) {\n this.#rotate = value;\n }\n\n /**\n * Add a Boundaries line\n * @param {{x1:number,y1:number,x2:number, y2:number}} boundaries \n */\n #addBoundaries(boundaries) {\n this.#boundaries.push([boundaries.x1, boundaries.y1, boundaries.x2, boundaries.y2]);\n }\n\n /**\n * Add array of boundaries lines\n * @param {Array>} boundaries \n * @ignore\n */\n _addBoundariesArray(boundaries) {\n this.#boundaries.push(...boundaries);\n }\n\n _addEllipseBoundaries(boundaries) {\n this.#ellipseBoundaries.push(...boundaries);\n }\n\n _addPointBoundaries(boundaries) {\n this.#pointBoundaries.push(...boundaries);\n }\n\n /**\n * Clear map boundaries\n * @ignore\n */\n _clearBoundaries() {\n this.#boundaries = [];\n this.#ellipseBoundaries = [];\n this.#pointBoundaries = [];\n }\n\n /**\n * \n * @param {number} width \n * @param {number} height \n * @ignore\n */\n _setWorldDimensions(width, height) {\n this.#worldWidth = width;\n this.#worldHeight = height;\n }\n\n /**\n * \n * @param {number} width \n * @param {number} height \n * @ignore\n */\n _setCanvasDimensions(width, height) {\n this.#viewWidth = width;\n this.#viewHeight = height;\n }\n\n /**\n * Set map borders\n * @ignore\n */\n _setMapBoundaries() {\n const [w, h] = [this.#worldWidth, this.#worldHeight],\n [offsetX, offsetY] = [this.#xOffset, this.#yOffset],\n wOffset = w - offsetX,\n hOffset = h -offsetY;\n if (!w || !h) {\n Warning(WARNING_CODES.WORLD_DIMENSIONS_NOT_SET, \"Can't set map boundaries.\");\n }\n this.#addBoundaries({x1: 0, y1: 0, x2: wOffset, y2: 0});\n this.#addBoundaries({x1: wOffset, y1: 0, x2: wOffset, y2: hOffset});\n this.#addBoundaries({x1: wOffset, y1: hOffset, x2: 0, y2: hOffset});\n this.#addBoundaries({x1: 0, y1: hOffset, x2: 0, y2: 0});\n }\n\n /**\n * @ignore\n */\n _setWholeWorldMapBoundaries() {\n const [w, h] = [this.#worldWidth, this.#worldHeight];\n if (!w || !h) {\n Warning(WARNING_CODES.WORLD_DIMENSIONS_NOT_SET, \"Can't set map boundaries.\");\n }\n this.#wholeWorldBoundaries.push([0, 0, w, 0]);\n this.#wholeWorldBoundaries.push([w, 0, w, h]);\n this.#wholeWorldBoundaries.push([w, h, 0, h]);\n this.#wholeWorldBoundaries.push([0, h, 0, 0]);\n }\n\n /**\n * Merge same boundaries\n * @ignore\n */\n _mergeBoundaries(isWholeMapBoundaries = false) {\n const boundaries = isWholeMapBoundaries ? this.getWholeWorldBoundaries() : this.getBoundaries(),\n boundariesSet = new Set(boundaries);\n for (const line of boundariesSet.values()) {\n const lineX1 = line[0],\n lineY1 = line[1],\n lineX2 = line[2],\n lineY2 = line[3];\n for (const line2 of boundariesSet.values()) {\n const line2X1 = line2[0],\n line2Y1 = line2[1],\n line2X2 = line2[2],\n line2Y2 = line2[3];\n if (lineX1 === line2X2 && lineY1 === line2Y2 &&\n lineX2 === line2X1 && lineY2 === line2Y1) {\n //remove double lines\n boundariesSet.delete(line);\n boundariesSet.delete(line2);\n }\n if (lineX2 === line2X1 && lineY2 === line2Y1 && (lineX1 === line2X2 || lineY1 === line2Y2)) {\n //merge lines\n line2[0] = lineX1;\n line2[1] = lineY1;\n boundariesSet.delete(line);\n }\n }\n }\n\n if (isWholeMapBoundaries) {\n this.#boundaries = Array.from(boundariesSet);\n } else {\n this.#wholeWorldBoundaries = Array.from(boundariesSet);\n }\n boundariesSet.clear();\n }\n\n /**\n * @ignore\n * @param {Array>} boundaries \n */\n _setWholeMapBoundaries(boundaries) {\n this.#wholeWorldBoundaries.push(...boundaries);\n }\n\n /**\n * @deprecated\n * @ignore\n */\n _enableMapBoundaries() {\n this.#isWorldBoundariesEnabled = true;\n }\n\n /**\n * \n * @returns {Array>}\n */\n getBoundaries() {\n return this.#boundaries;\n }\n\n /**\n * \n * @returns {Array>}\n */\n getEllipseBoundaries() {\n return this.#ellipseBoundaries;\n }\n\n /**\n * \n * @returns {Array>}\n */\n getPointBoundaries() {\n return this.#pointBoundaries;\n }\n\n getWholeWorldBoundaries() {\n return this.#wholeWorldBoundaries;\n }\n\n /**\n * @deprecated\n */\n get isWorldBoundariesEnabled() {\n return this.#isWorldBoundariesEnabled;\n }\n /**\n * @type {Array}\n */\n get canvasDimensions() {\n return [this.#viewWidth, this.#viewHeight];\n }\n\n /**\n * @type {Array}\n */\n get worldDimensions() {\n return [this.#worldWidth, this.#worldHeight];\n }\n \n /**\n * @type {Array}\n */\n get worldOffset() {\n return [this.#xOffset, this.#yOffset];\n }\n\n /**\n * @type {Array}\n */\n get mapCenter() {\n return [this.#centerX, this.#centerY];\n }\n\n /**\n * @type {number}\n */\n get mapRotate() {\n return this.#rotate;\n }\n\n /**\n * @method\n * @param {number} x \n * @param {number} y \n */\n centerCameraPosition = (x, y) => {\n let [mapOffsetX, mapOffsetY] = this.worldOffset;\n const [canvasWidth, canvasHeight] = this.canvasDimensions,\n [mapWidth, mapHeight] = this.worldDimensions,\n halfScreenWidth = canvasWidth/2,\n halfScreenHeight = canvasHeight/2,\n currentCenterX = halfScreenWidth - mapOffsetX,\n currentCenterY = halfScreenHeight - mapOffsetY;\n if (currentCenterX < x) {\n if (x < mapWidth - halfScreenWidth) {\n const newXOffset = x - halfScreenWidth;\n if (newXOffset >= 0)\n this.#xOffset = Math.round(newXOffset);\n } else if (mapWidth > canvasWidth) {\n const newXOffset = mapWidth - canvasWidth;\n this.#xOffset = Math.round(newXOffset);\n }\n }\n if (currentCenterY < y) {\n if (y < mapHeight - halfScreenHeight) {\n const newYOffset = y - halfScreenHeight;\n if (newYOffset >= 0)\n this.#yOffset = Math.round(newYOffset);\n } else if (mapHeight > canvasHeight) {\n const newYOffset = mapHeight - canvasHeight;\n this.#yOffset = Math.round(newYOffset);\n }\n }\n\n this.#centerX = x;\n this.#centerY = y;\n //Logger.debug(\"center camera position, offset: \", this.worldOffset);\n //Logger.debug(\"center: \", this.mapCenter); \n };\n\n personRotatedCenterCamera = (x, y, rotationAngle) => {\n console.log(\"new centering algorithm\");\n /*\n let [mapOffsetX, mapOffsetY] = this.worldOffset;\n const [canvasWidth, canvasHeight] = this.canvasDimensions,\n [mapWidth, mapHeight] = this.worldDimensions,\n halfScreenWidth = canvasWidth/2,\n halfScreenHeight = canvasHeight/2,\n currentCenterX = halfScreenWidth - mapOffsetX,\n currentCenterY = halfScreenHeight - mapOffsetY;\n if (currentCenterX < x) {\n if (x < mapWidth - halfScreenWidth) {\n const newXOffset = x - halfScreenWidth;\n if (newXOffset >= 0)\n this.#xOffset = Math.round(newXOffset);\n } else if (mapWidth > canvasWidth) {\n const newXOffset = mapWidth - canvasWidth;\n this.#xOffset = Math.round(newXOffset);\n }\n }\n if (currentCenterY < y) {\n if (y < mapHeight - halfScreenHeight) {\n const newYOffset = y - halfScreenHeight;\n if (newYOffset >= 0)\n this.#yOffset = Math.round(newYOffset);\n } else if (mapHeight > canvasHeight) {\n const newYOffset = mapHeight - canvasHeight;\n this.#yOffset = Math.round(newYOffset);\n }\n }\n\n this.#centerX = x;\n this.#centerY = y;\n Logger.debug(\"center camera position, offset: \", this.worldOffset);\n Logger.debug(\"center: \", this.mapCenter); \n */\n };\n\n /**\n * a getter to retrieve all attached renderObjects\n */\n get renderObjects() {\n return this.#renderObjects;\n }\n\n /**\n * Retrieve specific objects instances\n * @param {Object} instance - drawObjectInstance to retrieve \n * @returns {Array}\n */\n getObjectsByInstance(instance) {\n return this.#renderObjects.filter((object) => object instanceof instance);\n }\n\n /**\n * @ignore\n */\n _sortRenderObjectsBySortIndex() {\n this.#renderObjects = this.#renderObjects.sort((obj1, obj2) => obj1.sortIndex - obj2.sortIndex);\n }\n\n /**\n * @ignore\n */\n set _renderObject(object) {\n this.#renderObjects.push(object);\n } \n\n /**\n * @ignore\n */\n set _renderObjects(objects) {\n this.#renderObjects = objects;\n } \n}","import { ISystem } from \"./ISystem.js\";\n\n/**\n * Class for creating modules\n * Accessed via ISystem.extensionInterface\n */\nexport class IExtension {\n /**\n * @type {ISystem}\n */\n #systemReference;\n /**\n * @hideconstructor\n */\n constructor(iSystem) {\n this.#systemReference = iSystem;\n }\n /**\n * Is used for registering new Object in DrawObjectFactory, \\\n * registered method could be then called with this.draw[createInstanceKey]\n * @param {string} createInstanceKey - a key for calling method from DrawObjectFactory\n * @param {function} createInstanceMethod - method \n */\n registerDrawObject(createInstanceKey, createInstanceMethod) {\n this.#systemReference.drawObjectFactory._registerNewObjectMethod(createInstanceKey, createInstanceMethod);\n }\n\n /**\n * Used to register a new draw program\n * @param {string} programName\n * @param {string} vertexShader - raw vertex shader program\n * @param {string} fragmentShader - raw fragment shader program \n * @param {Array} uVars - program uniform variables names\n * @param {Array} aVars - program attribute variables names\n * @returns {Promise}\n */\n registerAndCompileWebGlProgram(programName, vertexShader, fragmentShader, uVars, aVars) {\n return this.#systemReference.iRender._registerAndCompileWebGlProgram(programName, vertexShader, fragmentShader, uVars, aVars);\n }\n\n /**\n * Inject method to render.init stage. Should be Promise based.\n * @param {function():Promise} method \n * @returns {void}\n */\n registerRenderInit(method) {\n this.#systemReference.iRender._registerRenderInit(method);\n }\n\n /**\n * Register render method for class.\n * @param {string} objectClassName - object name registered to DrawObjectFactory\n * @param {function(renderObject, gl, pageData, program, vars):Promise} objectRenderMethod - should be promise based returns vertices number and draw program\n * @param {string=} objectWebGlDrawProgram - a webgl program name previously registered with iExtension.registerAndCompileWebGlProgram()\n */\n registerObjectRender(objectClassName, objectRenderMethod, objectWebGlDrawProgram) {\n this.#systemReference.iRender._registerObjectRender(objectClassName, objectRenderMethod, objectWebGlDrawProgram);\n }\n}","import { CONST, ERROR_CODES } from \"../constants.js\";\nimport { Exception } from \"./Exception.js\";\nimport { Logger } from \"./Logger.js\";\nimport { SystemEvent } from \"./Events/SystemEvent.js\";\n\n/**\n * Represents Socket connection\n */\nexport class INetwork extends EventTarget {\n #systemSettings;\n #socket;\n\n /**\n * @hideconstructor\n */\n constructor(systemSettings) {\n super();\n if (!systemSettings) {\n Exception(ERROR_CODES.CREATE_INSTANCE_ERROR, \"systemSettings should be passed to class instance\");\n }\n this.#systemSettings = systemSettings;\n }\n\n init() {\n import(\"socket.io-client\").then((module) => {\n this.#socket = module.io(this.#systemSettings.network.address, {withCredentials: true});\n \n this.#registerSocketListeners();\n });\n }\n\n /**\n * @returns {boolean}\n */\n get isServerConnected () {\n if (this.#socket && this.#socket.connected) {\n return true;\n } else {\n return false;\n }\n }\n \n get playerId() {\n return this.#socket.id;\n }\n\n sendGatherRoomsInfo() {\n this.#socket.emit(CONST.EVENTS.WEBSOCKET.CLIENT_SERVER.ROOMS_INFO_REQUEST);\n }\n\n sendCreateOrJoinRoom(roomName, map) {\n this.#socket.emit(CONST.EVENTS.WEBSOCKET.CLIENT_SERVER.CREATE_OR_JOIN, roomName , map);\n }\n\n sendMessage(message) {\n this.#socket.emit(CONST.EVENTS.WEBSOCKET.CLIENT_SERVER.CLIENT_MESSAGE, message);\n }\n\n #onConnect = () => {\n Logger.debug(\"connected, socket id: \" + this.#socket.id);\n this.dispatchEvent(new Event(CONST.EVENTS.WEBSOCKET.SERVER_CLIENT.CONNECTION_STATUS_CHANGED));\n };\n\n #onDisconnect = (reason) => {\n Logger.debug(\"server disconnected, reason: \" + reason);\n this.dispatchEvent(new Event(CONST.EVENTS.WEBSOCKET.SERVER_CLIENT.CONNECTION_STATUS_CHANGED));\n };\n\n #onData = (event) => {\n console.warn(\"server data: \", event);\n };\n\n #onMessage = (message) => {\n Logger.debug(\"received new message from server: \" + message);\n this.dispatchEvent(new SystemEvent(CONST.EVENTS.WEBSOCKET.SERVER_CLIENT.SERVER_MESSAGE, message));\n };\n\n #onRoomsInfo = (rooms) => {\n Logger.debug(\"received roomsInfo \" + rooms);\n this.dispatchEvent(new SystemEvent(CONST.EVENTS.WEBSOCKET.SERVER_CLIENT.ROOMS_INFO, rooms));\n };\n\n #onCreateNewRoom = (room, map) => {\n Logger.debug(\"CLIENT SOCKET: Created room \" + room);\n this.dispatchEvent(new SystemEvent(CONST.EVENTS.WEBSOCKET.SERVER_CLIENT.CREATED, {room, map}));\n };\n\n #onRoomIsFull = (room) => {\n Logger.debug(\"CLIENT SOCKET: Room is full, can't join: \" + room);\n this.dispatchEvent(new SystemEvent(CONST.EVENTS.WEBSOCKET.SERVER_CLIENT.FULL, {room}));\n };\n\n #onJoinedToRoom = (room, map) => {\n Logger.debug(\"CLIENT SOCKET: Joined to room: \" + room, \", map: \", map);\n this.dispatchEvent(new SystemEvent(CONST.EVENTS.WEBSOCKET.SERVER_CLIENT.JOINED, {room, map}));\n };\n\n #onUnjoinedFromRoom = (playerId) => {\n this.dispatchEvent(new SystemEvent(CONST.EVENTS.WEBSOCKET.SERVER_CLIENT.DISCONNECTED, {playerId}));\n };\n\n #registerSocketListeners() {\n this.#socket.on(\"connect\", this.#onConnect);\n this.#socket.on(\"disconnect\", this.#onDisconnect);\n this.#socket.on(\"data\", this.#onData);\n\n this.#socket.on(\"roomsInfo\", this.#onRoomsInfo);\n \n this.#socket.on(\"created\", this.#onCreateNewRoom);\n \n this.#socket.on(\"full\", this.#onRoomIsFull);\n \n this.#socket.on(\"joined\", this.#onJoinedToRoom);\n \n this.#socket.on(\"log\", function(array) {\n console.log.apply(console, array);\n });\n \n this.#socket.on(\"message\", this.#onMessage);\n \n this.#socket.on(\"removed\", function(message) {\n console.log(\"removed message\");\n console.log(message);\n });\n\n this.#socket.on(\"disconnected\", this.#onUnjoinedFromRoom);\n\n addEventListener(\"beforeunload\", this.#disconnect);\n }\n\n #disconnect = () => {\n this.#socket.disconnect();\n };\n}","import { DrawTiledLayer } from \"./DrawTiledLayer.js\";\r\nimport { Exception, Warning } from \"./Exception.js\";\r\nimport { ERROR_CODES, WARNING_CODES } from \"../constants.js\";\r\nimport { WebGlEngine } from \"./WebGl/WebGlEngine.js\";\r\nimport { SystemSettings } from \"../configs.js\";\r\nimport { GameStageData } from \"./GameStageData.js\";\r\nimport AssetsManager from \"../../modules/assetsm/dist/assetsm.min.js\";\r\n//import { calculateBufferData } from \"../wa/release.js\";\r\nimport { CONST } from \"../constants.js\";\r\nimport { DrawImageObject } from \"./DrawImageObject.js\";\r\nimport { DrawCircleObject } from \"./DrawCircleObject.js\";\r\nimport { DrawConusObject } from \"./DrawConusObject.js\";\r\nimport { DrawLineObject } from \"./DrawLineObject.js\";\r\nimport { DrawPolygonObject } from \"./DrawPolygonObject.js\";\r\nimport { DrawRectObject } from \"./DrawRectObject.js\";\r\nimport { DrawTextObject } from \"./DrawTextObject.js\";\r\nimport { imgVertexShader, imgFragmentShader, imgUniforms, imgAttributes } from \"./WebGl/ImagesDrawProgram.js\";\r\nimport { primitivesVertexShader, primitivesFragmentShader, primitivesUniforms, primitivesAttributes } from \"./WebGl/PrimitivesDrawProgram.js\";\r\nimport { utils } from \"../index.js\";\r\n\r\n/**\r\n * IRender class controls the render(start/stop/speed) \r\n * And drawObjects(animations, removing, and rendering)\r\n * @see {@link GameStage} a part of GameStage\r\n * @hideconstructor\r\n */\r\nexport class IRender {\r\n /**\r\n * @type {HTMLCanvasElement}\r\n */\r\n #canvas;\r\n /**\r\n * @type {WebGLRenderingContext}\r\n */\r\n #drawContext;\r\n /**\r\n * @type {boolean}\r\n */\r\n #isCleared;\r\n /**\r\n * @type {boolean}\r\n */\r\n #isActive;\r\n /**\r\n * @type {WebGlEngine}\r\n */\r\n #webGlEngine;\r\n /**\r\n * @type {GameStageData | null}\r\n */\r\n #currentGameStageData;\r\n\r\n /**\r\n * ISystem.systemSettings\r\n * @type {SystemSettings}\r\n */\r\n #systemSettingsReference;\r\n /**\r\n * A reference to the systemInterface.iLoader\r\n * @type {AssetsManager}\r\n */\r\n #loaderReference;\r\n /**\r\n * @type {Array}\r\n */\r\n #tempRCircleT;\r\n /**\r\n * @type {NodeJS.Timer | null}\r\n */\r\n #fpsAverageCountTimer;\r\n /**\r\n * @type {boolean}\r\n */\r\n #isBoundariesPrecalculations = false;\r\n #minCycleTime;\r\n /**\r\n * @type {EventTarget}\r\n */\r\n #emitter = new EventTarget();\r\n #bindRenderLayerMethod;\r\n #registeredRenderObjects = new Map();\r\n\r\n /**\r\n * @type {Array>}\r\n */\r\n #initPromises = [];\r\n constructor(systemSettings, iLoader, canvasContainer) {\r\n this.#isCleared = false;\r\n this.#canvas = document.createElement(\"canvas\");\r\n canvasContainer.appendChild(this.#canvas);\r\n this.#drawContext = this.#canvas.getContext(\"webgl\", {stencil: true});\r\n\r\n this.#systemSettingsReference = systemSettings;\r\n this.#loaderReference = iLoader;\r\n\r\n this.#tempRCircleT = [];\r\n this.#minCycleTime = this.systemSettings.gameOptions.render.minCycleTime;\r\n\r\n this.#isBoundariesPrecalculations = this.systemSettings.gameOptions.render.boundaries.wholeWorldPrecalculations;\r\n\r\n this.#webGlEngine = new WebGlEngine(this.#drawContext, this.#systemSettingsReference.gameOptions);\r\n if (this.systemSettings.gameOptions.optimization === CONST.OPTIMIZATION.WEB_ASSEMBLY.NATIVE_WAT ||\r\n this.systemSettings.gameOptions.optimization === CONST.OPTIMIZATION.WEB_ASSEMBLY.ASSEMBLY_SCRIPT) {\r\n this._registerRenderInit(this.#webGlEngine._initiateWasm);\r\n }\r\n\r\n this._registerRenderInit(this.fixCanvasSize);\r\n this._registerRenderInit(\r\n () => this._registerAndCompileWebGlProgram(CONST.WEBGL.DRAW_PROGRAMS.IMAGES, imgVertexShader, imgFragmentShader, imgUniforms, imgAttributes)\r\n );\r\n this._registerRenderInit(\r\n () => this._registerAndCompileWebGlProgram(CONST.WEBGL.DRAW_PROGRAMS.PRIMITIVES, primitivesVertexShader, primitivesFragmentShader, primitivesUniforms, primitivesAttributes)\r\n );\r\n this._registerRenderInit(this.#webGlEngine._initWebGlAttributes);\r\n\r\n this._registerObjectRender(DrawTextObject.name, this.#webGlEngine._bindText, CONST.WEBGL.DRAW_PROGRAMS.IMAGES);\r\n this._registerObjectRender(DrawRectObject.name, this.#webGlEngine._bindPrimitives, CONST.WEBGL.DRAW_PROGRAMS.PRIMITIVES);\r\n this._registerObjectRender(DrawPolygonObject.name, this.#webGlEngine._bindPrimitives, CONST.WEBGL.DRAW_PROGRAMS.PRIMITIVES);\r\n this._registerObjectRender(DrawCircleObject.name, this.#webGlEngine._bindConus, CONST.WEBGL.DRAW_PROGRAMS.PRIMITIVES);\r\n this._registerObjectRender(DrawConusObject.name, this.#webGlEngine._bindConus, CONST.WEBGL.DRAW_PROGRAMS.PRIMITIVES);\r\n this._registerObjectRender(DrawTiledLayer.name, this.#webGlEngine._bindTileImages, CONST.WEBGL.DRAW_PROGRAMS.IMAGES);\r\n this._registerObjectRender(DrawLineObject.name, this.#webGlEngine._bindLine, CONST.WEBGL.DRAW_PROGRAMS.PRIMITIVES);\r\n }\r\n\r\n /**\r\n * \r\n * @param {string} eventName \r\n * @param {*} listener \r\n * @param {*=} options \r\n */\r\n addEventListener = (eventName, listener, options) => {\r\n this.#emitter.addEventListener(eventName, listener, options);\r\n };\r\n\r\n /**\r\n * \r\n * @param {string} eventName \r\n * @param {*} listener \r\n * @param {*=} options \r\n */\r\n removeEventListener = (eventName, listener, options) => {\r\n this.#emitter.removeEventListener(eventName, listener, options);\r\n };\r\n\r\n get stageData() {\r\n return this.#currentGameStageData;\r\n }\r\n\r\n get systemSettings() {\r\n return this.#systemSettingsReference;\r\n }\r\n\r\n get iLoader() {\r\n return this.#loaderReference;\r\n }\r\n\r\n get canvas() {\r\n return this.#canvas;\r\n }\r\n\r\n get drawContext() {\r\n return this.#drawContext;\r\n }\r\n\r\n /**\r\n * \r\n * @param {string} eventName\r\n * @param {...any} eventParams\r\n */\r\n emit = (eventName, ...eventParams) => {\r\n const event = new Event(eventName);\r\n event.data = [...eventParams];\r\n this.#emitter.dispatchEvent(event);\r\n };\r\n\r\n /**\r\n * Determines if all added files was loaded or not\r\n * @returns {boolean}\r\n */\r\n isAllFilesLoaded = () => {\r\n return this.iLoader.filesWaitingForUpload === 0;\r\n };\r\n\r\n initiateContext = () => {\r\n return Promise.all(this.#initPromises.map(method => method()));\r\n };\r\n\r\n clearContext() {\r\n this.#webGlEngine._clearView();\r\n }\r\n\r\n setCanvasSize(width, height) {\r\n this.#canvas.width = width;\r\n this.#canvas.height = height;\r\n if (this.#webGlEngine) {\r\n this.#webGlEngine._fixCanvasSize(width, height);\r\n }\r\n }\r\n\r\n fixCanvasSize = () => {\r\n const settings = this.systemSettings, \r\n canvasWidth = settings.canvasMaxSize.width && (settings.canvasMaxSize.width < window.innerWidth) ? settings.canvasMaxSize.width : window.innerWidth,\r\n canvasHeight = settings.canvasMaxSize.height && (settings.canvasMaxSize.height < window.innerHeight) ? settings.canvasMaxSize.height : window.innerHeight;\r\n this.setCanvasSize(canvasWidth, canvasHeight);\r\n return Promise.resolve();\r\n };\r\n\r\n /****************************\r\n * Extend functionality\r\n ****************************/\r\n /**\r\n * @ignore\r\n * @param {string} programName\r\n * @param {string} vertexShader - raw vertex shader program\r\n * @param {string} fragmentShader - raw fragment shader program \r\n * @param {Array} uVars - program uniform variables names\r\n * @param {Array} aVars - program attribute variables names\r\n * @returns {Promise}\r\n */\r\n _registerAndCompileWebGlProgram(programName, vertexShader, fragmentShader, uVars, aVars) {\r\n this.#webGlEngine._registerAndCompileWebGlProgram(programName, vertexShader, fragmentShader, uVars, aVars);\r\n return Promise.resolve();\r\n }\r\n\r\n /**\r\n * @ignore\r\n * @param {function():Promise} method \r\n * @returns {void}\r\n */\r\n _registerRenderInit(method) {\r\n this.#initPromises.push(method);\r\n //} else {\r\n // Exception(ERROR_CODES.UNEXPECTED_METHOD_TYPE, \"registerRenderInit() accept only Promise based methods!\");\r\n //}\r\n }\r\n\r\n /**\r\n * @ignore\r\n * @param {string} objectClassName - object name registered to DrawObjectFactory\r\n * @param {function(renderObject, gl, pageData, program, vars):Promise} objectRenderMethod - should be promise based returns vertices number and draw program\r\n * @param {string=} objectWebGlDrawProgram \r\n */\r\n _registerObjectRender(objectClassName, objectRenderMethod, objectWebGlDrawProgram) {\r\n this.#registeredRenderObjects.set(objectClassName, {method: objectRenderMethod, webglProgramName: objectWebGlDrawProgram});\r\n }\r\n\r\n /****************************\r\n * End of Extend functionality\r\n ****************************/\r\n\r\n /**\r\n * @returns {Promise}\r\n */\r\n async render() {\r\n let renderObjectsPromises = [],\r\n errors = [],\r\n isErrors = false;\r\n const renderObjects = this.stageData.renderObjects;\r\n if (renderObjects.length !== 0) {\r\n //this.#checkCollisions(view.renderObjects);\r\n for (let i = 0; i < renderObjects.length; i++) {\r\n const object = renderObjects[i];\r\n if (object.isRemoved) {\r\n renderObjects.splice(i, 1);\r\n i--;\r\n continue;\r\n }\r\n if (object.hasAnimations) {\r\n object._processActiveAnimations();\r\n }\r\n const promise = await this._bindRenderObject(object)\r\n .catch((err) => Promise.reject(err));\r\n renderObjectsPromises.push(promise);\r\n }\r\n if (this.systemSettings.gameOptions.debug.boundaries.drawLayerBoundaries) {\r\n renderObjectsPromises.push(this.#drawBoundariesWebGl()\r\n .catch((err) => Promise.reject(err))); \r\n }\r\n //const bindResults = await Promise.allSettled(renderObjectsPromises);\r\n //bindResults.forEach((result) => {\r\n // if (result.status === \"rejected\") {\r\n // reject(result.reason);\r\n // }\r\n //});\r\n\r\n //await this.#webGlEngine._executeImagesDraw();\r\n\r\n //this.#postRenderActions();\r\n }\r\n const bindResults = await Promise.allSettled(renderObjectsPromises);\r\n bindResults.forEach((result) => {\r\n if (result.status === \"rejected\") {\r\n Promise.reject(result.reason);\r\n isErrors = true;\r\n errors.push(result.reason);\r\n }\r\n });\r\n\r\n this.#postRenderActions();\r\n \r\n this._isCleared = false;\r\n if (isErrors === false) {\r\n return Promise.resolve();\r\n } else {\r\n return Promise.reject(errors);\r\n }\r\n }\r\n\r\n /**\r\n * @ignore\r\n */\r\n set _isCleared(value) {\r\n this.#isCleared = value;\r\n }\r\n\r\n /**\r\n * @ignore\r\n */\r\n get _isCleared() {\r\n return this.#isCleared;\r\n }\r\n\r\n _createBoundariesPrecalculations() {\r\n //const promises = [];\r\n //for (const layer of this.#renderLayers) {\r\n // promises.push(this.#layerBoundariesPrecalculation(layer).catch((err) => {\r\n // Exception(ERROR_CODES.UNHANDLED_PREPARE_EXCEPTION, err);\r\n // }));\r\n //}\r\n //return promises;\r\n }\r\n #postRenderActions() {\r\n //const images = this.stageData.getObjectsByInstance(DrawImageObject);\r\n //for (let i = 0; i < images.length; i++) {\r\n // const object = images[i];\r\n // if (object.isAnimations) {\r\n // object._processActiveAnimations();\r\n // }\r\n //}\r\n }\r\n\r\n //#clearTileMapPromises() {\r\n // this.#bindTileMapPromises = [];\r\n //}\r\n\r\n /**\r\n * \r\n * @param {DrawTiledLayer} renderLayer \r\n * @returns {Promise}\r\n */\r\n #layerBoundariesPrecalculation(renderLayer) {\r\n return new Promise((resolve, reject) => {\r\n if (renderLayer.setBoundaries) {\r\n const tilemap = this.iLoader.getTileMap(renderLayer.tileMapKey),\r\n tilesets = tilemap.tilesets,\r\n layerData = tilemap.layers.find((layer) => layer.name === renderLayer.layerKey),\r\n { tileheight:dtheight, tilewidth:dtwidth } = tilemap,\r\n tilewidth = dtwidth,\r\n tileheight = dtheight,\r\n [ settingsWorldWidth, settingsWorldHeight ] = this.stageData.worldDimensions;\r\n \r\n let boundaries = [];\r\n\r\n if (!layerData) {\r\n Warning(WARNING_CODES.NOT_FOUND, \"check tilemap and layers name\");\r\n reject();\r\n }\r\n \r\n for (let i = 0; i < tilesets.length; i++) {\r\n const layerCols = layerData.width,\r\n layerRows = layerData.height,\r\n worldW = tilewidth * layerCols,\r\n worldH = tileheight * layerRows;\r\n\r\n if (worldW !== settingsWorldWidth || worldH !== settingsWorldHeight) {\r\n Warning(WARNING_CODES.UNEXPECTED_WORLD_SIZE, \" World size from tilemap is different than settings one, fixing...\");\r\n this.stageData._setWorldDimensions(worldW, worldH);\r\n }\r\n \r\n if (renderLayer.setBoundaries && this.systemSettings.gameOptions.render.boundaries.mapBoundariesEnabled) {\r\n this.stageData._setWholeWorldMapBoundaries();\r\n }\r\n\r\n //calculate boundaries\r\n let mapIndex = 0;\r\n\r\n for (let row = 0; row < layerRows; row++) {\r\n for (let col = 0; col < layerCols; col++) {\r\n let tile = layerData.data[mapIndex],\r\n mapPosX = col * tilewidth,\r\n mapPosY = row * tileheight;\r\n if (tile !== 0) {\r\n tile -= 1;\r\n \r\n boundaries.push([mapPosX, mapPosY, mapPosX + tilewidth, mapPosY]);\r\n boundaries.push([mapPosX + tilewidth, mapPosY, mapPosX + tilewidth, mapPosY + tileheight]);\r\n boundaries.push([mapPosX + tilewidth, mapPosY + tileheight, mapPosX, mapPosY + tileheight]);\r\n boundaries.push([mapPosX, mapPosY + tileheight, mapPosX, mapPosY ]);\r\n \r\n }\r\n mapIndex++;\r\n }\r\n }\r\n }\r\n this.stageData._setWholeMapBoundaries(boundaries);\r\n this.stageData._mergeBoundaries(true);\r\n console.warn(\"precalculated boundaries set\");\r\n console.log(this.stageData.getWholeWorldBoundaries());\r\n resolve();\r\n } else {\r\n resolve();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * @ignore\r\n * @param {DrawImageObject | DrawCircleObject | DrawConusObject | DrawLineObject | DrawPolygonObject | DrawRectObject | DrawTextObject | DrawTiledLayer} renderObject \r\n * @returns {Promise}\r\n */\r\n _bindRenderObject(renderObject) {\r\n const name = renderObject.constructor.name,\r\n registeredRenderObject = this.#registeredRenderObjects.get(name);\r\n if (registeredRenderObject) {\r\n const name = registeredRenderObject.webglProgramName;\r\n if (name) {\r\n const program = this.#webGlEngine.getProgram(name),\r\n vars = this.#webGlEngine.getProgramVarLocations(name);\r\n return registeredRenderObject.method(renderObject, this.drawContext, this.stageData, program, vars)\r\n .then((results) => this.#webGlEngine._render(results[0], results[1])); \r\n } else {\r\n return registeredRenderObject.method(renderObject, this.drawContext, this.stageData);\r\n }\r\n } else {\r\n // a workaround for images and its extend classes drawing\r\n if (renderObject.type === CONST.DRAW_TYPE.IMAGE) {\r\n const program = this.#webGlEngine.getProgram(CONST.WEBGL.DRAW_PROGRAMS.IMAGES),\r\n vars = this.#webGlEngine.getProgramVarLocations(CONST.WEBGL.DRAW_PROGRAMS.IMAGES);\r\n\r\n if (!renderObject.image) {\r\n const image = this.iLoader.getImage(renderObject.key);\r\n if (!image) {\r\n Exception(ERROR_CODES.CANT_GET_THE_IMAGE, \"iLoader can't get the image with key: \" + renderObject.key);\r\n } else {\r\n renderObject.image = image;\r\n }\r\n }\r\n return this.#webGlEngine._bindImage(renderObject, this.drawContext, this.stageData, program, vars)\r\n .then((results) => this.#webGlEngine._render(results[0], results[1]))\r\n .then(() => {\r\n if (renderObject.vertices && this.systemSettings.gameOptions.debug.boundaries.drawObjectBoundaries) {\r\n return this.#webGlEngine._drawPolygon(renderObject, this.stageData);\r\n } else {\r\n return Promise.resolve();\r\n }\r\n });\r\n } else {\r\n console.warn(\"no registered draw object method for \" + name + \" skip draw\");\r\n return Promise.resolve();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * \r\n * @returns {Promise}\r\n */\r\n #drawBoundariesWebGl() {\r\n return new Promise((resolve) => {\r\n const b = this.stageData.getBoundaries(),\r\n eB = this.stageData.getEllipseBoundaries(),\r\n pB = this.stageData.getPointBoundaries(),\r\n len = b.length,\r\n eLen = eB.length,\r\n pLen = pB.length,\r\n linesArray = [];\r\n \r\n //for (let i = 0; i < len; i++) {\r\n // const item = b[i];\r\n // linesArray.push(item[0], item[1]);\r\n // linesArray.push(item[2], item[3]);\r\n //}\r\n this.#webGlEngine._drawLines(b.flat(), this.systemSettings.gameOptions.debug.boundaries.boundariesColor, this.systemSettings.gameOptions.debug.boundaries.boundariesWidth);\r\n if (eLen) {\r\n //draw ellipse boundaries\r\n eB.forEach(element => {\r\n const x = element[0],\r\n y = element[1],\r\n radX = element[2],\r\n radY = element[3],\r\n vertices = utils.calculateEllipseVertices(x, y, radX, radY);\r\n this.#webGlEngine._drawPolygon({x: 0, y: 0, vertices, isOffsetTurnedOff: true}, this.stageData);\r\n //this.#webGlEngine._drawLines(vertices, this.systemSettings.gameOptions.debug.boundaries.boundariesColor, this.systemSettings.gameOptions.debug.boundaries.boundariesWidth);\r\n });\r\n }\r\n if (pLen) {\r\n //draw point boundaries\r\n pB.forEach(element => {\r\n const x = element[0],\r\n y = element[1],\r\n vertices = [x,y, x+1,y+1];\r\n\r\n this.#webGlEngine._drawLines(vertices, this.systemSettings.gameOptions.debug.boundaries.boundariesColor, this.systemSettings.gameOptions.debug.boundaries.boundariesWidth);\r\n });\r\n }\r\n resolve();\r\n });\r\n }\r\n\r\n #countFPSaverage() {\r\n const timeLeft = this.systemSettings.gameOptions.render.cyclesTimeCalc.averageFPStime,\r\n steps = this.#tempRCircleT.length;\r\n let fullTime = 0;\r\n for (let i = 0; i < steps; i++) {\r\n const timeStep = this.#tempRCircleT[i];\r\n fullTime += timeStep;\r\n }\r\n console.log(\"FPS average for\", timeLeft/1000, \"sec, is \", (1000 / (fullTime / steps)).toFixed(2));\r\n\r\n // cleanup\r\n this.#tempRCircleT = [];\r\n }\r\n\r\n /**\r\n * @ignore\r\n * @param {GameStageData} stageData \r\n */\r\n _startRender = async (/*time*/stageData) => {\r\n const gameOptions = this.systemSettings.gameOptions;\r\n //Logger.debug(\"_render \" + this.name + \" class\");\r\n this.#isActive = true;\r\n this.#currentGameStageData = stageData;\r\n this.fixCanvasSize();\r\n switch (gameOptions.library) {\r\n case CONST.LIBRARY.WEBGL:\r\n await this.#prepareViews();\r\n this.timeStart = Date.now();\r\n setTimeout(() => requestAnimationFrame(this.#drawViews));\r\n break;\r\n }\r\n if (gameOptions.render.cyclesTimeCalc.check === CONST.OPTIMIZATION.CYCLE_TIME_CALC.AVERAGES) {\r\n this.#fpsAverageCountTimer = setInterval(() => this.#countFPSaverage(), gameOptions.render.cyclesTimeCalc.averageFPStime);\r\n }\r\n };\r\n\r\n /**\r\n * @ignore\r\n */\r\n _stopRender = () => {\r\n this.#isActive = false;\r\n this.#currentGameStageData = null;\r\n this.#tempRCircleT = [];\r\n clearInterval(this.#fpsAverageCountTimer);\r\n this.#fpsAverageCountTimer = null;\r\n };\r\n /**\r\n * \r\n * @returns {Promise}\r\n */\r\n #prepareViews() {\r\n return new Promise((resolve, reject) => {\r\n let viewPromises = [];\r\n const isBoundariesPrecalculations = this.#isBoundariesPrecalculations;\r\n viewPromises.push(this.initiateContext());\r\n if (isBoundariesPrecalculations) {\r\n console.warn(\"isBoundariesPrecalculations() is turned off\");\r\n //for (const view of this.#views.values()) {\r\n //viewPromises.push(this.#iRender._createBoundariesPrecalculations());\r\n //}\r\n }\r\n Promise.allSettled(viewPromises).then((drawingResults) => {\r\n drawingResults.forEach((result) => {\r\n if (result.status === \"rejected\") {\r\n const error = result.reason;\r\n Warning(WARNING_CODES.UNHANDLED_DRAW_ISSUE, error);\r\n reject(error);\r\n }\r\n });\r\n resolve();\r\n });\r\n });\r\n }\r\n\r\n #drawViews = async (/*drawTime*/) => {\r\n const timeStart = performance.now(),\r\n minCycleTime = this.#minCycleTime,\r\n isCyclesTimeCalcCheckCurrent = this.systemSettings.gameOptions.render.cyclesTimeCalc.check === CONST.OPTIMIZATION.CYCLE_TIME_CALC.CURRENT;\r\n \r\n this.emit(CONST.EVENTS.SYSTEM.RENDER.START);\r\n this.stageData._clearBoundaries();\r\n this.clearContext();\r\n \r\n this.render().then(() => {\r\n const currentRenderTime = performance.now() - timeStart,\r\n r_time_less = minCycleTime - currentRenderTime,\r\n wait_time = r_time_less > 0 ? r_time_less : 0,\r\n cycleTime = currentRenderTime + wait_time;\r\n \r\n if (isCyclesTimeCalcCheckCurrent && currentRenderTime > minCycleTime) {\r\n console.log(\"current draw take: \", (currentRenderTime), \" ms\");\r\n }\r\n\r\n this.emit(CONST.EVENTS.SYSTEM.RENDER.END);\r\n\r\n if (cycleTime > 0) {\r\n this.#tempRCircleT.push(cycleTime);\r\n }\r\n\r\n if (this.#isActive) {\r\n setTimeout(() => requestAnimationFrame(this.#drawViews), wait_time);\r\n }\r\n }).catch((errors) => {\r\n if (errors.forEach) {\r\n errors.forEach((err) => {\r\n Warning(WARNING_CODES.UNHANDLED_DRAW_ISSUE, err);\r\n });\r\n } else {\r\n Warning(WARNING_CODES.UNHANDLED_DRAW_ISSUE, errors.message);\r\n }\r\n this._stopRender();\r\n });\r\n };\r\n}","import { CONST, ERROR_CODES, WARNING_CODES } from \"../constants.js\";\nimport { Exception, Warning } from \"./Exception.js\";\nimport { INetwork } from \"./INetwork.js\";\nimport { ISystemAudio } from \"./ISystemAudio.js\";\nimport { SystemSettings } from \"../configs.js\";\nimport AssetsManager from \"../../modules/assetsm/dist/assetsm.min.js\";\nimport { DrawObjectFactory } from \"./DrawObjectFactory.js\";\nimport { GameStage } from \"./GameStage.js\";\nimport { IRender } from \"./IRender.js\";\nimport { IExtension } from \"./IExtension.js\";\n\n/**\n * Public interface for a System
\n * Can be used to start/stop GameStage render,
\n * And provides access to SystemSettings, INetwork and ISystemAudio
\n * IRender, DrawObjectFactory, AssetsManager and external modules\n * accessible via GameStage.iSystem and System.system\n * @see {@link System} a part of System class instance\n * @see {@link GameStage} a part of GameStage class instance\n */\nexport class ISystem {\n /**\n * @type {Object}\n */\n #systemSettings;\n /**\n * @type {IExtension}\n */\n #iExtension;\n /**\n * @type {INetwork}\n */\n #systemServerConnection;\n /**\n * @type {ISystemAudio}\n */\n #systemAudioInterface;\n /**\n * @type {AssetsManager}\n */\n #iLoader = new AssetsManager();\n /**\n * @type {IRender}\n */\n #iRender;\n /**\n * @type {DrawObjectFactory}\n */\n #drawObjectFactory = new DrawObjectFactory(this.#iLoader);\n \n #modules = new Map();\n /**\n * @type {Map}\n */\n #registeredStagesReference;\n /**\n * @type {EventTarget}\n */\n #emitter = new EventTarget();\n /**\n * @hideconstructor\n */\n constructor(systemSettings, registeredStages, canvasContainer) {\n if (!systemSettings) {\n Exception(ERROR_CODES.CREATE_INSTANCE_ERROR, \"systemSettings should be passed to class instance\");\n }\n this.#systemSettings = systemSettings;\n \n this.#systemAudioInterface = new ISystemAudio(this.iLoader);\n this.#systemServerConnection = new INetwork(systemSettings);\n this.#iRender = new IRender(this.systemSettings, this.iLoader, canvasContainer);\n this.#iExtension = new IExtension(this, this.#iRender);\n this.#registeredStagesReference = registeredStages;\n // broadcast render events\n this.#iRender.addEventListener(CONST.EVENTS.SYSTEM.RENDER.START, () => this.emit(CONST.EVENTS.SYSTEM.RENDER.START));\n this.#iRender.addEventListener(CONST.EVENTS.SYSTEM.RENDER.END, () => this.emit(CONST.EVENTS.SYSTEM.RENDER.END));\n }\n\n /**\n * \n * @param {string} eventName\n * @param {...any} eventParams\n */\n emit = (eventName, ...eventParams) => {\n const event = new Event(eventName);\n event.data = [...eventParams];\n this.#emitter.dispatchEvent(event);\n };\n\n /**\n * \n * @param {string} eventName \n * @param {*} listener \n * @param {*=} options \n */\n addEventListener = (eventName, listener, options) => {\n this.#emitter.addEventListener(eventName, listener, options);\n };\n\n /**\n * \n * @param {string} eventName \n * @param {*} listener \n * @param {*=} options \n */\n removeEventListener = (eventName, listener, options) => {\n this.#emitter.removeEventListener(eventName, listener, options);\n };\n \n /**\n * @type { INetwork }\n */\n get iNetwork () {\n return this.#systemServerConnection;\n }\n\n /**\n * @type { SystemSettings }\n */\n get systemSettings() {\n return this.#systemSettings;\n }\n\n /**\n * @type { ISystemAudio }\n */\n get audio() {\n return this.#systemAudioInterface;\n }\n\n /**\n * @type {AssetsManager}\n */\n get iLoader() {\n return this.#iLoader;\n }\n\n /**\n * @type {IRender}\n */\n get iRender() {\n return this.#iRender;\n }\n\n /**\n * @type {DrawObjectFactory}\n */\n get drawObjectFactory() {\n return this.#drawObjectFactory;\n }\n\n get iExtension() {\n return this.#iExtension;\n }\n /**\n * @type {Map}\n */\n get modules() {\n return this.#modules;\n }\n\n /**\n * \n * @param {string} moduleKey \n * @param {Object} moduleClass \n * @param {...any} args \n * @returns {Object}\n */\n installModule = (moduleKey, moduleClass, ...args) => {\n const moduleInstance = new moduleClass(this, ...args);\n if (this.#modules.has(moduleKey)) {\n Warning(WARNING_CODES.MODULE_ALREADY_INSTALLED, \"module \" + moduleKey + \" is already installed\");\n return this.#modules.get(moduleKey);\n } else {\n this.#modules.set(moduleKey, moduleInstance);\n }\n return moduleInstance;\n };\n\n /**\n * @method\n * @param {string} screenPageName\n * @param {Object} [options] - options\n */\n startGameStage = (screenPageName, options) => {\n if (this.#registeredStagesReference.has(screenPageName)) {\n const stage = this.#registeredStagesReference.get(screenPageName),\n pageData = stage.stageData;\n this.#drawObjectFactory._attachPageData(pageData);\n if (stage.isInitiated === false) {\n stage._init();\n }\n //stage._attachCanvasToContainer(this.#canvasContainer);\n stage._start(options);\n this.emit(CONST.EVENTS.SYSTEM.START_PAGE);\n this.#iRender._startRender(pageData);\n } else {\n Exception(ERROR_CODES.VIEW_NOT_EXIST, \"View \" + screenPageName + \" is not registered!\");\n }\n };\n\n /**\n * @method\n * @param {string} screenPageName\n */\n stopGameStage = (screenPageName) => {\n if (this.#registeredStagesReference.has(screenPageName)) {\n this.emit(CONST.EVENTS.SYSTEM.STOP_PAGE);\n this.drawObjectFactory._detachPageData();\n this.#iRender._stopRender();\n this.#registeredStagesReference.get(screenPageName)._stop();\n } else {\n Exception(ERROR_CODES.VIEW_NOT_EXIST, \"View \" + screenPageName + \" is not registered!\");\n }\n };\n}","import AssetsManager from \"../../modules/assetsm/dist/assetsm.min.js\";\nimport { WARNING_CODES } from \"../constants.js\";\nimport { Warning } from \"./Exception.js\";\n\n/**\n * An audio interface,
\n * controls all application audio,
\n * holds and retrieves audio, changes volume
\n * accessible via GameStage.audio\n * @see {@link GameStage} a part of GameStage\n * @hideconstructor\n */\nexport class ISystemAudio {\n #volume = 0.5;\n #audio = new Map();\n /**\n * @type {AssetsManager}\n */\n #loaderReference;\n\n constructor(iLoader) {\n this.#loaderReference = iLoader;\n }\n\n /**\n * Original track\n * @param {string} name \n * @returns {HTMLAudioElement | null}\n */\n getAudio = (name) => {\n const audio = this.#audio.get(name);\n if (audio === null) {\n Warning(WARNING_CODES.AUDIO_NOT_LOADED, \"Audio with key \" + name + \" exists, but not actually loaded\");\n return audio;\n }\n if (audio) {\n return audio;\n } else {\n Warning(WARNING_CODES.AUDIO_NOT_REGISTERED, \"\");\n return null;\n }\n };\n\n /**\n * Clone of original track\n * @param {string} name \n * @returns {HTMLAudioElement | null}\n */\n getAudioCloned = (name) => {\n const audio = this.#audio.get(name);\n if (audio === null) {\n Warning(WARNING_CODES.AUDIO_NOT_LOADED, \"Audio with key \" + name + \" exists, but not actually loaded\");\n return audio;\n }\n if (audio) {\n const audioCloned = audio.cloneNode();\n audioCloned.volume = this.#volume;\n return audioCloned;\n } else {\n Warning(WARNING_CODES.AUDIO_NOT_REGISTERED);\n return null;\n }\n };\n\n set volume(value) {\n this.#volume = value;\n this.#updateTracksVolumes(value);\n }\n /**\n * Used to set or get audio volume, \n * value should be from 0 to 1\n * @type {number}\n */\n get volume() {\n return this.#volume;\n }\n\n #updateTracksVolumes(value) {\n for (const track of this.#audio.values()) {\n if (track) {\n track.volume = value;\n }\n }\n }\n\n /**\n * Register audio in the iSystem\n * @param {string} name\n */\n registerAudio(name) {\n let mediaElement = this.#loaderReference.getAudio(name);\n this.#audio.set(name, mediaElement);\n }\n}","import { SystemSettings } from \"../configs.js\";\nimport { CONST } from \"../constants.js\";\n\nexport class Logger {\n static debug(...args) {\n if (SystemSettings.mode === CONST.MODE.DEBUG)\n args.forEach(message => console.log(message));\n }\n}","class Vertex {\n #x;\n #y;\n constructor(x, y) {\n this.#x = x;\n this.#y = y;\n }\n\n get x() {\n return this.#x;\n }\n\n get y() {\n return this.#y;\n }\n}\n\nclass Rectangle {\n #x;\n #y;\n #w;\n #h;\n constructor(x, y, w, h) {\n this.#x = x;\n this.#y = y;\n this.#w = w;\n this.#h = h; \n }\n /**\n * @type {number}\n */\n get x() {\n return this.#x;\n }\n /**\n * @type {number}\n */\n get y() {\n return this.#y;\n }\n /**\n * @type {number}\n */\n get width() {\n return this.#w;\n }\n /**\n * @type {number}\n */\n get height() {\n return this.#h;\n }\n}\n\nclass Vector {\n #x;\n #y;\n constructor(x1, y1, x2, y2) {\n this.#x = x2 - x1;\n this.#y = y2 - y1;\n }\n\n get x() {\n return this.#x;\n }\n\n get y() {\n return this.#y;\n }\n\n get length() {\n return Math.sqrt(Math.pow(this.#x, 2) + Math.pow(this.#y, 2));\n }\n\n get tetaAngle() {\n return Math.atan2(this.#y, this.#x);\n }\n}\n\nexport { Vertex, Rectangle, Vector };","import { ERROR_CODES } from \"../constants.js\";\nimport { Exception } from \"./Exception.js\";\nimport { GameStage } from \"./GameStage.js\";\nimport { ISystem } from \"./ISystem.js\";\nimport { SystemSettings } from \"../configs.js\";\n\nimport { LoadingStage } from \"../design/LoadingStage.js\";\n\nconst loadingPageName = \"loadingPage\";\n/**\n * A main app class,
\n * Holder class for GameStage,
\n * can register new GameStages,
\n * init and preload data for them,
\n */\nexport class System {\n /**\n * @type {Map}\n */\n #registeredStages;\n /**\n * @type {ISystem}\n */\n #iSystem;\n /**\n * @param {SystemSettings} iSystemSettings - holds iSystem settings\n * @param {HTMLElement | null} [canvasContainer = null] - If it is not passed, iSystem will create div element and attach it to body\n */\n constructor(iSystemSettings, canvasContainer) {\n if (!iSystemSettings) {\n Exception(ERROR_CODES.CREATE_INSTANCE_ERROR, \"iSystemSettings should be passed to class instance\");\n }\n this.#registeredStages = new Map();\n\n if (!canvasContainer) {\n canvasContainer = document.createElement(\"div\");\n document.body.appendChild(canvasContainer);\n }\n\n this.#iSystem = new ISystem(iSystemSettings, this.#registeredStages, canvasContainer);\n\n this.registerStage(loadingPageName, LoadingStage);\n\n this.#iSystem.iLoader.addEventListener(\"loadstart\", this.#loadStart);\n this.#iSystem.iLoader.addEventListener(\"progress\", this.#loadProgress);\n this.#iSystem.iLoader.addEventListener(\"load\", this.#loadComplete);\n }\n\n /**\n * @type {ISystem}\n */\n get iSystem() {\n return this.#iSystem;\n }\n\n /**\n * A main factory method for create GameStage instances,
\n * register them in a System and call GameStage.register() stage\n * @param {string} screenPageName\n * @param {typeof GameStage} stage\n */\n registerStage(screenPageName, stage) {\n if (screenPageName && typeof screenPageName === \"string\" && screenPageName.trim().length > 0) {\n const stageInstance = new stage();\n stageInstance._register(screenPageName, this.iSystem);\n this.#registeredStages.set(screenPageName, stageInstance);\n } else {\n Exception(ERROR_CODES.CREATE_INSTANCE_ERROR, \"valid class name should be provided\");\n }\n }\n\n /**\n * Preloads assets for all registered pages\n * @return {Promise}\n */\n preloadAllData() {\n return this.#iSystem.iLoader.preload();\n }\n\n #loadStart = (event) => {\n this.#iSystem.startGameStage(loadingPageName, {total: event.total});\n };\n\n #loadProgress = (event) => {\n const uploaded = event.loaded,\n left = event.total,\n loadingPage = this.#registeredStages.get(loadingPageName);\n \n loadingPage._progress(uploaded, left);\n };\n\n #loadComplete = () => {\n this.#iSystem.stopGameStage(loadingPageName);\n };\n}","const imgVertexShader = `\n attribute vec2 a_texCoord;\n\n attribute vec2 a_position;\n\n uniform vec2 u_translation;\n uniform float u_rotation;\n uniform vec2 u_scale;\n\n uniform vec2 u_resolution;\n\n varying vec2 v_texCoord;\n\n void main(void) {\n float c = cos(u_rotation);\n float s = sin(u_rotation);\n\n mat3 translationMatrix1 = mat3(\n 1, 0, 0,\n 0, 1, 0,\n u_translation.x, u_translation.y, 1\n );\n\n mat3 translationMatrix2 = mat3(\n 1, 0, 0,\n 0, 1, 0,\n -u_translation.x, -u_translation.y, 1\n );\n \n mat3 rotationMatrix = mat3(\n c, s, 0,\n -s, c, 0,\n 0, 0, 1\n );\n\n mat3 scalingMatrix = mat3(\n u_scale.x, 0, 0,\n 0, u_scale.y, 0,\n 0, 0, 1\n );\n\n mat3 matrix = translationMatrix1 * rotationMatrix * translationMatrix2 * scalingMatrix;\n \n vec2 position = (matrix * vec3(a_position, 1)).xy;\n\n vec2 clipSpace = position / u_resolution * 2.0 - 1.0;\n\n gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);\n \n v_texCoord = a_texCoord;\n }`;\nconst imgFragmentShader = `\n precision mediump float;\n\n uniform sampler2D u_image;\n\n //texCoords passed in from the vertex shader\n varying vec2 v_texCoord;\n void main() {\n vec4 color = texture2D(u_image, v_texCoord);\n gl_FragColor = color;\n }`;\nconst imgUniforms = [\"u_translation\", \"u_rotation\", \"u_scale\", \"u_resolution\",\"u_image\"];\nconst imgAttributes = [\"a_position\", \"a_texCoord\"];\n\nexport {imgVertexShader, imgFragmentShader, imgUniforms, imgAttributes};","const primitivesVertexShader = `\n precision mediump float;\n\n attribute vec2 a_position;\n\n uniform vec2 u_translation;\n uniform float u_rotation;\n uniform vec2 u_scale;\n\n uniform vec2 u_resolution;\n\n void main(void) {\n float c = cos(u_rotation);\n float s = sin(u_rotation);\n\n mat3 translationMatrix1 = mat3(\n 1, 0, 0,\n 0, 1, 0,\n u_translation.x, u_translation.y, 1\n );\n\n //mat3 translationMatrix2 = mat3(\n // 1, 0, 0,\n // 0, 1, 0,\n // -u_translation.x, -u_translation.y, 1\n //);\n \n mat3 rotationMatrix = mat3(\n c, s, 0,\n -s, c, 0,\n 0, 0, 1\n );\n\n mat3 scalingMatrix = mat3(\n u_scale.x, 0, 0,\n 0, u_scale.y, 0,\n 0, 0, 1\n );\n \n mat3 matrix = translationMatrix1 * rotationMatrix * scalingMatrix;\n\n vec2 position = (matrix * vec3(a_position, 1)).xy;\n\n vec2 clipSpace = position / u_resolution * 2.0 - 1.0;\n\n gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);\n }\n`;\nconst primitivesFragmentShader = `\n precision mediump float;\n\n uniform vec4 u_color;\n uniform float u_fade_min; \n uniform float u_fade_max;\n uniform vec2 u_resolution;\n uniform vec2 u_translation;\n\n void main(void) {\n vec4 p = u_color;\n if (u_fade_min > 0.0) {\n vec2 fix_tr = vec2(u_translation.x, u_resolution.y - u_translation.y); \n float distance = distance(fix_tr.xy, gl_FragCoord.xy);\n if (u_fade_min <= distance && distance <= u_fade_max) {\n float percent = ((distance - u_fade_max) / (u_fade_min - u_fade_max)) * 100.0;\n p.a = u_color.a * (percent / 100.0);\n }\n }\n\n gl_FragColor = p;\n }\n`;\nconst primitivesUniforms = [\"u_translation\", \"u_rotation\", \"u_scale\", \"u_resolution\", \"u_fade_min\", \"u_fade_max\", \"u_color\"];\nconst primitivesAttributes = [\"a_position\"];\n\nexport { primitivesVertexShader, primitivesFragmentShader, primitivesUniforms, primitivesAttributes };","/**\n * storing current WebGLTexture\n */\nexport class TextureStorage {\n /**\n * @type {Number}\n */\n #textureIndex;\n /**\n * @type {WebGLTexture}\n */\n #texture;\n /**\n * @type {boolean}\n */\n #isTextureRecalculated = true;\n constructor(texture, textureIndex = 0) {\n this.#texture = texture;\n this.#textureIndex = textureIndex;\n }\n\n get _isTextureRecalculated() {\n return this.#isTextureRecalculated;\n }\n\n set _isTextureRecalculated(value) {\n this.#isTextureRecalculated = value;\n }\n\n get _texture() {\n return this.#texture;\n }\n\n set _texture(value) {\n this.#texture = value;\n }\n\n get _textureIndex() {\n return this.#textureIndex;\n }\n}","import { ERROR_CODES, CONST, WARNING_CODES } from \"../../constants.js\";\r\nimport { crossProduct } from \"../../utils.js\";\r\nimport { Exception, Warning } from \"../Exception.js\";\r\nimport { GameStageData } from \"../GameStageData.js\";\r\nimport { TextureStorage } from \"./TextureStorage.js\";\r\n\r\nexport class WebGlEngine {\r\n /**\r\n * @type {WebGLRenderingContext}\r\n */\r\n #gl;\r\n /**\r\n * @type {number}\r\n */\r\n #MAX_TEXTURES;\r\n /**\r\n * @type {boolean}\r\n */\r\n #debug;\r\n /**\r\n * @type {Object}\r\n */\r\n #gameOptions;\r\n /**\r\n * @type {WebGLBuffer | null}\r\n */\r\n #positionBuffer;\r\n /**\r\n * @type {WebGLBuffer | null}\r\n */\r\n #texCoordBuffer;\r\n\r\n /**\r\n * @type {Map>}\r\n */\r\n #webGlProgramsVarsLocations = new Map();\r\n\r\n constructor(context, gameOptions) {\r\n if (!context || !(context instanceof WebGLRenderingContext)) {\r\n Exception(ERROR_CODES.UNEXPECTED_INPUT_PARAMS, \" context parameter should be specified and equal to WebGLRenderingContext\");\r\n }\r\n \r\n this.#gl = context;\r\n this.#gameOptions = gameOptions;\r\n this.#debug = gameOptions.debug.checkWebGlErrors;\r\n this.#MAX_TEXTURES = context.getParameter(context.MAX_TEXTURE_IMAGE_UNITS);\r\n this.#positionBuffer = context.createBuffer();\r\n this.#texCoordBuffer = context.createBuffer();\r\n }\r\n\r\n getProgram(name) {\r\n return this.#registeredWebGlPrograms.get(name);\r\n }\r\n\r\n getProgramVarLocations(name) {\r\n return this.#webGlProgramsVarsLocations.get(name);\r\n }\r\n\r\n _fixCanvasSize(width, height) {\r\n this.#gl.viewport(0, 0, width, height);\r\n }\r\n _initWebGlAttributes = () => {\r\n const gl = this.#gl;\r\n gl.enable(gl.BLEND);\r\n gl.enable(gl.STENCIL_TEST);\r\n gl.stencilFunc(gl.ALWAYS, 1, 0xFF);\r\n //if stencil test and depth test pass we replace the initial value\r\n gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);\r\n return Promise.resolve();\r\n };\r\n\r\n /**\r\n * \r\n * @returns {Promise}\r\n */\r\n _initiateWasm = () => {\r\n const url = this.#gameOptions.optimization === CONST.OPTIMIZATION.WEB_ASSEMBLY.NATIVE_WAT ? this.#gameOptions.optimizationWASMUrl : this.#gameOptions.optimizationAssemblyUrl;\r\n return new Promise((resolve, reject) => {\r\n this.layerData = new WebAssembly.Memory({\r\n initial:1000 // 6.4MiB x 10 = 64MiB(~67,1Mb)\r\n });\r\n this.layerDataFloat32 = new Float32Array(this.layerData.buffer);\r\n const importObject = {\r\n env: {\r\n memory: this.layerData,\r\n logi: console.log,\r\n logf: console.log\r\n }\r\n };\r\n\r\n fetch(url)\r\n .then((response) => response.arrayBuffer())\r\n .then((module) => WebAssembly.instantiate(module, importObject))\r\n .then((obj) => {\r\n this.calculateBufferData = obj.instance.exports.calculateBufferData;\r\n resolve();\r\n });\r\n });\r\n };\r\n\r\n _clearView() {\r\n const gl = this.#gl;\r\n //cleanup buffer, is it required?\r\n //gl.bindBuffer(gl.ARRAY_BUFFER, null);\r\n gl.clearColor(0, 0, 0, 0);// shouldn't be gl.clearColor(0, 0, 0, 1); ?\r\n // Clear the color buffer with specified clear color\r\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);\r\n }\r\n \r\n _render(verticesNumber, primitiveType, offset = 0) {\r\n const gl = this.#gl,\r\n err = this.#debug ? gl.getError() : 0;\r\n if (err !== 0) {\r\n console.error(err);\r\n throw new Error(\"Error num: \" + err);\r\n } else {\r\n gl.drawArrays(primitiveType, offset, verticesNumber);\r\n // set blend to default\r\n gl.stencilFunc(gl.ALWAYS, 1, 0xFF);\r\n }\r\n return new Promise((resolve, reject) => {\r\n if (this.#gameOptions.debug.delayBetweenObjectRender) {\r\n setTimeout(() => {\r\n resolve();\r\n }, 1000);\r\n } else {\r\n resolve();\r\n }\r\n });\r\n }\r\n\r\n /*************************************\r\n * Register and compile programs\r\n ************************************/\r\n\r\n /**\r\n * \r\n * @param {string} programName\r\n * @param {string} vertexShader - raw vertex shader program\r\n * @param {string} fragmentShader - raw fragment shader program \r\n * @param {Array} uVars - program uniform variables names\r\n * @param {Array} aVars - program attribute variables names\r\n * @returns {Promise}\r\n */\r\n _registerAndCompileWebGlProgram(programName, vertexShader, fragmentShader, uVars, aVars) {\r\n const program = this.#compileWebGlProgram(vertexShader, fragmentShader),\r\n varsLocations = this.#getProgramVarsLocations(program, uVars, aVars);\r\n this.#registeredWebGlPrograms.set(programName, program);\r\n this.#webGlProgramsVarsLocations.set(programName, varsLocations);\r\n\r\n return Promise.resolve();\r\n }\r\n\r\n /**\r\n * @returns {WebGLProgram}\r\n */\r\n #compileWebGlProgram (vertexShader, fragmentShader) {\r\n const gl = this.#gl,\r\n program = gl.createProgram();\r\n\r\n if (program) {\r\n const compVertexShader = this.#compileShader(gl, vertexShader, gl.VERTEX_SHADER);\r\n if (compVertexShader) {\r\n gl.attachShader(program, compVertexShader);\r\n } else {\r\n Exception(ERROR_CODES.WEBGL_ERROR, \"#compileShader(vertexShaderSource) is null\");\r\n }\r\n\r\n const compFragmentShader = this.#compileShader(gl, fragmentShader, gl.FRAGMENT_SHADER);\r\n if (compFragmentShader) {\r\n gl.attachShader(program, compFragmentShader);\r\n } else {\r\n Exception(ERROR_CODES.WEBGL_ERROR, \"#compileShader(fragmentShaderSource) is null\");\r\n }\r\n\r\n gl.linkProgram(program);\r\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\r\n const info = gl.getProgramInfoLog(program);\r\n Exception(ERROR_CODES.WEBGL_ERROR, `Could not compile WebGL program. \\n\\n${info}`);\r\n }\r\n } else {\r\n Exception(ERROR_CODES.WEBGL_ERROR, \"gl.createProgram() is null\");\r\n }\r\n return program;\r\n }\r\n\r\n /**\r\n * \r\n * @param {WebGLProgram} program\r\n * @param {Array} uVars - uniform variables\r\n * @param {Array} aVars - attributes variables\r\n * @returns {Object} - uniform or attribute\r\n */\r\n #getProgramVarsLocations(program, uVars, aVars) {\r\n const gl = this.#gl;\r\n let locations = {};\r\n uVars.forEach(elementName => {\r\n locations[elementName] = gl.getUniformLocation(program, elementName);\r\n });\r\n aVars.forEach(elementName => {\r\n locations[elementName] = gl.getAttribLocation(program, elementName);\r\n });\r\n return locations;\r\n }\r\n\r\n #compileShader(gl, shaderSource, shaderType) {\r\n const shader = gl.createShader(shaderType);\r\n if (shader) {\r\n gl.shaderSource(shader, shaderSource);\r\n gl.compileShader(shader);\r\n\r\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\r\n const info = gl.getShaderInfoLog(shader);\r\n Exception(ERROR_CODES.WEBGL_ERROR, \"Couldn't compile webGl program. \\n\\n\" + info);\r\n }\r\n } else {\r\n Exception(ERROR_CODES.WEBGL_ERROR, `gl.createShader(${shaderType}) is null`);\r\n }\r\n return shader;\r\n }\r\n /*------------------------------------\r\n * End of Register and compile programs\r\n -------------------------------------*/\r\n\r\n /**********************************\r\n * Predefined Drawing programs\r\n **********************************/\r\n _bindPrimitives = (renderObject, gl, pageData, program, vars) => {\r\n const [ xOffset, yOffset ] = renderObject.isOffsetTurnedOff === true ? [0,0] : pageData.worldOffset,\r\n x = renderObject.x - xOffset,\r\n y = renderObject.y - yOffset,\r\n scale = [1, 1],\r\n rotation = renderObject.rotation,\r\n blend = renderObject.blendFunc ? renderObject.blendFunc : [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA],\r\n { \r\n u_translation: translationLocation,\r\n u_rotation: rotationRotation,\r\n u_scale: scaleLocation,\r\n u_resolution: resolutionUniformLocation,\r\n u_color: colorUniformLocation,\r\n a_position: positionAttributeLocation,\r\n u_fade_min: fadeMinLocation\r\n } = vars;\r\n \r\n let verticesNumber = 0;\r\n gl.useProgram(program);\r\n // set the resolution\r\n gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);\r\n gl.uniform2f(translationLocation, x, y);\r\n gl.uniform2f(scaleLocation, scale[0], scale[1]);\r\n gl.uniform1f(rotationRotation, rotation);\r\n gl.uniform1f(fadeMinLocation, 0);\r\n\r\n gl.enableVertexAttribArray(positionAttributeLocation);\r\n\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#positionBuffer);\r\n\r\n switch (renderObject.type) {\r\n case CONST.DRAW_TYPE.RECTANGLE:\r\n this.#setSingleRectangle(renderObject.width, renderObject.height);\r\n verticesNumber += 6;\r\n break;\r\n case CONST.DRAW_TYPE.TEXT:\r\n break;\r\n case CONST.DRAW_TYPE.CIRCLE: {\r\n const coords = renderObject.vertices;\r\n gl.bufferData(gl.ARRAY_BUFFER, \r\n new Float32Array(coords), gl.STATIC_DRAW);\r\n verticesNumber += coords.length / 2;\r\n break;\r\n }\r\n case CONST.DRAW_TYPE.POLYGON: {\r\n const triangles = this.#triangulatePolygon(renderObject.vertices);\r\n this.#bindPolygon(triangles);\r\n const len = triangles.length;\r\n if (len % 3 !== 0) {\r\n Warning(WARNING_CODES.POLYGON_VERTICES_NOT_CORRECT, `polygons ${renderObject.id}, vertices are not correct, skip drawing`);\r\n return Promise.reject();\r\n }\r\n verticesNumber += len / 2;\r\n break;\r\n }\r\n }\r\n //Tell the attribute how to get data out of positionBuffer\r\n const size = 2,\r\n type = gl.FLOAT, // data is 32bit floats\r\n normalize = false,\r\n stride = 0, // move forward size * sizeof(type) each iteration to get next position\r\n offset = 0; // start of beginning of the buffer\r\n gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset);\r\n\r\n const colorArray = this.#rgbaToArray(renderObject.bgColor);\r\n gl.uniform4f(colorUniformLocation, colorArray[0]/255, colorArray[1]/255, colorArray[2]/255, colorArray[3]);\r\n \r\n if (blend) {\r\n gl.blendFunc(blend[0], blend[1]);\r\n }\r\n \r\n if (renderObject.isMaskAttached) {\r\n gl.stencilFunc(gl.EQUAL, renderObject._maskId, 0xFF);\r\n } else if (renderObject._isMask) {\r\n gl.stencilFunc(gl.ALWAYS, renderObject.id, 0xFF);\r\n }\r\n return Promise.resolve([verticesNumber, gl.TRIANGLES]);\r\n };\r\n _bindConus = (renderObject, gl, pageData, program, vars) => {\r\n const [ xOffset, yOffset ] = renderObject.isOffsetTurnedOff === true ? [0,0] : pageData.worldOffset,\r\n x = renderObject.x - xOffset,\r\n y = renderObject.y - yOffset,\r\n scale = [1, 1],\r\n rotation = renderObject.rotation,\r\n { \r\n u_translation: translationLocation,\r\n u_rotation: rotationRotation,\r\n u_scale: scaleLocation,\r\n u_resolution: resolutionUniformLocation,\r\n u_color: colorUniformLocation,\r\n a_position: positionAttributeLocation,\r\n u_fade_max: fadeMaxLocation,\r\n u_fade_min: fadeMinLocation\r\n } = vars,\r\n coords = renderObject.vertices,\r\n fillStyle = renderObject.bgColor,\r\n fade_min = renderObject.fade_min,\r\n fadeLen = renderObject.radius,\r\n blend = renderObject.blendFunc ? renderObject.blendFunc : [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA];\r\n let verticesNumber = 0;\r\n\r\n gl.useProgram(program);\r\n \r\n // set the resolution\r\n gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);\r\n gl.uniform2f(translationLocation, x, y);\r\n gl.uniform2f(scaleLocation, scale[0], scale[1]);\r\n gl.uniform1f(rotationRotation, rotation);\r\n gl.uniform1f(fadeMinLocation, fade_min);\r\n gl.uniform1f(fadeMaxLocation, fadeLen);\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#positionBuffer);\r\n\r\n gl.bufferData(gl.ARRAY_BUFFER, \r\n new Float32Array(coords), gl.STATIC_DRAW);\r\n\r\n gl.enableVertexAttribArray(positionAttributeLocation);\r\n //Tell the attribute how to get data out of positionBuffer\r\n const size = 2,\r\n type = gl.FLOAT, // data is 32bit floats\r\n normalize = false,\r\n stride = 0, // move forward size * sizeof(type) each iteration to get next position\r\n offset = 0; // start of beginning of the buffer\r\n gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset);\r\n\r\n verticesNumber += coords.length / 2;\r\n\r\n if (blend) {\r\n gl.blendFunc(blend[0], blend[1]);\r\n }\r\n\r\n const colorArray = this.#rgbaToArray(fillStyle);\r\n\r\n gl.uniform4f(colorUniformLocation, colorArray[0]/255, colorArray[1]/255, colorArray[2]/255, colorArray[3]);\r\n \r\n if (renderObject.isMaskAttached) {\r\n gl.stencilFunc(gl.EQUAL, renderObject._maskId, 0xFF);\r\n } else if (renderObject._isMask) {\r\n gl.stencilFunc(gl.ALWAYS, renderObject.id, 0xFF);\r\n }\r\n \r\n return Promise.resolve([verticesNumber, gl.TRIANGLE_FAN]);\r\n };\r\n\r\n _bindText = (renderObject, gl, pageData, program, vars) => {\r\n const { u_translation: translationLocation,\r\n u_rotation: rotationRotation,\r\n u_scale: scaleLocation,\r\n u_resolution: resolutionUniformLocation,\r\n a_position: positionAttributeLocation,\r\n a_texCoord: texCoordLocation,\r\n u_image: u_imageLocation } = vars;\r\n\r\n const {width:boxWidth, height:boxHeight} = renderObject.boundariesBox,\r\n image_name = renderObject.text,\r\n [ xOffset, yOffset ] = renderObject.isOffsetTurnedOff === true ? [0,0] : pageData.worldOffset,\r\n x = renderObject.x - xOffset,\r\n y = renderObject.y - yOffset - boxHeight,\r\n blend = renderObject.blendFunc ? renderObject.blendFunc : [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];\r\n\r\n const rotation = 0,\r\n scale = [1, 1];\r\n const vecX1 = x,\r\n vecY1 = y,\r\n vecX2 = vecX1 + boxWidth,\r\n vecY2 = vecY1 + boxHeight;\r\n const verticesBufferData = [\r\n vecX1, vecY1,\r\n vecX2, vecY1,\r\n vecX1, vecY2,\r\n vecX1, vecY2,\r\n vecX2, vecY1,\r\n vecX2, vecY2\r\n ],\r\n texturesBufferData = [\r\n 0, 0,\r\n 1, 0,\r\n 0, 1,\r\n 0, 1,\r\n 1, 0,\r\n 1, 1\r\n ];\r\n let verticesNumber = 0;\r\n\r\n gl.useProgram(program);\r\n // set the resolution\r\n gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);\r\n gl.uniform2f(translationLocation, x, y);\r\n gl.uniform2f(scaleLocation, scale[0], scale[1]);\r\n gl.uniform1f(rotationRotation, rotation);\r\n \r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#positionBuffer);\r\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verticesBufferData), gl.STATIC_DRAW);\r\n gl.enableVertexAttribArray(positionAttributeLocation);\r\n //Tell the attribute how to get data out of positionBuffer\r\n const size = 2,\r\n type = gl.FLOAT, // data is 32bit floats\r\n normalize = false,\r\n stride = 0, // move forward size * sizeof(type) each iteration to get next position\r\n offset = 0; // start of beginning of the buffer\r\n gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset);\r\n\r\n //textures buffer\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#texCoordBuffer);\r\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texturesBufferData), gl.STATIC_DRAW);\r\n\r\n gl.enableVertexAttribArray(texCoordLocation);\r\n gl.vertexAttribPointer(texCoordLocation, 2, gl.FLOAT, false, 0, 0);\r\n \r\n verticesNumber += 6;\r\n // remove box\r\n // fix text edges\r\n gl.blendFunc(blend[0], blend[1]);\r\n //\r\n //var currentTexture = gl.getParameter(gl.TEXTURE_BINDING_2D);\r\n \r\n let textureStorage = renderObject._textureStorage;\r\n if (!textureStorage) {\r\n //const activeTexture = gl.getParameter(gl.ACTIVE_TEXTURE);\r\n textureStorage = new TextureStorage(gl.createTexture());\r\n renderObject._textureStorage = textureStorage;\r\n }\r\n if (textureStorage._isTextureRecalculated === true) {\r\n this.#updateTextWebGlTexture(gl, textureStorage._texture, renderObject._textureCanvas);\r\n textureStorage._isTextureRecalculated = false;\r\n } else {\r\n this.#bindTexture(gl, textureStorage._texture);\r\n }\r\n gl.uniform1i(u_imageLocation, textureStorage._textureIndex);\r\n gl.depthMask(false);\r\n return Promise.resolve([verticesNumber, gl.TRIANGLES]);\r\n };\r\n\r\n _bindImage = (renderObject, gl, pageData, program, vars) => {\r\n const { \r\n u_translation: translationLocation,\r\n u_rotation: rotationRotation,\r\n u_scale: scaleLocation,\r\n u_resolution: resolutionUniformLocation,\r\n a_position: positionAttributeLocation,\r\n a_texCoord: texCoordLocation,\r\n u_image: u_imageLocation } = vars;\r\n\r\n const [ xOffset, yOffset ] = renderObject.isOffsetTurnedOff === true ? [0,0] : pageData.worldOffset,\r\n x = renderObject.x - xOffset,\r\n y = renderObject.y - yOffset;\r\n\r\n const atlasImage = renderObject.image,\r\n animationIndex = renderObject.imageIndex,\r\n image_name = renderObject.key,\r\n shapeMaskId = renderObject._maskId,\r\n spacing = renderObject.spacing,\r\n blend = renderObject.blendFunc ? renderObject.blendFunc : [gl.ONE, gl.ONE_MINUS_SRC_ALPHA],\r\n scale = [1, 1];\r\n let imageX = 0,\r\n imageY = 0,\r\n colNum = 0,\r\n rowNum = 0,\r\n verticesNumber = 0;\r\n if (animationIndex !== 0) {\r\n const imageColsNumber = (atlasImage.width + spacing) / (renderObject.width + spacing);\r\n colNum = animationIndex % imageColsNumber;\r\n rowNum = Math.floor(animationIndex / imageColsNumber);\r\n imageX = colNum * renderObject.width + (colNum * spacing),\r\n imageY = rowNum * renderObject.height + (rowNum * spacing);\r\n }\r\n const posX = x - renderObject.width / 2,\r\n posY = y - renderObject.height / 2;\r\n const vecX1 = posX,\r\n vecY1 = posY,\r\n vecX2 = vecX1 + renderObject.width,\r\n vecY2 = vecY1 + renderObject.height,\r\n texX1 = 1 / atlasImage.width * imageX,\r\n texY1 = 1 / atlasImage.height * imageY,\r\n texX2 = texX1 + (1 / atlasImage.width * renderObject.width),\r\n texY2 = texY1 + (1 / atlasImage.height * renderObject.height);\r\n const vectors = [\r\n vecX1, vecY1,\r\n vecX2, vecY1,\r\n vecX1, vecY2,\r\n vecX1, vecY2,\r\n vecX2, vecY1,\r\n vecX2, vecY2\r\n ],\r\n textures = [\r\n texX1, texY1,\r\n texX2, texY1,\r\n texX1, texY2,\r\n texX1, texY2,\r\n texX2, texY1,\r\n texX2, texY2\r\n ];\r\n gl.useProgram(program);\r\n // set the resolution\r\n gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);\r\n gl.uniform2f(translationLocation, x, y);\r\n gl.uniform2f(scaleLocation, scale[0], scale[1]);\r\n gl.uniform1f(rotationRotation, renderObject.rotation);\r\n \r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#positionBuffer);\r\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vectors), gl.STATIC_DRAW);\r\n\r\n verticesNumber += vectors.length / 2;\r\n gl.enableVertexAttribArray(positionAttributeLocation);\r\n //Tell the attribute how to get data out of positionBuffer\r\n const size = 2,\r\n type = gl.FLOAT, // data is 32bit floats\r\n normalize = false,\r\n stride = 0, // move forward size * sizeof(type) each iteration to get next position\r\n offset = 0; // start of beginning of the buffer\r\n gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset);\r\n\r\n //textures buffer\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#texCoordBuffer);\r\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textures), gl.STATIC_DRAW);\r\n\r\n gl.enableVertexAttribArray(texCoordLocation);\r\n gl.vertexAttribPointer(texCoordLocation, 2, gl.FLOAT, false, 0, 0);\r\n\r\n let textureStorage = renderObject._textureStorage;\r\n if (!textureStorage) {\r\n textureStorage = new TextureStorage(gl.createTexture());\r\n renderObject._textureStorage = textureStorage;\r\n } \r\n if (textureStorage._isTextureRecalculated === true) {\r\n this.#updateWebGlTexture(gl, textureStorage._texture, renderObject.image);\r\n textureStorage._isTextureRecalculated = false;\r\n } else {\r\n this.#bindTexture(gl, textureStorage._texture);\r\n }\r\n\r\n gl.uniform1i(u_imageLocation, textureStorage._textureIndex);\r\n // make image transparent parts transparent\r\n gl.blendFunc(blend[0], blend[1]);\r\n if (shapeMaskId) {\r\n gl.stencilFunc(gl.EQUAL, shapeMaskId, 0xFF);\r\n //gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);\r\n }\r\n\r\n return Promise.resolve([verticesNumber, gl.TRIANGLES]);\r\n };\r\n\r\n _bindTileImages = async(renderLayer, gl, pageData, program, vars) => {\r\n const { u_translation: translationLocation,\r\n u_rotation: rotationRotation,\r\n u_scale: scaleLocation,\r\n u_resolution: resolutionUniformLocation,\r\n a_position: positionAttributeLocation,\r\n a_texCoord: texCoordLocation,\r\n u_image: u_imageLocation } = vars;\r\n\r\n gl.useProgram(program);\r\n let renderLayerData;\r\n switch (this.#gameOptions.optimization) {\r\n case CONST.OPTIMIZATION.NATIVE_JS.NOT_OPTIMIZED:\r\n renderLayerData = await this.#prepareRenderLayerOld(renderLayer, pageData);\r\n break;\r\n case CONST.OPTIMIZATION.WEB_ASSEMBLY.ASSEMBLY_SCRIPT:\r\n case CONST.OPTIMIZATION.WEB_ASSEMBLY.NATIVE_WAT:\r\n renderLayerData = await this.#prepareRenderLayerWM(renderLayer, pageData);\r\n break;\r\n case CONST.OPTIMIZATION.NATIVE_JS.OPTIMIZED:\r\n default:\r\n renderLayerData = await this.#prepareRenderLayer(renderLayer, pageData);\r\n }\r\n const translation = [0, 0],\r\n scale = [1, 1],\r\n rotation = 0,\r\n drawMask = [\"ONE\", \"ONE_MINUS_SRC_ALPHA\"],\r\n shapeMaskId = renderLayer._maskId;\r\n\r\n let verticesNumber = 0,\r\n isTextureBind = false;\r\n for (let i = 0; i < renderLayerData.length; i++) {\r\n const data = renderLayerData[i],\r\n vectors = data[0],\r\n textures = data[1],\r\n image_name = data[2],\r\n image = data[3];\r\n // if layer use multiple tilesets\r\n if (vectors.length > 0 && textures.length > 0) {\r\n // need to have additional draw call for each new texture added\r\n // probably it could be combined in one draw call if multiple textures \r\n // could be used in one draw call\r\n if (isTextureBind) {\r\n await this._render(verticesNumber, gl.TRIANGLES);\r\n }\r\n // set the resolution\r\n gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);\r\n gl.uniform2f(translationLocation,translation[0], translation[1]);\r\n gl.uniform2f(scaleLocation, scale[0], scale[1]);\r\n gl.uniform1f(rotationRotation, rotation);\r\n \r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#positionBuffer);\r\n gl.bufferData(gl.ARRAY_BUFFER, vectors, gl.STATIC_DRAW);\r\n\r\n gl.enableVertexAttribArray(positionAttributeLocation);\r\n //Tell the attribute how to get data out of positionBuffer\r\n const size = 2,\r\n type = gl.FLOAT, // data is 32bit floats\r\n normalize = false,\r\n stride = 0, // move forward size * sizeof(type) each iteration to get next position\r\n offset = 0; // verticesNumber * 4; // start of beginning of the buffer\r\n gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset);\r\n\r\n //textures buffer\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#texCoordBuffer);\r\n gl.bufferData(gl.ARRAY_BUFFER, textures, gl.STATIC_DRAW);\r\n\r\n gl.enableVertexAttribArray(texCoordLocation);\r\n gl.vertexAttribPointer(texCoordLocation, 2, gl.FLOAT, false, 0, offset);\r\n\r\n let textureStorage = renderLayer._textureStorages[i];\r\n \r\n if (!textureStorage) {\r\n textureStorage = new TextureStorage(gl.createTexture(), i);\r\n renderLayer._setTextureStorage(i, textureStorage);\r\n }\r\n if (textureStorage._isTextureRecalculated === true) { \r\n this.#updateWebGlTexture(gl, textureStorage._texture, image, textureStorage._textureIndex);\r\n textureStorage._isTextureRecalculated = false;\r\n } else {\r\n this.#bindTexture(gl, textureStorage._texture, textureStorage._textureIndex);\r\n }\r\n gl.uniform1i(u_imageLocation, textureStorage._textureIndex);\r\n gl.blendFunc(gl[drawMask[0]], gl[drawMask[1]]);\r\n verticesNumber = vectors.length / 2;\r\n if (shapeMaskId) {\r\n gl.stencilFunc(gl.EQUAL, shapeMaskId, 0xFF);\r\n }\r\n isTextureBind = true;\r\n }\r\n }\r\n return Promise.resolve([verticesNumber, gl.TRIANGLES]);\r\n };\r\n\r\n _drawPolygon(renderObject, pageData) {\r\n const [ xOffset, yOffset ] = renderObject.isOffsetTurnedOff === true ? [0,0] : pageData.worldOffset,\r\n x = renderObject.x - xOffset,\r\n y = renderObject.y - yOffset,\r\n rotation = renderObject.rotation || 0,\r\n vertices = renderObject.vertices,\r\n color = this.#gameOptions.debug.boundaries.boundariesColor;\r\n const program = this.getProgram(CONST.WEBGL.DRAW_PROGRAMS.PRIMITIVES);\r\n const { u_translation: translationLocation,\r\n u_rotation: rotationRotation,\r\n u_scale: scaleLocation,\r\n u_resolution: resolutionUniformLocation,\r\n u_color: colorUniformLocation,\r\n a_position: positionAttributeLocation,\r\n u_fade_max: fadeMaxLocation,\r\n u_fade_min: fadeMinLocation\r\n } = this.getProgramVarLocations(CONST.WEBGL.DRAW_PROGRAMS.PRIMITIVES),\r\n gl = this.#gl;\r\n\r\n let verticesNumber = 0;\r\n gl.useProgram(program);\r\n // set the resolution\r\n gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);\r\n\r\n gl.uniform2f(translationLocation, x, y);\r\n gl.uniform2f(scaleLocation, 1, 1);\r\n gl.uniform1f(rotationRotation, rotation);\r\n gl.uniform1f(fadeMinLocation, 0);\r\n\r\n gl.enableVertexAttribArray(positionAttributeLocation);\r\n\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#positionBuffer);\r\n\r\n const triangles = this.#triangulatePolygon(vertices);\r\n \r\n const polygonVerticesNum = triangles.length;\r\n if (polygonVerticesNum % 3 !== 0) {\r\n Warning(WARNING_CODES.POLYGON_VERTICES_NOT_CORRECT, \"polygon boundaries vertices are not correct, skip drawing\");\r\n return;\r\n }\r\n this.#bindPolygon(triangles);\r\n verticesNumber += polygonVerticesNum / 2;\r\n //Tell the attribute how to get data out of positionBuffer\r\n const size = 2,\r\n type = gl.FLOAT, // data is 32bit floats\r\n normalize = false,\r\n stride = 0, // move forward size * sizeof(type) each iteration to get next position\r\n offset = 0; // start of beginning of the buffer\r\n gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset);\r\n\r\n const colorArray = this.#rgbaToArray(color);\r\n gl.uniform4f(colorUniformLocation, colorArray[0]/255, colorArray[1]/255, colorArray[2]/255, colorArray[3]);\r\n\r\n this._render(verticesNumber, gl.TRIANGLES);\r\n }\r\n\r\n _bindLine = (renderObject, gl, pageData, program, vars) => {\r\n const [ xOffset, yOffset ] = renderObject.isOffsetTurnedOff === true ? [0,0] : pageData.worldOffset,\r\n x = renderObject.x - xOffset,\r\n y = renderObject.y - yOffset,\r\n scale = [1, 1],\r\n rotation = renderObject.rotation,\r\n { \r\n u_translation: translationLocation,\r\n u_rotation: rotationRotation,\r\n u_scale: scaleLocation,\r\n u_resolution: resolutionUniformLocation,\r\n u_color: colorUniformLocation,\r\n a_position: positionAttributeLocation,\r\n u_fade_max: fadeMaxLocation,\r\n u_fade_min: fadeMinLocation\r\n } = vars,\r\n coords = renderObject.vertices,\r\n fillStyle = renderObject.bgColor,\r\n fade_min = renderObject.fade_min,\r\n fadeLen = renderObject.radius,\r\n lineWidth = this.#gameOptions.debug.boundaries.boundariesWidth;\r\n let verticesNumber = 0;\r\n\r\n gl.useProgram(program);\r\n // set the resolution\r\n gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);\r\n\r\n gl.uniform2f(translationLocation, x, y);\r\n gl.uniform2f(scaleLocation, 1, 1);\r\n gl.uniform1f(rotationRotation, rotation);\r\n gl.uniform1f(fadeMinLocation, 0);\r\n\r\n gl.enableVertexAttribArray(positionAttributeLocation);\r\n\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#positionBuffer);\r\n\r\n gl.bufferData(\r\n gl.ARRAY_BUFFER, \r\n new Float32Array(coords),\r\n gl.STATIC_DRAW);\r\n\r\n verticesNumber += coords.length / 2;\r\n //Tell the attribute how to get data out of positionBuffer\r\n const size = 2,\r\n type = gl.FLOAT, // data is 32bit floats\r\n normalize = false,\r\n stride = 0, // move forward size * sizeof(type) each iteration to get next position\r\n offset = 0; // start of beginning of the buffer\r\n gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset);\r\n\r\n const colorArray = this.#rgbaToArray(fillStyle);\r\n gl.uniform4f(colorUniformLocation, colorArray[0]/255, colorArray[1]/255, colorArray[2]/255, colorArray[3]);\r\n \r\n gl.lineWidth(lineWidth);\r\n\r\n return Promise.resolve([0, gl.LINES]);\r\n };\r\n \r\n _drawLines(linesArray, color, lineWidth = 1, rotation = 0, translation = [0, 0]) {\r\n const program = this.getProgram(CONST.WEBGL.DRAW_PROGRAMS.PRIMITIVES);\r\n const { u_translation: translationLocation,\r\n u_rotation: rotationRotation,\r\n u_scale: scaleLocation,\r\n u_resolution: resolutionUniformLocation,\r\n u_color: colorUniformLocation,\r\n a_position: positionAttributeLocation,\r\n u_fade_max: fadeMaxLocation,\r\n u_fade_min: fadeMinLocation\r\n } = this.getProgramVarLocations(CONST.WEBGL.DRAW_PROGRAMS.PRIMITIVES),\r\n gl = this.#gl;\r\n\r\n let verticesNumber = 0;\r\n gl.useProgram(program);\r\n // set the resolution\r\n gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);\r\n\r\n gl.uniform2f(translationLocation, translation[0], translation[1]);\r\n gl.uniform2f(scaleLocation, 1, 1);\r\n gl.uniform1f(rotationRotation, rotation);\r\n gl.uniform1f(fadeMinLocation, 0);\r\n\r\n gl.enableVertexAttribArray(positionAttributeLocation);\r\n\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#positionBuffer);\r\n\r\n gl.bufferData(\r\n gl.ARRAY_BUFFER, \r\n new Float32Array(linesArray),\r\n gl.STATIC_DRAW);\r\n\r\n verticesNumber += linesArray.length / 2;\r\n //Tell the attribute how to get data out of positionBuffer\r\n const size = 2,\r\n type = gl.FLOAT, // data is 32bit floats\r\n normalize = false,\r\n stride = 0, // move forward size * sizeof(type) each iteration to get next position\r\n offset = 0; // start of beginning of the buffer\r\n gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset);\r\n\r\n const colorArray = this.#rgbaToArray(color);\r\n gl.uniform4f(colorUniformLocation, colorArray[0]/255, colorArray[1]/255, colorArray[2]/255, colorArray[3]);\r\n \r\n gl.lineWidth(lineWidth);\r\n \r\n this._render(verticesNumber, gl.LINES);\r\n }\r\n\r\n /**\r\n * \r\n * @param {DrawTiledLayer} renderLayer \r\n * @param {GameStageData} pageData\r\n * @returns {Promise>}\r\n */\r\n #prepareRenderLayer(renderLayer, pageData) {\r\n const INDEX_TOP_LINE = 0,\r\n INDEX_RIGHT_LINE = 1,\r\n INDEX_BOTTOM_LINE = 2,\r\n INDEX_LEFT_LINE = 3;\r\n\r\n const INDEX_X1 = 0,\r\n INDEX_Y1 = 1,\r\n INDEX_X2 = 2,\r\n INDEX_Y2 = 3;\r\n return new Promise((resolve, reject) => {\r\n const tilemap = renderLayer.tilemap,\r\n tilesets = renderLayer.tilesets,\r\n tilesetImages = renderLayer.tilesetImages,\r\n layerData = renderLayer.layerData,\r\n { tileheight:dtheight, tilewidth:dtwidth } = tilemap,\r\n tilewidth = dtwidth,\r\n tileheight = dtheight,\r\n [ settingsWorldWidth, settingsWorldHeight ] = pageData.worldDimensions,\r\n [ canvasW, canvasH ] = pageData.canvasDimensions,\r\n [ xOffset, yOffset ] = renderLayer.isOffsetTurnedOff === true ? [0,0] : pageData.worldOffset,\r\n boundariesCalculations = this.#gameOptions.render.boundaries.realtimeCalculations,\r\n setBoundaries = renderLayer.setBoundaries;\r\n \r\n let boundariesRowsIndexes = new Map(),\r\n boundaries = [],\r\n ellipseBoundaries = [],\r\n pointBoundaries = [],\r\n tileImagesData = [];\r\n\r\n if (!layerData) {\r\n Warning(WARNING_CODES.NOT_FOUND, \"check tilemap and layers name\");\r\n reject();\r\n }\r\n \r\n for (let i = 0; i < tilesets.length; i++) {\r\n const tilesetData = tilesets[i].data,\r\n firstgid = tilesets[i].firstgid,\r\n nextTileset = tilesets[i + 1],\r\n nextgid = nextTileset ? nextTileset.firstgid : 1_000_000_000, // a workaround to avoid multiple conditions\r\n tilesetwidth = tilesetData.tilewidth,\r\n tilesetheight = tilesetData.tileheight,\r\n atlasImage = tilesetImages[i],\r\n //atlasWidth = atlasImage.width,\r\n //atlasHeight = atlasImage.height,\r\n atlasWidth = tilesetData.imagewidth,\r\n atlasHeight = tilesetData.imageheight,\r\n //atlasRows = atlasHeight / tileheight,\r\n atlasColumns = tilesetData.columns,\r\n layerCols = layerData.width,\r\n layerRows = layerData.height,\r\n worldW = tilewidth * layerCols,\r\n worldH = tileheight * layerRows,\r\n moduloTop = yOffset % tileheight,\r\n moduleLeft = xOffset % tilewidth,\r\n skipRowsTop = yOffset !== 0 ? Math.floor(yOffset / tileheight) : 0,\r\n skipColsLeft = xOffset !== 0 ? Math.floor(xOffset / tilewidth) : 0,\r\n // sometimes canvasW/H may be bigger than world itself\r\n screenRows = worldH > canvasH ? Math.ceil(canvasH / tileheight) + 1 : layerRows,\r\n screenCols = worldW > canvasW ? Math.ceil(canvasW / tilewidth) + 1 : layerCols,\r\n skipColsRight = layerCols - screenCols - skipColsLeft,\r\n cellSpacing = tilesetData.spacing,\r\n cellMargin = tilesetData.margin,\r\n\r\n hasAnimations = tilesetData._hasAnimations,\r\n\r\n verticesBufferData = [],\r\n texturesBufferData = [],\r\n \r\n // additional property which is set in DrawTiledLayer\r\n hasBoundaries = tilesetData._hasBoundaries,\r\n tilesetBoundaries = tilesetData._boundaries; // Map\r\n \r\n if (worldW !== settingsWorldWidth || worldH !== settingsWorldHeight) {\r\n Warning(WARNING_CODES.UNEXPECTED_WORLD_SIZE, \" World size from tilemap is different than settings one, fixing...\");\r\n pageData._setWorldDimensions(worldW, worldH);\r\n }\r\n if (setBoundaries) {\r\n // boundaries cleanups every draw cycles, we need to set world boundaries again\r\n if (this.#gameOptions.render.boundaries.mapBoundariesEnabled) {\r\n pageData._setMapBoundaries();\r\n }\r\n }\r\n\r\n let mapIndex = skipRowsTop * layerCols;\r\n for (let row = 0; row < screenRows; row++) {\r\n mapIndex += skipColsLeft;\r\n let currentRowIndexes = new Map();\r\n for (let col = 0; col < screenCols; col++) {\r\n let tile = layerData.data[mapIndex];\r\n\r\n if ((tile >= firstgid) && (tile < nextgid)) {\r\n const mapPosX = col * dtwidth - moduleLeft,\r\n mapPosY = row * dtheight - moduloTop;\r\n\r\n // actual tile index\r\n tile -= firstgid;\r\n // switch if animations are set\r\n if (hasAnimations) {\r\n const activeTile = tilesetData._animations.get(tile);\r\n if (typeof activeTile !== \"undefined\") {\r\n tile = activeTile;\r\n } \r\n }\r\n\r\n // calculate map position and atlas position\r\n const colNum = tile % atlasColumns,\r\n rowNum = Math.floor(tile / atlasColumns),\r\n atlasPosX = colNum * tilesetwidth + (colNum * cellSpacing),\r\n atlasPosY = rowNum * tilesetheight + (rowNum * cellSpacing),\r\n vecX1 = mapPosX,\r\n vecY1 = mapPosY,\r\n vecX2 = mapPosX + tilesetwidth,\r\n vecY2 = mapPosY + tilesetheight,\r\n texX1 = (1 / atlasWidth) * atlasPosX,\r\n texY1 = (1 / atlasHeight) * atlasPosY,\r\n texX2 = texX1 + (1 / atlasWidth * tilesetwidth),\r\n texY2 = texY1 + (1 / atlasHeight * tilesetheight);\r\n verticesBufferData.push(\r\n vecX1, vecY1,\r\n vecX2, vecY1,\r\n vecX1, vecY2,\r\n vecX1, vecY2,\r\n vecX2, vecY1,\r\n vecX2, vecY2);\r\n texturesBufferData.push(\r\n texX1, texY1,\r\n texX2, texY1,\r\n texX1, texY2,\r\n texX1, texY2,\r\n texX2, texY1,\r\n texX2, texY2\r\n );\r\n if (setBoundaries) {\r\n // if boundary is set in tilesetData\r\n let isBoundaryPreset = false;\r\n if (hasBoundaries && tilesetBoundaries.size > 0) {\r\n const tilesetBoundary = tilesetBoundaries.get(tile);\r\n if (tilesetBoundary) {\r\n isBoundaryPreset = true;\r\n const objectGroup = tilesetBoundary,\r\n objects = objectGroup.objects;\r\n \r\n objects.forEach((object) => {\r\n const baseX = mapPosX + object.x, \r\n baseY = mapPosY + object.y,\r\n rotation = object.rotation;\r\n if (rotation !== 0) {\r\n Warning(\"tilesetData.tiles.rotation property is not supported yet\");\r\n }\r\n if (object.polygon) {\r\n object.polygon.forEach(\r\n (point, idx) => {\r\n const next = object.polygon[idx + 1];\r\n if (next) {\r\n boundaries.push([point.x + baseX, point.y + baseY, next.x + baseX, next.y + baseY]);\r\n } else {\r\n // last point -> link to the first\r\n const first = object.polygon[0];\r\n boundaries.push([point.x + baseX, point.y + baseY, first.x + baseX, first.y + baseY]);\r\n }\r\n });\r\n } else if (object.point) {\r\n // x/y coordinate\r\n pointBoundaries.push([baseX, baseY]);\r\n } else if (object.ellipse) {\r\n const radX = object.width / 2,\r\n radY = object.height / 2;\r\n ellipseBoundaries.push([baseX + radX, baseY + radY, radX, radY]);\r\n } else {\r\n // object is rect\r\n const width = object.width,\r\n height = object.height,\r\n x2 = width + baseX,\r\n y2 = height + baseY;\r\n boundaries.push([baseX, baseY, x2, baseY]);\r\n boundaries.push([x2, baseY, x2, y2]);\r\n boundaries.push([x2, y2, baseX, y2]);\r\n boundaries.push([baseX, y2, baseX, baseY]);\r\n }\r\n });\r\n }\r\n\r\n // extract rect boundary for the whole tile\r\n }\r\n if (isBoundaryPreset === false) {\r\n\r\n let rightLine = [ mapPosX + tilesetwidth, mapPosY, mapPosX + tilesetwidth, mapPosY + tilesetheight ],\r\n bottomLine = [ mapPosX + tilesetwidth, mapPosY + tilesetheight, mapPosX, mapPosY + tilesetheight ],\r\n topLine = [ mapPosX, mapPosY, mapPosX + tilesetwidth, mapPosY],\r\n leftLine = [ mapPosX, mapPosY + tilesetheight, mapPosX, mapPosY ],\r\n currentAddedCellIndexes = [null, null, null, null];\r\n \r\n const topRow = row !== 0 ? boundariesRowsIndexes.get(row - 1) : undefined;\r\n if (topRow ) {\r\n const topCellIndexes = topRow.get(col);\r\n if (topCellIndexes) {\r\n //remove double lines from top\r\n const bottomTopCellIndex = topCellIndexes[INDEX_BOTTOM_LINE],\r\n bottomTopCell = boundaries[bottomTopCellIndex];\r\n if (bottomTopCell) {\r\n const bottomTopCellX1 = bottomTopCell[INDEX_X1],\r\n bottomTopCellY1 = bottomTopCell[INDEX_Y1],\r\n bottomTopCellX2 = bottomTopCell[INDEX_X2],\r\n bottomTopCellY2 = bottomTopCell[INDEX_Y2],\r\n topX1 = topLine[INDEX_X1],\r\n topY1 = topLine[INDEX_Y1],\r\n topX2 = topLine[INDEX_X2],\r\n topY2 = topLine[INDEX_Y2];\r\n \r\n if (topX1 === bottomTopCellX2 && topY1 === bottomTopCellY2 &&\r\n topX2 === bottomTopCellX1 && topY2 === bottomTopCellY1) {\r\n boundaries[bottomTopCellIndex] = undefined;\r\n topLine = undefined;\r\n }\r\n }\r\n\r\n // merge line from top right\r\n const rightTopCellIndex = topCellIndexes[INDEX_RIGHT_LINE],\r\n rightTopCell = boundaries[rightTopCellIndex];\r\n if (rightTopCell) {\r\n const rightTopCellX1 = rightTopCell[INDEX_X1],\r\n rightTopCellY1 = rightTopCell[INDEX_Y1],\r\n rightTopCellX2 = rightTopCell[INDEX_X2],\r\n rightX1 = rightLine[INDEX_X1],\r\n rightX2 = rightLine[INDEX_X2];\r\n if (rightTopCellX1 === rightX2 && rightTopCellX2 === rightX1) {\r\n boundaries[rightTopCellIndex] = undefined;\r\n rightLine[INDEX_X1] = rightTopCellX1;\r\n rightLine[INDEX_Y1] = rightTopCellY1;\r\n }\r\n }\r\n // merge line from top left\r\n const leftTopCellIndex = topCellIndexes[INDEX_LEFT_LINE],\r\n leftTopCell = boundaries[leftTopCellIndex];\r\n if (leftTopCell) {\r\n const leftTopCellX1 = leftTopCell[INDEX_X1],\r\n leftTopCellX2 = leftTopCell[INDEX_X2],\r\n leftTopCellY2 = leftTopCell[INDEX_Y2],\r\n leftX1 = leftLine[INDEX_X1],\r\n leftX2 = leftLine[INDEX_X2];\r\n if (leftTopCellX1 === leftX2 && leftTopCellX2 === leftX1) {\r\n boundaries[leftTopCellIndex] = undefined;\r\n leftLine[INDEX_X2] = leftTopCellX2;\r\n leftLine[INDEX_Y2] = leftTopCellY2;\r\n }\r\n }\r\n }\r\n }\r\n const leftCellIndexes = col !== 0 ? currentRowIndexes.get(col - 1) : undefined;\r\n if (leftCellIndexes) {\r\n\r\n //remove double lines from left\r\n const rightLeftCellIndex = leftCellIndexes[INDEX_RIGHT_LINE],\r\n rightLeftCell = boundaries[rightLeftCellIndex],\r\n rightLeftCellX1 = rightLeftCell[INDEX_X1],\r\n rightLeftCellY1 = rightLeftCell[INDEX_Y1],\r\n rightLeftCellX2 = rightLeftCell[INDEX_X2],\r\n rightLeftCellY2 = rightLeftCell[INDEX_Y2],\r\n leftX1 = leftLine[INDEX_X1],\r\n leftY1 = leftLine[INDEX_Y1],\r\n leftX2 = leftLine[INDEX_X2],\r\n leftY2 = leftLine[INDEX_Y2];\r\n\r\n if (leftX1 === rightLeftCellX2 && leftY1 === rightLeftCellY2 &&\r\n leftX2 === rightLeftCellX1 && leftY2 === rightLeftCellY1) {\r\n boundaries[rightLeftCellIndex] = undefined;\r\n leftLine = undefined;\r\n }\r\n\r\n //merge long lines from left top\r\n const topLeftCellIndex = leftCellIndexes[INDEX_TOP_LINE],\r\n topLeftCell = boundaries[topLeftCellIndex];\r\n if (topLeftCell && topLine) {\r\n const topLeftCellX1 = topLeftCell[INDEX_X1],\r\n topLeftCellY1 = topLeftCell[INDEX_Y1],\r\n topLeftCellY2 = topLeftCell[INDEX_Y2],\r\n topY1 = topLine[INDEX_Y1],\r\n topY2 = topLine[INDEX_Y2];\r\n if (topLeftCellY1 === topY2 && topLeftCellY2 === topY1 ) {\r\n boundaries[topLeftCellIndex] = undefined;\r\n topLine[INDEX_X1] = topLeftCellX1;\r\n topLine[INDEX_Y1] = topLeftCellY1;\r\n }\r\n }\r\n\r\n // merge long lines from left bottom\r\n const bottomLeftCellIndex = leftCellIndexes[INDEX_BOTTOM_LINE],\r\n bottomLeftCell = boundaries[bottomLeftCellIndex];\r\n if (bottomLeftCell) {\r\n const bottomLeftCellY1 = bottomLeftCell[INDEX_Y1],\r\n bottomLeftCellX2 = bottomLeftCell[INDEX_X2],\r\n bottomLeftCellY2 = bottomLeftCell[INDEX_Y2],\r\n bottomY1 = bottomLine[INDEX_Y1],\r\n bottomY2 = bottomLine[INDEX_Y2];\r\n if (bottomLeftCellY1 === bottomY2 && bottomLeftCellY2 === bottomY1 ) {\r\n boundaries[bottomLeftCellIndex] = undefined;\r\n //opposite direction\r\n bottomLine[INDEX_X2] = bottomLeftCellX2;\r\n bottomLine[INDEX_Y2] = bottomLeftCellY2;\r\n }\r\n }\r\n\r\n }\r\n\r\n if (topLine) {\r\n boundaries.push(topLine);\r\n currentAddedCellIndexes[INDEX_TOP_LINE] = boundaries.length - 1;\r\n }\r\n boundaries.push(rightLine);\r\n currentAddedCellIndexes[INDEX_RIGHT_LINE] = boundaries.length - 1;\r\n boundaries.push(bottomLine);\r\n currentAddedCellIndexes[INDEX_BOTTOM_LINE] = boundaries.length - 1;\r\n if (leftLine) {\r\n boundaries.push(leftLine);\r\n currentAddedCellIndexes[INDEX_LEFT_LINE] = boundaries.length - 1;\r\n }\r\n //save values indexes cols info\r\n currentRowIndexes.set(col, currentAddedCellIndexes);\r\n }\r\n }\r\n }\r\n mapIndex++;\r\n }\r\n if (currentRowIndexes.size > 0) {\r\n //save values indexes rows info\r\n boundariesRowsIndexes.set(row, currentRowIndexes);\r\n }\r\n mapIndex += skipColsRight;\r\n }\r\n //this.#bindTileImages(verticesBufferData, texturesBufferData, atlasImage, tilesetData.name, renderLayer._maskId);\r\n tileImagesData.push([new Float32Array(verticesBufferData), new Float32Array(texturesBufferData), tilesetData.name, atlasImage]);\r\n }\r\n \r\n if (setBoundaries) {\r\n // filter undefined value\r\n const filtered = boundaries.filter(array => array);\r\n pageData._addBoundariesArray(filtered);\r\n if (ellipseBoundaries.length > 0) {\r\n pageData._addEllipseBoundaries(ellipseBoundaries);\r\n }\r\n if (pointBoundaries.length > 0) {\r\n pageData._addPointBoundaries(pointBoundaries);\r\n }\r\n }\r\n resolve(tileImagesData);\r\n });\r\n }\r\n\r\n #prepareRenderLayerOld(renderLayer, pageData) {\r\n return new Promise((resolve, reject) => {\r\n const tilemap = renderLayer.tilemap,\r\n tilesets = renderLayer.tilesets,\r\n tilesetImages = renderLayer.tilesetImages,\r\n layerData = renderLayer.layerData,\r\n { tileheight:dtheight, tilewidth:dtwidth } = tilemap,\r\n tilewidth = dtwidth,\r\n tileheight = dtheight,\r\n setBoundaries = renderLayer.setBoundaries,\r\n [ settingsWorldWidth, settingsWorldHeight ] = pageData.worldDimensions,\r\n [ canvasW, canvasH ] = pageData.canvasDimensions,\r\n [ xOffset, yOffset ] = renderLayer.isOffsetTurnedOff === true ? [0,0] : pageData.worldOffset;\r\n \r\n let tileImagesData = [];\r\n if (!layerData) {\r\n Warning(WARNING_CODES.NOT_FOUND, \"check tilemap and layers name\");\r\n reject();\r\n }\r\n for (let i = 0; i <= tilesets.length - 1; i++) {\r\n const tilesetData = tilesets[i].data,\r\n firstgid = tilesets[i].firstgid,\r\n nextTileset = tilesets[i + 1],\r\n nextgid = nextTileset ? nextTileset.firstgid : 1_000_000_000, // a workaround to avoid multiple conditions\r\n //tilesetImages = this.iLoader.getTilesetImageArray(tilesetData.name),\r\n tilesetwidth = tilesetData.tilewidth,\r\n tilesetheight = tilesetData.tileheight,\r\n //atlasRows = tilesetData.imageheight / tileheight,\r\n //atlasColumns = tilesetData.imagewidth / tilewidth,\r\n atlasColumns = tilesetData.columns,\r\n layerCols = layerData.width,\r\n layerRows = layerData.height,\r\n worldW = tilewidth * layerCols,\r\n worldH = tileheight * layerRows,\r\n visibleCols = Math.ceil(canvasW / tilewidth),\r\n visibleRows = Math.ceil(canvasH / tileheight),\r\n atlasImage = tilesetImages[i],\r\n atlasWidth = atlasImage.width,\r\n atlasHeight = atlasImage.height,\r\n cellSpacing = tilesetData.spacing,\r\n cellMargin = tilesetData.margin;\r\n \r\n let mapIndex = 0,\r\n verticesBufferData = [],\r\n texturesBufferData = [];\r\n\r\n if (worldW !== settingsWorldWidth || worldH !== settingsWorldHeight) {\r\n Warning(WARNING_CODES.UNEXPECTED_WORLD_SIZE, \" World size from tilemap is different than settings one, fixing...\");\r\n pageData._setWorldDimensions(worldW, worldH);\r\n }\r\n for (let row = 0; row < layerRows; row++) {\r\n for (let col = 0; col < layerCols; col++) {\r\n let tile = layerData.data[mapIndex];\r\n \r\n if (tile >= firstgid && (tile < nextgid)) {\r\n\r\n tile -= firstgid;\r\n const colNum = tile % atlasColumns,\r\n rowNum = Math.floor(tile / atlasColumns),\r\n atlasPosX = colNum * tilesetwidth + (colNum * cellSpacing),\r\n atlasPosY = rowNum * tilesetheight + (rowNum * cellSpacing),\r\n vecX1 = col * dtwidth - xOffset,\r\n vecY1 = row * dtheight - yOffset,\r\n vecX2 = vecX1 + tilesetwidth,\r\n vecY2 = vecY1 + tilesetheight,\r\n texX1 = 1 / atlasWidth * atlasPosX,\r\n texY1 = 1 / atlasHeight * atlasPosY,\r\n texX2 = texX1 + (1 / atlasWidth * tilesetwidth),\r\n texY2 = texY1 + (1 / atlasHeight * tilesetheight);\r\n \r\n verticesBufferData.push(\r\n vecX1, vecY1,\r\n vecX2, vecY1,\r\n vecX1, vecY2,\r\n vecX1, vecY2,\r\n vecX2, vecY1,\r\n vecX2, vecY2);\r\n texturesBufferData.push(\r\n texX1, texY1,\r\n texX2, texY1,\r\n texX1, texY2,\r\n texX1, texY2,\r\n texX2, texY1,\r\n texX2, texY2\r\n );\r\n\r\n }\r\n mapIndex++;\r\n }\r\n }\r\n const v = new Float32Array(verticesBufferData);\r\n const t = new Float32Array(texturesBufferData);\r\n tileImagesData.push([v, t, tilesetData.name, atlasImage]);\r\n }\r\n resolve(tileImagesData);\r\n });\r\n }\r\n\r\n /**\r\n * \r\n * @param {DrawTiledLayer} renderLayer \r\n * @param {GameStageData} pageData\r\n * @returns {Promise}\r\n */\r\n #prepareRenderLayerWM = (renderLayer, pageData) => {\r\n return new Promise((resolve, reject) => {\r\n const tilemap = renderLayer.tilemap,\r\n tilesets = tilemap.tilesets,\r\n tilesetImages = renderLayer.tilesetImages,\r\n layerData = renderLayer.layerData,\r\n { tileheight:dtheight, tilewidth:dtwidth } = tilemap,\r\n tilewidth = dtwidth,\r\n tileheight = dtheight,\r\n offsetDataItemsFullNum = layerData.data.length,\r\n offsetDataItemsFilteredNum = layerData.data.filter((item) => item !== 0).length,\r\n setBoundaries = false, //renderLayer.setBoundaries,\r\n [ settingsWorldWidth, settingsWorldHeight ] = pageData.worldDimensions,\r\n //[ canvasW, canvasH ] = this.stageData.drawDimensions,\r\n [ xOffset, yOffset ] = renderLayer.isOffsetTurnedOff === true ? [0,0] : pageData.worldOffset;\r\n const tileImagesData = [];\r\n // clear data\r\n // this.layerDataFloat32.fill(0);\r\n // set data for webgl processing\r\n this.layerDataFloat32.set(layerData.data);\r\n if (!layerData) {\r\n Warning(WARNING_CODES.NOT_FOUND, \"check tilemap and layers name\");\r\n reject();\r\n }\r\n \r\n for (let i = 0; i < tilesets.length; i++) {\r\n const tilesetData = tilesets[i].data,\r\n firstgid = tilesets[i].firstgid,\r\n nextTileset = tilesets[i + 1],\r\n nextgid = nextTileset ? nextTileset.firstgid : 1_000_000_000, // a workaround to avoid multiple conditions\r\n //tilesetImages = this.iLoader.getTilesetImageArray(tilesetData.name),\r\n tilesetwidth = tilesetData.tilewidth,\r\n tilesetheight = tilesetData.tileheight,\r\n //atlasRows = tilesetData.imageheight / tileheight,\r\n atlasColumns = tilesetData.columns,\r\n layerCols = layerData.width,\r\n layerRows = layerData.height,\r\n //visibleCols = Math.ceil(canvasW / tilewidth),\r\n //visibleRows = Math.ceil(canvasH / tileheight),\r\n //offsetCols = layerCols - visibleCols,\r\n //offsetRows = layerRows - visibleRows,\r\n worldW = tilewidth * layerCols,\r\n worldH = tileheight * layerRows,\r\n atlasImage = tilesetImages[i],\r\n atlasWidth = atlasImage.width,\r\n atlasHeight = atlasImage.height,\r\n items = layerRows * layerCols,\r\n dataCellSizeBytes = 4,\r\n vectorCoordsItemsNum = 12,\r\n texturesCoordsItemsNum = 12,\r\n vectorDataItemsNum = offsetDataItemsFilteredNum * vectorCoordsItemsNum,\r\n texturesDataItemsNum = offsetDataItemsFilteredNum * texturesCoordsItemsNum,\r\n cellSpacing = tilesetData.spacing,\r\n cellMargin = tilesetData.margin;\r\n \r\n if (worldW !== settingsWorldWidth || worldH !== settingsWorldHeight) {\r\n Warning(WARNING_CODES.UNEXPECTED_WORLD_SIZE, \" World size from tilemap is different than settings one, fixing...\");\r\n pageData._setWorldDimensions(worldW, worldH);\r\n }\r\n\r\n //if (this.canvas.width !== worldW || this.canvas.height !== worldH) {\r\n // this._setCanvasSize(worldW, worldH);\r\n //}\r\n // boundaries cleanups every draw cycles, we need to set world boundaries again\r\n if (this.#gameOptions.render.boundaries.mapBoundariesEnabled) {\r\n pageData._setMapBoundaries();\r\n }\r\n const itemsProcessed = this.calculateBufferData(dataCellSizeBytes, offsetDataItemsFullNum, vectorDataItemsNum, layerRows, layerCols, dtwidth, dtheight, tilesetwidth, tilesetheight, atlasColumns, atlasWidth, atlasHeight, xOffset, yOffset, firstgid, nextgid, cellSpacing, setBoundaries);\r\n \r\n const verticesBufferData = itemsProcessed > 0 ? this.layerDataFloat32.slice(offsetDataItemsFullNum, vectorDataItemsNum + offsetDataItemsFullNum) : [],\r\n texturesBufferData = itemsProcessed > 0 ? this.layerDataFloat32.slice(vectorDataItemsNum + offsetDataItemsFullNum, vectorDataItemsNum + texturesDataItemsNum + offsetDataItemsFullNum) : [];\r\n \r\n tileImagesData.push([verticesBufferData, texturesBufferData, tilesetData.name, atlasImage]);\r\n if (setBoundaries) {\r\n pageData._mergeBoundaries();\r\n renderLayer.setBoundaries = false;\r\n }\r\n }\r\n resolve(tileImagesData);\r\n });\r\n };\r\n\r\n /**\r\n * \r\n * @param {string} rgbaColor \r\n * @returns {number[]}\r\n */\r\n #rgbaToArray (rgbaColor) {\r\n return rgbaColor.replace(\"rgba(\", \"\").replace(\")\", \"\").split(\",\").map((/** @param {string} */item) => Number(item.trim()));\r\n }\r\n\r\n #triangulatePolygon(vertices) {\r\n return this.#triangulate(vertices);\r\n }\r\n\r\n /**\r\n * \r\n * @param {Array>} polygonVertices \r\n * @param {Array} triangulatedPolygon \r\n * @returns {Array}\r\n */\r\n #triangulate (polygonVertices, triangulatedPolygon = []) {\r\n const len = polygonVertices.length,\r\n vectorsCS = (a, b, c) => crossProduct({x:c[0] - a[0], y: c[1] - a[1]}, {x:b[0] - a[0], y: b[1] - a[1]});\r\n\r\n if (len <= 3) {\r\n polygonVertices.forEach(vertex => {\r\n triangulatedPolygon.push(vertex[0]);\r\n triangulatedPolygon.push(vertex[1]);\r\n });\r\n return triangulatedPolygon;\r\n }\r\n const verticesSortedByY = [...polygonVertices].sort((curr, next) => next[1] - curr[1]);\r\n const topVertexIndex = polygonVertices.indexOf(verticesSortedByY[0]),\r\n startVertexIndex = topVertexIndex !== len - 1 ? topVertexIndex + 1 : 0;\r\n \r\n let processedVertices = polygonVertices,\r\n processedVerticesLen = processedVertices.length,\r\n skipCount = 0,\r\n i = startVertexIndex;\r\n \r\n while(processedVertices.length > 2) {\r\n // if overflowed, start from beginning\r\n const currLen = processedVertices.length;\r\n if (i >= currLen) {\r\n i -= currLen;\r\n }\r\n \r\n const prevVertex = i === 0 ? processedVertices[currLen - 1] : processedVertices[i - 1],\r\n currentVertex = processedVertices[i],\r\n nextVertex = currLen === i + 1 ? processedVertices[0] : processedVertices[i + 1];\r\n \r\n \r\n const cs = vectorsCS(prevVertex, currentVertex, nextVertex);\r\n \r\n if (cs < 0) {\r\n triangulatedPolygon.push(prevVertex[0]);\r\n triangulatedPolygon.push(prevVertex[1]);\r\n triangulatedPolygon.push(currentVertex[0]);\r\n triangulatedPolygon.push(currentVertex[1]);\r\n triangulatedPolygon.push(nextVertex[0]);\r\n triangulatedPolygon.push(nextVertex[1]);\r\n processedVertices = processedVertices.filter((val, index) => index !== i);\r\n } else {\r\n skipCount += 1;\r\n if (skipCount > processedVerticesLen) {\r\n // sometimes fails\r\n Warning(WARNING_CODES.TRIANGULATE_ISSUE, \"Can't extract all triangles vertices.\");\r\n return triangulatedPolygon;\r\n }\r\n i++;\r\n }\r\n // if (cs < 0): it's jumping over next vertex, maybe not a good solution? Moving up\r\n // i++;\r\n }\r\n \r\n return triangulatedPolygon;\r\n }\r\n\r\n #bindPolygon(vertices) {\r\n this.#gl.bufferData(\r\n this.#gl.ARRAY_BUFFER, \r\n new Float32Array(vertices),\r\n this.#gl.STATIC_DRAW);\r\n }\r\n\r\n #setSingleRectangle(width, height) {\r\n const x1 = 0,\r\n x2 = 0 + width,\r\n y1 = 0,\r\n y2 = 0 + height;\r\n this.#gl.bufferData(this.#gl.ARRAY_BUFFER, \r\n new Float32Array([\r\n x1, y1,\r\n x2, y1,\r\n x1, y2,\r\n x1, y2,\r\n x2, y1,\r\n x2, y2]), this.#gl.STATIC_DRAW);\r\n }\r\n /*------------------------------------\r\n * End of Predefined Drawing programs\r\n -------------------------------------*/\r\n\r\n /**-----------------------------------\r\n * Textures\r\n ------------------------------------*/\r\n #updateWebGlTexture(gl, texture, textureImage, textureNum = 0, useMipMaps = false) {\r\n this.#bindTexture(gl, texture, textureNum);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureImage);\r\n // LINEAR filtering is better for images and tiles, but for texts it produces a small blur\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\r\n // for textures not power of 2 (texts for example)\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, useMipMaps ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);\r\n }\r\n\r\n #updateTextWebGlTexture(gl, texture, textureImage, textureNum = 0) {\r\n this.#bindTexture(gl, texture, textureNum);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureImage);\r\n // LINEAR filtering is better for images and tiles, but for texts it produces a small blur\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n // for textures not power of 2 (texts for example)\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n }\r\n\r\n #bindTexture(gl, texture, textureNum = 0) {\r\n gl.activeTexture(gl.TEXTURE0 + textureNum);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n }\r\n\r\n #removeTexture(gl, texture) {\r\n gl.deleteTexture(texture);\r\n }\r\n /*------------------------------------\r\n * End Textures\r\n --------------------------------------*/\r\n\r\n isPowerOfTwo(value) {\r\n return (value & (value - 1)) === 0;\r\n }\r\n\r\n nextHighestPowerOfTwo(x) {\r\n --x;\r\n for (var i = 1; i < 32; i <<= 1) {\r\n x = x | x >> i;\r\n }\r\n return x + 1;\r\n }\r\n}","import { CONST } from \"./constants.js\";\n/**\n * Settings object, should be passed as a parameter to System.constructor().\n */\nexport class SystemSettings {\n /**\n * @hideconstructor\n */\n constructor(){}\n /**\n * DEBUG/PRODUCTION, for debug mode system Logger will show debug information in the console\n */\n static mode = CONST.MODE.DEBUG;\n\n static gameOptions = {\n // no other variants only WEBGL for now\n library: CONST.LIBRARY.WEBGL,\n optimization: CONST.OPTIMIZATION.NATIVE_JS.OPTIMIZED,\n optimizationWASMUrl: \"/src/wa/calculateBufferDataWat.wasm\",\n optimizationAssemblyUrl: \"/src/wa/calculateBufferDataAssembly.wasm\",\n loadingScreen: {\n backgroundColor: \"rgba(128, 128, 128, 0.6)\",\n loadingBarBg: \"rgba(128, 128, 128, 1)\",\n loadingBarProgress: \"rgba(128, 128, 128, 0.2)\",\n },\n render: {\n minCycleTime: 16.666, //ms which is ~60 FPS\n cyclesTimeCalc: {\n check: CONST.OPTIMIZATION.CYCLE_TIME_CALC.AVERAGES,\n averageFPStime: 10000\n },\n boundaries: {\n mapBoundariesEnabled: true,\n realtimeCalculations: true,\n wholeWorldPrecalculations: false\n },\n \n },\n debug: {\n checkWebGlErrors: false,\n debugMobileTouch: false,\n boundaries: {\n drawLayerBoundaries: false,\n drawObjectBoundaries: false,\n boundariesColor: \"rgba(224, 12, 21, 0.6)\",\n boundariesWidth: 2\n },\n delayBetweenObjectRender: false, // 1 sec delay for debug proposes\n }\n };\n \n\n static network = {\n address: \"https://gameserver.reslc.ru:9009\",\n gatherRoomsInfoInterval: 5000\n };\n\n static canvasMaxSize = {\n width: 1800,\n height: 1800\n };\n\n static worldSize = {\n width: 960,\n height: 960\n };\n\n static defaultCanvasKey = \"default\";\n\n static customSettings = {};\n}","export const CONST = {\r\n MODE: {\r\n DEBUG: \"DEBUG\",\r\n PRODUCTION: \"PRODUCTION\"\r\n },\r\n SCREENS: {},\r\n AUDIO: {},\r\n CONNECTION_STATUS: {\r\n DISCONNECTED: \"disconnected\",\r\n CONNECTED: \"connected\",\r\n CONNECTION_LOST: \"connection lost\"\r\n },\r\n EVENTS: {\r\n SYSTEM: {\r\n START_PAGE:\"START_PAGE\",\r\n STOP_PAGE: \"STOP_PAGE\",\r\n RENDER: {\r\n START: \"start\",\r\n END: \"end\"\r\n }\r\n },\r\n GAME: {\r\n BOUNDARIES_COLLISION: \"BOUNDARIES_COLLISION\",\r\n OBJECTS_COLLISION: \"OBJECTS_COLLISION\"\r\n },\r\n WEBSOCKET: {\r\n SERVER_CLIENT: {\r\n CONNECTION_STATUS_CHANGED: \"CONNECTION_STATUS_CHANGED\",\r\n ROOMS_INFO: \"roomsInfo\",\r\n CREATED: \"created\",\r\n JOINED: \"joined\",\r\n FULL: \"full\",\r\n DISCONNECTED: \"disconnected\",\r\n SERVER_MESSAGE: \"message\",\r\n RESTARTED: \"restarted\",\r\n },\r\n CLIENT_SERVER: {\r\n ROOMS_INFO_REQUEST: \"gatherRoomsInfo\",\r\n CREATE_OR_JOIN: \"create or join\",\r\n RESTART_REQUEST: \"restart\",\r\n CLIENT_MESSAGE: \"message\"\r\n }\r\n }\r\n },\r\n WEBGL: {\r\n DRAW_PROGRAMS: {\r\n PRIMITIVES: \"drawPrimitives\",\r\n IMAGES: \"drawImages\"\r\n }\r\n },\r\n DRAW_TYPE: {\r\n RECTANGLE: \"rect\",\r\n CONUS: \"conus\",\r\n CIRCLE: \"circle\",\r\n POLYGON: \"polygon\",\r\n LINE: \"line\",\r\n TEXT: \"text\",\r\n IMAGE: \"image\"\r\n },\r\n LAYERS: {\r\n DEFAULT: \"default-view-layer\",\r\n BOUNDARIES: \"boundaries-view-layer\"\r\n },\r\n GAME_OPTIONS: {},\r\n LIBRARY: {\r\n WEBGL: \"webgl\"\r\n },\r\n OPTIMIZATION: {\r\n CYCLE_TIME_CALC: {\r\n AVERAGES: \"AVERAGES\",\r\n CURRENT: \"CURRENT\"\r\n },\r\n NATIVE_JS: {\r\n NOT_OPTIMIZED: \"NOT_OPTIMIZED\",\r\n OPTIMIZED: \"OPTIMIZED\"\r\n },\r\n WEB_ASSEMBLY: {\r\n ASSEMBLY_SCRIPT: \"ASSEMBLY_SCRIPT\",\r\n NATIVE_WAT: \"WASM\"\r\n }\r\n }\r\n};\r\n\r\nexport const ERROR_CODES = {\r\n CREATE_INSTANCE_ERROR: \"CREATE_INSTANCE_ERROR\",\r\n VIEW_NOT_EXIST: \"VIEW_NOT_EXIST\",\r\n ELEMENT_NOT_EXIST: \"ELEMENT_NOT_EXIST\",\r\n FILE_NOT_EXIST: \"FILE_NOT_EXIST\",\r\n CANT_GET_THE_IMAGE: \"CANT_GET_THE_IMAGE\",\r\n UNEXPECTED_INPUT_PARAMS: \"UNEXPECTED_INPUT_PARAMS\",\r\n UNHANDLED_EXCEPTION: \"UNHANDLED_EXCEPTION\",\r\n CANVAS_KEY_NOT_SPECIFIED: \"CANVAS_KEY_NOT_SPECIFIED\",\r\n CANVAS_WITH_KEY_NOT_EXIST: \"CANVAS_WITH_KEY_NOT_EXIST\",\r\n WRONG_TYPE_ERROR: \"WRONG_TYPE_ERROR\",\r\n UNEXPECTED_WS_MESSAGE: \"UNEXPECTED_WS_MESSAGE\",\r\n UNEXPECTED_PLAYER_ID: \"UNEXPECTED_PLAYER_ID\",\r\n UNEXPECTED_BULLET_ID: \"UNEXPECTED_BULLET_ID\",\r\n UNEXPECTED_EVENT_NAME: \"UNEXPECTED_EVENT_NAME\",\r\n WEBGL_ERROR: \"WEBGL_ERROR\",\r\n DRAW_PREPARE_ERROR: \"DRAW_PREPARE_ERROR\",\r\n UNEXPECTED_TILE_ID: \"UNEXPECTED_TILE_ID\",\r\n UNEXPECTED_TOUCH_AREA: \"UNEXPECTED TOUCH AREA\",\r\n UNEXPECTED_METHOD_TYPE: \"UNEXPECTED METHOD TYPE\"\r\n};\r\n\r\nexport const WARNING_CODES = {\r\n FILE_LOADING_ISSUE: \"FILE_LOADING_ISSUE\",\r\n ASSETS_NOT_READY: \"ASSETS_NOT_READY\",\r\n NOT_FOUND: \"NOT_FOUND\",\r\n NOT_TESTED: \"NOT_TESTED\",\r\n WORLD_DIMENSIONS_NOT_SET: \"WORLD_DIMENSIONS_NOT_SET\",\r\n INCORRECT_RENDER_TYPE: \"INCORRECT_RENDER_TYPE\",\r\n UNHANDLED_DRAW_ISSUE: \"UNHANDLED_DRAW_ISSUE\",\r\n UNEXPECTED_WORLD_SIZE: \"UNEXPECTED_WORLD_SIZE\",\r\n AUDIO_ALREADY_REGISTERED: \"AUDIO_ALREADY_REGISTERED\",\r\n AUDIO_NOT_REGISTERED: \"AUDIO_NOT_REGISTERED\",\r\n AUDIO_NOT_LOADED: \"AUDIO_NOT_LOADED\",\r\n UNKNOWN_DRAW_OBJECT: \"UNKNOWN_DRAW_OBJECT\",\r\n METHOD_NOT_IMPLEMENTED: \"METHOD_NOT_IMPLEMENTED\",\r\n POLYGON_VERTICES_NOT_CORRECT: \"POLYGON_VERTICES_NOT_CORRECT\",\r\n MODULE_ALREADY_INSTALLED: \"MODULE_ALREADY_INSTALLED\",\r\n DEPRECATED_PARAMETER: \"DEPRECATED_PARAMETER\",\r\n NEW_BEHAVIOR_INTRODUCED: \"NEW_BEHAVIOR_INTRODUCED\",\r\n TEXTURE_IMAGE_TEMP_OVERFLOW: \"TEXTURE_IMAGE_TEMP_OVERFLOW\",\r\n TRIANGULATE_ISSUE: \"TRIANGULATE_ISSUE\"\r\n};","import { GameStage } from \"../base/GameStage.js\";\n\nexport class LoadingStage extends GameStage {\n #total = 0;\n #loaded = 0;\n #barWidth = 0;\n register() {\n //this.iLoader.addImage(logoKey, \"./images/icon.png\");\n }\n\n init() {\n const [w, h] = this.stageData.canvasDimensions,\n barWidth = w/3,\n barHeight = 20;\n //this.logo = this.draw.image(w/2, h/2, 300, 200, logoKey);\n this.background = this.draw.rect(0, 0, w, h, this.systemSettings.gameOptions.loadingScreen.backgroundColor); \n this.loadingBarBg = this.draw.rect(w/2 - (barWidth/2), h/2 - (barHeight/2), barWidth, barHeight, this.systemSettings.gameOptions.loadingScreen.loadingBarBg);\n this.loadingBarProgress = this.draw.rect(w/2 - (barWidth/2), h/2 - (barHeight/2), barWidth, barHeight, this.systemSettings.gameOptions.loadingScreen.loadingBarProgress);\n this.text = this.draw.text(w/2 - 20, h/2 - 2 * barHeight, \"JsGE\", \"24px sans-serif\", \"black\");\n this.#barWidth = barWidth;\n }\n\n _progress = (loaded) => {\n const widthPart = this.#barWidth / this.#total;\n\n this.#loaded = loaded;\n const newWidth = widthPart * this.#loaded;\n // sometimes additional items are added to queue in load process\n // to avoid bar width overflow additional check added below:\n const applyWidth = loaded > this.#total ? this.#barWidth : newWidth;\n\n this.loadingBarProgress.width = applyWidth;\n };\n\n start(options) {\n this.#total = options.total;\n }\n\n // a workaround for checking upload progress before render\n //get iLoader() {\n // return ({filesWaitingForUpload:0});\n //}\n} ","import { System } from \"./base/System.js\";\nimport { GameStage } from \"./base/GameStage.js\";\nimport { DrawImageObject } from \"./base/DrawImageObject.js\";\nimport { ISystemAudio } from \"./base/ISystemAudio.js\";\nimport * as Primitives from \"./base/Primitives.js\";\nimport { SystemSettings } from \"./configs.js\";\nimport { CONST } from \"./constants.js\";\nimport * as utils from \"./utils.js\";\n\nexport { System, SystemSettings, CONST, GameStage, DrawImageObject, ISystemAudio, Primitives, utils };","import { Vector } from \"./base/Primitives.js\";\r\n\r\nfunction isMobile() {\r\n return /Android|webOS|iPhone|iPad|iPod|Opera Mini/i.test(navigator.userAgent) ;\r\n}\r\n\r\nfunction isSafari() {\r\n return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\r\n}\r\n\r\nfunction pointToCircleDistance(x, y, circle) {\r\n const pointToCircleCenterDistance = new Vector(x, y, circle.x, circle.y).length;\r\n return pointToCircleCenterDistance - circle.r;\r\n}\r\n\r\nfunction countClosestTraversal(line, sight) {\r\n const x1 = sight.x1,\r\n y1 = sight.y1,\r\n x2 = sight.x2,\r\n y2 = sight.y2;\r\n const x3 = line.x1,\r\n y3 = line.y1,\r\n x4 = line.x2,\r\n y4 = line.y2;\r\n\r\n const r_px = x1,\r\n r_py = y1,\r\n r_dx = x2-x1,\r\n r_dy = y2-y1;\r\n\r\n const s_px = x3,\r\n s_py = y3,\r\n s_dx = x4-x3,\r\n s_dy = y4-y3;\r\n\r\n const r_mag = Math.sqrt(r_dx*r_dx+r_dy*r_dy),\r\n s_mag = Math.sqrt(s_dx*s_dx+s_dy*s_dy);\r\n if(r_dx/r_mag==s_dx/s_mag && r_dy/r_mag==s_dy/s_mag){\r\n return null;\r\n }\r\n\r\n const T2 = (r_dx*(s_py-r_py) + r_dy*(r_px-s_px))/(s_dx*r_dy - s_dy*r_dx),\r\n T1 = (s_px+s_dx*T2-r_px)/r_dx;\r\n\r\n if(T1<0 || isNaN(T1)) return null;\r\n if(T2<0 || T2>1) return null;\r\n\r\n return {\r\n x: r_px+r_dx*T1,\r\n y: r_py+r_dy*T1,\r\n p: T1\r\n };\r\n}\r\n\r\n/**\r\n * \r\n * @param {{x1:number, y1:number, x2:number, y2:number}} line1 \r\n * @param {{x1:number, y1:number, x2:number, y2:number}} line2 \r\n * @returns {{x:number, y:number, p:number} | undefined}\r\n * @ignore\r\n */\r\nfunction countClosestTraversal2(line1, line2) {\r\n const x1 = line2.x1,\r\n y1 = line2.y1,\r\n x2 = line2.x2,\r\n y2 = line2.y2;\r\n const x3 = line1.x1,\r\n y3 = line1.y1,\r\n x4 = line1.x2,\r\n y4 = line1.y2;\r\n\r\n const det = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);\r\n // lines are parallel, or coincident\r\n if (det === 0){\r\n return;\r\n }\r\n let x = ((x1*y2 - y1*x2) * (x3 - x4) - (x1 - x2) * (x3*y4 - y3*x4)) / det;\r\n let y = ((x1*y2 - y1*x2) * (y3 - y4) - (y1 - y2) * (x3*y4 - y3*x4)) / det;\r\n const point = {x, y};\r\n \r\n if (isPointOnTheLine(point, line1, 0.0000000000001) && isPointOnTheLine(point, line2, 0.0000000000001)) {\r\n const p = Math.sqrt(Math.pow((x - x1), 2) + Math.pow((y - y1), 2));\r\n return {x, y, p};\r\n } else {\r\n return;\r\n }\r\n}\r\n\r\nfunction angle_2points(x1, y1, x2, y2) {\r\n return Math.atan2(y2 - y1, x2 - x1);\r\n}\r\n\r\nfunction angle_3points(a, b, c) {\r\n const x1 = a.x - b.x,\r\n x2 = c.x - b.x,\r\n y1 = a.y - b.y,\r\n y2 = c.y - b.y,\r\n d1 = Math.sqrt(x1 * x1 + y1 * y1),\r\n d2 = Math.sqrt(x2 * x2 + y2 * y2);\r\n //console.log(\"angle: \", (Math.acos((x1* x2 + y1 * y2) / (d1 * d2))* 180) / Math.PI);\r\n return Math.acos((x1* x2 + y1 * y2) / (d1 * d2));\r\n}\r\n\r\nfunction dotProductWithAngle(lenA, lenB, angle) {\r\n return lenA * lenB * Math.cos(angle);\r\n}\r\n\r\nfunction dotProduct(vec1, vec2) {\r\n return vec1.x * vec2.x + vec1.y * vec2.y;\r\n}\r\n\r\nfunction crossProduct(a, b) {\r\n return (a.x * b.y - b.x * a.y);\r\n}\r\n\r\nfunction isPointOnTheLine(point, line, m_error = 0) {\r\n return (\r\n ((point.x >= (line.x1 - m_error)) && (point.x <= (line.x2 + m_error))) || \r\n ((point.x <= (line.x1 + m_error)) && (point.x >= (line.x2 - m_error)))\r\n ) && (\r\n ((point.y >= (line.y1 - m_error)) && (point.y <= (line.y2 + m_error))) || \r\n ((point.y <= (line.y1 + m_error)) && (point.y >= (line.y2 - m_error)))\r\n );\r\n}\r\n\r\nfunction countDistance(obj1, obj2) {\r\n return new Vector(obj1.x, obj1.y, obj2.x, obj2.y).length;\r\n}\r\n\r\nfunction isLineShorter(line1, line2) {\r\n return (new Vector(line1.x1, line1.y1, line1.x2, line1.y2)).length < (new Vector(line2.x1, line2.y1, line2.x2, line2.y2)).length;\r\n}\r\n\r\nfunction isPointLineIntersect(point, line) {\r\n const lineL = new Vector(line.x1, line.y1, line.x2, line.y2).length,\r\n lengthAB = new Vector(line.x1, line.y1, point.x, point.y).length + new Vector(line.x2, line.y2, point.x, point.y).length;\r\n\r\n if (lengthAB <= lineL + 0.2) {\r\n //console.log(\"point to line intersect. line len: \" + lineL + \", line AB len: \" + lengthAB);\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * \r\n * @param {Array>} polygon \r\n * @param {{x1:number, y1:number, x2:number, y2:number}} line \r\n * @returns {{x:number, y:number, p:number} | null}\r\n * @ignore\r\n */\r\nfunction isPolygonLineIntersect(polygon, line) {\r\n const len = polygon.length;\r\n for (let i = 0; i < len; i+=1) {\r\n let curr = polygon[i],\r\n next = polygon[i+1];\r\n //if next item not exist and current is not first\r\n if (!next) {\r\n // if current vertex is not the first one\r\n if (!(curr[0] === polygon[0][0] && curr[1] === polygon[0][1])) {\r\n next = polygon[0];\r\n } else {\r\n continue;\r\n }\r\n }\r\n const edge = { x1: curr[0], y1: curr[1], x2: next[0], y2: next[1] };\r\n const intersection = countClosestTraversal2(edge, line);\r\n if (intersection) {\r\n return intersection;\r\n }\r\n }\r\n if (polygon[len-1][0] !== polygon[0][0] && polygon[len-1][1] !== polygon[0][1]) {\r\n //check one last item\r\n const curr = polygon[len - 1],\r\n next = polygon[0];\r\n const edge = { x1: curr[0], y1: curr[1], x2: next[0], y2: next[1] };\r\n const intersection = countClosestTraversal2(edge, line);\r\n if (intersection) {\r\n return intersection;\r\n }\r\n }\r\n return null;\r\n}\r\n\r\nfunction isPointPolygonIntersect(x, y, polygon) {\r\n const len = polygon.length;\r\n \r\n for (let i = 0; i < len; i+=1) {\r\n let vertex1 = polygon[i],\r\n vertex2 = polygon[i + 1];\r\n\r\n // if last vertex, set vertex2 as the first\r\n if (!vertex2) {\r\n vertex2 = polygon[0];\r\n }\r\n\r\n if (isPointLineIntersect({x,y}, {x1: vertex1[0], y1: vertex1[1], x2: vertex2[0], y2: vertex2[1]})) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\nfunction isPointInsidePolygon(x, y, polygon) {\r\n const len = polygon.length;\r\n let intersections = 0;\r\n\r\n for (let i = 0; i < len; i++) {\r\n let vertex1 = polygon[i],\r\n vertex2 = polygon[i + 1] ? polygon[i + 1] : polygon[0],\r\n x1 = vertex1[0],\r\n y1 = vertex1[1],\r\n x2 = vertex2[0],\r\n y2 = vertex2[1];\r\n \r\n if (y < y1 !== y < y2 && \r\n x < (x2 - x1) * (y - y1) / (y2 - y1) + x1) {\r\n intersections++;\r\n }\r\n }\r\n \r\n if (intersections > 0) {\r\n if (intersections % 2 === 0) {\r\n return false;\r\n } else {\r\n return true;\r\n }\r\n } else {\r\n return false;\r\n }\r\n}\r\n\r\nfunction isPointRectIntersect(x, y, rect) {\r\n if (x >= rect.x && x <= rect.width + rect.x && y >= rect.y && y <= rect.y + rect.height) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * \r\n * @param {number} x \r\n * @param {number} y \r\n * @param {{x:number, y:number, r:number}} circle \r\n * @returns {boolean}\r\n */\r\nfunction isPointCircleIntersect(x, y, circle) {\r\n const radius = circle.r,\r\n lineToCircleCenter = new Vector(x, y, circle.x, circle.y),\r\n pointCircleLineLength = lineToCircleCenter.length;\r\n \r\n if (pointCircleLineLength < radius)\r\n return true;\r\n else\r\n return false;\r\n}\r\n\r\nfunction isCircleLineIntersect(x, y, r, line) {\r\n const x1 = line.x1,\r\n y1 = line.y1,\r\n x2 = line.x2,\r\n y2 = line.y2,\r\n vec1 = {x: x1 - x, y: y1-y}, //new Vector(x, y, x1, y1),\r\n vec2 = {x: x2 - x, y: y2-y}, //new Vector(x, y, x2, y2),\r\n vec3 = {x: x2 - x1, y: y2-y1}, //new Vector(x1 ,y1, x2, y2),\r\n vec4 = {x: x1 - x2, y: y1-y2}, //new Vector(x2, y2, x1, y1),\r\n vec3Len = Math.sqrt(Math.pow(vec3.x, 2) + Math.pow(vec3.y, 2)),//vec3.length,\r\n dotP1 = dotProduct(vec1, vec4),\r\n dotP2 = dotProduct(vec2, vec3);\r\n // checks if the line is inside the circle,\r\n // max_dist = Math.max(vec1Len, vec2Len);\r\n let min_dist;\r\n \r\n if (dotP1 > 0 && dotP2 > 0) {\r\n min_dist = crossProduct(vec1,vec2)/vec3Len;\r\n if (min_dist < 0) {\r\n min_dist *= -1;\r\n }\r\n } else {\r\n min_dist = Math.min(vec1.length, vec2.length);\r\n }\r\n \r\n if (min_dist <= r) { // && max_dist >= r) {\r\n return true;\r\n } else {\r\n return false;\r\n } \r\n}\r\n\r\n/**\r\n * \r\n * @param {Array} ellipse - x,y,radX,radY\r\n * @param {Array>} line [x1,y1],[x2,y2]\r\n */\r\nfunction isEllipseLineIntersect(ellipse, line) {\r\n const x = ellipse[0],\r\n y = ellipse[1],\r\n radX = ellipse[2],\r\n radY = ellipse[3],\r\n x1 = line[0][0],\r\n y1 = line[0][1],\r\n x2 = line[1][0],\r\n y2 = line[1][1],\r\n lineAToElCenter = { x: x - x1, y: y - y1 }, //new Vector(x, y, x1, y1),\r\n lineBToElCenter = { x: x - x2, y: y - y2 }, //new Vector(x, y, x2, y2),\r\n lineAToElCenterLen = Math.sqrt(Math.pow(lineAToElCenter.x, 2) + Math.pow(lineAToElCenter.y, 2)),\r\n lineBToElCenterLen = Math.sqrt(Math.pow(lineBToElCenter.x, 2) + Math.pow(lineBToElCenter.y, 2)),\r\n lineToCenterLenMin = Math.min(lineAToElCenterLen, lineBToElCenterLen),\r\n ellipseMax = Math.max(radX, radY);\r\n \r\n if (lineToCenterLenMin > ellipseMax) {\r\n return false;\r\n }\r\n \r\n const traversalLine = lineToCenterLenMin === lineAToElCenterLen ? lineAToElCenter : lineBToElCenter,\r\n angleToAxisX = Math.atan2(traversalLine.y, traversalLine.x);\r\n \r\n const intersectX = Math.cos(angleToAxisX) * radX,\r\n intersectY = Math.sin(angleToAxisX) * radY,\r\n lineToCenter = { x: 0 - intersectX, y: 0 - intersectY },\r\n intersectLineLen = Math.sqrt(Math.pow(lineToCenter.x, 2) + Math.pow(lineToCenter.y, 2));\r\n //console.log(\"lenToCheck: \", lenToCheck);\r\n //console.log(\"x: \", intersectX);\r\n if (lineToCenterLenMin > intersectLineLen) {\r\n return false;\r\n }\r\n return true;\r\n}\r\n\r\n/**\r\n * \r\n * @param {Array} ellipse - x,y,radX,radY\r\n * @param {{x:number, y:number, r:number}} circle\r\n * @returns {{x:number, y:number, p:number} | boolean}\r\n */\r\nfunction isEllipseCircleIntersect(ellipse, circle) {\r\n const ellipseX = ellipse[0],\r\n ellipseY = ellipse[1],\r\n ellipseToCircleLine = { x: ellipseX - circle.x, y: ellipseY - circle.y },\r\n len = Math.sqrt(Math.pow(ellipseToCircleLine.x, 2) + Math.pow(ellipseToCircleLine.y, 2)),\r\n maxRad = Math.max(ellipse[2], ellipse[3]);\r\n // no collisions for sure\r\n if (len > (maxRad + circle.r)) {\r\n return false;\r\n } else {\r\n // check possible collision\r\n const angle = angle_2points(ellipseX, ellipseY, circle.x, circle.y),\r\n traversalX = ellipseX + (ellipse[2] * Math.cos(angle)),\r\n traversalY = ellipseY + (ellipse[3] * Math.sin(angle)),\r\n vecTrX = ellipseX - traversalX,\r\n vecTrY = ellipseY - traversalY,\r\n traversalLen = Math.sqrt(Math.pow(vecTrX, 2) + Math.pow(vecTrY, 2)) + circle.r;\r\n if (len <= traversalLen) {\r\n return {x: vecTrX, y: vecTrY, p:1};\r\n } else {\r\n return false;\r\n }\r\n }\r\n \r\n}\r\n\r\n/**\r\n * \r\n * @param {Array} ellipse - x,y,radX,radY\r\n * @param {Array>} polygon - x,y\r\n * @returns {boolean}\r\n */\r\nfunction isEllipsePolygonIntersect(ellipse, polygon) {\r\n const len = polygon.length;\r\n\r\n for (let i = 0; i < len; i+=1) {\r\n let vertex1 = polygon[i],\r\n vertex2 = polygon[i + 1];\r\n\r\n // if last vertex, set vertex2 as the first\r\n if (!vertex2) {\r\n vertex2 = polygon[0];\r\n }\r\n\r\n if (isEllipseLineIntersect(ellipse, [vertex1, vertex2])) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\nfunction generateUniqId() {\r\n return Math.round(Math.random() * 1000000); \r\n}\r\n\r\nfunction randomFromArray(array) {\r\n return array[Math.floor(Math.random()*array.length)];\r\n}\r\n\r\nfunction verticesArrayToArrayNumbers(array) {\r\n const len = array.length,\r\n numbers = [];\r\n for (let i = 0; i < len; i++) {\r\n const vertex = array[i];\r\n numbers.push([vertex.x, vertex.y]);\r\n }\r\n return numbers;\r\n}\r\n\r\n/**\r\n * @param {number} x\r\n * @param {number} y\r\n * @param {number} radiusX\r\n * @param {number} radiusY\r\n * @param {number} [angle = 2 * Math.PI]\r\n * @param {number} [step = Math.PI/12] \r\n * @returns {Array}\r\n */\r\nfunction calculateEllipseVertices(x = 0, y = 0, radiusX, radiusY, angle = 2*Math.PI, step = Math.PI/8) {\r\n let ellipsePolygonCoords = [];\r\n\r\n for (let r = 0; r <= angle; r += step) {\r\n let x2 = Math.cos(r) * radiusX + x,\r\n y2 = Math.sin(r) * radiusY + y;\r\n\r\n ellipsePolygonCoords.push([x2, y2]);\r\n }\r\n\r\n return ellipsePolygonCoords;\r\n}\r\n\r\nexport { \r\n isMobile, \r\n isSafari, \r\n pointToCircleDistance, \r\n countClosestTraversal, \r\n countClosestTraversal2,\r\n angle_2points,\r\n angle_3points,\r\n dotProductWithAngle,\r\n dotProduct,\r\n crossProduct,\r\n isPointOnTheLine,\r\n isLineShorter,\r\n isPointLineIntersect,\r\n isPointPolygonIntersect,\r\n isPointRectIntersect,\r\n isPointCircleIntersect,\r\n isPolygonLineIntersect,\r\n isCircleLineIntersect,\r\n isEllipseLineIntersect,\r\n isEllipseCircleIntersect,\r\n isEllipsePolygonIntersect,\r\n isPointInsidePolygon,\r\n generateUniqId,\r\n randomFromArray,\r\n verticesArrayToArrayNumbers,\r\n countDistance,\r\n calculateEllipseVertices };","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.f = {};\n// This file contains only the entry chunk.\n// The chunk loading function for additional chunks\n__webpack_require__.e = (chunkId) => {\n\treturn Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {\n\t\t__webpack_require__.f[key](chunkId, promises);\n\t\treturn promises;\n\t}, []));\n};","// This function allow to reference async chunks\n__webpack_require__.u = (chunkId) => {\n\t// return url for filenames based on template\n\treturn \"\" + chunkId + \".index.es6.js\";\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","var inProgress = {};\nvar dataWebpackPrefix = \"jsge:\";\n// loadScript function to load a script via script tag\n__webpack_require__.l = (url, done, key, chunkId) => {\n\tif(inProgress[url]) { inProgress[url].push(done); return; }\n\tvar script, needAttach;\n\tif(key !== undefined) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tfor(var i = 0; i < scripts.length; i++) {\n\t\t\tvar s = scripts[i];\n\t\t\tif(s.getAttribute(\"src\") == url || s.getAttribute(\"data-webpack\") == dataWebpackPrefix + key) { script = s; break; }\n\t\t}\n\t}\n\tif(!script) {\n\t\tneedAttach = true;\n\t\tscript = document.createElement('script');\n\t\tscript.type = \"module\";\n\t\tscript.charset = 'utf-8';\n\t\tscript.timeout = 120;\n\t\tif (__webpack_require__.nc) {\n\t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n\t\t}\n\t\tscript.setAttribute(\"data-webpack\", dataWebpackPrefix + key);\n\t\tscript.src = url;\n\t}\n\tinProgress[url] = [done];\n\tvar onScriptComplete = (prev, event) => {\n\t\t// avoid mem leaks in IE.\n\t\tscript.onerror = script.onload = null;\n\t\tclearTimeout(timeout);\n\t\tvar doneFns = inProgress[url];\n\t\tdelete inProgress[url];\n\t\tscript.parentNode && script.parentNode.removeChild(script);\n\t\tdoneFns && doneFns.forEach((fn) => (fn(event)));\n\t\tif(prev) return prev(event);\n\t};\n\tvar timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);\n\tscript.onerror = onScriptComplete.bind(null, script.onerror);\n\tscript.onload = onScriptComplete.bind(null, script.onload);\n\tneedAttach && document.head.appendChild(script);\n};","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","var scriptUrl;\nif (typeof import.meta.url === \"string\") scriptUrl = import.meta.url\n// When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration\n// or pass an empty string (\"\") and set the __webpack_public_path__ variable from your code to use your own logic.\nif (!scriptUrl) throw new Error(\"Automatic publicPath is not supported in this browser\");\nscriptUrl = scriptUrl.replace(/#.*$/, \"\").replace(/\\?.*$/, \"\").replace(/\\/[^\\/]+$/, \"/\");\n__webpack_require__.p = scriptUrl;","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t\"main\": 0\n};\n\n__webpack_require__.f.j = (chunkId, promises) => {\n\t\t// JSONP chunk loading for javascript\n\t\tvar installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;\n\t\tif(installedChunkData !== 0) { // 0 means \"already installed\".\n\n\t\t\t// a Promise means \"currently loading\".\n\t\t\tif(installedChunkData) {\n\t\t\t\tpromises.push(installedChunkData[2]);\n\t\t\t} else {\n\t\t\t\tif(true) { // all chunks have JS\n\t\t\t\t\t// setup Promise in chunk cache\n\t\t\t\t\tvar promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));\n\t\t\t\t\tpromises.push(installedChunkData[2] = promise);\n\n\t\t\t\t\t// start chunk loading\n\t\t\t\t\tvar url = __webpack_require__.p + __webpack_require__.u(chunkId);\n\t\t\t\t\t// create error before stack unwound to get useful stacktrace later\n\t\t\t\t\tvar error = new Error();\n\t\t\t\t\tvar loadingEnded = (event) => {\n\t\t\t\t\t\tif(__webpack_require__.o(installedChunks, chunkId)) {\n\t\t\t\t\t\t\tinstalledChunkData = installedChunks[chunkId];\n\t\t\t\t\t\t\tif(installedChunkData !== 0) installedChunks[chunkId] = undefined;\n\t\t\t\t\t\t\tif(installedChunkData) {\n\t\t\t\t\t\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n\t\t\t\t\t\t\t\tvar realSrc = event && event.target && event.target.src;\n\t\t\t\t\t\t\t\terror.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';\n\t\t\t\t\t\t\t\terror.name = 'ChunkLoadError';\n\t\t\t\t\t\t\t\terror.type = errorType;\n\t\t\t\t\t\t\t\terror.request = realSrc;\n\t\t\t\t\t\t\t\tinstalledChunkData[1](error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\t__webpack_require__.l(url, loadingEnded, \"chunk-\" + chunkId, chunkId);\n\t\t\t\t} else installedChunks[chunkId] = 0;\n\t\t\t}\n\t\t}\n};\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n// no on chunks loaded\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = (parentChunkLoadingFunction, data) => {\n\tvar [chunkIds, moreModules, runtime] = data;\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some((id) => (installedChunks[id] !== 0))) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunkjsge\"] = self[\"webpackChunkjsge\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(\"./src/index.js\");\n",""],"names":[],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"index.es6.js","mappings":";;;;;;;;;;;;AAAA,2BAA2B,oGAAoG,iBAAiB,63BAA63B,aAAa,GAAG,GAAG,WAAW,WAAW,iBAAiB,+BAA+B,oBAAoB,yDAAyD,6DAA6D,+BAA+B,wHAAwH,GAAG,QAAQ,iBAAiB,MAAM,kBAAkB,4BAA4B,oBAAoB,mBAAmB,eAAe,mBAAmB,eAAe,iBAAiB,6GAA6G,iCAAiC,2BAA0C,oBAAoB,KAAK,mBAAmB,WAAW,KAAK,cAAc,ySAAyS,4BAA4B,QAAQ,2EAA2E,iDAAiD,2BAA2B,yBAAyB,wFAAwF,wCAAwC,kBAAkB,UAAU,2CAA2C,qBAAqB,cAAc,cAAc,KAAK,GAAG,GAAG,QAAQ,2BAA2B,4DAA4D,gBAAgB,kDAAkD,4EAA4E,kBAAkB,GAAG,KAAK,4BAA4B,SAAS,0CAA0C,kDAAkD,2EAA2E,UAAU,GAAG,mCAAmC,kBAAkB,0BAA0B,iBAAiB,kEAAkE,MAAM,GAAG,GAAG,2BAA2B,uIAAuI,8BAA8B,sCAAsC,wIAAwI,iGAAiG,MAAM,mBAAmB,kEAAkE,yDAAyD,sCAAsC,IAAI,4DAA4D,oFAAoF,8BAA8B,WAAW,SAAS,qDAAqD,gBAAgB,iNAAiN,kDAAkD,+BAA+B,aAAa,mCAAmC,mBAAmB,aAAa,0CAA0C,mBAAmB,GAAG,gBAAgB,+DAA+D,mBAAmB,SAAS,GAAG,mFAAmF,MAAM,2DAA2D,GAAG,iGAAiG,eAAe,2DAA2D,wCAAwC,IAAI,qCAAqC,4EAA4E,mBAAmB,4CAA4C,WAAW,mCAAmC,MAAM,oBAAoB,qFAAqF,UAAU,4BAA4B,YAAY,WAAW,KAAK,aAAa,qBAAqB,0BAA0B,GAAG,0BAA0B,6IAA6I,mCAAmC,qBAAqB,sCAAsC,eAAe,oCAAoC,yDAAyD,mBAAmB,GAAG,GAAG,uDAAuD,UAAU,KAAK,kBAAkB,8BAA8B,qBAAqB,+BAA+B,YAAY,eAAe,GAAG,gBAAgB,yDAAyD,mBAAmB,UAAU,GAAG,MAAM,6EAA6E,MAAM,sGAAsG,MAAM,sGAAsG,MAAM,sYAAsY,MAAM,oCAAoC,kOAAkO,oBAAoB,uBAAuB,4FAA4F,mBAAmB,uBAAuB,gCAAgC,iDAAiD,aAAa,uBAAuB,0BAA0B,iDAAiD,UAAU,kDAAkD,oGAAoG,KAAK,iCAAiC,uEAAuE,QAAQ,GAAG,KAAK,mEAAmE,KAAK,mCAAmC,iFAAiF,2CAA2C,GAAG,MAAM,oGAAoG,QAAQ,IAAI,sBAAsB,mBAAmB,oBAAoB;;;;;;;;;;;;;;ACAlmQ;AACP;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;;;;;;;;;;;;;;;AC9FwC;AACe;;AAEvD;AACA;AACA;AACA,SAAS,yBAAyB;AAClC;AACO,+BAA+B,gEAAe;AACrD;AACA,cAAc;AACd;AACA;;AAEA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,iEAAsB;AACpC;AACA;AACA;;AAEA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AC9CwC;AACe;;AAEvD;AACA;AACA;AACA,SAAS,yBAAyB;AAClC;AACO,8BAA8B,gEAAe;AACpD;AACA,cAAc;AACd;AACA;;AAEA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,gEAAqB;AACnC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;AC5EqD;AACA;AACE;AACI;AACP;AACpD;AACA;AACA;AACA,SAAS,yBAAyB;AAClC;AACO,8BAA8B,gEAAe;AACpD;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,gEAAqB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,GAAG;AAClB,eAAe,GAAG;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,GAAG;AAClB,eAAe,GAAG;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,SAAS;AACzB,gBAAgB,uBAAuB,2BAA2B,IAAI;AACtE,gBAAgB,UAAU;AAC1B;AACA;AACA;AACA,YAAY,wDAAS,CAAC,8EAAmC,4EAA4E,2BAA2B;AAChK;AACA,mCAAmC,8DAAc;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACrSwC;AACe;;AAEvD;AACA;AACA;AACA,SAAS,yBAAyB;AAClC;AACO,6BAA6B,gEAAe;AACnD;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,+DAAoB;AAClC;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;AChCqD;AACA;AACE;AACA;AACF;AACM;AACF;AACJ;AACE;AACJ;AACR;AACG;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,iBAAiB;AAC1B;AACO;AACP;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,GAAG;AAClB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA,iCAAiC,8DAAc;AAC/C;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA,iCAAiC,8DAAc;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB;AACjB;AACA;AACA,iCAAiC,gEAAe;AAChD;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA,iCAAiC,kEAAgB;AACjD;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,OAAO,mBAAmB,KAAK,SAAS,GAAG;AAC1D,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,YAAY,yDAAS,CAAC,0EAA8B;AACpD;AACA;AACA,iCAAiC,gEAAe;AAChD;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,eAAe;AAC9B,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA,iCAAiC,8DAAc;AAC/C;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO,mBAAmB,GAAG;AAC5C,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA,iCAAiC,oEAAiB;AAClD;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,UAAU;AACzB,eAAe,kBAAkB;AACjC,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,8DAAc;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,UAAU;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,UAAU;AACzB,eAAe,YAAY;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,eAAe;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AC7MwC;AACe;;AAEvD;AACA;AACA,SAAS,yBAAyB;AAClC;AACO,gCAAgC,gEAAe;AACtD;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,kEAAuB;AACrC;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AC/BwC;AACe;;AAEvD;AACA;AACA,SAAS,yBAAyB;AAClC;AACO,6BAA6B,gEAAe;AACnD;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,oEAAyB;AACvC;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AC1DwC;AACJ;;AAEpC;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA,cAAc;AACd,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA,UAAU,2DAAoB;AAC9B;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,cAAc;AACd,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,iBAAiB;AAChC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA,wBAAwB,YAAY;AACpC;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA,wBAAwB,YAAY;AACpC;AACA;;AAEA;AACA;;AAEA;AACA;;;AAGA;AACA,eAAe,8BAA8B,mBAAmB,GAAG;AACnE,iBAAiB;AACjB;AACA;AACA;AACA;AACA,mBAAmB,wEAAiC;AACpD,UAAU;AACV;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;AC1QuD;AACX;AACS;AACV;AACgB;;AAE3D;AACA;AACA,SAAS,yBAAyB;AAClC;AACO,6BAA6B,gEAAe;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,+DAAoB;AAClC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,mBAAmB,qDAAS;AAC5B;;AAEA;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,2DAA2D,0BAA0B,GAAG;AACxF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAU;AACV,YAAY,wDAAS,CAAC,0EAA+B;AACrD;AACA;AACA;;;;;;;;;;;;;;;;;AC9NqD;AACE;AACI;AAC3D;AACA;AACA,SAAS,yBAAyB;AAClC;AACO;AACP;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,iBAAiB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,GAAG;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,8DAAc;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO,+BAA+B,GAAG;AACxD,iBAAiB,OAAO,2BAA2B;AACnD;AACA;AACA,mDAAmD,4DAA4D;AAC/G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACjRwD;AACZ;;AAErC;AACP;AACA;AACA;AACA;AACA,YAAY,wDAAS,CAAC,4EAAiC;AACvD;AACA;AACA;;AAEA;AACA,6BAA6B,+EAAoC;AACjE;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACpBO;AACP;AACA;;AAEO;AACP;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACNoE;AACjB;AACC;AACkB;AACX;AACF;AACF;AACA;AACF;AACM;AACN;AACA;AACd;AACU;AACF;AACwK;AAC9K;AACzC;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,cAAc;AACvB;AACA;AACO;AACP;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,8BAA8B,4DAAa;AAC3C;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,aAAa;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA,YAAY,sDAAO,CAAC,gFAAqC;AACzD,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,GAAG;AAClB,eAAe,IAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,GAAG;AAClB,eAAe,IAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,mBAAmB;AAClC,eAAe,aAAa;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,iBAAiB;AAChC,kBAAkB,8BAA8B;AAChD;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,+DAAoB;AACjC,aAAa,oEAAyB;AACtC,aAAa,gEAAqB;AAClC,aAAa,gEAAqB;AAClC;AACA;AACA,cAAc;AACd;AACA;AACA,aAAa,iEAAsB;AACnC,YAAY,sDAAO,CAAC,qFAA0C;AAC9D;AACA,aAAa,+DAAoB;AACjC,YAAY,sDAAO,CAAC,qFAA0C;AAC9D;AACA;AACA,YAAY,sDAAO,CAAC,kFAAuC;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,iBAAiB;AAChC,eAAe,wBAAwB;AACvC,kBAAkB,8BAA8B,WAAW;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,+DAAoB;AACjC,aAAa,oEAAyB;AACtC,aAAa,gEAAqB;AAClC,aAAa,gEAAqB;AAClC;AACA;AACA,cAAc;AACd;AACA;AACA,aAAa,iEAAsB;AACnC,YAAY,sDAAO,CAAC,qFAA0C;AAC9D;AACA,aAAa,+DAAoB;AACjC,YAAY,sDAAO,CAAC,qFAA0C;AAC9D;AACA;AACA,YAAY,sDAAO,CAAC,kFAAuC;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,+DAAoB;AACrC,iBAAiB,oEAAyB;AAC1C,iBAAiB,gEAAqB;AACtC,iBAAiB,gEAAqB;AACtC;AACA;AACA,iBAAiB,iEAAsB;AACvC;AACA;AACA,iBAAiB,+DAAoB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,+DAAoB;AACrC,iBAAiB,oEAAyB;AAC1C,iBAAiB,gEAAqB;AACtC,iBAAiB,gEAAqB;AACtC;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,iBAAiB,iEAAsB;AACvC;AACA;AACA,iBAAiB,+DAAoB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,4BAA4B,iEAAqB;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,mDAAM;AAC9B;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,4BAA4B,kEAAsB;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,mDAAM;AACjC,0BAA0B,yDAAa;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,kBAAkB,8BAA8B;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,4BAA4B,iEAAqB;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,UAAU;AACtC;AACA,gCAAgC,oEAAwB,WAAW,gCAAgC;AACnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,UAAU;AACtC;AACA;AACA;AACA,gCAAgC,kEAAsB,UAAU,gCAAgC;AAChG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,sBAAsB;AACrC,eAAe,QAAQ;AACvB,kBAAkB,8BAA8B;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,4BAA4B,kEAAsB;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,UAAU;AACtC;AACA,gCAAgC,qEAAyB;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,UAAU;AACtC;AACA;AACA;AACA,gCAAgC,mEAAuB;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AC3oBgD;AACP;AACzC;AACA;AACA;AACA,SAAS,iBAAiB;AAC1B;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,gBAAgB,2CAA2C;AAC3D;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,sBAAsB;AACrC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,sDAAO,CAAC,iFAAsC;AAC1D;AACA,6BAA6B,iCAAiC;AAC9D,6BAA6B,6CAA6C;AAC1E,6BAA6B,6CAA6C;AAC1E,6BAA6B,iCAAiC;AAC9D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,sDAAO,CAAC,iFAAsC;AAC1D;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,sBAAsB;AACrC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACxYuC;;AAEvC;AACA;AACA;AACA;AACO;AACP;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,UAAU;AACzB;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,eAAe;AAC9B,eAAe,eAAe;AAC9B,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,0BAA0B;AACzC,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,oEAAoE;AACnF,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;AC1DqD;AACV;AACN;AACiB;;AAEtD;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,wDAAS,CAAC,4EAAiC;AACvD;AACA;AACA;;AAEA;AACA,QAAQ,mOAA0B;AAClC,4EAA4E,sBAAsB;AAClG;AACA;AACA,SAAS;AACT;;AAEA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,0BAA0B,kGAAuD;AACjF;;AAEA;AACA,0BAA0B,8FAAmD;AAC7E;;AAEA;AACA,0BAA0B,8FAAmD;AAC7E;;AAEA;AACA,QAAQ,oDAAY;AACpB,qCAAqC,yGAA8D;AACnG;;AAEA;AACA,QAAQ,oDAAY;AACpB,qCAAqC,yGAA8D;AACnG;;AAEA;AACA;AACA;;AAEA;AACA,QAAQ,oDAAY;AACpB,+BAA+B,+DAAW,CAAC,8FAAmD;AAC9F;;AAEA;AACA,QAAQ,oDAAY;AACpB,+BAA+B,+DAAW,CAAC,0FAA+C;AAC1F;;AAEA;AACA,QAAQ,oDAAY;AACpB,+BAA+B,+DAAW,CAAC,uFAA4C,GAAG,UAAU;AACpG;;AAEA;AACA,QAAQ,oDAAY;AACpB,+BAA+B,+DAAW,CAAC,oFAAyC,GAAG,KAAK;AAC5F;;AAEA;AACA,QAAQ,oDAAY;AACpB,+BAA+B,+DAAW,CAAC,sFAA2C,GAAG,UAAU;AACnG;;AAEA;AACA,+BAA+B,+DAAW,CAAC,4FAAiD,GAAG,SAAS;AACxG;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACxIqD;AACD;AACS;AACR;AACN;AACI;AACmB;AACtE,WAAW,sBAAsB;AACO;AACe;AACE;AACF;AACF;AACM;AACN;AACA;AACyD;AACgC;AAC1G;AACpC;AACA;AACA;AACA;AACA,SAAS,iBAAiB;AAC1B;AACA;AACO;AACP;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,8DAA8D,cAAc;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,8DAAW;AAC3C,6DAA6D,qFAA0C;AACvG,6DAA6D,0FAA+C;AAC5G;AACA;AACA;AACA;AACA;AACA,uDAAuD,2EAAgC,EAAE,yEAAe,EAAE,2EAAiB,EAAE,qEAAW,EAAE,uEAAa;AACvJ;AACA;AACA,uDAAuD,+EAAoC,EAAE,oFAAsB,EAAE,sFAAwB,EAAE,gFAAkB,EAAE,kFAAoB;AACvL;AACA;AACA;AACA,mCAAmC,oEAAmB,+BAA+B,2EAAgC;AACrH,mCAAmC,oEAAmB,qCAAqC,+EAAoC;AAC/H,mCAAmC,0EAAsB,qCAAqC,+EAAoC;AAClI,mCAAmC,uEAAqB,gCAAgC,+EAAoC;AAC5H,mCAAmC,qEAAoB,gCAAgC,+EAAoC;AAC3H,mCAAmC,mEAAmB,qCAAqC,2EAAgC;AAC3H,mCAAmC,oEAAmB,+BAA+B,+EAAoC;AACzH;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,GAAG;AAClB,eAAe,IAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,GAAG;AAClB,eAAe,IAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,eAAe;AAC9B,eAAe,eAAe;AAC9B,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,0BAA0B;AACzC,iBAAiB;AACjB;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,oEAAoE;AACnF,eAAe,SAAS;AACxB;AACA;AACA,4DAA4D,qEAAqE;AACjI;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,0BAA0B;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA;AACA,0BAA0B,mBAAmB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,gBAAgB;AAC/B,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,yCAAyC;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,sDAAO,CAAC,kEAAuB;AACnD;AACA;AACA;AACA,gCAAgC,qBAAqB;AACrD;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,sDAAO,CAAC,8EAAmC;AACnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,iBAAiB;AACvD,0CAA0C,iBAAiB;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,eAAe,8IAA8I;AAC7J,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,UAAU;AACV;AACA,sCAAsC,gEAAqB;AAC3D,6DAA6D,2EAAgC;AAC7F,oEAAoE,2EAAgC;AACpG;AACA;AACA;AACA;AACA,wBAAwB,wDAAS,CAAC,yEAA8B;AAChE,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA,qBAAqB;AACrB,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,SAAS;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,sEAA8B;AACjE,oDAAoD,8CAA8C;AAClG;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,eAAe;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,8DAAmB;AAChC;AACA;AACA;AACA;AACA;AACA,wDAAwD,sFAA2C;AACnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,sDAAO,CAAC,6EAAkC;AAClE;AACA;AACA,iBAAiB;AACjB;AACA,aAAa;AACb,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,2GAA2G,qFAA0C;AACrJ;AACA,kBAAkB,2EAAgC;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,yEAA8B;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,oBAAoB,sDAAO,CAAC,6EAAkC;AAC9D,iBAAiB;AACjB,cAAc;AACd,gBAAgB,sDAAO,CAAC,6EAAkC;AAC1D;AACA;AACA,SAAS;AACT;AACA;;;;;;;;;;;;;;;;;;;;;;;;AC9mBoE;AAChB;AACX;AACQ;AACF;AACuB;AACX;AAChB;AACJ;AACM;;AAE7C;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,cAAc;AACvB,SAAS,iBAAiB;AAC1B;AACO;AACP;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA,mBAAmB,4EAAa;AAChC;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA,6BAA6B,oEAAiB;AAC9C;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,wDAAS,CAAC,4EAAiC;AACvD;AACA;AACA;AACA,yCAAyC,0DAAY;AACrD,4EAA4E,kDAAQ;AACpF,4BAA4B,gDAAO;AACnC,+BAA+B,sDAAU;AACzC;AACA;AACA,uCAAuC,2EAAgC,kBAAkB,2EAAgC;AACzH,uCAAuC,yEAA8B,kBAAkB,yEAA8B;AACrH;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,GAAG;AAClB,eAAe,IAAI;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,GAAG;AAClB,eAAe,IAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;;AAEA;AACA,eAAe;AACf;AACA;AACA;AACA;;AAEA;AACA,eAAe;AACf;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,gBAAgB,QAAQ;AACxB,iBAAiB;AACjB;AACA;AACA;AACA;AACA,YAAY,sDAAO,CAAC,iFAAsC;AAC1D;AACA,UAAU;AACV;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,yEAA8B;AACpD;AACA,UAAU;AACV,YAAY,wDAAS,CAAC,qEAA0B;AAChD;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA,sBAAsB,wEAA6B;AACnD;AACA;AACA;AACA,UAAU;AACV,YAAY,wDAAS,CAAC,qEAA0B;AAChD;AACA;AACA;;;;;;;;;;;;;;;;;ACvNuE;AACvB;AACP;;AAEzC;AACA;AACA;AACA;AACA;AACA,SAAS,iBAAiB;AAC1B;AACA;AACO;AACP;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;AACA,YAAY,sDAAO,CAAC,yEAA8B;AAClD;AACA;AACA;AACA;AACA,UAAU;AACV,YAAY,sDAAO,CAAC,6EAAkC;AACtD;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;AACA,YAAY,sDAAO,CAAC,yEAA8B;AAClD;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,YAAY,sDAAO,CAAC,6EAAkC;AACtD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AC7F+C;AACP;;AAEjC;AACP;AACA,YAAY,4DAAmB,KAAK,2DAAgB;AACpD;AACA;AACA;;;;;;;;;;;;;;;;ACRA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;AC7E8C;AACH;AACA;AACJ;AACQ;;AAEU;;AAEzD;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,eAAe,gBAAgB;AAC/B,eAAe,oBAAoB;AACnC;AACA;AACA;AACA,YAAY,wDAAS,CAAC,4EAAiC;AACvD;AACA;;AAEA;AACA;AACA;AACA;;AAEA,4BAA4B,gDAAO;;AAEnC,4CAA4C,iEAAY;;AAExD;AACA;AACA;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,WAAW;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,YAAY,wDAAS,CAAC,4EAAiC;AACvD;AACA;;AAEA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;;AAEA;AACA,uDAAuD,mBAAmB;AAC1E;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;AC9FA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;;;;;;;;;;;;;;;;;;AC/DA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACxEA;AACA;AACA;AACO;AACP;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;ACxCuE;AACzB;AACO;AACD;AACC;AACrD;AACO;AACP;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,YAAY,wDAAS,CAAC,8EAAmC;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,uDAAuD,qFAA0C;AACjG;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,2CAA2C;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,cAAc;AACd;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,eAAe;AAC9B,eAAe,eAAe;AAC9B,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,gBAAgB,wDAAS,CAAC,kEAAuB;AACjD;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,gBAAgB,wDAAS,CAAC,kEAAuB;AACjD;AACA;AACA;AACA;AACA;AACA,gBAAgB,wDAAS,CAAC,kEAAuB,0CAA0C,KAAK;AAChG;AACA,UAAU;AACV,YAAY,wDAAS,CAAC,kEAAuB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,cAAc;AAC7B,eAAe,eAAe;AAC9B,eAAe,eAAe;AAC9B,iBAAiB,+CAA+C;AAChE;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,wDAAS,CAAC,kEAAuB;AACjD;AACA,UAAU;AACV,YAAY,wDAAS,CAAC,kEAAuB,qBAAqB,WAAW;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,oEAAyB;AACtC;AACA;AACA;AACA,aAAa,+DAAoB;AACjC;AACA,aAAa,iEAAsB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,kEAAuB;AACpC;AACA;AACA;AACA;AACA,gBAAgB,sDAAO,CAAC,qFAA0C,cAAc,gBAAgB;AAChG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA,uCAAuC;AACvC;AACA,eAAe,kCAAkC;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,8DAAc;AAC/C;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,8DAAc;AAC/C;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA,uCAAuC;AACvC;AACA;AACA;AACA;AACA,aAAa,qFAA0C;AACvD;AACA;AACA,aAAa,0FAA+C;AAC5D,aAAa,qFAA0C;AACvD;AACA;AACA,aAAa,iFAAsC;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,4BAA4B;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,uBAAuB;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,8DAAc;AACvD;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,+EAAoC;AAC5E,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,8BAA8B,+EAAoC;AAChF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,sDAAO,CAAC,qFAA0C;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,+EAAoC;AAC5E,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,8BAA8B,+EAAoC;AAChF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,gBAAgB;AAC/B,eAAe,eAAe;AAC9B,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,yCAAyC;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,sDAAO,CAAC,kEAAuB;AAC/C;AACA;AACA;AACA,4BAA4B,qBAAqB;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAiE;AACjE;AACA;AACA,oBAAoB,sDAAO,CAAC,8EAAmC;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,kBAAkB;AACpD;AACA;AACA,sCAAsC,kBAAkB;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,sDAAO;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0DAA0D;AAC1D;AACA;AACA;AACA;AACA,qDAAqD;AACrD,8CAA8C;AAC9C;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,yCAAyC;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,sDAAO,CAAC,kEAAuB;AAC/C;AACA;AACA,4BAA4B,0BAA0B;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,sDAAO,CAAC,8EAAmC;AAC/D;AACA;AACA,kCAAkC,iBAAiB;AACnD,sCAAsC,iBAAiB;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,eAAe,gBAAgB;AAC/B,eAAe,eAAe;AAC9B,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,yCAAyC;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,sDAAO,CAAC,kEAAuB;AAC/C;AACA;AACA;AACA,4BAA4B,qBAAqB;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,sDAAO,CAAC,8EAAmC;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA,2FAA2F,QAAQ;AACnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,sBAAsB;AACrC,eAAe,eAAe;AAC9B,iBAAiB;AACjB;AACA;AACA;AACA,qCAAqC,uDAAY,EAAE,8BAA8B,GAAG,8BAA8B;AAClH;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,oBAAoB,sDAAO,CAAC,0EAA+B;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACh/CuC;AACvC;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,2DAAgB;;AAElC;AACA;AACA,iBAAiB,8DAAmB;AACpC,sBAAsB,iFAAsC;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,uBAAuB,sFAA2C;AAClE;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;;;;;;;;;;;;;;;ACxEO;AACP;AACA;AACA;AACA,KAAK;AACL,eAAe;AACf,aAAa;AACb;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,KAAK;AACL,oBAAoB;AACpB;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;AC7HiD;;AAE1C,2BAA2B,yDAAS;AAC3C;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,mBAAmB,wBAAwB;AAC3C;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC1C0C;AACM;AACY;AACN;AACH;AACL;AACP;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACPU;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,uDAAM;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,6CAA6C;AACzD,YAAY,6CAA6C;AACzD,cAAc,8BAA8B;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB;AACnB;AACA;AACA;AACA,gBAAgB;AAChB,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,uDAAM;AACrB;AACA;AACA;AACA,gBAAgB,uDAAM,wDAAwD,uDAAM;AACpF;AACA;AACA;AACA,sBAAsB,uDAAM;AAC5B,uBAAuB,uDAAM,kDAAkD,uDAAM;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,sBAAsB;AACjC,YAAY,6CAA6C;AACzD,cAAc,8BAA8B;AAC5C;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,IAAI,GAAG,+DAA+D;AACxG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,YAAY,+BAA+B;AAC3C,aAAa;AACb;AACA;AACA;AACA,iCAAiC,uDAAM;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,mBAAmB;AACnC,gBAAgB,mBAAmB;AACnC,gBAAgB,qBAAqB;AACrC,gBAAgB,qBAAqB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,yBAAyB;AACzB;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,eAAe;AAC1B,WAAW,sBAAsB;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,sBAAsB;AAClD,4BAA4B,sBAAsB;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,sCAAsC;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,eAAe;AAC1B,YAAY,+BAA+B;AAC3C,cAAc,8BAA8B;AAC5C;AACA;AACA;AACA;AACA,gCAAgC,gDAAgD;AAChF;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,eAAe;AAC1B,WAAW,sBAAsB;AACjC,aAAa;AACb;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa;AACb;AACA;AACA;AACA;AACA,oBAAoB,YAAY;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;SC1aA;SACA;;SAEA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;;SAEA;SACA;;SAEA;SACA;SACA;;SAEA;SACA;;;;;UCzBA;UACA;UACA;UACA;UACA,yCAAyC,wCAAwC;UACjF;UACA;UACA;;;;;UCPA;UACA;UACA;UACA;UACA;UACA;UACA;UACA,EAAE;UACF;;;;;UCRA;UACA;UACA;UACA;UACA;;;;;UCJA;;;;;UCAA;UACA;UACA;UACA;UACA,uBAAuB,4BAA4B;UACnD;UACA;UACA;UACA,iBAAiB,oBAAoB;UACrC;UACA,mGAAmG,YAAY;UAC/G;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA,mEAAmE,iCAAiC;UACpG;UACA;UACA;UACA;;;;;UCxCA;UACA;UACA;UACA,uDAAuD,iBAAiB;UACxE;UACA,gDAAgD,aAAa;UAC7D;;;;;UCNA;UACA;UACA;UACA;UACA;UACA;UACA;;;;;UCNA;;UAEA;UACA;UACA;UACA;UACA;UACA;;UAEA;UACA;UACA;UACA,iCAAiC;;UAEjC;UACA;UACA;UACA,KAAK;UACL,eAAe;UACf;UACA;UACA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA,MAAM;UACN;UACA;UACA;;UAEA;;UAEA;;UAEA;;UAEA;;UAEA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA,MAAM,qBAAqB;UAC3B;UACA;UACA;UACA;UACA;UACA;;UAEA;;UAEA;UACA;UACA;;;;;SErFA;SACA;SACA;SACA","sources":["webpack://jsge/./modules/assetsm/dist/assetsm.min.js","webpack://jsge/./src/base/AnimationEvent.js","webpack://jsge/./src/base/DrawCircleObject.js","webpack://jsge/./src/base/DrawConusObject.js","webpack://jsge/./src/base/DrawImageObject.js","webpack://jsge/./src/base/DrawLineObject.js","webpack://jsge/./src/base/DrawObjectFactory.js","webpack://jsge/./src/base/DrawPolygonObject.js","webpack://jsge/./src/base/DrawRectObject.js","webpack://jsge/./src/base/DrawShapeObject.js","webpack://jsge/./src/base/DrawTextObject.js","webpack://jsge/./src/base/DrawTiledLayer.js","webpack://jsge/./src/base/Events/SystemEvent.js","webpack://jsge/./src/base/Exception.js","webpack://jsge/./src/base/GameStage.js","webpack://jsge/./src/base/GameStageData.js","webpack://jsge/./src/base/IExtension.js","webpack://jsge/./src/base/INetwork.js","webpack://jsge/./src/base/IRender.js","webpack://jsge/./src/base/ISystem.js","webpack://jsge/./src/base/ISystemAudio.js","webpack://jsge/./src/base/Logger.js","webpack://jsge/./src/base/Primitives.js","webpack://jsge/./src/base/System.js","webpack://jsge/./src/base/WebGl/ImagesDrawProgram.js","webpack://jsge/./src/base/WebGl/PrimitivesDrawProgram.js","webpack://jsge/./src/base/WebGl/TextureStorage.js","webpack://jsge/./src/base/WebGl/WebGlEngine.js","webpack://jsge/./src/configs.js","webpack://jsge/./src/constants.js","webpack://jsge/./src/design/LoadingStage.js","webpack://jsge/./src/index.js","webpack://jsge/./src/utils.js","webpack://jsge/webpack/bootstrap","webpack://jsge/webpack/runtime/define property getters","webpack://jsge/webpack/runtime/ensure chunk","webpack://jsge/webpack/runtime/get javascript chunk filename","webpack://jsge/webpack/runtime/hasOwnProperty shorthand","webpack://jsge/webpack/runtime/load script","webpack://jsge/webpack/runtime/make namespace object","webpack://jsge/webpack/runtime/publicPath","webpack://jsge/webpack/runtime/jsonp chunk loading","webpack://jsge/webpack/before-startup","webpack://jsge/webpack/startup","webpack://jsge/webpack/after-startup"],"sourcesContent":["const PROGRESS_EVENT_TYPE={loadstart:\"loadstart\",progress:\"progress\",abort:\"abort\",error:\"error\",load:\"load\",timeout:\"timeout\"},ERROR_MESSAGES={LOADER_NOT_REGISTERED:\" loader is not registered.\",RECURSION_ERROR:\"Too much recursion. Stop iteration.\",NOT_CORRECT_METHOD_TYPE:\"uploadMethod should be instance of Promise and return upload result value\",XML_FILE_EXTENSION_INCORRECT:\" AtlasXML file extension is incorrect, only .xml file supported\",TILESET_FILE_EXTENSION_INCORRECT:\" tileset file extension is not correct, only .tsj or .json files are supported\",TILEMAP_FILE_EXTENSION_INCORRECT:\" tilemap file extension is not correct, only .tmj or .json files are supported\",INPUT_PARAMS_ARE_INCORRECT:\" fileKey and url should be provided\",ATLAS_IMAGE_LOADING_FAILED:\"Error loading atlas image \",TILESET_LOADING_FAILED:\"Error loading related tileset \",TILEMAP_LOADING_FAILED:\"Error loading tilemap \",AUDIO_LOADING_FAILED:\"Error loading audio \",IMAGE_LOADING_FAILED:\"Error loading image \",XML_FORMAT_INCORRECT:\" XML format is not correct.\"};class Loader{#e;#t;#r=new Map;#s=new Map;constructor(e,t){this.#e=e,this.#t=(e,r,...s)=>{const i=t(e,r,...s);if(i instanceof Promise)return i.then((t=>this.#i(t,e)));throw new TypeError(ERROR_MESSAGES.NOT_CORRECT_METHOD_TYPE)}}#i=(e,t)=>new Promise(((r,s)=>{e||null===e||Warning(\"AssetsManager: uploadMethod for \"+this.#e+\" returns incorrect value\"),this.#o(t,e),this.#a(t),r()}));#o(e,t){this.#s.set(e,t)}#a(e){this.#r.delete(e)}get filesWaitingForUpload(){return this.#r.size}get loadingQueue(){return this.#r}get uploadMethod(){return this.#t}_addFile=(e,t)=>{this.#r.has(e)&&Warning(\"AssetsManager: File \"+this.#e+\" with key \"+e+\" is already added\"),this.#r.set(e,t)};_isFileInQueue=e=>this.#r.has(e);_getFile=e=>this.#s.get(e)}export default class AssetsManager{#n=5;#l=new EventTarget;#d=new Map;#E=0;constructor(){this.registerLoader(\"Audio\",this._loadAudio),this.registerLoader(\"Image\",this._loadImage),this.registerLoader(\"TileMap\",this._loadTileMap),this.registerLoader(\"TileSet\",this._loadTileSet),this.registerLoader(\"AtlasImageMap\",this._loadAtlasImage),this.registerLoader(\"AtlasXML\",this._loadAtlasXml)}get filesWaitingForUpload(){let e=0;return Array.from(this.#d.values()).map((t=>e+=t.filesWaitingForUpload)),e}registerLoader=(e,t=this._defaultUploadMethod)=>{this[\"add\"+e]=(t,r,...s)=>{this.addFile(e,t,r,...s)},this[\"get\"+e]=t=>this.getFile(e,t),this[\"is\"+e+[\"InQueue\"]]=t=>this.isFileInQueue(e,t);const r=this.#d.get(e)||new Loader(e,t);this.#d.set(e,r)};preload(){return this.#h(),new Promise((async(e,t)=>{this.#u().then((()=>{this.#c(),e()})).catch((e=>{t(e)}))}))}#u(e=0){return this.#R().then((t=>{if(0===this.filesWaitingForUpload)return Promise.resolve(t);if(++e>this.#n){const e=new Error(ERROR_MESSAGES.RECURSION_ERROR);return this.#g(e),Promise.reject(new Error(ERROR_MESSAGES.RECURSION_ERROR))}return this.#u(e)}))}#R(){return new Promise(((e,t)=>{let r=[];Array.from(this.#d.values()).forEach((e=>{Array.from(e.loadingQueue.entries()).forEach((t=>{const s=new Promise(((r,s)=>e.uploadMethod(t[0],...t[1]).then((e=>r(e)))));r.push(s)}))})),Promise.allSettled(r).then((r=>{for(const s of r){if(\"rejected\"===s.status){const e=s.reason;this.#_(e)?t(e):(Warning(\"AssetsManager: \"+e.message),this.#g(e))}e(r)}}))}))}addEventListener(e,t,...r){PROGRESS_EVENT_TYPE[e]?this.#l.addEventListener(e,t,...r):Warning(\"AssetsManager: Event type should be one of the ProgressEvent.type\")}removeEventListener(e,t,...r){this.#l.removeEventListener(e,t,...r)}_loadAtlasXml=(e,t)=>(this.#m(t),fetch(t).then((e=>e.text())).then((e=>(new window.DOMParser).parseFromString(e,\"text/xml\"))).then((r=>{const s=r.documentElement||r.activeElement,i=s.attributes.getNamedItem(\"imagePath\"),o=s.children;if(i){const r=this.#p(t);return this.addAtlasImageMap(e,r+i.value,o,r),Promise.resolve(s)}{const t=new Error(e+ERROR_MESSAGES.XML_FORMAT_INCORRECT);return this.#g(t),Promise.resolve(t)}})));_loadAtlasImage=(e,t,r,s=\"anonymous\")=>new Promise(((e,i)=>{const o=new Image,a=new Map,n=document.createElement(\"canvas\"),l=n.getContext(\"2d\");o.crossOrigin=s,o.onload=()=>{const t=[];let s=[];n.width=o.width,n.height=o.height,l.drawImage(o,0,0);for(let e of r){const r=e.attributes,i=r.getNamedItem(\"name\").value,o=i.includes(\".\")?i.split(\".\")[0]:i,a=r.getNamedItem(\"x\").value,n=r.getNamedItem(\"y\").value,d=r.getNamedItem(\"width\").value,E=r.getNamedItem(\"height\").value;t.push(createImageBitmap(l.getImageData(a,n,d,E),{premultiplyAlpha:\"premultiply\"})),s.push(o)}this.#S(),Promise.all(t).then((t=>{t.forEach(((e,t)=>{const r=s[t];a.set(r,e),this.addImage(r,\"empty url\",e)})),n.remove(),e(a)}))},o.onerror=()=>{const r=new Error(ERROR_MESSAGES.ATLAS_IMAGE_LOADING_FAILED+t);this.#g(r),e(null)},o.src=t}));_loadTileSet=(e,t,r=1,s)=>(this.#I(t),fetch(s?s+t:t).then((e=>e.json())).then((e=>{const{name:t,image:i,spacing:o,margin:a,tilewidth:n,tileheight:l}=e;return t&&i&&!this.isFileInQueue(\"Image\",t)&&this.addImage(t,s?s+i:i),e.gid=r,Promise.resolve(e)})).catch((()=>{const e=new Error(ERROR_MESSAGES.TILESET_LOADING_FAILED+t);return this.#g(e),Promise.resolve(null)})));_defaultUploadMethod=(e,t)=>fetch(t);_loadTileMap=(e,t,r=!0)=>(this.#L(t),fetch(t).then((e=>e.json())).then((e=>{const s=this.#p(t);if(!0===r&&e.tilesets&&e.tilesets.length>0){const t=[];return e.tilesets.forEach(((e,r)=>{const{firstgid:i,source:o}=e,a=this._loadTileSet(\"default-\"+i,o,i,s).then((e=>(this.#S(),Promise.resolve(e))));t.push(a)})),Promise.all(t).then((t=>{for(let r=0;r(e.message.includes(\"JSON.parse:\")&&(e=new Error(ERROR_MESSAGES.TILEMAP_LOADING_FAILED+t)),this.#g(e),Promise.resolve(null)))));_loadAudio=(e,t)=>new Promise((e=>{const r=new Audio(t);r.addEventListener(\"loadeddata\",(()=>{this.#S(),e(r)})),r.addEventListener(\"error\",(()=>{const r=new Error(ERROR_MESSAGES.AUDIO_LOADING_FAILED+t);this.#g(r),e(null)}))}));_loadImage=(e,t,r,s=\"anonymous\")=>new Promise(((e,i)=>{if(r)e(r);else{const r=new Image;r.crossOrigin=s,r.onload=()=>{createImageBitmap(r,{premultiplyAlpha:\"premultiply\"}).then((t=>{this.#S(),e(t)}))},r.onerror=()=>{const r=new Error(ERROR_MESSAGES.IMAGE_LOADING_FAILED+t);this.#g(r),e(null)},r.src=t}}));#m(e){e.includes(\".xml\")||Exception(e+ERROR_MESSAGES.XML_FILE_EXTENSION_INCORRECT)}#I(e){e.includes(\".tsj\")||e.includes(\".json\")||Exception(e+ERROR_MESSAGES.TILESET_FILE_EXTENSION_INCORRECT)}#L(e){e.includes(\".tmj\")||e.includes(\".json\")||Exception(e+ERROR_MESSAGES.TILEMAP_FILE_EXTENSION_INCORRECT)}#_(e){return e.message.includes(ERROR_MESSAGES.NOT_CORRECT_METHOD_TYPE)||e.message.includes(ERROR_MESSAGES.XML_FILE_EXTENSION_INCORRECT)||e.message.includes(ERROR_MESSAGES.TILESET_FILE_EXTENSION_INCORRECT)||e.message.includes(ERROR_MESSAGES.TILEMAP_FILE_EXTENSION_INCORRECT)||e.message.includes(ERROR_MESSAGES.INPUT_PARAMS_ARE_INCORRECT)||e.message.includes(ERROR_MESSAGES.LOADER_NOT_REGISTERED)}#p(e){let t=e.split(\"/\"),r=t.length,s=\"/\";return t[r-1].includes(\".tmj\")||t[r-1].includes(\".xml\")||t[r-1].includes(\".json\")?(t.pop(),s=t.join(\"/\")+\"/\"):(t[r-2].includes(\".tmj\")||t[r-2].includes(\".xml\")||t[r-2].includes(\".json\"))&&(t.splice(r-2,2),s=t.join(\"/\")+\"/\"),s}addFile(e,t,r,...s){const i=this.#d.get(e);i?(this.#A(t,r,e),i._addFile(t,[r,...s])):Exception(e+ERROR_MESSAGES.LOADER_NOT_REGISTERED)}isFileInQueue(e,t){const r=this.#d.get(e);if(r)return r._isFileInQueue(t);Exception(\"Loader for \"+e+\" is not registered!\")}getFile(e,t){const r=this.#d.get(e);if(r)return r._getFile(t);Exception(\"Loader for \"+e+\" is not registered!\")}#A(e,t,r){const s=ERROR_MESSAGES.INPUT_PARAMS_ARE_INCORRECT;e&&0!==e.trim().length||Exception(\"add\"+r+\"()\"+s),t&&0!==t.trim().length||Exception(\"add\"+r+\"()\"+s)}#h(){let e=this.filesWaitingForUpload;this.#l.dispatchEvent(new ProgressEvent(PROGRESS_EVENT_TYPE.loadstart,{total:e}))}#c(){this.#l.dispatchEvent(new ProgressEvent(PROGRESS_EVENT_TYPE.load))}#S(){const e=this.filesWaitingForUpload;this.#E+=1,this.#l.dispatchEvent(new ProgressEvent(PROGRESS_EVENT_TYPE.progress,{lengthComputable:!0,loaded:this.#E,total:e}))}#g(e){Warning(\"AssetsManger: \"+e.message),this.#l.dispatchEvent(new ErrorEvent(PROGRESS_EVENT_TYPE.error,{error:e}))}}function Exception(e){throw new Error(e)}function Warning(e){console.warn(e)}","export class AnimationEvent {\n #eventName;\n /**\n * @type {number}\n */\n #defaultDurationTime = 100;\n /**\n * Array [sprite index, duration]\n * @type { Array> }\n */\n #animationSpriteIndexes;\n /**\n * \n * @type {number}\n */\n #currentAnimationItemIndex;\n /**\n * @type {boolean}\n */\n #isActive;\n /**\n * @type {boolean}\n */\n #isRepeated;\n #lastAnimationTimeStamp;\n \n constructor(eventName, animationSpriteIndexes, isRepeated = false, currentSpriteIndex, isActive = false) {\n this.#eventName = eventName;\n this.#animationSpriteIndexes = this.#convertToArray(animationSpriteIndexes);\n this.#currentAnimationItemIndex = currentSpriteIndex ? currentSpriteIndex : 0;\n this.#isActive = isActive;\n this.#isRepeated = isRepeated;\n }\n\n get name() {\n return this.#eventName;\n }\n\n get isActive() {\n return this.#isActive;\n }\n\n get currentSprite() {\n return this.#animationSpriteIndexes[this.#currentAnimationItemIndex][0];\n }\n\n get _isLastSprite() {\n return (this.#animationSpriteIndexes.length - 1) === this.#currentAnimationItemIndex;\n }\n\n iterateAnimationIndex() {\n const currentIndex = this.#currentAnimationItemIndex,\n currentDuration = this.#animationSpriteIndexes[currentIndex][1],\n lastIterationTime = Date.now() - this.#lastAnimationTimeStamp;\n // iterate or skip\n if (currentDuration < lastIterationTime) {\n if (!this._isLastSprite) {\n this.#currentAnimationItemIndex++;\n } else {\n if (!this.#isRepeated) {\n this.deactivateAnimation();\n } else {\n // take first element\n this.#currentAnimationItemIndex = 0;\n \n }\n }\n // reset timestamp\n this.#lastAnimationTimeStamp = Date.now();\n }\n }\n\n activateAnimation = () => {\n this.#isActive = true;\n this.#currentAnimationItemIndex = 0;\n this.#lastAnimationTimeStamp = Date.now();\n };\n\n deactivateAnimation = () => {\n this.#isActive = false;\n };\n\n #convertToArray(animationSpriteIndexes) {\n let animationArray = [];\n animationSpriteIndexes.forEach(element => {\n if (typeof element.id === \"number\" && typeof element.duration === \"number\") {\n animationArray.push([element.id, element.duration]);\n } else {\n animationArray.push([element, this.#defaultDurationTime]);\n }\n \n });\n return animationArray;\n }\n}","import { CONST } from \"../constants.js\";\nimport { DrawShapeObject } from \"./DrawShapeObject.js\";\n\n/**\n * Circle object to draw.\n * @extends DrawShapeObject\n * @see {@link DrawObjectFactory} should be created with factory method\n */\nexport class DrawCircleObject extends DrawShapeObject {\n /**\n * @type {number}\n */\n #radius;\n\n /**\n * @type {Array}\n */\n #vertices;\n\n /**\n * @hideconstructor\n */\n constructor(x, y, radius, bgColor) {\n super(CONST.DRAW_TYPE.CIRCLE, x, y, bgColor);\n this.#radius = radius;\n this.#vertices = this._interpolateConus(radius);\n }\n\n /**\n * Array of [x,y] cords.\n * @type {Array}\n */\n get vertices () {\n return this.#vertices;\n }\n\n set vertices(value) {\n this.#vertices = value;\n }\n\n /**\n * @type {number}\n */\n get radius() {\n return this.#radius;\n }\n}","import { CONST } from \"../constants.js\";\nimport { DrawShapeObject } from \"./DrawShapeObject.js\";\n\n/**\n * Conus object to draw.\n * @extends DrawShapeObject\n * @see {@link DrawObjectFactory} should be created with factory method\n */\nexport class DrawConusObject extends DrawShapeObject {\n /**\n * @type {number}\n */\n #radius;\n\n /**\n * @type {number}\n */\n #angle;\n\n /**\n * Array of [x,y] cords.\n * @type {Array}\n */\n #vertices;\n #fade_min;\n\n /**\n * @hideconstructor\n */\n constructor(x, y, radius, bgColor, angle, fade = 0) {\n super(CONST.DRAW_TYPE.CONUS, x, y, bgColor);\n this.#radius = radius;\n this.#angle = angle;\n this.#fade_min = fade;\n this.#vertices = this._interpolateConus(radius, angle);\n }\n\n /**\n * Array of [x,y] cords.\n * @type {Array}\n */\n get vertices () {\n return this.#vertices;\n }\n\n set vertices(value) {\n this.#vertices = value;\n }\n\n /**\n * @type {number}\n */\n get radius() {\n return this.#radius;\n }\n\n /**\n * @type {number}\n */\n get angle() {\n return this.#angle;\n }\n\n /**\n * @type {number}\n */\n get fade_min() {\n return this.#fade_min;\n }\n\n /**\n * @param {number} value - fade start pos in px\n */\n set fade_min(value) {\n this.#fade_min = value;\n }\n}","import { AnimationEvent } from \"./AnimationEvent.js\";\r\nimport { CONST, ERROR_CODES } from \"../constants.js\";\r\nimport { DrawShapeObject } from \"./DrawShapeObject.js\";\r\nimport { TextureStorage } from \"./WebGl/TextureStorage.js\";\r\nimport { Exception, Warning } from \"./Exception.js\";\r\n/**\r\n * Image object to draw\r\n * @extends DrawShapeObject\r\n * @see {@link DrawObjectFactory} should be created with factory method\r\n */\r\nexport class DrawImageObject extends DrawShapeObject {\r\n /**\r\n * @type {number}\r\n */\r\n #w;\r\n /**\r\n * @type {number}\r\n */\r\n #h;\r\n /**\r\n * Image sprite key\r\n * @type {string}\r\n */\r\n #key;\r\n /**\r\n * @type {ImageBitmap}\r\n */\r\n #image;\r\n /**\r\n * @type {EventTarget}\r\n */\r\n #emitter;\r\n /**\r\n * @type {Map}\r\n */\r\n #animations;\r\n /**\r\n * @type {null | string}\r\n */\r\n #activeAnimation;\r\n /**\r\n * @type {number}\r\n */\r\n #imageIndex;\r\n /**\r\n * @type {number}\r\n */\r\n #spacing = 0;\r\n /**\r\n * @type {Array>}\r\n */\r\n #vertices;\r\n /**\r\n * @type {Object | null}\r\n */\r\n #circleBoundaries;\r\n /**\r\n * @type {TextureStorage}\r\n */\r\n #textureStorage;\r\n\r\n /**\r\n * @hideconstructor\r\n */\r\n constructor(mapX, mapY, width, height, key, imageIndex = 0, boundaries, image, spacing = 0) {\r\n super(CONST.DRAW_TYPE.IMAGE, mapX, mapY);\r\n this.#key = key;\r\n this.#emitter = new EventTarget();\r\n this.#animations = new Map();\r\n this.image = image;\r\n this.#imageIndex = imageIndex;\r\n this.#spacing = spacing;\r\n this.#w = width;\r\n this.#h = height;\r\n this.#vertices = boundaries && !boundaries.r ? this._convertVerticesArray(boundaries) : boundaries && boundaries.r ? this._calculateConusBoundaries(boundaries.r) : this._calculateRectVertices(width, height);\r\n this.#circleBoundaries = boundaries && typeof boundaries.r !== \"undefined\" ? boundaries : null;\r\n }\r\n\r\n /**\r\n * @type {number}\r\n */\r\n get width() {\r\n return this.#w;\r\n }\r\n\r\n /**\r\n * @type {number}\r\n */\r\n get height() {\r\n return this.#h;\r\n }\r\n\r\n set width(w) {\r\n this.#w = w;\r\n }\r\n\r\n set height(h) {\r\n this.#h = h;\r\n }\r\n\r\n /**\r\n * A key should match an image loaded through AssetsManager\r\n * @type {string}\r\n */\r\n get key() {\r\n return this.#key;\r\n }\r\n\r\n /**\r\n * @type {ImageBitmap}\r\n */\r\n get image() {\r\n return this.#image;\r\n }\r\n\r\n set image(value) {\r\n if (this.#textureStorage) {\r\n this.#textureStorage._isTextureRecalculated = true;\r\n }\r\n\r\n this.#image = value;\r\n }\r\n\r\n /**\r\n * Current image index\r\n * @type {number}\r\n */\r\n get imageIndex() {\r\n return this.#imageIndex;\r\n }\r\n\r\n set imageIndex(value) {\r\n this.#imageIndex = value;\r\n }\r\n\r\n /**\r\n * Image spacing (for tilesets.spacing > 0)\r\n * @type {number}\r\n */\r\n get spacing() {\r\n return this.#spacing;\r\n }\r\n\r\n /**\r\n * Determines if image is animated or not\r\n * @type {boolean}\r\n */\r\n get hasAnimations() {\r\n return this.#animations.size > 0;\r\n }\r\n\r\n /**\r\n * @type {null | string}\r\n */\r\n get activeAnimation() {\r\n return this.#activeAnimation;\r\n }\r\n\r\n /**\r\n * @deprecated - use .vertices instead \r\n * @type {Array>}\r\n */\r\n get boundaries() {\r\n return this.#vertices;\r\n }\r\n\r\n get vertices() {\r\n return this.#vertices;\r\n }\r\n\r\n get circleBoundaries() {\r\n return this.#circleBoundaries;\r\n }\r\n\r\n /**\r\n * @ignore\r\n */\r\n _processActiveAnimations() {\r\n const activeAnimation = this.#activeAnimation;\r\n if (activeAnimation) {\r\n const animationEvent = this.#animations.get(activeAnimation);\r\n animationEvent.iterateAnimationIndex();\r\n this.#imageIndex = animationEvent.currentSprite;\r\n }\r\n }\r\n /**\r\n * @ignore\r\n */\r\n get _textureStorage() {\r\n return this.#textureStorage;\r\n }\r\n\r\n /**\r\n * @ignore\r\n */\r\n set _textureStorage(texture) {\r\n this.#textureStorage = texture;\r\n }\r\n\r\n /**\r\n * Emit event\r\n * @param {string} eventName \r\n * @param {...any} eventParams \r\n */\r\n emit(eventName, ...eventParams) {\r\n const event = new Event(eventName);\r\n event.data = [...eventParams];\r\n this.#emitter.dispatchEvent(event);\r\n }\r\n\r\n /**\r\n * Subscribe\r\n * @param {string} eventName \r\n * @param {*} listener \r\n * @param {*} options \r\n */\r\n addEventListener(eventName, listener, options) {\r\n this.#emitter.addEventListener(eventName, listener, options);\r\n }\r\n\r\n /**\r\n * Unsubscribe\r\n * @param {string} eventName \r\n * @param {*} listener \r\n * @param {*} options \r\n */\r\n removeEventListener(eventName, listener, options) {\r\n this.#emitter.removeEventListener(eventName, listener, options);\r\n }\r\n\r\n /**\r\n * Adds image animations\r\n * @param { string } eventName -animation name\r\n * @param { Array | Array<{duration:number, id:number}> } animationSpriteIndexes - animation image indexes\r\n * @param { boolean } [isRepeated = false] - animation is cycled or not, cycled animation could be stopped only with stopRepeatedAnimation();\r\n */\r\n addAnimation (eventName, animationSpriteIndexes, isRepeated) {\r\n if (!this.#checkAnimationParams(animationSpriteIndexes)) {\r\n Exception(ERROR_CODES.UNEXPECTED_INPUT_PARAMS, \" animationSpriteIndexes should be Array of indexes, or Array of objects {duration:number, id:number}\");\r\n }\r\n const animationEvent = new AnimationEvent(eventName, animationSpriteIndexes, isRepeated);\r\n this.#animations.set(eventName, animationEvent);\r\n this.addEventListener(eventName, this.#activateAnimation);\r\n }\r\n\r\n #checkAnimationParams (animationSpriteIndexes) {\r\n let isCorrect = true;\r\n animationSpriteIndexes.forEach(element => {\r\n if (typeof element !== \"number\") {\r\n if (typeof element.duration !== \"number\" || typeof element.id !== \"number\") {\r\n isCorrect = false;\r\n }\r\n } \r\n });\r\n return isCorrect;\r\n }\r\n #activateAnimation = (event) => {\r\n const animationName = event.type,\r\n animationEvent = this.#animations.get(animationName);\r\n // only one active animation can exist at a time\r\n if (this.#activeAnimation && this.#activeAnimation !== animationName) {\r\n this.stopRepeatedAnimation(this.#activeAnimation);\r\n }\r\n animationEvent.activateAnimation();\r\n this.#activeAnimation = animationName;\r\n this.#imageIndex = animationEvent.currentSprite;\r\n }; \r\n\r\n /**\r\n *\r\n * @param {string=} eventName - animation name, if not provided - stop current active animation event\r\n */\r\n stopRepeatedAnimation (eventName) {\r\n this.#animations.get(eventName).deactivateAnimation();\r\n this.#activeAnimation = null;\r\n }\r\n\r\n /**\r\n * Removes animations\r\n */\r\n removeAllAnimations() {\r\n for (let [eventName, animationEvent] of this.#animations.entries()) {\r\n this.removeEventListener(eventName, animationEvent.activateAnimation);\r\n animationEvent.deactivateAnimation();\r\n }\r\n this.#animations.clear();\r\n this.#animations = undefined;\r\n }\r\n\r\n destroy() {\r\n this.removeAllAnimations();\r\n super.destroy();\r\n }\r\n}","import { CONST } from \"../constants.js\";\nimport { DrawShapeObject } from \"./DrawShapeObject.js\";\n\n/**\n * Line object to draw.\n * @extends DrawShapeObject\n * @see {@link DrawObjectFactory} should be created with factory method\n */\nexport class DrawLineObject extends DrawShapeObject {\n /**\n * @type {Array>}\n */\n #vertices;\n\n /**\n * @hideconstructor\n */\n constructor(vertices, bgColor) {\n super(CONST.DRAW_TYPE.LINE, vertices[0][0], vertices[0][1], bgColor);\n this.#vertices = vertices;\n }\n\n /**\n * @type {Array>}\n */\n get vertices () {\n return this.#vertices;\n }\n\n set vertices(value) {\n this.#vertices = value;\n }\n}","import { DrawRectObject } from \"./DrawRectObject.js\";\r\nimport { DrawTextObject } from \"./DrawTextObject.js\";\r\nimport { DrawConusObject } from \"./DrawConusObject.js\";\r\nimport { DrawImageObject } from \"./DrawImageObject.js\";\r\nimport { DrawLineObject } from \"./DrawLineObject.js\";\r\nimport { DrawPolygonObject } from \"./DrawPolygonObject.js\";\r\nimport { DrawCircleObject } from \"./DrawCircleObject.js\";\r\nimport { DrawTiledLayer } from \"./DrawTiledLayer.js\";\r\nimport { DrawShapeObject } from \"./DrawShapeObject.js\";\r\nimport { GameStageData } from \"./GameStageData.js\";\r\nimport { Exception } from \"./Exception.js\";\r\nimport { ERROR_CODES } from \"../constants.js\";\r\n\r\n/**\r\n * Creates drawObjects instances.
\r\n * accessible via GameStage.draw
\r\n * Attach images for image objects and tilemaps
\r\n * Adds drawObjects to current GameStage.stageData\r\n * @see {@link GameStage} a part of GameStage\r\n */\r\nexport class DrawObjectFactory {\r\n /**\r\n * @type {AssetsManager}\r\n */\r\n #iLoader;\r\n /**\r\n * @type {GameStageData | null}\r\n */\r\n #currentPageData;\r\n /**\r\n * @hideconstructor \r\n */\r\n constructor(iLoader) {\r\n this.#iLoader = iLoader;\r\n }\r\n\r\n /**\r\n * @returns {GameStageData}\r\n */\r\n get stageData() {\r\n return this.#currentPageData;\r\n }\r\n\r\n /**\r\n * \r\n * @param {*} renderObject \r\n * @returns {Object}\r\n */\r\n #addObjectToPageData(renderObject) {\r\n this.#currentPageData._renderObject = renderObject;\r\n this.#currentPageData._sortRenderObjectsBySortIndex();\r\n return renderObject;\r\n }\r\n /**\r\n * @param {number} x \r\n * @param {number} y \r\n * @param {number} width \r\n * @param {number} height \r\n * @param {string} backgroundColor - rgba(r,g,b,a)\r\n * @returns {DrawRectObject}\r\n */\r\n rect(x, y, width, height, backgroundColor) {\r\n const renderObject = new DrawRectObject(x, y, width, height, backgroundColor);\r\n this.#addObjectToPageData(renderObject);\r\n return renderObject; \r\n }\r\n\r\n /**\r\n * @param {number} x \r\n * @param {number} y \r\n * @param {string} text \r\n * @param {string} font - size fontFamily\r\n * @param {string} color - rgba(r,g,b,a)\r\n * @returns {DrawTextObject}\r\n */\r\n text(x, y, text, font, color) {\r\n const renderObject = new DrawTextObject(x, y, text, font, color);\r\n this.#addObjectToPageData(renderObject);\r\n return renderObject;\r\n }\r\n\r\n /**\r\n * \r\n * @param {number} radius \r\n * @param {string} bgColor - rgba(r,g,b,a)\r\n * @param {number=} angle\r\n * @param {number=} [fade=0] (0 - 1)\r\n * @returns {DrawConusObject}\r\n */\r\n conus(x, y, radius, bgColor, angle, fade = 0) {\r\n const renderObject = new DrawConusObject(x, y, radius, bgColor, angle, fade);\r\n this.#addObjectToPageData(renderObject);\r\n return renderObject;\r\n }\r\n\r\n /**\r\n * \r\n * @param {number} radius \r\n * @param {string} bgColor - rgba(r,g,b,a)\r\n * @returns {DrawCircleObject}\r\n */\r\n circle(x, y, radius, bgColor) {\r\n const renderObject = new DrawCircleObject(x, y, radius, bgColor);\r\n this.#addObjectToPageData(renderObject);\r\n return renderObject;\r\n }\r\n\r\n /**\r\n * @param {number} x \r\n * @param {number} y \r\n * @param {number} width \r\n * @param {number} height \r\n * @param {string} key \r\n * @param {number} [imageIndex = 0]\r\n * @param {Array<{x:Number, y:Number}> | {r:number}=} boundaries - boundaries as polygon, or circle\r\n * @param {number} [spacing = 0] - for tilesets.spacing > 0\r\n * @returns {DrawImageObject}\r\n */\r\n image(x, y, width, height, key, imageIndex = 0, boundaries, spacing = 0) {\r\n const image = this.#iLoader.getImage(key);\r\n\r\n if (!image) {\r\n Exception(ERROR_CODES.CANT_GET_THE_IMAGE, \"iLoader can't get the image with key: \" + key);\r\n }\r\n \r\n const renderObject = new DrawImageObject(x, y, width, height, key, imageIndex, boundaries, image, spacing);\r\n \r\n this.#addObjectToPageData(renderObject);\r\n return renderObject;\r\n }\r\n\r\n /**\r\n * @param {Array} vertices \r\n * @param {string} color - rgba(r,g,b,a)\r\n * @returns {DrawLineObject}\r\n */\r\n line(vertices, color) {\r\n const renderObject = new DrawLineObject(vertices, color);\r\n this.#addObjectToPageData(renderObject);\r\n return renderObject;\r\n }\r\n\r\n /**\r\n * @param {Array<{x:number, y:number}>} vertices - should go in anticlockwise order\r\n * @param {string} bgColor - rgba(r,g,b,a)\r\n * @returns {DrawPolygonObject}\r\n */\r\n polygon(vertices, bgColor) {\r\n const renderObject = new DrawPolygonObject(vertices, bgColor);\r\n this.#addObjectToPageData(renderObject);\r\n return renderObject;\r\n }\r\n\r\n /**\r\n * \r\n * @param {string} layerKey \r\n * @param {string} tileMapKey \r\n * @param {boolean=} setBoundaries \r\n * @param {DrawShapeObject=} shapeMask \r\n * @returns {DrawTiledLayer}\r\n */\r\n tiledLayer(layerKey, tileMapKey, setBoundaries, shapeMask) {\r\n const tilemap = this.#iLoader.getTileMap(tileMapKey),\r\n tilesets = tilemap.tilesets,\r\n tilesetImages = tilesets.map((tileset) => this.#iLoader.getImage(tileset.data.name)),\r\n layerData = tilemap.layers.find((layer) => layer.name === layerKey),\r\n renderObject = new DrawTiledLayer(layerKey, tileMapKey, tilemap, tilesets, tilesetImages, layerData, setBoundaries, shapeMask);\r\n\r\n this.#addObjectToPageData(renderObject);\r\n return renderObject;\r\n }\r\n\r\n /**\r\n * @ignore\r\n * @param {string} methodKey \r\n * @param {Function} createObjectInstance\r\n */\r\n _registerNewObjectMethod = (methodKey, createObjectInstance) => {\r\n this[methodKey] = (...args) => this.#createObjectAndAddToPageData(createObjectInstance, ...args);\r\n };\r\n\r\n /**\r\n * @ignore\r\n * @param {Function} createInstance\r\n * @param {Array} args\r\n */\r\n #createObjectAndAddToPageData = (createInstance, ...args) => {\r\n const instance = createInstance(...args);\r\n this.#addObjectToPageData(instance);\r\n return instance;\r\n };\r\n\r\n /**\r\n * @ignore\r\n * @param {GameStageData} pageData;\r\n */\r\n _attachPageData = (pageData) => {\r\n this.#currentPageData = pageData;\r\n };\r\n /**\r\n * @ignore\r\n */\r\n _detachPageData = () => {\r\n this.#currentPageData = null;\r\n };\r\n}","import { CONST } from \"../constants.js\";\nimport { DrawShapeObject } from \"./DrawShapeObject.js\";\n\n/**\n * @extends DrawShapeObject\n * @see {@link DrawObjectFactory} should be created with factory method\n */\nexport class DrawPolygonObject extends DrawShapeObject {\n /**\n * @type {Array>}\n */\n #vertices;\n\n /**\n * @hideconstructor\n */\n constructor(vertices, bgColor) {\n super(CONST.DRAW_TYPE.POLYGON, vertices[0].x, vertices[0].y, bgColor);\n this.#vertices = this._convertVerticesArray(vertices);\n }\n\n /**\n * @type {Array>}\n */\n get vertices () {\n return this.#vertices;\n }\n\n set vertices(value) {\n this.#vertices = value;\n }\n}","import { CONST } from \"../constants.js\";\nimport { DrawShapeObject } from \"./DrawShapeObject.js\";\n\n/**\n * @extends DrawShapeObject\n * @see {@link DrawObjectFactory} should be created with factory method\n */\nexport class DrawRectObject extends DrawShapeObject {\n /**\n * @type {number}\n */\n #w;\n /**\n * @type {number}\n */\n #h;\n /**\n * @type {Array>}\n */\n #vertices;\n\n /**\n * @hideconstructor\n */\n constructor(x, y, w, h, bgColor) {\n super(CONST.DRAW_TYPE.RECTANGLE, x, y, bgColor);\n this.#w = w;\n this.#h = h;\n this.#vertices = this._calculateRectVertices(w,h);\n }\n\n /**\n * @type {Array>}\n */\n get vertices () {\n return this.#vertices;\n }\n /**\n * @type {number}\n */\n get width() {\n return this.#w;\n }\n\n /**\n * @type {number}\n */\n get height() {\n return this.#h;\n }\n\n set width(w) {\n this.#w = w;\n }\n\n set height(h) {\n this.#h = h;\n }\n}","import { CONST } from \"../constants.js\";\nimport { utils } from \"../index.js\";\n\n/**\n * A base draw object.\n */\nexport class DrawShapeObject {\n #x;\n #y;\n #bg;\n /**\n * @type {string}\n * @enum {CONST.DRAW_TYPE}\n */\n #type;\n /**\n * Is used for blending pixel arithmetic\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/blendFunc.\n * @type {Array}\n */\n #blendFunc;\n \n /**\n * @type {number}\n */\n #sortIndex = 0;\n /**\n * @type {number}\n */\n #rotation = 0;\n /**\n * @type {number}\n */\n #id = utils.generateUniqId();\n /**\n * @type {boolean}\n */\n #isRemoved = false;\n /**\n * @type {undefined | number | null}\n */\n #attachedMaskId;\n /**\n * @type {boolean}\n */\n #isMask;\n /**\n * @type {boolean}\n */\n #isOffsetTurnedOff = false;\n\n /**\n * @type {boolean}\n */\n #isChanged = false;\n /**\n * @hideconstructor\n */\n constructor(type, mapX, mapY, bgColor) {\n this.#x = mapX;\n this.#y = mapY;\n this.#bg = bgColor;\n this.#type = type;\n }\n\n /**\n * Background color as rgba(r,g,b,a).\n * @type {string}\n */\n get bgColor() {\n return this.#bg;\n }\n\n set bgColor(value) {\n this.#bg = value;\n }\n\n /**\n * @type {string}\n * @enum {CONST.DRAW_TYPE}\n */\n get type() {\n return this.#type;\n }\n\n /**\n * @type {number}\n */\n get x() {\n return this.#x;\n }\n\n /**\n * @type {number}\n */\n get y () {\n return this.#y;\n }\n\n set x(posX) {\n this.#x = posX;\n }\n\n set y(posY) {\n this.#y = posY;\n }\n\n /**\n * @type {number}\n */\n get sortIndex () {\n return this.#sortIndex;\n }\n\n set sortIndex(value) {\n this.#sortIndex = value;\n }\n\n get blendFunc () {\n return this.#blendFunc;\n }\n\n set blendFunc(value) {\n this.#blendFunc = value;\n }\n\n /**\n * @type {number}\n */\n get rotation() {\n return this.#rotation;\n }\n\n set rotation(value) {\n this.#rotation = value;\n }\n\n /**\n * @type {number}\n */\n get id() {\n return this.#id;\n }\n\n /**\n * @type {boolean}\n */\n get isRemoved() {\n return this.#isRemoved;\n }\n /**\n * Destroy object on next render iteration.\n */\n destroy() {\n this.#isRemoved = true;\n }\n\n get isMaskAttached() {\n return !!this.#attachedMaskId;\n }\n\n /**\n * @ignore\n */\n get _maskId() {\n return this.#attachedMaskId;\n }\n\n /**\n * \n * @param {DrawShapeObject} mask \n */\n setMask(mask) {\n mask._isMask = true;\n this.#attachedMaskId = mask.id;\n }\n\n removeMask() {\n this.#attachedMaskId = null;\n }\n\n set _isMask(isSet) {\n this.#isMask = isSet;\n }\n\n get _isMask() {\n return this.#isMask;\n }\n\n get isOffsetTurnedOff() {\n return this.#isOffsetTurnedOff;\n }\n\n /**\n * turn off offset for specific draw object\n * gameStageData.centerCameraPosition() will take no effect on such object\n * Can be used for something that should be always on screen: control buttons, overlay masks etc.\n */\n turnOffOffset() {\n this.#isOffsetTurnedOff = true;\n }\n /**\n * @ignore\n * @param {number} width \n * @param {number} height \n * @returns {Array>}\n */\n _calculateRectVertices = (width, height) => {\n const halfW = width/2,\n halfH = height/2;\n return [[-halfW, -halfH], [halfW, -halfH], [halfW, halfH], [-halfW, halfH]];\n };\n\n /**\n * @param {number} radius \n * @param {number} [angle = 2 * Math.PI]\n * @param {number} [step = Math.PI/12] \n * @returns {Array}\n * @ignore\n */\n _interpolateConus(radius, angle = 2*Math.PI, step = Math.PI/14) {\n let conusPolygonCoords = [0, 0];\n\n for (let r = 0; r <= angle; r += step) {\n let x2 = Math.cos(r) * radius,\n y2 = Math.sin(r) * radius;\n\n conusPolygonCoords.push(x2, y2);\n }\n\n return conusPolygonCoords;\n }\n\n /**\n * @param {number} radius \n * @param {number} [angle = 2 * Math.PI]\n * @param {number} [step = Math.PI/12] \n * @returns {Array>}\n * @ignore\n */\n _calculateConusBoundaries(radius, angle = 2*Math.PI, step = Math.PI/14) {\n let conusPolygonCoords = [];\n\n for (let r = 0; r <= angle; r += step) {\n let x2 = Math.cos(r) * radius,\n y2 = Math.sin(r) * radius;\n\n conusPolygonCoords.push([x2, y2]);\n }\n\n return conusPolygonCoords;\n }\n\n\n /**\n * @param {Array> | Array<{x:number, y:number}>} boundaries\n * @returns {Array>}\n * @ignore\n */\n _convertVerticesArray(boundaries) {\n if (typeof boundaries[0].x !== \"undefined\" && typeof boundaries[0].y !== \"undefined\") {\n return utils.verticesArrayToArrayNumbers(boundaries);\n } else {\n return boundaries;\n }\n }\n}","import { DrawShapeObject } from \"./DrawShapeObject.js\";\nimport { Rectangle } from \"./Primitives.js\";\nimport { CONST, ERROR_CODES } from \"../constants.js\";\nimport { Exception } from \"./Exception.js\";\nimport { TextureStorage } from \"./WebGl/TextureStorage.js\";\n\n/**\n * @extends DrawShapeObject\n * @see {@link DrawObjectFactory} should be created with factory method\n */\nexport class DrawTextObject extends DrawShapeObject {\n #font;\n #textAlign;\n #textBaseline;\n #fillStyle;\n #strokeStyle;\n #text;\n #textMetrics;\n /**\n * @type {HTMLCanvasElement}\n */\n #textureCanvas = document.createElement(\"canvas\");\n\n /**\n * @type {TextureStorage}\n */\n #textureStorage;\n\n /**\n * @hideconstructor\n */\n constructor(mapX, mapY, text, font, fillStyle) {\n super(CONST.DRAW_TYPE.TEXT, mapX, mapY);\n this.#text = text;\n this.#font = font;\n this.#fillStyle = fillStyle;\n this.#textMetrics;\n this.#calculateCanvasTextureAndMeasurements();\n }\n\n /**\n * Rectangle text box.\n * @type {Rectangle}\n */\n get boundariesBox() {\n const width = this.textMetrics ? Math.floor(this.textMetrics.width) : 300,\n height = this.textMetrics ? Math.floor(this.textMetrics.fontBoundingBoxAscent + this.textMetrics.fontBoundingBoxDescent): 30;\n return new Rectangle(this.x, this.y - height, width, height);\n }\n\n get vertices() {\n const bb = this.boundariesBox;\n return this._calculateRectVertices(bb.width, bb.height);\n }\n\n /**\n * @type {string}\n */\n get text() {\n return this.#text;\n }\n\n set text(value) {\n if (value !== this.#text) {\n this.#text = value;\n this.#calculateCanvasTextureAndMeasurements();\n }\n }\n\n /**\n * @type {string}\n */\n get font() {\n return this.#font;\n }\n\n set font(value) {\n if (value !== this.#font) {\n this.#font = value;\n this.#calculateCanvasTextureAndMeasurements();\n }\n }\n\n /**\n * @type {string}\n */\n get textAlign() {\n return this.#textAlign;\n }\n\n set textAlign(value) {\n if (value !== this.#textAlign) {\n this.#textAlign = value;\n this.#calculateCanvasTextureAndMeasurements();\n }\n }\n\n /**\n * @type {string}\n */\n get textBaseline() {\n return this.#textBaseline;\n }\n\n set textBaseline(value) {\n if (value !== this.#textBaseline) {\n this.#textBaseline = value;\n this.#calculateCanvasTextureAndMeasurements();\n }\n }\n\n /**\n * font color\n * @type {string}\n */\n get fillStyle() {\n return this.#fillStyle;\n }\n\n /**\n * font color\n */\n set fillStyle(value) {\n if (value !== this.#fillStyle) {\n this.#fillStyle = value;\n this.#calculateCanvasTextureAndMeasurements();\n }\n }\n\n /**\n * font stroke color\n * @type {string}\n */\n get strokeStyle() {\n return this.#strokeStyle;\n }\n\n /**\n * font stroke color\n */\n set strokeStyle(value) {\n if (value !== this.#strokeStyle) {\n this.#strokeStyle = value;\n this.#calculateCanvasTextureAndMeasurements();\n }\n }\n\n /**\n * @type {TextMetrics}\n */\n get textMetrics() {\n return this.#textMetrics;\n }\n\n /**\n * @ignore\n */\n set _textMetrics(value) {\n this.#textMetrics = value;\n }\n\n /**\n * @ignore\n */\n get _textureStorage() {\n return this.#textureStorage;\n }\n\n /**\n * @ignore\n */\n set _textureStorage(texture) {\n this.#textureStorage = texture;\n }\n\n /**\n * @ignore\n */\n get _textureCanvas() {\n return this.#textureCanvas;\n }\n\n /**\n * \n * @returns {void}\n */\n #calculateCanvasTextureAndMeasurements() {\n const ctx = this.#textureCanvas.getContext(\"2d\", { willReadFrequently: true }); // cpu counting instead gpu\n if (ctx) {\n //ctx.clearRect(0, 0, this.#textureCanvas.width, this.#textureCanvas.height);\n ctx.font = this.font;\n this._textMetrics = ctx.measureText(this.text);\n const boxWidth = this.boundariesBox.width, \n boxHeight = this.boundariesBox.height;\n \n ctx.canvas.width = boxWidth;\n ctx.canvas.height = boxHeight;\n // after canvas resize, have to cleanup and set the font again\n ctx.clearRect(0, 0, boxWidth, boxHeight);\n ctx.font = this.font;\n ctx.textBaseline = \"bottom\";// bottom\n if (this.fillStyle) {\n ctx.fillStyle = this.fillStyle;\n ctx.fillText(this.text, 0, boxHeight);\n } \n if (this.strokeStyle) {\n ctx.strokeStyle = this.strokeStyle;\n ctx.strokeText(this.text, 0, boxHeight);\n }\n \n if (this.#textureStorage) {\n this.#textureStorage._isTextureRecalculated = true;\n }\n\n // debug canvas\n // this.#textureCanvas.style.position = \"absolute\";\n // document.body.appendChild(this.#textureCanvas);\n \n } else {\n Exception(ERROR_CODES.UNHANDLED_EXCEPTION, \"can't getContext('2d')\");\n }\n }\n}","import { AnimationEvent } from \"./AnimationEvent.js\";\r\nimport { DrawShapeObject } from \"./DrawShapeObject.js\";\r\nimport { TextureStorage } from \"./WebGl/TextureStorage.js\";\r\n/**\r\n * A render object represents a layer from tiled editor\r\n * @see {@link DrawObjectFactory} should be created with factory method\r\n */\r\nexport class DrawTiledLayer {\r\n #layerKey;\r\n #tileMapKey;\r\n #tilemap;\r\n #tilesets;\r\n /**\r\n * @type {string}\r\n */\r\n #DELIMITER = \"-#-\";\r\n #tilesetImages;\r\n /**\r\n * @type {Array}\r\n */\r\n #textureStorages;\r\n #layerData;\r\n #setBoundaries;\r\n #drawBoundaries;\r\n #attachedMaskId;\r\n /**\r\n * @type {number}\r\n */\r\n #sortIndex = 0;\r\n /**\r\n * @type {Map}\r\n */\r\n #animations = new Map();\r\n #isOffsetTurnedOff;\r\n\r\n /**\r\n * @hideconstructor\r\n */\r\n constructor(layerKey, tileMapKey, tilemap, tilesets, tilesetImages, layerData, setBoundaries = false, shapeMask) {\r\n this.#layerKey = layerKey;\r\n this.#tileMapKey = tileMapKey;\r\n this.#tilemap = tilemap;\r\n this.#tilesets = tilesets;\r\n this.#textureStorages = [];\r\n this.#tilesetImages = tilesetImages;\r\n this.#layerData = layerData;\r\n this.#setBoundaries = setBoundaries;\r\n this.#drawBoundaries = setBoundaries ? setBoundaries : false;\r\n if (shapeMask) {\r\n this.setMask(shapeMask);\r\n }\r\n this.#processTilesets(tilesets);\r\n }\r\n\r\n /**\r\n * A layer name.\r\n * @type {string}\r\n */\r\n get layerKey() {\r\n return this.#layerKey;\r\n }\r\n\r\n /**\r\n * A tilemap layer key, should match key from the tilemap.\r\n * @type {string}\r\n */\r\n get tileMapKey() {\r\n return this.#tileMapKey;\r\n }\r\n\r\n get tilemap() {\r\n return this.#tilemap;\r\n }\r\n \r\n get tilesets() {\r\n return this.#tilesets;\r\n }\r\n\r\n get tilesetImages() {\r\n return this.#tilesetImages;\r\n }\r\n\r\n get layerData() {\r\n return this.#layerData;\r\n }\r\n /**\r\n * Should the layer borders used as boundaries, or not\r\n * Can be set in GameStage.addRenderLayer() method.\r\n * @type {boolean}\r\n */\r\n get setBoundaries() {\r\n return this.#setBoundaries;\r\n }\r\n\r\n /**\r\n * Should draw a boundaries helper, or not\r\n * Can be set in SystemSettings.\r\n * @type {boolean}\r\n */\r\n get drawBoundaries() {\r\n return this.#drawBoundaries;\r\n }\r\n\r\n set drawBoundaries(value) {\r\n this.#drawBoundaries = value;\r\n }\r\n\r\n /**\r\n * @ignore\r\n */\r\n get _maskId() {\r\n return this.#attachedMaskId;\r\n }\r\n /**\r\n * \r\n * @param {DrawShapeObject} mask \r\n */\r\n setMask(mask) {\r\n mask._isMask = true;\r\n this.#attachedMaskId = mask.id;\r\n }\r\n\r\n removeMask() {\r\n this.#attachedMaskId = null;\r\n }\r\n\r\n /**\r\n * @type {number}\r\n */\r\n get sortIndex () {\r\n return this.#sortIndex;\r\n }\r\n\r\n set sortIndex(value) {\r\n this.#sortIndex = value;\r\n }\r\n\r\n get isOffsetTurnedOff() {\r\n return this.#isOffsetTurnedOff;\r\n }\r\n turnOffOffset() {\r\n this.#isOffsetTurnedOff = true;\r\n }\r\n\r\n /**\r\n * Determines if image is animated or not\r\n * @type {boolean}\r\n */\r\n get hasAnimations() {\r\n return this.#animations.size > 0;\r\n }\r\n\r\n /**\r\n * @ignore\r\n */\r\n get _textureStorages() {\r\n return this.#textureStorages;\r\n }\r\n\r\n /**\r\n * @ignore\r\n */\r\n _setTextureStorage(index, value) {\r\n this.#textureStorages[index] = value;\r\n }\r\n\r\n /**\r\n * Tilesets has a property tiles, which could contain tile animations\r\n * or object boundaries, this is workaround for split this and add\r\n * additional properties for use in draw phase:\r\n * _hasAnimations\r\n * _animations - Map\r\n * _hasBoundaries\r\n * _boundaries - Map\r\n * @param {*} tilesets\r\n */\r\n #processTilesets(tilesets) {\r\n for (let tileset of tilesets) {\r\n const tiles = tileset.data.tiles,\r\n name = tileset.data.name;\r\n if (tiles) {\r\n for (let tile of tiles) {\r\n const animation = tile.animation,\r\n objectgroup = tile.objectgroup,\r\n id = tile.id;\r\n if (animation) {\r\n const eventName = name + this.#DELIMITER + id, \r\n animationIndexes = this.#fixAnimationsItems(animation),\r\n animationEvent = new AnimationEvent(eventName, animationIndexes, true);\r\n\r\n this.#animations.set(eventName, animationEvent);\r\n // add additional properties\r\n if (!tileset.data._hasAnimations) {\r\n tileset.data._hasAnimations = true;\r\n tileset.data._animations = new Map();\r\n //\r\n tileset.data._animations.set(id, animationIndexes[0][0]);\r\n }\r\n this.#activateAnimation(animationEvent);\r\n }\r\n if (objectgroup) {\r\n if (tileset.data._hasBoundaries) {\r\n tileset.data._boundaries.set(id, objectgroup);\r\n } else {\r\n // add additional properties\r\n tileset.data._hasBoundaries = true;\r\n tileset.data._boundaries = new Map();\r\n tileset.data._boundaries.set(id, objectgroup);\r\n }\r\n \r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * \r\n * @param {Array<{duration:number, tileid:number}>} animation \r\n * @returns {Array<{duration:number, id:number}>}\r\n */\r\n #fixAnimationsItems(animation) {\r\n return animation.map((animation_item) => ({duration:animation_item.duration, id: animation_item.tileid}));\r\n }\r\n /**\r\n * @ignore\r\n */\r\n _processActiveAnimations() {\r\n for (let animationEvent of this.#animations.values()) {\r\n if (animationEvent.isActive) {\r\n animationEvent.iterateAnimationIndex();\r\n this.#switchCurrentActiveSprite(animationEvent);\r\n }\r\n }\r\n }\r\n\r\n #activateAnimation = (animationEvent) => {\r\n animationEvent.activateAnimation();\r\n this.#switchCurrentActiveSprite(animationEvent);\r\n }; \r\n\r\n #switchCurrentActiveSprite = (animationEvent) => {\r\n const [tilesetKey, animationId] = animationEvent.name.split(this.#DELIMITER),\r\n tilesetIndex = this.#tilesets.findIndex(tileset => tileset.data.name === tilesetKey),\r\n tileset = this.#tilesets[tilesetIndex];\r\n \r\n tileset.data._animations.set(parseInt(animationId), animationEvent.currentSprite);\r\n };\r\n\r\n /**\r\n *\r\n * @param {string} eventName - animation name\r\n */\r\n stopRepeatedAnimation (eventName) {\r\n this.#animations.get(eventName).deactivateAnimation();\r\n }\r\n\r\n /**\r\n * Removes animations\r\n */\r\n removeAllAnimations() {\r\n for (let [eventName, animationEvent] of this.#animations.entries()) {\r\n this.removeEventListener(eventName, animationEvent.activateAnimation);\r\n animationEvent.deactivateAnimation();\r\n }\r\n this.#animations.clear();\r\n this.#animations = undefined;\r\n }\r\n\r\n destroy() {\r\n this.removeAllAnimations();\r\n super.destroy();\r\n }\r\n}\r\n","import { CONST, ERROR_CODES } from \"../../constants.js\";\nimport { Exception } from \"../Exception.js\";\n\nexport class SystemEvent extends Event {\n #data;\n constructor(eventValue, data){\n super(eventValue);\n if (!this.#isEventExist(eventValue)) {\n Exception(ERROR_CODES.UNEXPECTED_EVENT_NAME, \", Please check if event is exist\");\n }\n this.#data = data;\n }\n\n #isEventExist(eventValue) {\n return Object.values(CONST.EVENTS.WEBSOCKET.SERVER_CLIENT).find(eventVal => eventVal === eventValue);\n }\n\n get data () {\n return this.#data;\n }\n}","export function Exception (code, message) {\n throw new Error(code + \": \" + message);\n}\n\nexport function Warning (code, message) {\n console.warn(code, message);\n}","import { CONST, ERROR_CODES, WARNING_CODES } from \"../constants.js\";\r\nimport { GameStageData } from \"./GameStageData.js\";\r\nimport { Exception, Warning } from \"./Exception.js\";\r\nimport AssetsManager from \"../../modules/assetsm/dist/assetsm.min.js\";\r\nimport { DrawObjectFactory } from \"./DrawObjectFactory.js\";\r\nimport { DrawCircleObject } from \"./DrawCircleObject.js\";\r\nimport { DrawConusObject } from \"./DrawConusObject.js\";\r\nimport { DrawImageObject } from \"./DrawImageObject.js\";\r\nimport { DrawLineObject } from \"./DrawLineObject.js\";\r\nimport { DrawPolygonObject } from \"./DrawPolygonObject.js\";\r\nimport { DrawRectObject } from \"./DrawRectObject.js\";\r\nimport { DrawTextObject } from \"./DrawTextObject.js\";\r\nimport { ISystem } from \"./ISystem.js\";\r\nimport { ISystemAudio } from \"./ISystemAudio.js\";\r\nimport { SystemSettings } from \"../configs.js\";\r\nimport { isPointLineIntersect, isEllipseCircleIntersect, isPointCircleIntersect, isEllipsePolygonIntersect, isPolygonLineIntersect, isPointPolygonIntersect, angle_2points, isCircleLineIntersect } from \"../utils.js\";\r\nimport { Vector } from \"./Primitives.js\";\r\n\r\n/**\r\n * Represents the stage of the game,
\r\n * Contains pages logic.
\r\n * Instances should be created and registered with System.registerStage() factory method\r\n * \r\n * @see {@link System} instances of this class holds by the System class\r\n * @hideconstructor\r\n */\r\nexport class GameStage {\r\n /**\r\n * @type {string}\r\n */\r\n #name;\r\n /**\r\n * @type {boolean}\r\n */\r\n #isInitiated = false;\r\n /**\r\n * @type {boolean}\r\n */\r\n #isActive;\r\n /**\r\n * @typedef {ISystem}\r\n */\r\n #iSystemReference;\r\n /**\r\n * @type {GameStageData}\r\n */\r\n #stageData;\r\n\r\n constructor() {\r\n this.#isActive = false;\r\n this.#stageData = new GameStageData();\r\n }\r\n\r\n /**\r\n * Register stage\r\n * @param {string} name\r\n * @param {ISystem} system \r\n * @ignore\r\n */\r\n _register(name, system) {\r\n this.#name = name;\r\n this.#iSystemReference = system;\r\n this.#setWorldDimensions();\r\n this.#setCanvasSize();\r\n this.register();\r\n }\r\n\r\n /**\r\n * Initialization stage\r\n * @ignore\r\n */\r\n _init() {\r\n this.init();\r\n this.#isInitiated = true;\r\n }\r\n\r\n /**\r\n * @tutorial stages_lifecycle\r\n * Custom logic for register stage\r\n */\r\n register() {}\r\n /**\r\n * @tutorial stages_lifecycle\r\n * Custom logic for init stage\r\n */\r\n init() {}\r\n /**\r\n * Custom logic for start stage\r\n * @param {Object=} options\r\n */\r\n start(options) {}\r\n /**\r\n * @tutorial stages_lifecycle\r\n * Custom logic for stop stage\r\n */\r\n stop() {}\r\n /**\r\n * Custom logic for resize stage\r\n */\r\n resize() {}\r\n\r\n /**\r\n * @tutorial assets_manager\r\n * @type {AssetsManager}\r\n */\r\n get iLoader() {\r\n return this.#iSystemReference.iLoader;\r\n }\r\n\r\n /**\r\n * @type {DrawObjectFactory}\r\n */\r\n get draw() {\r\n return this.#iSystemReference.drawObjectFactory;\r\n }\r\n\r\n /**\r\n * Attach all canvas elements from the #views to container\r\n * @param {HTMLElement} container\r\n * @ignore\r\n */\r\n _attachCanvasToContainer(container) {\r\n this.#attachElementToContainer(this.canvasHtmlElement, container);\r\n }\r\n\r\n /**\r\n * Add render object to the stageData\r\n * @param { DrawConusObject | DrawImageObject | \r\n * DrawLineObject | DrawPolygonObject | \r\n * DrawRectObject | DrawCircleObject | \r\n * DrawTextObject } renderObject \r\n */\r\n addRenderObject = (renderObject) => {\r\n const data = this.stageData,\r\n isDataAlreadyAdded = data.renderObjects.indexOf(renderObject) !== -1;\r\n if (isDataAlreadyAdded) {\r\n Warning(WARNING_CODES.NEW_BEHAVIOR_INTRODUCED, \"stage.draw methods add objects to pageData, no need to call addRenderObject\");\r\n } else {\r\n data._renderObject = renderObject;\r\n data._sortRenderObjectsBySortIndex(); \r\n }\r\n };\r\n\r\n /**\r\n * Determines if this stage render is Active or not\r\n * @type {boolean}\r\n */\r\n get isActive() {\r\n return this.#isActive;\r\n }\r\n\r\n /**\r\n * Determines if this stage is initialized or not\r\n * @type {boolean}\r\n */\r\n get isInitiated() {\r\n return this.#isInitiated;\r\n }\r\n\r\n /**\r\n * Current stage name\r\n * @type {string}\r\n */\r\n get name () {\r\n return this.#name;\r\n }\r\n\r\n /**\r\n * @type {GameStageData}\r\n */\r\n get stageData() {\r\n return this.#stageData;\r\n }\r\n\r\n /**\r\n * @type {SystemSettings}\r\n */\r\n get systemSettings() {\r\n return this.#iSystemReference.systemSettings;\r\n }\r\n\r\n /**\r\n * @type {ISystemAudio}\r\n */\r\n get audio() {\r\n return this.#iSystemReference.audio;\r\n }\r\n\r\n /**\r\n * @type {ISystem}\r\n */\r\n get iSystem() {\r\n return this.#iSystemReference;\r\n }\r\n\r\n get canvasHtmlElement() {\r\n return document.getElementsByTagName(\"canvas\")[0];\r\n }\r\n\r\n /**\r\n * \r\n * @param {string} eventName \r\n * @param {*} listener \r\n * @param {*=} options \r\n */\r\n addEventListener = (eventName, listener, options) => {\r\n this.iSystem.addEventListener(eventName, listener, options);\r\n };\r\n\r\n /**\r\n * \r\n * @param {string} eventName \r\n * @param {*} listener \r\n * @param {*=} options \r\n */\r\n removeEventListener = (eventName, listener, options) => {\r\n this.iSystem.removeEventListener(eventName, listener, options);\r\n };\r\n\r\n /**\r\n * Start stage render\r\n * @param {Object=} options \r\n * @ignore\r\n */\r\n _start(options) {\r\n this.start(options);\r\n this.#isActive = true;\r\n window.addEventListener(\"resize\", this._resize);\r\n this._resize();\r\n }\r\n\r\n /**\r\n * Stop stage render\r\n * @ignore\r\n */\r\n _stop() {\r\n this.#isActive = false;\r\n window.removeEventListener(\"resize\", this._resize);\r\n this.stop();\r\n }\r\n\r\n /**\r\n * Resize event\r\n * @ignore\r\n */\r\n _resize = () => {\r\n this.#setCanvasSize();\r\n this.resize();\r\n };\r\n\r\n /**\r\n * \r\n * @param {HTMLCanvasElement} htmlElement \r\n * @param {HTMLElement} container \r\n */\r\n #attachElementToContainer(htmlElement, container) {\r\n container.appendChild(htmlElement);\r\n }\r\n\r\n #setWorldDimensions() {\r\n const width = this.systemSettings.worldSize ? this.systemSettings.worldSize.width : 0,\r\n height = this.systemSettings.worldSize ? this.systemSettings.worldSize.height : 0;\r\n \r\n this.stageData._setWorldDimensions(width, height);\r\n }\r\n\r\n //////////////////////////////////////////////////////\r\n //***************************************************/\r\n //****************** Collisions ********************//\r\n //**************************************************//\r\n //////////////////////////////////////////////////////\r\n\r\n /**\r\n * \r\n * @param {number} x \r\n * @param {number} y \r\n * @param {DrawImageObject} drawObject \r\n * @returns {{x:number, y:number, p:number} | boolean}\r\n */\r\n isBoundariesCollision = (x, y, drawObject) => {\r\n const drawObjectType = drawObject.type,\r\n vertices = drawObject.vertices,\r\n circleBoundaries = drawObject.circleBoundaries;\r\n switch(drawObjectType) {\r\n case CONST.DRAW_TYPE.TEXT:\r\n case CONST.DRAW_TYPE.RECTANGLE:\r\n case CONST.DRAW_TYPE.CONUS:\r\n case CONST.DRAW_TYPE.IMAGE:\r\n if (!circleBoundaries) {\r\n return this.#isPolygonToBoundariesCollision(x, y, vertices, drawObject.rotation);\r\n } else {\r\n return this.#isCircleToBoundariesCollision(x, y, drawObject.circleBoundaries.r);\r\n }\r\n case CONST.DRAW_TYPE.CIRCLE:\r\n Warning(CONST.WARNING_CODES.METHOD_NOT_IMPLEMENTED, \"isObjectCollision.circle check is not implemented yet!\");\r\n break;\r\n case CONST.DRAW_TYPE.LINE:\r\n Warning(CONST.WARNING_CODES.METHOD_NOT_IMPLEMENTED, \"isObjectCollision.line check is not implemented yet, please use .rect instead line!\");\r\n break;\r\n default:\r\n Warning(CONST.WARNING_CODES.UNKNOWN_DRAW_OBJECT, \"unknown object type!\");\r\n }\r\n return false;\r\n };\r\n\r\n /**\r\n * \r\n * @param {number} x \r\n * @param {number} y \r\n * @param {DrawImageObject} drawObject\r\n * @param {Array} objects - objects array to check\r\n * @returns {{x:number, y:number, p:number} | boolean} - the closest collision\r\n */\r\n isObjectsCollision = (x, y, drawObject, objects) => {\r\n const drawObjectType = drawObject.type,\r\n drawObjectBoundaries = drawObject.vertices,\r\n circleBoundaries = drawObject.circleBoundaries;\r\n switch(drawObjectType) {\r\n case CONST.DRAW_TYPE.TEXT:\r\n case CONST.DRAW_TYPE.RECTANGLE:\r\n case CONST.DRAW_TYPE.CONUS:\r\n case CONST.DRAW_TYPE.IMAGE:\r\n if (!circleBoundaries) {\r\n return this.#isPolygonToObjectsCollision(x, y, drawObjectBoundaries, drawObject.rotation, objects);\r\n } else {\r\n return this.#isCircleToObjectsCollision(x, y, circleBoundaries, objects);\r\n }\r\n case CONST.DRAW_TYPE.CIRCLE:\r\n Warning(CONST.WARNING_CODES.METHOD_NOT_IMPLEMENTED, \"isObjectCollision.circle check is not implemented yet!\");\r\n break;\r\n case CONST.DRAW_TYPE.LINE:\r\n Warning(CONST.WARNING_CODES.METHOD_NOT_IMPLEMENTED, \"isObjectCollision.line check is not implemented yet, please use .rect instead line!\");\r\n break;\r\n default:\r\n Warning(CONST.WARNING_CODES.UNKNOWN_DRAW_OBJECT, \"unknown object type!\");\r\n }\r\n return false;\r\n };\r\n #isPolygonToObjectsCollision(x, y, polygonVertices, polygonRotation, objects) {\r\n const len = objects.length;\r\n\r\n let collisions = [];\r\n for (let i = 0; i < len; i++) {\r\n const mapObject = objects[i],\r\n drawMapObjectType = mapObject.type;\r\n\r\n let coll;\r\n \r\n switch(drawMapObjectType) {\r\n case CONST.DRAW_TYPE.TEXT:\r\n case CONST.DRAW_TYPE.RECTANGLE:\r\n case CONST.DRAW_TYPE.CONUS:\r\n case CONST.DRAW_TYPE.IMAGE:\r\n coll = this.#isPolygonToPolygonCollision(x, y, polygonVertices, polygonRotation, mapObject);\r\n break;\r\n case CONST.DRAW_TYPE.CIRCLE:\r\n console.warn(\"isObjectCollision.circle check is not implemented yet!\");\r\n break;\r\n case CONST.DRAW_TYPE.LINE:\r\n console.warn(\"isObjectCollision.line check is not implemented, please use rect instead\");\r\n break;\r\n default:\r\n console.warn(\"unknown object type!\");\r\n }\r\n if (coll) {\r\n collisions.push(coll);\r\n }\r\n }\r\n if (collisions.length > 0) {\r\n return this.#takeTheClosestCollision(collisions);\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n #isCircleToObjectsCollision(x, y, drawObjectBoundaries, objects) {\r\n const radius = drawObjectBoundaries.r;\r\n\r\n const len = objects.length;\r\n\r\n let collisions = [];\r\n for (let i = 0; i < len; i++) {\r\n const mapObject = objects[i],\r\n drawMapObjectType = mapObject.type,\r\n circleBoundaries = mapObject.circleBoundaries;\r\n\r\n let coll;\r\n \r\n switch(drawMapObjectType) {\r\n case CONST.DRAW_TYPE.TEXT:\r\n case CONST.DRAW_TYPE.RECTANGLE:\r\n case CONST.DRAW_TYPE.CONUS:\r\n case CONST.DRAW_TYPE.IMAGE:\r\n if (!circleBoundaries) {\r\n coll = this.#isCircleToPolygonCollision(x, y, radius, mapObject);\r\n } else {\r\n coll = this.#isCircleToCircleCollision(x, y, radius, mapObject.x, mapObject.y, circleBoundaries.r);\r\n }\r\n break;\r\n case CONST.DRAW_TYPE.CIRCLE:\r\n console.warn(\"isObjectCollision.circle check is not implemented yet!\");\r\n break;\r\n case CONST.DRAW_TYPE.LINE:\r\n console.warn(\"isObjectCollision.line check is not implemented, please use rect instead\");\r\n break;\r\n default:\r\n console.warn(\"unknown object type!\");\r\n }\r\n if (coll) {\r\n collisions.push(coll);\r\n }\r\n }\r\n if (collisions.length > 0) {\r\n return this.#takeTheClosestCollision(collisions);\r\n } else {\r\n return null;\r\n }\r\n }\r\n \r\n #takeTheClosestCollision(collisions) {\r\n return collisions.sort((a,b) => a.p < b.p)[0];\r\n }\r\n\r\n #isCircleToPolygonCollision(x, y, radius, mapObject) {\r\n const [mapOffsetX, mapOffsetY] = this.stageData.worldOffset,\r\n xWithOffset = x - mapOffsetX,\r\n yWithOffset = y - mapOffsetY,\r\n mapObjXWithOffset = mapObject.x - mapOffsetX,\r\n mapObjYWithOffset = mapObject.y - mapOffsetY,\r\n mapObjVertices = mapObject.vertices, \r\n mapObjRotation = mapObject.rotation,\r\n len = mapObjVertices.length;\r\n //console.log(\"map object check:\");\r\n //console.log(mapObject);\r\n for (let i = 0; i < len; i+=1) {\r\n const mapObjFirstVertex = mapObjVertices[i];\r\n let mapObjNextVertex = mapObjVertices[i + 1];\r\n if (!mapObjNextVertex) {\r\n mapObjNextVertex = mapObjVertices[0];\r\n }\r\n const vertex = this.#calculateShiftedVertexPos(mapObjFirstVertex, mapObjXWithOffset, mapObjYWithOffset, mapObjRotation),\r\n nextVertex = this.#calculateShiftedVertexPos(mapObjNextVertex, mapObjXWithOffset, mapObjYWithOffset, mapObjRotation),\r\n edge = {\r\n x1: vertex[0],\r\n y1: vertex[1],\r\n x2: nextVertex[0],\r\n y2: nextVertex[1]\r\n },\r\n intersect = isCircleLineIntersect(xWithOffset, yWithOffset, radius, edge);\r\n if (intersect) {\r\n //console.log(\"polygon: \", polygonWithOffsetAndRotation);\r\n //console.log(\"intersect: \", intersect);\r\n return intersect;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n #isCircleToCircleCollision(circle1X, circle1Y, circle1R, circle2X, circle2Y, circle2R) {\r\n const len = new Vector(circle1X, circle1Y, circle2X, circle2Y).length;\r\n console.log(len);\r\n console.log(circle1R);\r\n console.log(circle2R);\r\n if ((len - (circle1R + circle2R)) > 0) {\r\n return false;\r\n } else {\r\n //@todo calculate point of intersect\r\n return true;\r\n }\r\n }\r\n\r\n #isPolygonToPolygonCollision(x, y, polygonVertices, polygonRotation, mapObject) {\r\n const [mapOffsetX, mapOffsetY] = this.stageData.worldOffset,\r\n xWithOffset = x - mapOffsetX,\r\n yWithOffset = y - mapOffsetY,\r\n mapObjXWithOffset = mapObject.x - mapOffsetX,\r\n mapObjYWithOffset = mapObject.y - mapOffsetY,\r\n mapObjVertices = mapObject.vertices, \r\n mapObjRotation = mapObject.rotation,\r\n polygonWithOffsetAndRotation = polygonVertices.map((vertex) => (this.#calculateShiftedVertexPos(vertex, xWithOffset, yWithOffset, polygonRotation))),\r\n len = mapObjVertices.length;\r\n //console.log(\"map object check:\");\r\n //console.log(mapObject);\r\n for (let i = 0; i < len; i+=1) {\r\n const mapObjFirstVertex = mapObjVertices[i];\r\n let mapObjNextVertex = mapObjVertices[i + 1];\r\n if (!mapObjNextVertex) {\r\n mapObjNextVertex = mapObjVertices[0];\r\n }\r\n const vertex = this.#calculateShiftedVertexPos(mapObjFirstVertex, mapObjXWithOffset, mapObjYWithOffset, mapObjRotation),\r\n nextVertex = this.#calculateShiftedVertexPos(mapObjNextVertex, mapObjXWithOffset, mapObjYWithOffset, mapObjRotation),\r\n edge = {\r\n x1: vertex[0],\r\n y1: vertex[1],\r\n x2: nextVertex[0],\r\n y2: nextVertex[1]\r\n },\r\n intersect = isPolygonLineIntersect(polygonWithOffsetAndRotation, edge);\r\n if (intersect) {\r\n //console.log(\"polygon: \", polygonWithOffsetAndRotation);\r\n //console.log(\"intersect: \", intersect);\r\n return intersect;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n #calculateShiftedVertexPos(vertex, centerX, centerY, rotation) {\r\n const vector = new Vector(0, 0, vertex[0], vertex[1]),\r\n vertexAngle = angle_2points(0, 0, vertex[0], vertex[1]),\r\n len = vector.length;\r\n \r\n const newX = centerX + (len * Math.cos(rotation + vertexAngle)),\r\n newY = centerY + (len * Math.sin(rotation + vertexAngle));\r\n return [newX, newY];\r\n }\r\n /**\r\n * \r\n * @param {number} x \r\n * @param {number} y \r\n * @param {number} r \r\n * @returns {{x:number, y:number, p:number} | boolean}\r\n */\r\n #isCircleToBoundariesCollision(x, y, r) {\r\n const mapObjects = this.stageData.getBoundaries(),\r\n ellipseB = this.stageData.getEllipseBoundaries(),\r\n pointB = this.stageData.getPointBoundaries(),\r\n [mapOffsetX, mapOffsetY] = this.stageData.worldOffset,\r\n xWithOffset = x - mapOffsetX,\r\n yWithOffset = y - mapOffsetY,\r\n len = mapObjects.length,\r\n eLen = ellipseB.length,\r\n pLen = pointB.length;\r\n\r\n for (let i = 0; i < len; i+=1) {\r\n const item = mapObjects[i];\r\n const object = {\r\n x1: item[0],\r\n y1: item[1],\r\n x2: item[2],\r\n y2: item[3]\r\n },\r\n intersect = isCircleLineIntersect(xWithOffset, yWithOffset, r, object);\r\n if (intersect) {\r\n //console.log(\"rotation: \", rotation);\r\n //console.log(\"polygon: \", polygonWithOffsetAndRotation);\r\n //console.log(\"intersect: \", intersect);\r\n return intersect;\r\n }\r\n }\r\n if (eLen > 0) {\r\n for (let i = 0; i < eLen; i+=1) {\r\n const ellipse = ellipseB[i],\r\n intersect = isEllipseCircleIntersect(ellipse, {x:xWithOffset, y:yWithOffset, r});\r\n if (intersect) {\r\n //console.log(\"rotation: \", rotation);\r\n //console.log(\"polygon: \", polygonWithOffsetAndRotation);\r\n //console.log(\"intersect: \", intersect);\r\n return intersect;\r\n }\r\n }\r\n }\r\n \r\n if (pLen > 0) {\r\n for (let i = 0; i < pLen; i+=1) {\r\n const point = pointB[i],\r\n xP = point[0],\r\n yP = point[1],\r\n intersect = isPointCircleIntersect(xP, yP, {x:xWithOffset, y:yWithOffset, r});\r\n if (intersect) {\r\n //console.log(\"rotation: \", rotation);\r\n //console.log(\"polygon: \", polygonWithOffsetAndRotation);\r\n //console.log(\"intersect: \", intersect);\r\n return intersect;\r\n }\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * @param {number} x\r\n * @param {number} y\r\n * @param {Array>} polygon\r\n * @param {number} rotation \r\n * @returns {{x:number, y:number, p:number} | boolean}\r\n */\r\n #isPolygonToBoundariesCollision(x, y, polygon, rotation) {\r\n const mapObjects = this.stageData.getBoundaries(),\r\n ellipseB = this.stageData.getEllipseBoundaries(),\r\n pointB = this.stageData.getPointBoundaries(),\r\n [mapOffsetX, mapOffsetY] = this.stageData.worldOffset,\r\n xWithOffset = x - mapOffsetX,\r\n yWithOffset = y - mapOffsetY,\r\n polygonWithOffsetAndRotation = polygon.map((vertex) => (this.#calculateShiftedVertexPos(vertex, xWithOffset, yWithOffset, rotation))),\r\n len = mapObjects.length,\r\n eLen = ellipseB.length,\r\n pLen = pointB.length;\r\n\r\n for (let i = 0; i < len; i+=1) {\r\n const item = mapObjects[i];\r\n const object = {\r\n x1: item[0],\r\n y1: item[1],\r\n x2: item[2],\r\n y2: item[3]\r\n },\r\n intersect = isPolygonLineIntersect(polygonWithOffsetAndRotation, object);\r\n if (intersect) {\r\n //console.log(\"rotation: \", rotation);\r\n //console.log(\"polygon: \", polygonWithOffsetAndRotation);\r\n //console.log(\"intersect: \", intersect);\r\n return intersect;\r\n }\r\n }\r\n if (eLen > 0) {\r\n for (let i = 0; i < eLen; i+=1) {\r\n const ellipse = ellipseB[i],\r\n intersect = isEllipsePolygonIntersect(ellipse, polygonWithOffsetAndRotation);\r\n if (intersect) {\r\n //console.log(\"rotation: \", rotation);\r\n //console.log(\"polygon: \", polygonWithOffsetAndRotation);\r\n //console.log(\"intersect: \", intersect);\r\n return intersect;\r\n }\r\n }\r\n }\r\n \r\n if (pLen > 0) {\r\n for (let i = 0; i < pLen; i+=1) {\r\n const point = pointB[i],\r\n x = point[0],\r\n y = point[1],\r\n intersect = isPointPolygonIntersect(x, y, polygonWithOffsetAndRotation);\r\n if (intersect) {\r\n //console.log(\"rotation: \", rotation);\r\n //console.log(\"polygon: \", polygonWithOffsetAndRotation);\r\n //console.log(\"intersect: \", intersect);\r\n return intersect;\r\n }\r\n }\r\n }\r\n return false;\r\n }\r\n //****************** End Collisions ****************//\r\n\r\n #setCanvasSize() {\r\n const canvasWidth = this.systemSettings.canvasMaxSize.width && (this.systemSettings.canvasMaxSize.width < window.innerWidth) ? this.systemSettings.canvasMaxSize.width : window.innerWidth,\r\n canvasHeight = this.systemSettings.canvasMaxSize.height && (this.systemSettings.canvasMaxSize.height < window.innerHeight) ? this.systemSettings.canvasMaxSize.height : window.innerHeight;\r\n this.stageData._setCanvasDimensions(canvasWidth, canvasHeight);\r\n }\r\n}","import { WARNING_CODES } from \"../constants.js\";\nimport { Warning } from \"./Exception.js\";\n/**\n * A storage for stage data, such as gameObjects,\n * boundaries, worldDimensions and offset\n * @see {@link GameStage} a part of GameStage\n * @hideconstructor\n */\nexport class GameStageData {\n #worldWidth;\n #worldHeight;\n #viewWidth;\n #viewHeight;\n #xOffset = 0;\n #yOffset = 0;\n #centerX = 0;\n #centerY = 0;\n #rotate = 0;\n /**\n * current screen boundaries, recalculated every render cycles\n * @type {Array>}\n */\n #boundaries = [];\n /**\n * ellipse boundaries\n * @type {Array>}\n */\n #ellipseBoundaries = [];\n /**\n * point boundaries\n * @type {Array>}\n */\n #pointBoundaries = [];\n /**\n * whole world boundaries, calculated once on prepare stage\n * @type {Array>}\n */\n #wholeWorldBoundaries = [];\n /**\n * @type {Array}\n */\n #renderObjects = [];\n \n /**\n * @type {boolean}\n */\n #isOffsetTurnedOff;\n /**\n * @deprecated\n * @type {boolean}\n */\n #isWorldBoundariesEnabled = false;\n\n /**\n * \n * @returns {boolean}\n */\n isOffsetTurnedOff() {\n return this.#isOffsetTurnedOff;\n }\n set mapRotate(value) {\n this.#rotate = value;\n }\n\n /**\n * Add a Boundaries line\n * @param {{x1:number,y1:number,x2:number, y2:number}} boundaries \n */\n #addBoundaries(boundaries) {\n this.#boundaries.push([boundaries.x1, boundaries.y1, boundaries.x2, boundaries.y2]);\n }\n\n /**\n * Add array of boundaries lines\n * @param {Array>} boundaries \n * @ignore\n */\n _addBoundariesArray(boundaries) {\n this.#boundaries.push(...boundaries);\n }\n\n _addEllipseBoundaries(boundaries) {\n this.#ellipseBoundaries.push(...boundaries);\n }\n\n _addPointBoundaries(boundaries) {\n this.#pointBoundaries.push(...boundaries);\n }\n\n /**\n * Clear map boundaries\n * @ignore\n */\n _clearBoundaries() {\n this.#boundaries = [];\n this.#ellipseBoundaries = [];\n this.#pointBoundaries = [];\n }\n\n /**\n * \n * @param {number} width \n * @param {number} height \n * @ignore\n */\n _setWorldDimensions(width, height) {\n this.#worldWidth = width;\n this.#worldHeight = height;\n }\n\n /**\n * \n * @param {number} width \n * @param {number} height \n * @ignore\n */\n _setCanvasDimensions(width, height) {\n this.#viewWidth = width;\n this.#viewHeight = height;\n }\n\n /**\n * Set map borders\n * @ignore\n */\n _setMapBoundaries() {\n const [w, h] = [this.#worldWidth, this.#worldHeight],\n [offsetX, offsetY] = [this.#xOffset, this.#yOffset],\n wOffset = w - offsetX,\n hOffset = h -offsetY;\n if (!w || !h) {\n Warning(WARNING_CODES.WORLD_DIMENSIONS_NOT_SET, \"Can't set map boundaries.\");\n }\n this.#addBoundaries({x1: 0, y1: 0, x2: wOffset, y2: 0});\n this.#addBoundaries({x1: wOffset, y1: 0, x2: wOffset, y2: hOffset});\n this.#addBoundaries({x1: wOffset, y1: hOffset, x2: 0, y2: hOffset});\n this.#addBoundaries({x1: 0, y1: hOffset, x2: 0, y2: 0});\n }\n\n /**\n * @ignore\n */\n _setWholeWorldMapBoundaries() {\n const [w, h] = [this.#worldWidth, this.#worldHeight];\n if (!w || !h) {\n Warning(WARNING_CODES.WORLD_DIMENSIONS_NOT_SET, \"Can't set map boundaries.\");\n }\n this.#wholeWorldBoundaries.push([0, 0, w, 0]);\n this.#wholeWorldBoundaries.push([w, 0, w, h]);\n this.#wholeWorldBoundaries.push([w, h, 0, h]);\n this.#wholeWorldBoundaries.push([0, h, 0, 0]);\n }\n\n /**\n * Merge same boundaries\n * @ignore\n */\n _mergeBoundaries(isWholeMapBoundaries = false) {\n const boundaries = isWholeMapBoundaries ? this.getWholeWorldBoundaries() : this.getBoundaries(),\n boundariesSet = new Set(boundaries);\n for (const line of boundariesSet.values()) {\n const lineX1 = line[0],\n lineY1 = line[1],\n lineX2 = line[2],\n lineY2 = line[3];\n for (const line2 of boundariesSet.values()) {\n const line2X1 = line2[0],\n line2Y1 = line2[1],\n line2X2 = line2[2],\n line2Y2 = line2[3];\n if (lineX1 === line2X2 && lineY1 === line2Y2 &&\n lineX2 === line2X1 && lineY2 === line2Y1) {\n //remove double lines\n boundariesSet.delete(line);\n boundariesSet.delete(line2);\n }\n if (lineX2 === line2X1 && lineY2 === line2Y1 && (lineX1 === line2X2 || lineY1 === line2Y2)) {\n //merge lines\n line2[0] = lineX1;\n line2[1] = lineY1;\n boundariesSet.delete(line);\n }\n }\n }\n\n if (isWholeMapBoundaries) {\n this.#boundaries = Array.from(boundariesSet);\n } else {\n this.#wholeWorldBoundaries = Array.from(boundariesSet);\n }\n boundariesSet.clear();\n }\n\n /**\n * @ignore\n * @param {Array>} boundaries \n */\n _setWholeMapBoundaries(boundaries) {\n this.#wholeWorldBoundaries.push(...boundaries);\n }\n\n /**\n * @deprecated\n * @ignore\n */\n _enableMapBoundaries() {\n this.#isWorldBoundariesEnabled = true;\n }\n\n /**\n * \n * @returns {Array>}\n */\n getBoundaries() {\n return this.#boundaries;\n }\n\n /**\n * \n * @returns {Array>}\n */\n getEllipseBoundaries() {\n return this.#ellipseBoundaries;\n }\n\n /**\n * \n * @returns {Array>}\n */\n getPointBoundaries() {\n return this.#pointBoundaries;\n }\n\n getWholeWorldBoundaries() {\n return this.#wholeWorldBoundaries;\n }\n\n /**\n * @deprecated\n */\n get isWorldBoundariesEnabled() {\n return this.#isWorldBoundariesEnabled;\n }\n /**\n * @type {Array}\n */\n get canvasDimensions() {\n return [this.#viewWidth, this.#viewHeight];\n }\n\n /**\n * @type {Array}\n */\n get worldDimensions() {\n return [this.#worldWidth, this.#worldHeight];\n }\n \n /**\n * @type {Array}\n */\n get worldOffset() {\n return [this.#xOffset, this.#yOffset];\n }\n\n /**\n * @type {Array}\n */\n get mapCenter() {\n return [this.#centerX, this.#centerY];\n }\n\n /**\n * @type {number}\n */\n get mapRotate() {\n return this.#rotate;\n }\n\n /**\n * @method\n * @param {number} x \n * @param {number} y \n */\n centerCameraPosition = (x, y) => {\n let [mapOffsetX, mapOffsetY] = this.worldOffset;\n const [canvasWidth, canvasHeight] = this.canvasDimensions,\n [mapWidth, mapHeight] = this.worldDimensions,\n halfScreenWidth = canvasWidth/2,\n halfScreenHeight = canvasHeight/2,\n currentCenterX = halfScreenWidth - mapOffsetX,\n currentCenterY = halfScreenHeight - mapOffsetY;\n if (currentCenterX < x) {\n if (x < mapWidth - halfScreenWidth) {\n const newXOffset = x - halfScreenWidth;\n if (newXOffset >= 0)\n this.#xOffset = Math.round(newXOffset);\n } else if (mapWidth > canvasWidth) {\n const newXOffset = mapWidth - canvasWidth;\n this.#xOffset = Math.round(newXOffset);\n }\n }\n if (currentCenterY < y) {\n if (y < mapHeight - halfScreenHeight) {\n const newYOffset = y - halfScreenHeight;\n if (newYOffset >= 0)\n this.#yOffset = Math.round(newYOffset);\n } else if (mapHeight > canvasHeight) {\n const newYOffset = mapHeight - canvasHeight;\n this.#yOffset = Math.round(newYOffset);\n }\n }\n\n this.#centerX = x;\n this.#centerY = y;\n //Logger.debug(\"center camera position, offset: \", this.worldOffset);\n //Logger.debug(\"center: \", this.mapCenter); \n };\n\n personRotatedCenterCamera = (x, y, rotationAngle) => {\n console.log(\"new centering algorithm\");\n /*\n let [mapOffsetX, mapOffsetY] = this.worldOffset;\n const [canvasWidth, canvasHeight] = this.canvasDimensions,\n [mapWidth, mapHeight] = this.worldDimensions,\n halfScreenWidth = canvasWidth/2,\n halfScreenHeight = canvasHeight/2,\n currentCenterX = halfScreenWidth - mapOffsetX,\n currentCenterY = halfScreenHeight - mapOffsetY;\n if (currentCenterX < x) {\n if (x < mapWidth - halfScreenWidth) {\n const newXOffset = x - halfScreenWidth;\n if (newXOffset >= 0)\n this.#xOffset = Math.round(newXOffset);\n } else if (mapWidth > canvasWidth) {\n const newXOffset = mapWidth - canvasWidth;\n this.#xOffset = Math.round(newXOffset);\n }\n }\n if (currentCenterY < y) {\n if (y < mapHeight - halfScreenHeight) {\n const newYOffset = y - halfScreenHeight;\n if (newYOffset >= 0)\n this.#yOffset = Math.round(newYOffset);\n } else if (mapHeight > canvasHeight) {\n const newYOffset = mapHeight - canvasHeight;\n this.#yOffset = Math.round(newYOffset);\n }\n }\n\n this.#centerX = x;\n this.#centerY = y;\n Logger.debug(\"center camera position, offset: \", this.worldOffset);\n Logger.debug(\"center: \", this.mapCenter); \n */\n };\n\n /**\n * a getter to retrieve all attached renderObjects\n */\n get renderObjects() {\n return this.#renderObjects;\n }\n\n /**\n * Retrieve specific objects instances\n * @param {Object} instance - drawObjectInstance to retrieve \n * @returns {Array}\n */\n getObjectsByInstance(instance) {\n return this.#renderObjects.filter((object) => object instanceof instance);\n }\n\n /**\n * @ignore\n */\n _sortRenderObjectsBySortIndex() {\n this.#renderObjects = this.#renderObjects.sort((obj1, obj2) => obj1.sortIndex - obj2.sortIndex);\n }\n\n /**\n * @ignore\n */\n set _renderObject(object) {\n this.#renderObjects.push(object);\n } \n\n /**\n * @ignore\n */\n set _renderObjects(objects) {\n this.#renderObjects = objects;\n } \n}","import { ISystem } from \"./ISystem.js\";\n\n/**\n * Class for creating modules\n * Accessed via ISystem.extensionInterface\n */\nexport class IExtension {\n /**\n * @type {ISystem}\n */\n #systemReference;\n /**\n * @hideconstructor\n */\n constructor(iSystem) {\n this.#systemReference = iSystem;\n }\n /**\n * Is used for registering new Object in DrawObjectFactory, \\\n * registered method could be then called with this.draw[createInstanceKey]\n * @param {string} createInstanceKey - a key for calling method from DrawObjectFactory\n * @param {function} createInstanceMethod - method \n */\n registerDrawObject(createInstanceKey, createInstanceMethod) {\n this.#systemReference.drawObjectFactory._registerNewObjectMethod(createInstanceKey, createInstanceMethod);\n }\n\n /**\n * Used to register a new draw program\n * @param {string} programName\n * @param {string} vertexShader - raw vertex shader program\n * @param {string} fragmentShader - raw fragment shader program \n * @param {Array} uVars - program uniform variables names\n * @param {Array} aVars - program attribute variables names\n * @returns {Promise}\n */\n registerAndCompileWebGlProgram(programName, vertexShader, fragmentShader, uVars, aVars) {\n return this.#systemReference.iRender._registerAndCompileWebGlProgram(programName, vertexShader, fragmentShader, uVars, aVars);\n }\n\n /**\n * Inject method to render.init stage. Should be Promise based.\n * @param {function():Promise} method \n * @returns {void}\n */\n registerRenderInit(method) {\n this.#systemReference.iRender._registerRenderInit(method);\n }\n\n /**\n * Register render method for class.\n * @param {string} objectClassName - object name registered to DrawObjectFactory\n * @param {function(renderObject, gl, pageData, program, vars):Promise} objectRenderMethod - should be promise based returns vertices number and draw program\n * @param {string} objectWebGlDrawProgram - a webgl program name previously registered with iExtension.registerAndCompileWebGlProgram()\n */\n registerObjectRender(objectClassName, objectRenderMethod, objectWebGlDrawProgram) {\n this.#systemReference.iRender._registerObjectRender(objectClassName, objectRenderMethod, objectWebGlDrawProgram);\n }\n}","import { CONST, ERROR_CODES } from \"../constants.js\";\nimport { Exception } from \"./Exception.js\";\nimport { Logger } from \"./Logger.js\";\nimport { SystemEvent } from \"./Events/SystemEvent.js\";\n\n/**\n * Represents Socket connection\n * \n * From 1.4.4 disabled by default,\n * to enable, set settings.network.enabled to true\n */\nexport class INetwork extends EventTarget {\n #systemSettings;\n #socket;\n\n /**\n * @hideconstructor\n */\n constructor(systemSettings) {\n super();\n if (!systemSettings) {\n Exception(ERROR_CODES.CREATE_INSTANCE_ERROR, \"systemSettings should be passed to class instance\");\n }\n this.#systemSettings = systemSettings;\n }\n\n init() {\n import(\"socket.io-client\").then((module) => {\n this.#socket = module.io(this.#systemSettings.network.address, {withCredentials: true});\n \n this.#registerSocketListeners();\n });\n }\n\n /**\n * @returns {boolean}\n */\n get isServerConnected () {\n if (this.#socket && this.#socket.connected) {\n return true;\n } else {\n return false;\n }\n }\n \n get playerId() {\n return this.#socket.id;\n }\n\n sendGatherRoomsInfo() {\n this.#socket.emit(CONST.EVENTS.WEBSOCKET.CLIENT_SERVER.ROOMS_INFO_REQUEST);\n }\n\n sendCreateOrJoinRoom(roomName, map) {\n this.#socket.emit(CONST.EVENTS.WEBSOCKET.CLIENT_SERVER.CREATE_OR_JOIN, roomName , map);\n }\n\n sendMessage(message) {\n this.#socket.emit(CONST.EVENTS.WEBSOCKET.CLIENT_SERVER.CLIENT_MESSAGE, message);\n }\n\n #onConnect = () => {\n Logger.debug(\"connected, socket id: \" + this.#socket.id);\n this.dispatchEvent(new Event(CONST.EVENTS.WEBSOCKET.SERVER_CLIENT.CONNECTION_STATUS_CHANGED));\n };\n\n #onDisconnect = (reason) => {\n Logger.debug(\"server disconnected, reason: \" + reason);\n this.dispatchEvent(new Event(CONST.EVENTS.WEBSOCKET.SERVER_CLIENT.CONNECTION_STATUS_CHANGED));\n };\n\n #onData = (event) => {\n console.warn(\"server data: \", event);\n };\n\n #onMessage = (message) => {\n Logger.debug(\"received new message from server: \" + message);\n this.dispatchEvent(new SystemEvent(CONST.EVENTS.WEBSOCKET.SERVER_CLIENT.SERVER_MESSAGE, message));\n };\n\n #onRoomsInfo = (rooms) => {\n Logger.debug(\"received roomsInfo \" + rooms);\n this.dispatchEvent(new SystemEvent(CONST.EVENTS.WEBSOCKET.SERVER_CLIENT.ROOMS_INFO, rooms));\n };\n\n #onCreateNewRoom = (room, map) => {\n Logger.debug(\"CLIENT SOCKET: Created room \" + room);\n this.dispatchEvent(new SystemEvent(CONST.EVENTS.WEBSOCKET.SERVER_CLIENT.CREATED, {room, map}));\n };\n\n #onRoomIsFull = (room) => {\n Logger.debug(\"CLIENT SOCKET: Room is full, can't join: \" + room);\n this.dispatchEvent(new SystemEvent(CONST.EVENTS.WEBSOCKET.SERVER_CLIENT.FULL, {room}));\n };\n\n #onJoinedToRoom = (room, map) => {\n Logger.debug(\"CLIENT SOCKET: Joined to room: \" + room, \", map: \", map);\n this.dispatchEvent(new SystemEvent(CONST.EVENTS.WEBSOCKET.SERVER_CLIENT.JOINED, {room, map}));\n };\n\n #onUnjoinedFromRoom = (playerId) => {\n this.dispatchEvent(new SystemEvent(CONST.EVENTS.WEBSOCKET.SERVER_CLIENT.DISCONNECTED, {playerId}));\n };\n\n #registerSocketListeners() {\n this.#socket.on(\"connect\", this.#onConnect);\n this.#socket.on(\"disconnect\", this.#onDisconnect);\n this.#socket.on(\"data\", this.#onData);\n\n this.#socket.on(\"roomsInfo\", this.#onRoomsInfo);\n \n this.#socket.on(\"created\", this.#onCreateNewRoom);\n \n this.#socket.on(\"full\", this.#onRoomIsFull);\n \n this.#socket.on(\"joined\", this.#onJoinedToRoom);\n \n this.#socket.on(\"log\", function(array) {\n console.log.apply(console, array);\n });\n \n this.#socket.on(\"message\", this.#onMessage);\n \n this.#socket.on(\"removed\", function(message) {\n console.log(\"removed message\");\n console.log(message);\n });\n\n this.#socket.on(\"disconnected\", this.#onUnjoinedFromRoom);\n\n addEventListener(\"beforeunload\", this.#disconnect);\n }\n\n #disconnect = () => {\n this.#socket.disconnect();\n };\n}","import { DrawTiledLayer } from \"./DrawTiledLayer.js\";\r\nimport { Exception, Warning } from \"./Exception.js\";\r\nimport { ERROR_CODES, WARNING_CODES } from \"../constants.js\";\r\nimport { WebGlEngine } from \"./WebGl/WebGlEngine.js\";\r\nimport { SystemSettings } from \"../configs.js\";\r\nimport { GameStageData } from \"./GameStageData.js\";\r\nimport AssetsManager from \"../../modules/assetsm/dist/assetsm.min.js\";\r\n//import { calculateBufferData } from \"../wa/release.js\";\r\nimport { CONST } from \"../constants.js\";\r\nimport { DrawImageObject } from \"./DrawImageObject.js\";\r\nimport { DrawCircleObject } from \"./DrawCircleObject.js\";\r\nimport { DrawConusObject } from \"./DrawConusObject.js\";\r\nimport { DrawLineObject } from \"./DrawLineObject.js\";\r\nimport { DrawPolygonObject } from \"./DrawPolygonObject.js\";\r\nimport { DrawRectObject } from \"./DrawRectObject.js\";\r\nimport { DrawTextObject } from \"./DrawTextObject.js\";\r\nimport { imgVertexShader, imgFragmentShader, imgUniforms, imgAttributes } from \"./WebGl/ImagesDrawProgram.js\";\r\nimport { primitivesVertexShader, primitivesFragmentShader, primitivesUniforms, primitivesAttributes } from \"./WebGl/PrimitivesDrawProgram.js\";\r\nimport { utils } from \"../index.js\";\r\n\r\n/**\r\n * IRender class controls the render(start/stop/speed) \r\n * And drawObjects(animations, removing, and rendering)\r\n * @see {@link GameStage} a part of GameStage\r\n * @hideconstructor\r\n */\r\nexport class IRender {\r\n /**\r\n * @type {HTMLCanvasElement}\r\n */\r\n #canvas;\r\n /**\r\n * @type {WebGLRenderingContext}\r\n */\r\n #drawContext;\r\n /**\r\n * @type {boolean}\r\n */\r\n #isCleared;\r\n /**\r\n * @type {boolean}\r\n */\r\n #isActive;\r\n /**\r\n * @type {WebGlEngine}\r\n */\r\n #webGlEngine;\r\n /**\r\n * @type {GameStageData | null}\r\n */\r\n #currentGameStageData;\r\n\r\n /**\r\n * ISystem.systemSettings\r\n * @type {SystemSettings}\r\n */\r\n #systemSettingsReference;\r\n /**\r\n * A reference to the systemInterface.iLoader\r\n * @type {AssetsManager}\r\n */\r\n #loaderReference;\r\n /**\r\n * @type {Array}\r\n */\r\n #tempRCircleT;\r\n /**\r\n * @type {NodeJS.Timer | null}\r\n */\r\n #fpsAverageCountTimer;\r\n /**\r\n * @type {boolean}\r\n */\r\n #isBoundariesPrecalculations = false;\r\n #minCycleTime;\r\n /**\r\n * @type {EventTarget}\r\n */\r\n #emitter = new EventTarget();\r\n #bindRenderLayerMethod;\r\n #registeredRenderObjects = new Map();\r\n\r\n /**\r\n * @type {Array>}\r\n */\r\n #initPromises = [];\r\n constructor(systemSettings, iLoader, canvasContainer) {\r\n this.#isCleared = false;\r\n this.#canvas = document.createElement(\"canvas\");\r\n canvasContainer.appendChild(this.#canvas);\r\n this.#drawContext = this.#canvas.getContext(\"webgl\", {stencil: true});\r\n\r\n this.#systemSettingsReference = systemSettings;\r\n this.#loaderReference = iLoader;\r\n\r\n this.#tempRCircleT = [];\r\n this.#minCycleTime = this.systemSettings.gameOptions.render.minCycleTime;\r\n\r\n this.#isBoundariesPrecalculations = this.systemSettings.gameOptions.render.boundaries.wholeWorldPrecalculations;\r\n\r\n this.#webGlEngine = new WebGlEngine(this.#drawContext, this.#systemSettingsReference.gameOptions);\r\n if (this.systemSettings.gameOptions.optimization === CONST.OPTIMIZATION.WEB_ASSEMBLY.NATIVE_WAT ||\r\n this.systemSettings.gameOptions.optimization === CONST.OPTIMIZATION.WEB_ASSEMBLY.ASSEMBLY_SCRIPT) {\r\n this._registerRenderInit(this.#webGlEngine._initiateWasm);\r\n }\r\n\r\n this._registerRenderInit(this.fixCanvasSize);\r\n this._registerRenderInit(\r\n () => this._registerAndCompileWebGlProgram(CONST.WEBGL.DRAW_PROGRAMS.IMAGES, imgVertexShader, imgFragmentShader, imgUniforms, imgAttributes)\r\n );\r\n this._registerRenderInit(\r\n () => this._registerAndCompileWebGlProgram(CONST.WEBGL.DRAW_PROGRAMS.PRIMITIVES, primitivesVertexShader, primitivesFragmentShader, primitivesUniforms, primitivesAttributes)\r\n );\r\n this._registerRenderInit(this.#webGlEngine._initWebGlAttributes);\r\n\r\n this._registerObjectRender(DrawTextObject.name, this.#webGlEngine._bindText, CONST.WEBGL.DRAW_PROGRAMS.IMAGES);\r\n this._registerObjectRender(DrawRectObject.name, this.#webGlEngine._bindPrimitives, CONST.WEBGL.DRAW_PROGRAMS.PRIMITIVES);\r\n this._registerObjectRender(DrawPolygonObject.name, this.#webGlEngine._bindPrimitives, CONST.WEBGL.DRAW_PROGRAMS.PRIMITIVES);\r\n this._registerObjectRender(DrawCircleObject.name, this.#webGlEngine._bindConus, CONST.WEBGL.DRAW_PROGRAMS.PRIMITIVES);\r\n this._registerObjectRender(DrawConusObject.name, this.#webGlEngine._bindConus, CONST.WEBGL.DRAW_PROGRAMS.PRIMITIVES);\r\n this._registerObjectRender(DrawTiledLayer.name, this.#webGlEngine._bindTileImages, CONST.WEBGL.DRAW_PROGRAMS.IMAGES);\r\n this._registerObjectRender(DrawLineObject.name, this.#webGlEngine._bindLine, CONST.WEBGL.DRAW_PROGRAMS.PRIMITIVES);\r\n }\r\n\r\n /**\r\n * \r\n * @param {string} eventName \r\n * @param {*} listener \r\n * @param {*=} options \r\n */\r\n addEventListener = (eventName, listener, options) => {\r\n this.#emitter.addEventListener(eventName, listener, options);\r\n };\r\n\r\n /**\r\n * \r\n * @param {string} eventName \r\n * @param {*} listener \r\n * @param {*=} options \r\n */\r\n removeEventListener = (eventName, listener, options) => {\r\n this.#emitter.removeEventListener(eventName, listener, options);\r\n };\r\n\r\n get stageData() {\r\n return this.#currentGameStageData;\r\n }\r\n\r\n get systemSettings() {\r\n return this.#systemSettingsReference;\r\n }\r\n\r\n get iLoader() {\r\n return this.#loaderReference;\r\n }\r\n\r\n get canvas() {\r\n return this.#canvas;\r\n }\r\n\r\n get drawContext() {\r\n return this.#drawContext;\r\n }\r\n\r\n /**\r\n * \r\n * @param {string} eventName\r\n * @param {...any} eventParams\r\n */\r\n emit = (eventName, ...eventParams) => {\r\n const event = new Event(eventName);\r\n event.data = [...eventParams];\r\n this.#emitter.dispatchEvent(event);\r\n };\r\n\r\n /**\r\n * Determines if all added files was loaded or not\r\n * @returns {boolean}\r\n */\r\n isAllFilesLoaded = () => {\r\n return this.iLoader.filesWaitingForUpload === 0;\r\n };\r\n\r\n initiateContext = () => {\r\n return Promise.all(this.#initPromises.map(method => method()));\r\n };\r\n\r\n clearContext() {\r\n this.#webGlEngine._clearView();\r\n }\r\n\r\n setCanvasSize(width, height) {\r\n this.#canvas.width = width;\r\n this.#canvas.height = height;\r\n if (this.#webGlEngine) {\r\n this.#webGlEngine._fixCanvasSize(width, height);\r\n }\r\n }\r\n\r\n fixCanvasSize = () => {\r\n const settings = this.systemSettings, \r\n canvasWidth = settings.canvasMaxSize.width && (settings.canvasMaxSize.width < window.innerWidth) ? settings.canvasMaxSize.width : window.innerWidth,\r\n canvasHeight = settings.canvasMaxSize.height && (settings.canvasMaxSize.height < window.innerHeight) ? settings.canvasMaxSize.height : window.innerHeight;\r\n this.setCanvasSize(canvasWidth, canvasHeight);\r\n return Promise.resolve();\r\n };\r\n\r\n /****************************\r\n * Extend functionality\r\n ****************************/\r\n /**\r\n * @ignore\r\n * @param {string} programName\r\n * @param {string} vertexShader - raw vertex shader program\r\n * @param {string} fragmentShader - raw fragment shader program \r\n * @param {Array} uVars - program uniform variables names\r\n * @param {Array} aVars - program attribute variables names\r\n * @returns {Promise}\r\n */\r\n _registerAndCompileWebGlProgram(programName, vertexShader, fragmentShader, uVars, aVars) {\r\n this.#webGlEngine._registerAndCompileWebGlProgram(programName, vertexShader, fragmentShader, uVars, aVars);\r\n return Promise.resolve();\r\n }\r\n\r\n /**\r\n * @ignore\r\n * @param {function():Promise} method \r\n * @returns {void}\r\n */\r\n _registerRenderInit(method) {\r\n this.#initPromises.push(method);\r\n //} else {\r\n // Exception(ERROR_CODES.UNEXPECTED_METHOD_TYPE, \"registerRenderInit() accept only Promise based methods!\");\r\n //}\r\n }\r\n\r\n /**\r\n * @ignore\r\n * @param {string} objectClassName - object name registered to DrawObjectFactory\r\n * @param {function(renderObject, gl, pageData, program, vars):Promise} objectRenderMethod - should be promise based returns vertices number and draw program\r\n * @param {string=} objectWebGlDrawProgram \r\n */\r\n _registerObjectRender(objectClassName, objectRenderMethod, objectWebGlDrawProgram) {\r\n this.#registeredRenderObjects.set(objectClassName, {method: objectRenderMethod, webglProgramName: objectWebGlDrawProgram});\r\n }\r\n\r\n /****************************\r\n * End of Extend functionality\r\n ****************************/\r\n\r\n /**\r\n * @returns {Promise}\r\n */\r\n async render() {\r\n let renderObjectsPromises = [],\r\n errors = [],\r\n isErrors = false;\r\n const renderObjects = this.stageData.renderObjects;\r\n if (renderObjects.length !== 0) {\r\n //this.#checkCollisions(view.renderObjects);\r\n for (let i = 0; i < renderObjects.length; i++) {\r\n const object = renderObjects[i];\r\n if (object.isRemoved) {\r\n renderObjects.splice(i, 1);\r\n i--;\r\n continue;\r\n }\r\n if (object.hasAnimations) {\r\n object._processActiveAnimations();\r\n }\r\n const promise = await this._bindRenderObject(object)\r\n .catch((err) => Promise.reject(err));\r\n renderObjectsPromises.push(promise);\r\n }\r\n if (this.systemSettings.gameOptions.debug.boundaries.drawLayerBoundaries) {\r\n renderObjectsPromises.push(this.#drawBoundariesWebGl()\r\n .catch((err) => Promise.reject(err))); \r\n }\r\n //const bindResults = await Promise.allSettled(renderObjectsPromises);\r\n //bindResults.forEach((result) => {\r\n // if (result.status === \"rejected\") {\r\n // reject(result.reason);\r\n // }\r\n //});\r\n\r\n //await this.#webGlEngine._executeImagesDraw();\r\n\r\n //this.#postRenderActions();\r\n }\r\n const bindResults = await Promise.allSettled(renderObjectsPromises);\r\n bindResults.forEach((result) => {\r\n if (result.status === \"rejected\") {\r\n Promise.reject(result.reason);\r\n isErrors = true;\r\n errors.push(result.reason);\r\n }\r\n });\r\n\r\n this.#postRenderActions();\r\n \r\n this._isCleared = false;\r\n if (isErrors === false) {\r\n return Promise.resolve();\r\n } else {\r\n return Promise.reject(errors);\r\n }\r\n }\r\n\r\n /**\r\n * @ignore\r\n */\r\n set _isCleared(value) {\r\n this.#isCleared = value;\r\n }\r\n\r\n /**\r\n * @ignore\r\n */\r\n get _isCleared() {\r\n return this.#isCleared;\r\n }\r\n\r\n _createBoundariesPrecalculations() {\r\n //const promises = [];\r\n //for (const layer of this.#renderLayers) {\r\n // promises.push(this.#layerBoundariesPrecalculation(layer).catch((err) => {\r\n // Exception(ERROR_CODES.UNHANDLED_PREPARE_EXCEPTION, err);\r\n // }));\r\n //}\r\n //return promises;\r\n }\r\n #postRenderActions() {\r\n //const images = this.stageData.getObjectsByInstance(DrawImageObject);\r\n //for (let i = 0; i < images.length; i++) {\r\n // const object = images[i];\r\n // if (object.isAnimations) {\r\n // object._processActiveAnimations();\r\n // }\r\n //}\r\n }\r\n\r\n //#clearTileMapPromises() {\r\n // this.#bindTileMapPromises = [];\r\n //}\r\n\r\n /**\r\n * \r\n * @param {DrawTiledLayer} renderLayer \r\n * @returns {Promise}\r\n */\r\n #layerBoundariesPrecalculation(renderLayer) {\r\n return new Promise((resolve, reject) => {\r\n if (renderLayer.setBoundaries) {\r\n const tilemap = this.iLoader.getTileMap(renderLayer.tileMapKey),\r\n tilesets = tilemap.tilesets,\r\n layerData = tilemap.layers.find((layer) => layer.name === renderLayer.layerKey),\r\n { tileheight:dtheight, tilewidth:dtwidth } = tilemap,\r\n tilewidth = dtwidth,\r\n tileheight = dtheight,\r\n [ settingsWorldWidth, settingsWorldHeight ] = this.stageData.worldDimensions;\r\n \r\n let boundaries = [];\r\n\r\n if (!layerData) {\r\n Warning(WARNING_CODES.NOT_FOUND, \"check tilemap and layers name\");\r\n reject();\r\n }\r\n \r\n for (let i = 0; i < tilesets.length; i++) {\r\n const layerCols = layerData.width,\r\n layerRows = layerData.height,\r\n worldW = tilewidth * layerCols,\r\n worldH = tileheight * layerRows;\r\n\r\n if (worldW !== settingsWorldWidth || worldH !== settingsWorldHeight) {\r\n Warning(WARNING_CODES.UNEXPECTED_WORLD_SIZE, \" World size from tilemap is different than settings one, fixing...\");\r\n this.stageData._setWorldDimensions(worldW, worldH);\r\n }\r\n \r\n if (renderLayer.setBoundaries && this.systemSettings.gameOptions.render.boundaries.mapBoundariesEnabled) {\r\n this.stageData._setWholeWorldMapBoundaries();\r\n }\r\n\r\n //calculate boundaries\r\n let mapIndex = 0;\r\n\r\n for (let row = 0; row < layerRows; row++) {\r\n for (let col = 0; col < layerCols; col++) {\r\n let tile = layerData.data[mapIndex],\r\n mapPosX = col * tilewidth,\r\n mapPosY = row * tileheight;\r\n if (tile !== 0) {\r\n tile -= 1;\r\n \r\n boundaries.push([mapPosX, mapPosY, mapPosX + tilewidth, mapPosY]);\r\n boundaries.push([mapPosX + tilewidth, mapPosY, mapPosX + tilewidth, mapPosY + tileheight]);\r\n boundaries.push([mapPosX + tilewidth, mapPosY + tileheight, mapPosX, mapPosY + tileheight]);\r\n boundaries.push([mapPosX, mapPosY + tileheight, mapPosX, mapPosY ]);\r\n \r\n }\r\n mapIndex++;\r\n }\r\n }\r\n }\r\n this.stageData._setWholeMapBoundaries(boundaries);\r\n this.stageData._mergeBoundaries(true);\r\n console.warn(\"precalculated boundaries set\");\r\n console.log(this.stageData.getWholeWorldBoundaries());\r\n resolve();\r\n } else {\r\n resolve();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * @ignore\r\n * @param {DrawImageObject | DrawCircleObject | DrawConusObject | DrawLineObject | DrawPolygonObject | DrawRectObject | DrawTextObject | DrawTiledLayer} renderObject \r\n * @returns {Promise}\r\n */\r\n _bindRenderObject(renderObject) {\r\n const name = renderObject.constructor.name,\r\n registeredRenderObject = this.#registeredRenderObjects.get(name);\r\n if (registeredRenderObject) {\r\n const name = registeredRenderObject.webglProgramName;\r\n if (name) {\r\n const program = this.#webGlEngine.getProgram(name),\r\n vars = this.#webGlEngine.getProgramVarLocations(name);\r\n return registeredRenderObject.method(renderObject, this.drawContext, this.stageData, program, vars)\r\n .then((results) => this.#webGlEngine._render(results[0], results[1])); \r\n } else {\r\n return registeredRenderObject.method(renderObject, this.drawContext, this.stageData);\r\n }\r\n } else {\r\n // a workaround for images and its extend classes drawing\r\n if (renderObject.type === CONST.DRAW_TYPE.IMAGE) {\r\n const program = this.#webGlEngine.getProgram(CONST.WEBGL.DRAW_PROGRAMS.IMAGES),\r\n vars = this.#webGlEngine.getProgramVarLocations(CONST.WEBGL.DRAW_PROGRAMS.IMAGES);\r\n\r\n if (!renderObject.image) {\r\n const image = this.iLoader.getImage(renderObject.key);\r\n if (!image) {\r\n Exception(ERROR_CODES.CANT_GET_THE_IMAGE, \"iLoader can't get the image with key: \" + renderObject.key);\r\n } else {\r\n renderObject.image = image;\r\n }\r\n }\r\n return this.#webGlEngine._bindImage(renderObject, this.drawContext, this.stageData, program, vars)\r\n .then((results) => this.#webGlEngine._render(results[0], results[1]))\r\n .then(() => {\r\n if (renderObject.vertices && this.systemSettings.gameOptions.debug.boundaries.drawObjectBoundaries) {\r\n return this.#webGlEngine._drawPolygon(renderObject, this.stageData);\r\n } else {\r\n return Promise.resolve();\r\n }\r\n });\r\n } else {\r\n console.warn(\"no registered draw object method for \" + name + \" skip draw\");\r\n return Promise.resolve();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * \r\n * @returns {Promise}\r\n */\r\n #drawBoundariesWebGl() {\r\n return new Promise((resolve) => {\r\n const b = this.stageData.getBoundaries(),\r\n eB = this.stageData.getEllipseBoundaries(),\r\n pB = this.stageData.getPointBoundaries(),\r\n len = b.length,\r\n eLen = eB.length,\r\n pLen = pB.length,\r\n linesArray = [];\r\n \r\n //for (let i = 0; i < len; i++) {\r\n // const item = b[i];\r\n // linesArray.push(item[0], item[1]);\r\n // linesArray.push(item[2], item[3]);\r\n //}\r\n this.#webGlEngine._drawLines(b.flat(), this.systemSettings.gameOptions.debug.boundaries.boundariesColor, this.systemSettings.gameOptions.debug.boundaries.boundariesWidth);\r\n if (eLen) {\r\n //draw ellipse boundaries\r\n eB.forEach(element => {\r\n const x = element[0],\r\n y = element[1],\r\n radX = element[2],\r\n radY = element[3],\r\n vertices = utils.calculateEllipseVertices(x, y, radX, radY);\r\n this.#webGlEngine._drawPolygon({x: 0, y: 0, vertices, isOffsetTurnedOff: true}, this.stageData);\r\n //this.#webGlEngine._drawLines(vertices, this.systemSettings.gameOptions.debug.boundaries.boundariesColor, this.systemSettings.gameOptions.debug.boundaries.boundariesWidth);\r\n });\r\n }\r\n if (pLen) {\r\n //draw point boundaries\r\n pB.forEach(element => {\r\n const x = element[0],\r\n y = element[1],\r\n vertices = [x,y, x+1,y+1];\r\n\r\n this.#webGlEngine._drawLines(vertices, this.systemSettings.gameOptions.debug.boundaries.boundariesColor, this.systemSettings.gameOptions.debug.boundaries.boundariesWidth);\r\n });\r\n }\r\n resolve();\r\n });\r\n }\r\n\r\n #countFPSaverage() {\r\n const timeLeft = this.systemSettings.gameOptions.render.cyclesTimeCalc.averageFPStime,\r\n steps = this.#tempRCircleT.length;\r\n let fullTime = 0;\r\n for (let i = 0; i < steps; i++) {\r\n const timeStep = this.#tempRCircleT[i];\r\n fullTime += timeStep;\r\n }\r\n console.log(\"FPS average for\", timeLeft/1000, \"sec, is \", (1000 / (fullTime / steps)).toFixed(2));\r\n\r\n // cleanup\r\n this.#tempRCircleT = [];\r\n }\r\n\r\n /**\r\n * @ignore\r\n * @param {GameStageData} stageData \r\n */\r\n _startRender = async (/*time*/stageData) => {\r\n const gameOptions = this.systemSettings.gameOptions;\r\n //Logger.debug(\"_render \" + this.name + \" class\");\r\n this.#isActive = true;\r\n this.#currentGameStageData = stageData;\r\n this.fixCanvasSize();\r\n switch (gameOptions.library) {\r\n case CONST.LIBRARY.WEBGL:\r\n await this.#prepareViews();\r\n this.timeStart = Date.now();\r\n setTimeout(() => requestAnimationFrame(this.#drawViews));\r\n break;\r\n }\r\n if (gameOptions.render.cyclesTimeCalc.check === CONST.OPTIMIZATION.CYCLE_TIME_CALC.AVERAGES) {\r\n this.#fpsAverageCountTimer = setInterval(() => this.#countFPSaverage(), gameOptions.render.cyclesTimeCalc.averageFPStime);\r\n }\r\n };\r\n\r\n /**\r\n * @ignore\r\n */\r\n _stopRender = () => {\r\n this.#isActive = false;\r\n this.#currentGameStageData = null;\r\n this.#tempRCircleT = [];\r\n clearInterval(this.#fpsAverageCountTimer);\r\n this.#fpsAverageCountTimer = null;\r\n };\r\n /**\r\n * \r\n * @returns {Promise}\r\n */\r\n #prepareViews() {\r\n return new Promise((resolve, reject) => {\r\n let viewPromises = [];\r\n const isBoundariesPrecalculations = this.#isBoundariesPrecalculations;\r\n viewPromises.push(this.initiateContext());\r\n if (isBoundariesPrecalculations) {\r\n console.warn(\"isBoundariesPrecalculations() is turned off\");\r\n //for (const view of this.#views.values()) {\r\n //viewPromises.push(this.#iRender._createBoundariesPrecalculations());\r\n //}\r\n }\r\n Promise.allSettled(viewPromises).then((drawingResults) => {\r\n drawingResults.forEach((result) => {\r\n if (result.status === \"rejected\") {\r\n const error = result.reason;\r\n Warning(WARNING_CODES.UNHANDLED_DRAW_ISSUE, error);\r\n reject(error);\r\n }\r\n });\r\n resolve();\r\n });\r\n });\r\n }\r\n\r\n #drawViews = async (/*drawTime*/) => {\r\n const timeStart = performance.now(),\r\n minCycleTime = this.#minCycleTime,\r\n isCyclesTimeCalcCheckCurrent = this.systemSettings.gameOptions.render.cyclesTimeCalc.check === CONST.OPTIMIZATION.CYCLE_TIME_CALC.CURRENT;\r\n \r\n this.emit(CONST.EVENTS.SYSTEM.RENDER.START);\r\n this.stageData._clearBoundaries();\r\n this.clearContext();\r\n \r\n this.render().then(() => {\r\n const currentRenderTime = performance.now() - timeStart,\r\n r_time_less = minCycleTime - currentRenderTime,\r\n wait_time = r_time_less > 0 ? r_time_less : 0,\r\n cycleTime = currentRenderTime + wait_time;\r\n \r\n if (isCyclesTimeCalcCheckCurrent && currentRenderTime > minCycleTime) {\r\n console.log(\"current draw take: \", (currentRenderTime), \" ms\");\r\n }\r\n\r\n this.emit(CONST.EVENTS.SYSTEM.RENDER.END);\r\n\r\n if (cycleTime > 0) {\r\n this.#tempRCircleT.push(cycleTime);\r\n }\r\n\r\n if (this.#isActive) {\r\n setTimeout(() => requestAnimationFrame(this.#drawViews), wait_time);\r\n }\r\n }).catch((errors) => {\r\n if (errors.forEach) {\r\n errors.forEach((err) => {\r\n Warning(WARNING_CODES.UNHANDLED_DRAW_ISSUE, err);\r\n });\r\n } else {\r\n Warning(WARNING_CODES.UNHANDLED_DRAW_ISSUE, errors.message);\r\n }\r\n this._stopRender();\r\n });\r\n };\r\n}","import { CONST, ERROR_CODES, WARNING_CODES } from \"../constants.js\";\nimport { Exception, Warning } from \"./Exception.js\";\nimport { INetwork } from \"./INetwork.js\";\nimport { ISystemAudio } from \"./ISystemAudio.js\";\nimport { SystemSettings } from \"../configs.js\";\nimport AssetsManager from \"../../modules/assetsm/dist/assetsm.min.js\";\nimport { DrawObjectFactory } from \"./DrawObjectFactory.js\";\nimport { GameStage } from \"./GameStage.js\";\nimport { IRender } from \"./IRender.js\";\nimport { IExtension } from \"./IExtension.js\";\n\n/**\n * Public interface for a System
\n * Can be used to start/stop GameStage render,
\n * And provides access to SystemSettings, INetwork and ISystemAudio
\n * IRender, DrawObjectFactory, AssetsManager and external modules\n * accessible via GameStage.iSystem and System.system\n * @see {@link System} a part of System class instance\n * @see {@link GameStage} a part of GameStage class instance\n */\nexport class ISystem {\n /**\n * @type {Object}\n */\n #systemSettings;\n /**\n * @type {IExtension}\n */\n #iExtension;\n /**\n * @type {INetwork | null}\n */\n #systemServerConnection;\n /**\n * @type {ISystemAudio}\n */\n #systemAudioInterface;\n /**\n * @type {AssetsManager}\n */\n #iLoader = new AssetsManager();\n /**\n * @type {IRender}\n */\n #iRender;\n /**\n * @type {DrawObjectFactory}\n */\n #drawObjectFactory = new DrawObjectFactory(this.#iLoader);\n \n #modules = new Map();\n /**\n * @type {Map}\n */\n #registeredStagesReference;\n /**\n * @type {EventTarget}\n */\n #emitter = new EventTarget();\n /**\n * @hideconstructor\n */\n constructor(systemSettings, registeredStages, canvasContainer) {\n if (!systemSettings) {\n Exception(ERROR_CODES.CREATE_INSTANCE_ERROR, \"systemSettings should be passed to class instance\");\n }\n this.#systemSettings = systemSettings;\n \n this.#systemAudioInterface = new ISystemAudio(this.iLoader);\n this.#systemServerConnection = systemSettings.network.enabled ? new INetwork(systemSettings) : null;\n this.#iRender = new IRender(this.systemSettings, this.iLoader, canvasContainer);\n this.#iExtension = new IExtension(this, this.#iRender);\n this.#registeredStagesReference = registeredStages;\n // broadcast render events\n this.#iRender.addEventListener(CONST.EVENTS.SYSTEM.RENDER.START, () => this.emit(CONST.EVENTS.SYSTEM.RENDER.START));\n this.#iRender.addEventListener(CONST.EVENTS.SYSTEM.RENDER.END, () => this.emit(CONST.EVENTS.SYSTEM.RENDER.END));\n }\n\n /**\n * \n * @param {string} eventName\n * @param {...any} eventParams\n */\n emit = (eventName, ...eventParams) => {\n const event = new Event(eventName);\n event.data = [...eventParams];\n this.#emitter.dispatchEvent(event);\n };\n\n /**\n * \n * @param {string} eventName \n * @param {*} listener \n * @param {*=} options \n */\n addEventListener = (eventName, listener, options) => {\n this.#emitter.addEventListener(eventName, listener, options);\n };\n\n /**\n * \n * @param {string} eventName \n * @param {*} listener \n * @param {*=} options \n */\n removeEventListener = (eventName, listener, options) => {\n this.#emitter.removeEventListener(eventName, listener, options);\n };\n \n /**\n * @type { INetwork | null }\n */\n get iNetwork () {\n return this.#systemServerConnection;\n }\n\n /**\n * @type { SystemSettings }\n */\n get systemSettings() {\n return this.#systemSettings;\n }\n\n /**\n * @type { ISystemAudio }\n */\n get audio() {\n return this.#systemAudioInterface;\n }\n\n /**\n * @type {AssetsManager}\n */\n get iLoader() {\n return this.#iLoader;\n }\n\n /**\n * @type {IRender}\n */\n get iRender() {\n return this.#iRender;\n }\n\n /**\n * @type {DrawObjectFactory}\n */\n get drawObjectFactory() {\n return this.#drawObjectFactory;\n }\n\n get iExtension() {\n return this.#iExtension;\n }\n /**\n * @type {Map}\n */\n get modules() {\n return this.#modules;\n }\n\n /**\n * \n * @param {string} moduleKey \n * @param {Object} moduleClass \n * @param {...any} args \n * @returns {Object}\n */\n installModule = (moduleKey, moduleClass, ...args) => {\n const moduleInstance = new moduleClass(this, ...args);\n if (this.#modules.has(moduleKey)) {\n Warning(WARNING_CODES.MODULE_ALREADY_INSTALLED, \"module \" + moduleKey + \" is already installed\");\n return this.#modules.get(moduleKey);\n } else {\n this.#modules.set(moduleKey, moduleInstance);\n }\n return moduleInstance;\n };\n\n /**\n * @method\n * @param {string} screenPageName\n * @param {Object} [options] - options\n */\n startGameStage = (screenPageName, options) => {\n if (this.#registeredStagesReference.has(screenPageName)) {\n const stage = this.#registeredStagesReference.get(screenPageName),\n pageData = stage.stageData;\n this.#drawObjectFactory._attachPageData(pageData);\n if (stage.isInitiated === false) {\n stage._init();\n }\n //stage._attachCanvasToContainer(this.#canvasContainer);\n stage._start(options);\n this.emit(CONST.EVENTS.SYSTEM.START_PAGE);\n this.#iRender._startRender(pageData);\n } else {\n Exception(ERROR_CODES.VIEW_NOT_EXIST, \"View \" + screenPageName + \" is not registered!\");\n }\n };\n\n /**\n * @method\n * @param {string} screenPageName\n */\n stopGameStage = (screenPageName) => {\n if (this.#registeredStagesReference.has(screenPageName)) {\n this.emit(CONST.EVENTS.SYSTEM.STOP_PAGE);\n this.drawObjectFactory._detachPageData();\n this.#iRender._stopRender();\n this.#registeredStagesReference.get(screenPageName)._stop();\n } else {\n Exception(ERROR_CODES.VIEW_NOT_EXIST, \"View \" + screenPageName + \" is not registered!\");\n }\n };\n}","import AssetsManager from \"../../modules/assetsm/dist/assetsm.min.js\";\nimport { WARNING_CODES } from \"../constants.js\";\nimport { Warning } from \"./Exception.js\";\n\n/**\n * An audio interface,
\n * controls all application audio,
\n * holds and retrieves audio, changes volume
\n * accessible via GameStage.audio\n * @see {@link GameStage} a part of GameStage\n * @hideconstructor\n */\nexport class ISystemAudio {\n #volume = 0.5;\n #audio = new Map();\n /**\n * @type {AssetsManager}\n */\n #loaderReference;\n\n constructor(iLoader) {\n this.#loaderReference = iLoader;\n }\n\n /**\n * Original track\n * @param {string} name \n * @returns {HTMLAudioElement | null}\n */\n getAudio = (name) => {\n const audio = this.#audio.get(name);\n if (audio === null) {\n Warning(WARNING_CODES.AUDIO_NOT_LOADED, \"Audio with key \" + name + \" exists, but not actually loaded\");\n return audio;\n }\n if (audio) {\n return audio;\n } else {\n Warning(WARNING_CODES.AUDIO_NOT_REGISTERED, \"\");\n return null;\n }\n };\n\n /**\n * Clone of original track\n * @param {string} name \n * @returns {HTMLAudioElement | null}\n */\n getAudioCloned = (name) => {\n const audio = this.#audio.get(name);\n if (audio === null) {\n Warning(WARNING_CODES.AUDIO_NOT_LOADED, \"Audio with key \" + name + \" exists, but not actually loaded\");\n return audio;\n }\n if (audio) {\n const audioCloned = audio.cloneNode();\n audioCloned.volume = this.#volume;\n return audioCloned;\n } else {\n Warning(WARNING_CODES.AUDIO_NOT_REGISTERED);\n return null;\n }\n };\n\n set volume(value) {\n this.#volume = value;\n this.#updateTracksVolumes(value);\n }\n /**\n * Used to set or get audio volume, \n * value should be from 0 to 1\n * @type {number}\n */\n get volume() {\n return this.#volume;\n }\n\n #updateTracksVolumes(value) {\n for (const track of this.#audio.values()) {\n if (track) {\n track.volume = value;\n }\n }\n }\n\n /**\n * Register audio in the iSystem\n * @param {string} name\n */\n registerAudio(name) {\n let mediaElement = this.#loaderReference.getAudio(name);\n this.#audio.set(name, mediaElement);\n }\n}","import { SystemSettings } from \"../configs.js\";\nimport { CONST } from \"../constants.js\";\n\nexport class Logger {\n static debug(...args) {\n if (SystemSettings.mode === CONST.MODE.DEBUG)\n args.forEach(message => console.log(message));\n }\n}","class Vertex {\n #x;\n #y;\n constructor(x, y) {\n this.#x = x;\n this.#y = y;\n }\n\n get x() {\n return this.#x;\n }\n\n get y() {\n return this.#y;\n }\n}\n\nclass Rectangle {\n #x;\n #y;\n #w;\n #h;\n constructor(x, y, w, h) {\n this.#x = x;\n this.#y = y;\n this.#w = w;\n this.#h = h; \n }\n /**\n * @type {number}\n */\n get x() {\n return this.#x;\n }\n /**\n * @type {number}\n */\n get y() {\n return this.#y;\n }\n /**\n * @type {number}\n */\n get width() {\n return this.#w;\n }\n /**\n * @type {number}\n */\n get height() {\n return this.#h;\n }\n}\n\nclass Vector {\n #x;\n #y;\n constructor(x1, y1, x2, y2) {\n this.#x = x2 - x1;\n this.#y = y2 - y1;\n }\n\n get x() {\n return this.#x;\n }\n\n get y() {\n return this.#y;\n }\n\n get length() {\n return Math.sqrt(Math.pow(this.#x, 2) + Math.pow(this.#y, 2));\n }\n\n get tetaAngle() {\n return Math.atan2(this.#y, this.#x);\n }\n}\n\nexport { Vertex, Rectangle, Vector };","import { ERROR_CODES } from \"../constants.js\";\nimport { Exception } from \"./Exception.js\";\nimport { GameStage } from \"./GameStage.js\";\nimport { ISystem } from \"./ISystem.js\";\nimport { SystemSettings } from \"../configs.js\";\n\nimport { LoadingStage } from \"../design/LoadingStage.js\";\n\nconst loadingPageName = \"loadingPage\";\n/**\n * A main app class,
\n * Holder class for GameStage,
\n * can register new GameStages,
\n * init and preload data for them,
\n */\nexport class System {\n /**\n * @type {Map}\n */\n #registeredStages;\n /**\n * @type {ISystem}\n */\n #iSystem;\n /**\n * @param {SystemSettings} iSystemSettings - holds iSystem settings\n * @param {HTMLElement | null} [canvasContainer = null] - If it is not passed, iSystem will create div element and attach it to body\n */\n constructor(iSystemSettings, canvasContainer) {\n if (!iSystemSettings) {\n Exception(ERROR_CODES.CREATE_INSTANCE_ERROR, \"iSystemSettings should be passed to class instance\");\n }\n this.#registeredStages = new Map();\n\n if (!canvasContainer) {\n canvasContainer = document.createElement(\"div\");\n document.body.appendChild(canvasContainer);\n }\n\n this.#iSystem = new ISystem(iSystemSettings, this.#registeredStages, canvasContainer);\n\n this.registerStage(loadingPageName, LoadingStage);\n\n this.#iSystem.iLoader.addEventListener(\"loadstart\", this.#loadStart);\n this.#iSystem.iLoader.addEventListener(\"progress\", this.#loadProgress);\n this.#iSystem.iLoader.addEventListener(\"load\", this.#loadComplete);\n }\n\n /**\n * @type {ISystem}\n */\n get iSystem() {\n return this.#iSystem;\n }\n\n /**\n * A main factory method for create GameStage instances,
\n * register them in a System and call GameStage.register() stage\n * @param {string} screenPageName\n * @param {GameStage} stage\n */\n registerStage(screenPageName, stage) {\n if (screenPageName && typeof screenPageName === \"string\" && screenPageName.trim().length > 0) {\n const stageInstance = new stage();\n stageInstance._register(screenPageName, this.iSystem);\n this.#registeredStages.set(screenPageName, stageInstance);\n } else {\n Exception(ERROR_CODES.CREATE_INSTANCE_ERROR, \"valid class name should be provided\");\n }\n }\n\n /**\n * Preloads assets for all registered pages\n * @return {Promise}\n */\n preloadAllData() {\n return this.#iSystem.iLoader.preload();\n }\n\n #loadStart = (event) => {\n this.#iSystem.startGameStage(loadingPageName, {total: event.total});\n };\n\n #loadProgress = (event) => {\n const uploaded = event.loaded,\n left = event.total,\n loadingPage = this.#registeredStages.get(loadingPageName);\n \n loadingPage._progress(uploaded, left);\n };\n\n #loadComplete = () => {\n this.#iSystem.stopGameStage(loadingPageName);\n };\n}","const imgVertexShader = `\n attribute vec2 a_texCoord;\n\n attribute vec2 a_position;\n\n uniform vec2 u_translation;\n uniform float u_rotation;\n uniform vec2 u_scale;\n\n uniform vec2 u_resolution;\n\n varying vec2 v_texCoord;\n\n void main(void) {\n float c = cos(u_rotation);\n float s = sin(u_rotation);\n\n mat3 translationMatrix1 = mat3(\n 1, 0, 0,\n 0, 1, 0,\n u_translation.x, u_translation.y, 1\n );\n\n mat3 translationMatrix2 = mat3(\n 1, 0, 0,\n 0, 1, 0,\n -u_translation.x, -u_translation.y, 1\n );\n \n mat3 rotationMatrix = mat3(\n c, s, 0,\n -s, c, 0,\n 0, 0, 1\n );\n\n mat3 scalingMatrix = mat3(\n u_scale.x, 0, 0,\n 0, u_scale.y, 0,\n 0, 0, 1\n );\n\n mat3 matrix = translationMatrix1 * rotationMatrix * translationMatrix2 * scalingMatrix;\n \n vec2 position = (matrix * vec3(a_position, 1)).xy;\n\n vec2 clipSpace = position / u_resolution * 2.0 - 1.0;\n\n gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);\n \n v_texCoord = a_texCoord;\n }`;\nconst imgFragmentShader = `\n precision mediump float;\n\n uniform sampler2D u_image;\n\n //texCoords passed in from the vertex shader\n varying vec2 v_texCoord;\n void main() {\n vec4 color = texture2D(u_image, v_texCoord);\n gl_FragColor = color;\n }`;\nconst imgUniforms = [\"u_translation\", \"u_rotation\", \"u_scale\", \"u_resolution\",\"u_image\"];\nconst imgAttributes = [\"a_position\", \"a_texCoord\"];\n\nexport {imgVertexShader, imgFragmentShader, imgUniforms, imgAttributes};","const primitivesVertexShader = `\n precision mediump float;\n\n attribute vec2 a_position;\n\n uniform vec2 u_translation;\n uniform float u_rotation;\n uniform vec2 u_scale;\n\n uniform vec2 u_resolution;\n\n void main(void) {\n float c = cos(u_rotation);\n float s = sin(u_rotation);\n\n mat3 translationMatrix1 = mat3(\n 1, 0, 0,\n 0, 1, 0,\n u_translation.x, u_translation.y, 1\n );\n\n //mat3 translationMatrix2 = mat3(\n // 1, 0, 0,\n // 0, 1, 0,\n // -u_translation.x, -u_translation.y, 1\n //);\n \n mat3 rotationMatrix = mat3(\n c, s, 0,\n -s, c, 0,\n 0, 0, 1\n );\n\n mat3 scalingMatrix = mat3(\n u_scale.x, 0, 0,\n 0, u_scale.y, 0,\n 0, 0, 1\n );\n \n mat3 matrix = translationMatrix1 * rotationMatrix * scalingMatrix;\n\n vec2 position = (matrix * vec3(a_position, 1)).xy;\n\n vec2 clipSpace = position / u_resolution * 2.0 - 1.0;\n\n gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);\n }\n`;\nconst primitivesFragmentShader = `\n precision mediump float;\n\n uniform vec4 u_color;\n uniform float u_fade_min; \n uniform float u_fade_max;\n uniform vec2 u_resolution;\n uniform vec2 u_translation;\n\n void main(void) {\n vec4 p = u_color;\n if (u_fade_min > 0.0) {\n vec2 fix_tr = vec2(u_translation.x, u_resolution.y - u_translation.y); \n float distance = distance(fix_tr.xy, gl_FragCoord.xy);\n if (u_fade_min <= distance && distance <= u_fade_max) {\n float percent = ((distance - u_fade_max) / (u_fade_min - u_fade_max)) * 100.0;\n p.a = u_color.a * (percent / 100.0);\n }\n }\n\n gl_FragColor = p;\n }\n`;\nconst primitivesUniforms = [\"u_translation\", \"u_rotation\", \"u_scale\", \"u_resolution\", \"u_fade_min\", \"u_fade_max\", \"u_color\"];\nconst primitivesAttributes = [\"a_position\"];\n\nexport { primitivesVertexShader, primitivesFragmentShader, primitivesUniforms, primitivesAttributes };","/**\n * storing current WebGLTexture\n */\nexport class TextureStorage {\n /**\n * @type {Number}\n */\n #textureIndex;\n /**\n * @type {WebGLTexture}\n */\n #texture;\n /**\n * @type {boolean}\n */\n #isTextureRecalculated = true;\n constructor(texture, textureIndex = 0) {\n this.#texture = texture;\n this.#textureIndex = textureIndex;\n }\n\n get _isTextureRecalculated() {\n return this.#isTextureRecalculated;\n }\n\n set _isTextureRecalculated(value) {\n this.#isTextureRecalculated = value;\n }\n\n get _texture() {\n return this.#texture;\n }\n\n set _texture(value) {\n this.#texture = value;\n }\n\n get _textureIndex() {\n return this.#textureIndex;\n }\n}","import { ERROR_CODES, CONST, WARNING_CODES } from \"../../constants.js\";\r\nimport { crossProduct } from \"../../utils.js\";\r\nimport { Exception, Warning } from \"../Exception.js\";\r\nimport { GameStageData } from \"../GameStageData.js\";\r\nimport { TextureStorage } from \"./TextureStorage.js\";\r\n\r\nexport class WebGlEngine {\r\n /**\r\n * @type {WebGLRenderingContext}\r\n */\r\n #gl;\r\n /**\r\n * @type {number}\r\n */\r\n #MAX_TEXTURES;\r\n /**\r\n * @type {boolean}\r\n */\r\n #debug;\r\n /**\r\n * @type {Object}\r\n */\r\n #gameOptions;\r\n /**\r\n * @type {WebGLBuffer | null}\r\n */\r\n #positionBuffer;\r\n /**\r\n * @type {WebGLBuffer | null}\r\n */\r\n #texCoordBuffer;\r\n\r\n /**\r\n * @type {Map>}\r\n */\r\n #webGlProgramsVarsLocations = new Map();\r\n\r\n constructor(context, gameOptions) {\r\n if (!context || !(context instanceof WebGLRenderingContext)) {\r\n Exception(ERROR_CODES.UNEXPECTED_INPUT_PARAMS, \" context parameter should be specified and equal to WebGLRenderingContext\");\r\n }\r\n \r\n this.#gl = context;\r\n this.#gameOptions = gameOptions;\r\n this.#debug = gameOptions.debug.checkWebGlErrors;\r\n this.#MAX_TEXTURES = context.getParameter(context.MAX_TEXTURE_IMAGE_UNITS);\r\n this.#positionBuffer = context.createBuffer();\r\n this.#texCoordBuffer = context.createBuffer();\r\n }\r\n\r\n getProgram(name) {\r\n return this.#registeredWebGlPrograms.get(name);\r\n }\r\n\r\n getProgramVarLocations(name) {\r\n return this.#webGlProgramsVarsLocations.get(name);\r\n }\r\n\r\n _fixCanvasSize(width, height) {\r\n this.#gl.viewport(0, 0, width, height);\r\n }\r\n _initWebGlAttributes = () => {\r\n const gl = this.#gl;\r\n gl.enable(gl.BLEND);\r\n gl.enable(gl.STENCIL_TEST);\r\n gl.stencilFunc(gl.ALWAYS, 1, 0xFF);\r\n //if stencil test and depth test pass we replace the initial value\r\n gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);\r\n return Promise.resolve();\r\n };\r\n\r\n /**\r\n * \r\n * @returns {Promise}\r\n */\r\n _initiateWasm = () => {\r\n const url = this.#gameOptions.optimization === CONST.OPTIMIZATION.WEB_ASSEMBLY.NATIVE_WAT ? this.#gameOptions.optimizationWASMUrl : this.#gameOptions.optimizationAssemblyUrl;\r\n return new Promise((resolve, reject) => {\r\n this.layerData = new WebAssembly.Memory({\r\n initial:1000 // 6.4MiB x 10 = 64MiB(~67,1Mb)\r\n });\r\n this.layerDataFloat32 = new Float32Array(this.layerData.buffer);\r\n const importObject = {\r\n env: {\r\n memory: this.layerData,\r\n logi: console.log,\r\n logf: console.log\r\n }\r\n };\r\n\r\n fetch(url)\r\n .then((response) => response.arrayBuffer())\r\n .then((module) => WebAssembly.instantiate(module, importObject))\r\n .then((obj) => {\r\n this.calculateBufferData = obj.instance.exports.calculateBufferData;\r\n resolve();\r\n });\r\n });\r\n };\r\n\r\n _clearView() {\r\n const gl = this.#gl;\r\n //cleanup buffer, is it required?\r\n //gl.bindBuffer(gl.ARRAY_BUFFER, null);\r\n gl.clearColor(0, 0, 0, 0);// shouldn't be gl.clearColor(0, 0, 0, 1); ?\r\n // Clear the color buffer with specified clear color\r\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);\r\n }\r\n \r\n _render(verticesNumber, primitiveType, offset = 0) {\r\n const gl = this.#gl,\r\n err = this.#debug ? gl.getError() : 0;\r\n if (err !== 0) {\r\n console.error(err);\r\n throw new Error(\"Error num: \" + err);\r\n } else {\r\n gl.drawArrays(primitiveType, offset, verticesNumber);\r\n // set blend to default\r\n gl.stencilFunc(gl.ALWAYS, 1, 0xFF);\r\n }\r\n return new Promise((resolve, reject) => {\r\n if (this.#gameOptions.debug.delayBetweenObjectRender) {\r\n setTimeout(() => {\r\n resolve();\r\n }, 1000);\r\n } else {\r\n resolve();\r\n }\r\n });\r\n }\r\n\r\n /*************************************\r\n * Register and compile programs\r\n ************************************/\r\n\r\n /**\r\n * \r\n * @param {string} programName\r\n * @param {string} vertexShader - raw vertex shader program\r\n * @param {string} fragmentShader - raw fragment shader program \r\n * @param {Array} uVars - program uniform variables names\r\n * @param {Array} aVars - program attribute variables names\r\n * @returns {Promise}\r\n */\r\n _registerAndCompileWebGlProgram(programName, vertexShader, fragmentShader, uVars, aVars) {\r\n const program = this.#compileWebGlProgram(vertexShader, fragmentShader),\r\n varsLocations = this.#getProgramVarsLocations(program, uVars, aVars);\r\n this.#registeredWebGlPrograms.set(programName, program);\r\n this.#webGlProgramsVarsLocations.set(programName, varsLocations);\r\n\r\n return Promise.resolve();\r\n }\r\n\r\n /**\r\n * @returns {WebGLProgram}\r\n */\r\n #compileWebGlProgram (vertexShader, fragmentShader) {\r\n const gl = this.#gl,\r\n program = gl.createProgram();\r\n\r\n if (program) {\r\n const compVertexShader = this.#compileShader(gl, vertexShader, gl.VERTEX_SHADER);\r\n if (compVertexShader) {\r\n gl.attachShader(program, compVertexShader);\r\n } else {\r\n Exception(ERROR_CODES.WEBGL_ERROR, \"#compileShader(vertexShaderSource) is null\");\r\n }\r\n\r\n const compFragmentShader = this.#compileShader(gl, fragmentShader, gl.FRAGMENT_SHADER);\r\n if (compFragmentShader) {\r\n gl.attachShader(program, compFragmentShader);\r\n } else {\r\n Exception(ERROR_CODES.WEBGL_ERROR, \"#compileShader(fragmentShaderSource) is null\");\r\n }\r\n\r\n gl.linkProgram(program);\r\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\r\n const info = gl.getProgramInfoLog(program);\r\n Exception(ERROR_CODES.WEBGL_ERROR, `Could not compile WebGL program. \\n\\n${info}`);\r\n }\r\n } else {\r\n Exception(ERROR_CODES.WEBGL_ERROR, \"gl.createProgram() is null\");\r\n }\r\n return program;\r\n }\r\n\r\n /**\r\n * \r\n * @param {WebGLProgram} program\r\n * @param {Array} uVars - uniform variables\r\n * @param {Array} aVars - attributes variables\r\n * @returns {Object} - uniform or attribute\r\n */\r\n #getProgramVarsLocations(program, uVars, aVars) {\r\n const gl = this.#gl;\r\n let locations = {};\r\n uVars.forEach(elementName => {\r\n locations[elementName] = gl.getUniformLocation(program, elementName);\r\n });\r\n aVars.forEach(elementName => {\r\n locations[elementName] = gl.getAttribLocation(program, elementName);\r\n });\r\n return locations;\r\n }\r\n\r\n #compileShader(gl, shaderSource, shaderType) {\r\n const shader = gl.createShader(shaderType);\r\n if (shader) {\r\n gl.shaderSource(shader, shaderSource);\r\n gl.compileShader(shader);\r\n\r\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\r\n const info = gl.getShaderInfoLog(shader);\r\n Exception(ERROR_CODES.WEBGL_ERROR, \"Couldn't compile webGl program. \\n\\n\" + info);\r\n }\r\n } else {\r\n Exception(ERROR_CODES.WEBGL_ERROR, `gl.createShader(${shaderType}) is null`);\r\n }\r\n return shader;\r\n }\r\n /*------------------------------------\r\n * End of Register and compile programs\r\n -------------------------------------*/\r\n\r\n /**********************************\r\n * Predefined Drawing programs\r\n **********************************/\r\n _bindPrimitives = (renderObject, gl, pageData, program, vars) => {\r\n const [ xOffset, yOffset ] = renderObject.isOffsetTurnedOff === true ? [0,0] : pageData.worldOffset,\r\n x = renderObject.x - xOffset,\r\n y = renderObject.y - yOffset,\r\n scale = [1, 1],\r\n rotation = renderObject.rotation,\r\n blend = renderObject.blendFunc ? renderObject.blendFunc : [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA],\r\n { \r\n u_translation: translationLocation,\r\n u_rotation: rotationRotation,\r\n u_scale: scaleLocation,\r\n u_resolution: resolutionUniformLocation,\r\n u_color: colorUniformLocation,\r\n a_position: positionAttributeLocation,\r\n u_fade_min: fadeMinLocation\r\n } = vars;\r\n \r\n let verticesNumber = 0;\r\n gl.useProgram(program);\r\n // set the resolution\r\n gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);\r\n gl.uniform2f(translationLocation, x, y);\r\n gl.uniform2f(scaleLocation, scale[0], scale[1]);\r\n gl.uniform1f(rotationRotation, rotation);\r\n gl.uniform1f(fadeMinLocation, 0);\r\n\r\n gl.enableVertexAttribArray(positionAttributeLocation);\r\n\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#positionBuffer);\r\n\r\n switch (renderObject.type) {\r\n case CONST.DRAW_TYPE.RECTANGLE:\r\n this.#setSingleRectangle(renderObject.width, renderObject.height);\r\n verticesNumber += 6;\r\n break;\r\n case CONST.DRAW_TYPE.TEXT:\r\n break;\r\n case CONST.DRAW_TYPE.CIRCLE: {\r\n const coords = renderObject.vertices;\r\n gl.bufferData(gl.ARRAY_BUFFER, \r\n new Float32Array(coords), gl.STATIC_DRAW);\r\n verticesNumber += coords.length / 2;\r\n break;\r\n }\r\n case CONST.DRAW_TYPE.POLYGON: {\r\n const triangles = this.#triangulatePolygon(renderObject.vertices);\r\n this.#bindPolygon(triangles);\r\n const len = triangles.length;\r\n if (len % 3 !== 0) {\r\n Warning(WARNING_CODES.POLYGON_VERTICES_NOT_CORRECT, `polygons ${renderObject.id}, vertices are not correct, skip drawing`);\r\n return Promise.reject();\r\n }\r\n verticesNumber += len / 2;\r\n break;\r\n }\r\n }\r\n //Tell the attribute how to get data out of positionBuffer\r\n const size = 2,\r\n type = gl.FLOAT, // data is 32bit floats\r\n normalize = false,\r\n stride = 0, // move forward size * sizeof(type) each iteration to get next position\r\n offset = 0; // start of beginning of the buffer\r\n gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset);\r\n\r\n const colorArray = this.#rgbaToArray(renderObject.bgColor);\r\n gl.uniform4f(colorUniformLocation, colorArray[0]/255, colorArray[1]/255, colorArray[2]/255, colorArray[3]);\r\n \r\n if (blend) {\r\n gl.blendFunc(blend[0], blend[1]);\r\n }\r\n \r\n if (renderObject.isMaskAttached) {\r\n gl.stencilFunc(gl.EQUAL, renderObject._maskId, 0xFF);\r\n } else if (renderObject._isMask) {\r\n gl.stencilFunc(gl.ALWAYS, renderObject.id, 0xFF);\r\n }\r\n return Promise.resolve([verticesNumber, gl.TRIANGLES]);\r\n };\r\n _bindConus = (renderObject, gl, pageData, program, vars) => {\r\n const [ xOffset, yOffset ] = renderObject.isOffsetTurnedOff === true ? [0,0] : pageData.worldOffset,\r\n x = renderObject.x - xOffset,\r\n y = renderObject.y - yOffset,\r\n scale = [1, 1],\r\n rotation = renderObject.rotation,\r\n { \r\n u_translation: translationLocation,\r\n u_rotation: rotationRotation,\r\n u_scale: scaleLocation,\r\n u_resolution: resolutionUniformLocation,\r\n u_color: colorUniformLocation,\r\n a_position: positionAttributeLocation,\r\n u_fade_max: fadeMaxLocation,\r\n u_fade_min: fadeMinLocation\r\n } = vars,\r\n coords = renderObject.vertices,\r\n fillStyle = renderObject.bgColor,\r\n fade_min = renderObject.fade_min,\r\n fadeLen = renderObject.radius,\r\n blend = renderObject.blendFunc ? renderObject.blendFunc : [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA];\r\n let verticesNumber = 0;\r\n\r\n gl.useProgram(program);\r\n \r\n // set the resolution\r\n gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);\r\n gl.uniform2f(translationLocation, x, y);\r\n gl.uniform2f(scaleLocation, scale[0], scale[1]);\r\n gl.uniform1f(rotationRotation, rotation);\r\n gl.uniform1f(fadeMinLocation, fade_min);\r\n gl.uniform1f(fadeMaxLocation, fadeLen);\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#positionBuffer);\r\n\r\n gl.bufferData(gl.ARRAY_BUFFER, \r\n new Float32Array(coords), gl.STATIC_DRAW);\r\n\r\n gl.enableVertexAttribArray(positionAttributeLocation);\r\n //Tell the attribute how to get data out of positionBuffer\r\n const size = 2,\r\n type = gl.FLOAT, // data is 32bit floats\r\n normalize = false,\r\n stride = 0, // move forward size * sizeof(type) each iteration to get next position\r\n offset = 0; // start of beginning of the buffer\r\n gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset);\r\n\r\n verticesNumber += coords.length / 2;\r\n\r\n if (blend) {\r\n gl.blendFunc(blend[0], blend[1]);\r\n }\r\n\r\n const colorArray = this.#rgbaToArray(fillStyle);\r\n\r\n gl.uniform4f(colorUniformLocation, colorArray[0]/255, colorArray[1]/255, colorArray[2]/255, colorArray[3]);\r\n \r\n if (renderObject.isMaskAttached) {\r\n gl.stencilFunc(gl.EQUAL, renderObject._maskId, 0xFF);\r\n } else if (renderObject._isMask) {\r\n gl.stencilFunc(gl.ALWAYS, renderObject.id, 0xFF);\r\n }\r\n \r\n return Promise.resolve([verticesNumber, gl.TRIANGLE_FAN]);\r\n };\r\n\r\n _bindText = (renderObject, gl, pageData, program, vars) => {\r\n const { u_translation: translationLocation,\r\n u_rotation: rotationRotation,\r\n u_scale: scaleLocation,\r\n u_resolution: resolutionUniformLocation,\r\n a_position: positionAttributeLocation,\r\n a_texCoord: texCoordLocation,\r\n u_image: u_imageLocation } = vars;\r\n\r\n const {width:boxWidth, height:boxHeight} = renderObject.boundariesBox,\r\n image_name = renderObject.text,\r\n [ xOffset, yOffset ] = renderObject.isOffsetTurnedOff === true ? [0,0] : pageData.worldOffset,\r\n x = renderObject.x - xOffset,\r\n y = renderObject.y - yOffset - boxHeight,\r\n blend = renderObject.blendFunc ? renderObject.blendFunc : [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];\r\n\r\n const rotation = 0,\r\n scale = [1, 1];\r\n const vecX1 = x,\r\n vecY1 = y,\r\n vecX2 = vecX1 + boxWidth,\r\n vecY2 = vecY1 + boxHeight;\r\n const verticesBufferData = [\r\n vecX1, vecY1,\r\n vecX2, vecY1,\r\n vecX1, vecY2,\r\n vecX1, vecY2,\r\n vecX2, vecY1,\r\n vecX2, vecY2\r\n ],\r\n texturesBufferData = [\r\n 0, 0,\r\n 1, 0,\r\n 0, 1,\r\n 0, 1,\r\n 1, 0,\r\n 1, 1\r\n ];\r\n let verticesNumber = 0;\r\n\r\n gl.useProgram(program);\r\n // set the resolution\r\n gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);\r\n gl.uniform2f(translationLocation, x, y);\r\n gl.uniform2f(scaleLocation, scale[0], scale[1]);\r\n gl.uniform1f(rotationRotation, rotation);\r\n \r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#positionBuffer);\r\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verticesBufferData), gl.STATIC_DRAW);\r\n gl.enableVertexAttribArray(positionAttributeLocation);\r\n //Tell the attribute how to get data out of positionBuffer\r\n const size = 2,\r\n type = gl.FLOAT, // data is 32bit floats\r\n normalize = false,\r\n stride = 0, // move forward size * sizeof(type) each iteration to get next position\r\n offset = 0; // start of beginning of the buffer\r\n gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset);\r\n\r\n //textures buffer\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#texCoordBuffer);\r\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texturesBufferData), gl.STATIC_DRAW);\r\n\r\n gl.enableVertexAttribArray(texCoordLocation);\r\n gl.vertexAttribPointer(texCoordLocation, 2, gl.FLOAT, false, 0, 0);\r\n \r\n verticesNumber += 6;\r\n // remove box\r\n // fix text edges\r\n gl.blendFunc(blend[0], blend[1]);\r\n //\r\n //var currentTexture = gl.getParameter(gl.TEXTURE_BINDING_2D);\r\n \r\n let textureStorage = renderObject._textureStorage;\r\n if (!textureStorage) {\r\n //const activeTexture = gl.getParameter(gl.ACTIVE_TEXTURE);\r\n textureStorage = new TextureStorage(gl.createTexture());\r\n renderObject._textureStorage = textureStorage;\r\n }\r\n if (textureStorage._isTextureRecalculated === true) {\r\n this.#updateTextWebGlTexture(gl, textureStorage._texture, renderObject._textureCanvas);\r\n textureStorage._isTextureRecalculated = false;\r\n } else {\r\n this.#bindTexture(gl, textureStorage._texture);\r\n }\r\n gl.uniform1i(u_imageLocation, textureStorage._textureIndex);\r\n gl.depthMask(false);\r\n return Promise.resolve([verticesNumber, gl.TRIANGLES]);\r\n };\r\n\r\n _bindImage = (renderObject, gl, pageData, program, vars) => {\r\n const { \r\n u_translation: translationLocation,\r\n u_rotation: rotationRotation,\r\n u_scale: scaleLocation,\r\n u_resolution: resolutionUniformLocation,\r\n a_position: positionAttributeLocation,\r\n a_texCoord: texCoordLocation,\r\n u_image: u_imageLocation } = vars;\r\n\r\n const [ xOffset, yOffset ] = renderObject.isOffsetTurnedOff === true ? [0,0] : pageData.worldOffset,\r\n x = renderObject.x - xOffset,\r\n y = renderObject.y - yOffset;\r\n\r\n const atlasImage = renderObject.image,\r\n animationIndex = renderObject.imageIndex,\r\n image_name = renderObject.key,\r\n shapeMaskId = renderObject._maskId,\r\n spacing = renderObject.spacing,\r\n blend = renderObject.blendFunc ? renderObject.blendFunc : [gl.ONE, gl.ONE_MINUS_SRC_ALPHA],\r\n scale = [1, 1];\r\n let imageX = 0,\r\n imageY = 0,\r\n colNum = 0,\r\n rowNum = 0,\r\n verticesNumber = 0;\r\n if (animationIndex !== 0) {\r\n const imageColsNumber = (atlasImage.width + spacing) / (renderObject.width + spacing);\r\n colNum = animationIndex % imageColsNumber;\r\n rowNum = Math.floor(animationIndex / imageColsNumber);\r\n imageX = colNum * renderObject.width + (colNum * spacing),\r\n imageY = rowNum * renderObject.height + (rowNum * spacing);\r\n }\r\n const posX = x - renderObject.width / 2,\r\n posY = y - renderObject.height / 2;\r\n const vecX1 = posX,\r\n vecY1 = posY,\r\n vecX2 = vecX1 + renderObject.width,\r\n vecY2 = vecY1 + renderObject.height,\r\n texX1 = 1 / atlasImage.width * imageX,\r\n texY1 = 1 / atlasImage.height * imageY,\r\n texX2 = texX1 + (1 / atlasImage.width * renderObject.width),\r\n texY2 = texY1 + (1 / atlasImage.height * renderObject.height);\r\n const vectors = [\r\n vecX1, vecY1,\r\n vecX2, vecY1,\r\n vecX1, vecY2,\r\n vecX1, vecY2,\r\n vecX2, vecY1,\r\n vecX2, vecY2\r\n ],\r\n textures = [\r\n texX1, texY1,\r\n texX2, texY1,\r\n texX1, texY2,\r\n texX1, texY2,\r\n texX2, texY1,\r\n texX2, texY2\r\n ];\r\n gl.useProgram(program);\r\n // set the resolution\r\n gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);\r\n gl.uniform2f(translationLocation, x, y);\r\n gl.uniform2f(scaleLocation, scale[0], scale[1]);\r\n gl.uniform1f(rotationRotation, renderObject.rotation);\r\n \r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#positionBuffer);\r\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vectors), gl.STATIC_DRAW);\r\n\r\n verticesNumber += vectors.length / 2;\r\n gl.enableVertexAttribArray(positionAttributeLocation);\r\n //Tell the attribute how to get data out of positionBuffer\r\n const size = 2,\r\n type = gl.FLOAT, // data is 32bit floats\r\n normalize = false,\r\n stride = 0, // move forward size * sizeof(type) each iteration to get next position\r\n offset = 0; // start of beginning of the buffer\r\n gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset);\r\n\r\n //textures buffer\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#texCoordBuffer);\r\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textures), gl.STATIC_DRAW);\r\n\r\n gl.enableVertexAttribArray(texCoordLocation);\r\n gl.vertexAttribPointer(texCoordLocation, 2, gl.FLOAT, false, 0, 0);\r\n\r\n let textureStorage = renderObject._textureStorage;\r\n if (!textureStorage) {\r\n textureStorage = new TextureStorage(gl.createTexture());\r\n renderObject._textureStorage = textureStorage;\r\n } \r\n if (textureStorage._isTextureRecalculated === true) {\r\n this.#updateWebGlTexture(gl, textureStorage._texture, renderObject.image);\r\n textureStorage._isTextureRecalculated = false;\r\n } else {\r\n this.#bindTexture(gl, textureStorage._texture);\r\n }\r\n\r\n gl.uniform1i(u_imageLocation, textureStorage._textureIndex);\r\n // make image transparent parts transparent\r\n gl.blendFunc(blend[0], blend[1]);\r\n if (shapeMaskId) {\r\n gl.stencilFunc(gl.EQUAL, shapeMaskId, 0xFF);\r\n //gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);\r\n }\r\n\r\n return Promise.resolve([verticesNumber, gl.TRIANGLES]);\r\n };\r\n\r\n _bindTileImages = async(renderLayer, gl, pageData, program, vars) => {\r\n const { u_translation: translationLocation,\r\n u_rotation: rotationRotation,\r\n u_scale: scaleLocation,\r\n u_resolution: resolutionUniformLocation,\r\n a_position: positionAttributeLocation,\r\n a_texCoord: texCoordLocation,\r\n u_image: u_imageLocation } = vars;\r\n\r\n gl.useProgram(program);\r\n let renderLayerData;\r\n switch (this.#gameOptions.optimization) {\r\n case CONST.OPTIMIZATION.NATIVE_JS.NOT_OPTIMIZED:\r\n renderLayerData = await this.#prepareRenderLayerOld(renderLayer, pageData);\r\n break;\r\n case CONST.OPTIMIZATION.WEB_ASSEMBLY.ASSEMBLY_SCRIPT:\r\n case CONST.OPTIMIZATION.WEB_ASSEMBLY.NATIVE_WAT:\r\n renderLayerData = await this.#prepareRenderLayerWM(renderLayer, pageData);\r\n break;\r\n case CONST.OPTIMIZATION.NATIVE_JS.OPTIMIZED:\r\n default:\r\n renderLayerData = await this.#prepareRenderLayer(renderLayer, pageData);\r\n }\r\n const translation = [0, 0],\r\n scale = [1, 1],\r\n rotation = 0,\r\n drawMask = [\"ONE\", \"ONE_MINUS_SRC_ALPHA\"],\r\n shapeMaskId = renderLayer._maskId;\r\n\r\n let verticesNumber = 0,\r\n isTextureBind = false;\r\n for (let i = 0; i < renderLayerData.length; i++) {\r\n const data = renderLayerData[i],\r\n vectors = data[0],\r\n textures = data[1],\r\n image_name = data[2],\r\n image = data[3];\r\n // if layer use multiple tilesets\r\n if (vectors.length > 0 && textures.length > 0) {\r\n // need to have additional draw call for each new texture added\r\n // probably it could be combined in one draw call if multiple textures \r\n // could be used in one draw call\r\n if (isTextureBind) {\r\n await this._render(verticesNumber, gl.TRIANGLES);\r\n }\r\n // set the resolution\r\n gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);\r\n gl.uniform2f(translationLocation,translation[0], translation[1]);\r\n gl.uniform2f(scaleLocation, scale[0], scale[1]);\r\n gl.uniform1f(rotationRotation, rotation);\r\n \r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#positionBuffer);\r\n gl.bufferData(gl.ARRAY_BUFFER, vectors, gl.STATIC_DRAW);\r\n\r\n gl.enableVertexAttribArray(positionAttributeLocation);\r\n //Tell the attribute how to get data out of positionBuffer\r\n const size = 2,\r\n type = gl.FLOAT, // data is 32bit floats\r\n normalize = false,\r\n stride = 0, // move forward size * sizeof(type) each iteration to get next position\r\n offset = 0; // verticesNumber * 4; // start of beginning of the buffer\r\n gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset);\r\n\r\n //textures buffer\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#texCoordBuffer);\r\n gl.bufferData(gl.ARRAY_BUFFER, textures, gl.STATIC_DRAW);\r\n\r\n gl.enableVertexAttribArray(texCoordLocation);\r\n gl.vertexAttribPointer(texCoordLocation, 2, gl.FLOAT, false, 0, offset);\r\n\r\n let textureStorage = renderLayer._textureStorages[i];\r\n \r\n if (!textureStorage) {\r\n textureStorage = new TextureStorage(gl.createTexture(), i);\r\n renderLayer._setTextureStorage(i, textureStorage);\r\n }\r\n if (textureStorage._isTextureRecalculated === true) { \r\n this.#updateWebGlTexture(gl, textureStorage._texture, image, textureStorage._textureIndex);\r\n textureStorage._isTextureRecalculated = false;\r\n } else {\r\n this.#bindTexture(gl, textureStorage._texture, textureStorage._textureIndex);\r\n }\r\n gl.uniform1i(u_imageLocation, textureStorage._textureIndex);\r\n gl.blendFunc(gl[drawMask[0]], gl[drawMask[1]]);\r\n verticesNumber = vectors.length / 2;\r\n if (shapeMaskId) {\r\n gl.stencilFunc(gl.EQUAL, shapeMaskId, 0xFF);\r\n }\r\n isTextureBind = true;\r\n }\r\n }\r\n return Promise.resolve([verticesNumber, gl.TRIANGLES]);\r\n };\r\n\r\n _drawPolygon(renderObject, pageData) {\r\n const [ xOffset, yOffset ] = renderObject.isOffsetTurnedOff === true ? [0,0] : pageData.worldOffset,\r\n x = renderObject.x - xOffset,\r\n y = renderObject.y - yOffset,\r\n rotation = renderObject.rotation || 0,\r\n vertices = renderObject.vertices,\r\n color = this.#gameOptions.debug.boundaries.boundariesColor;\r\n const program = this.getProgram(CONST.WEBGL.DRAW_PROGRAMS.PRIMITIVES);\r\n const { u_translation: translationLocation,\r\n u_rotation: rotationRotation,\r\n u_scale: scaleLocation,\r\n u_resolution: resolutionUniformLocation,\r\n u_color: colorUniformLocation,\r\n a_position: positionAttributeLocation,\r\n u_fade_max: fadeMaxLocation,\r\n u_fade_min: fadeMinLocation\r\n } = this.getProgramVarLocations(CONST.WEBGL.DRAW_PROGRAMS.PRIMITIVES),\r\n gl = this.#gl;\r\n\r\n let verticesNumber = 0;\r\n gl.useProgram(program);\r\n // set the resolution\r\n gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);\r\n\r\n gl.uniform2f(translationLocation, x, y);\r\n gl.uniform2f(scaleLocation, 1, 1);\r\n gl.uniform1f(rotationRotation, rotation);\r\n gl.uniform1f(fadeMinLocation, 0);\r\n\r\n gl.enableVertexAttribArray(positionAttributeLocation);\r\n\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#positionBuffer);\r\n\r\n const triangles = this.#triangulatePolygon(vertices);\r\n \r\n const polygonVerticesNum = triangles.length;\r\n if (polygonVerticesNum % 3 !== 0) {\r\n Warning(WARNING_CODES.POLYGON_VERTICES_NOT_CORRECT, \"polygon boundaries vertices are not correct, skip drawing\");\r\n return;\r\n }\r\n this.#bindPolygon(triangles);\r\n verticesNumber += polygonVerticesNum / 2;\r\n //Tell the attribute how to get data out of positionBuffer\r\n const size = 2,\r\n type = gl.FLOAT, // data is 32bit floats\r\n normalize = false,\r\n stride = 0, // move forward size * sizeof(type) each iteration to get next position\r\n offset = 0; // start of beginning of the buffer\r\n gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset);\r\n\r\n const colorArray = this.#rgbaToArray(color);\r\n gl.uniform4f(colorUniformLocation, colorArray[0]/255, colorArray[1]/255, colorArray[2]/255, colorArray[3]);\r\n\r\n this._render(verticesNumber, gl.TRIANGLES);\r\n }\r\n\r\n _bindLine = (renderObject, gl, pageData, program, vars) => {\r\n const [ xOffset, yOffset ] = renderObject.isOffsetTurnedOff === true ? [0,0] : pageData.worldOffset,\r\n x = renderObject.x - xOffset,\r\n y = renderObject.y - yOffset,\r\n scale = [1, 1],\r\n rotation = renderObject.rotation,\r\n { \r\n u_translation: translationLocation,\r\n u_rotation: rotationRotation,\r\n u_scale: scaleLocation,\r\n u_resolution: resolutionUniformLocation,\r\n u_color: colorUniformLocation,\r\n a_position: positionAttributeLocation,\r\n u_fade_max: fadeMaxLocation,\r\n u_fade_min: fadeMinLocation\r\n } = vars,\r\n coords = renderObject.vertices,\r\n fillStyle = renderObject.bgColor,\r\n fade_min = renderObject.fade_min,\r\n fadeLen = renderObject.radius,\r\n lineWidth = this.#gameOptions.debug.boundaries.boundariesWidth;\r\n let verticesNumber = 0;\r\n\r\n gl.useProgram(program);\r\n // set the resolution\r\n gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);\r\n\r\n gl.uniform2f(translationLocation, x, y);\r\n gl.uniform2f(scaleLocation, 1, 1);\r\n gl.uniform1f(rotationRotation, rotation);\r\n gl.uniform1f(fadeMinLocation, 0);\r\n\r\n gl.enableVertexAttribArray(positionAttributeLocation);\r\n\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#positionBuffer);\r\n\r\n gl.bufferData(\r\n gl.ARRAY_BUFFER, \r\n new Float32Array(coords),\r\n gl.STATIC_DRAW);\r\n\r\n verticesNumber += coords.length / 2;\r\n //Tell the attribute how to get data out of positionBuffer\r\n const size = 2,\r\n type = gl.FLOAT, // data is 32bit floats\r\n normalize = false,\r\n stride = 0, // move forward size * sizeof(type) each iteration to get next position\r\n offset = 0; // start of beginning of the buffer\r\n gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset);\r\n\r\n const colorArray = this.#rgbaToArray(fillStyle);\r\n gl.uniform4f(colorUniformLocation, colorArray[0]/255, colorArray[1]/255, colorArray[2]/255, colorArray[3]);\r\n \r\n gl.lineWidth(lineWidth);\r\n\r\n return Promise.resolve([0, gl.LINES]);\r\n };\r\n \r\n _drawLines(linesArray, color, lineWidth = 1, rotation = 0, translation = [0, 0]) {\r\n const program = this.getProgram(CONST.WEBGL.DRAW_PROGRAMS.PRIMITIVES);\r\n const { u_translation: translationLocation,\r\n u_rotation: rotationRotation,\r\n u_scale: scaleLocation,\r\n u_resolution: resolutionUniformLocation,\r\n u_color: colorUniformLocation,\r\n a_position: positionAttributeLocation,\r\n u_fade_max: fadeMaxLocation,\r\n u_fade_min: fadeMinLocation\r\n } = this.getProgramVarLocations(CONST.WEBGL.DRAW_PROGRAMS.PRIMITIVES),\r\n gl = this.#gl;\r\n\r\n let verticesNumber = 0;\r\n gl.useProgram(program);\r\n // set the resolution\r\n gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);\r\n\r\n gl.uniform2f(translationLocation, translation[0], translation[1]);\r\n gl.uniform2f(scaleLocation, 1, 1);\r\n gl.uniform1f(rotationRotation, rotation);\r\n gl.uniform1f(fadeMinLocation, 0);\r\n\r\n gl.enableVertexAttribArray(positionAttributeLocation);\r\n\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.#positionBuffer);\r\n\r\n gl.bufferData(\r\n gl.ARRAY_BUFFER, \r\n new Float32Array(linesArray),\r\n gl.STATIC_DRAW);\r\n\r\n verticesNumber += linesArray.length / 2;\r\n //Tell the attribute how to get data out of positionBuffer\r\n const size = 2,\r\n type = gl.FLOAT, // data is 32bit floats\r\n normalize = false,\r\n stride = 0, // move forward size * sizeof(type) each iteration to get next position\r\n offset = 0; // start of beginning of the buffer\r\n gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset);\r\n\r\n const colorArray = this.#rgbaToArray(color);\r\n gl.uniform4f(colorUniformLocation, colorArray[0]/255, colorArray[1]/255, colorArray[2]/255, colorArray[3]);\r\n \r\n gl.lineWidth(lineWidth);\r\n \r\n this._render(verticesNumber, gl.LINES);\r\n }\r\n\r\n /**\r\n * \r\n * @param {DrawTiledLayer} renderLayer \r\n * @param {GameStageData} pageData\r\n * @returns {Promise>}\r\n */\r\n #prepareRenderLayer(renderLayer, pageData) {\r\n const INDEX_TOP_LINE = 0,\r\n INDEX_RIGHT_LINE = 1,\r\n INDEX_BOTTOM_LINE = 2,\r\n INDEX_LEFT_LINE = 3;\r\n\r\n const INDEX_X1 = 0,\r\n INDEX_Y1 = 1,\r\n INDEX_X2 = 2,\r\n INDEX_Y2 = 3;\r\n return new Promise((resolve, reject) => {\r\n const tilemap = renderLayer.tilemap,\r\n tilesets = renderLayer.tilesets,\r\n tilesetImages = renderLayer.tilesetImages,\r\n layerData = renderLayer.layerData,\r\n { tileheight:dtheight, tilewidth:dtwidth } = tilemap,\r\n tilewidth = dtwidth,\r\n tileheight = dtheight,\r\n [ settingsWorldWidth, settingsWorldHeight ] = pageData.worldDimensions,\r\n [ canvasW, canvasH ] = pageData.canvasDimensions,\r\n [ xOffset, yOffset ] = renderLayer.isOffsetTurnedOff === true ? [0,0] : pageData.worldOffset,\r\n boundariesCalculations = this.#gameOptions.render.boundaries.realtimeCalculations,\r\n setBoundaries = renderLayer.setBoundaries;\r\n \r\n let boundariesRowsIndexes = new Map(),\r\n boundaries = [],\r\n ellipseBoundaries = [],\r\n pointBoundaries = [],\r\n tileImagesData = [];\r\n\r\n if (!layerData) {\r\n Warning(WARNING_CODES.NOT_FOUND, \"check tilemap and layers name\");\r\n reject();\r\n }\r\n \r\n for (let i = 0; i < tilesets.length; i++) {\r\n const tilesetData = tilesets[i].data,\r\n firstgid = tilesets[i].firstgid,\r\n nextTileset = tilesets[i + 1],\r\n nextgid = nextTileset ? nextTileset.firstgid : 1_000_000_000, // a workaround to avoid multiple conditions\r\n tilesetwidth = tilesetData.tilewidth,\r\n tilesetheight = tilesetData.tileheight,\r\n atlasImage = tilesetImages[i],\r\n //atlasWidth = atlasImage.width,\r\n //atlasHeight = atlasImage.height,\r\n atlasWidth = tilesetData.imagewidth,\r\n atlasHeight = tilesetData.imageheight,\r\n //atlasRows = atlasHeight / tileheight,\r\n atlasColumns = tilesetData.columns,\r\n layerCols = layerData.width,\r\n layerRows = layerData.height,\r\n worldW = tilewidth * layerCols,\r\n worldH = tileheight * layerRows,\r\n moduloTop = yOffset % tileheight,\r\n moduleLeft = xOffset % tilewidth,\r\n skipRowsTop = yOffset !== 0 ? Math.floor(yOffset / tileheight) : 0,\r\n skipColsLeft = xOffset !== 0 ? Math.floor(xOffset / tilewidth) : 0,\r\n // sometimes canvasW/H may be bigger than world itself\r\n screenRows = worldH > canvasH ? Math.ceil(canvasH / tileheight) + 1 : layerRows,\r\n screenCols = worldW > canvasW ? Math.ceil(canvasW / tilewidth) + 1 : layerCols,\r\n skipColsRight = layerCols - screenCols - skipColsLeft,\r\n cellSpacing = tilesetData.spacing,\r\n cellMargin = tilesetData.margin,\r\n\r\n hasAnimations = tilesetData._hasAnimations,\r\n\r\n verticesBufferData = [],\r\n texturesBufferData = [],\r\n \r\n // additional property which is set in DrawTiledLayer\r\n hasBoundaries = tilesetData._hasBoundaries,\r\n tilesetBoundaries = tilesetData._boundaries; // Map\r\n \r\n if (worldW !== settingsWorldWidth || worldH !== settingsWorldHeight) {\r\n Warning(WARNING_CODES.UNEXPECTED_WORLD_SIZE, \" World size from tilemap is different than settings one, fixing...\");\r\n pageData._setWorldDimensions(worldW, worldH);\r\n }\r\n if (setBoundaries) {\r\n // boundaries cleanups every draw cycles, we need to set world boundaries again\r\n if (this.#gameOptions.render.boundaries.mapBoundariesEnabled) {\r\n pageData._setMapBoundaries();\r\n }\r\n }\r\n\r\n let mapIndex = skipRowsTop * layerCols;\r\n for (let row = 0; row < screenRows; row++) {\r\n mapIndex += skipColsLeft;\r\n let currentRowIndexes = new Map();\r\n for (let col = 0; col < screenCols; col++) {\r\n let tile = layerData.data[mapIndex];\r\n\r\n if ((tile >= firstgid) && (tile < nextgid)) {\r\n const mapPosX = col * dtwidth - moduleLeft,\r\n mapPosY = row * dtheight - moduloTop;\r\n\r\n // actual tile index\r\n tile -= firstgid;\r\n // switch if animations are set\r\n if (hasAnimations) {\r\n const activeTile = tilesetData._animations.get(tile);\r\n if (typeof activeTile !== \"undefined\") {\r\n tile = activeTile;\r\n } \r\n }\r\n\r\n // calculate map position and atlas position\r\n const colNum = tile % atlasColumns,\r\n rowNum = Math.floor(tile / atlasColumns),\r\n atlasPosX = colNum * tilesetwidth + (colNum * cellSpacing),\r\n atlasPosY = rowNum * tilesetheight + (rowNum * cellSpacing),\r\n vecX1 = mapPosX,\r\n vecY1 = mapPosY,\r\n vecX2 = mapPosX + tilesetwidth,\r\n vecY2 = mapPosY + tilesetheight,\r\n texX1 = (1 / atlasWidth) * atlasPosX,\r\n texY1 = (1 / atlasHeight) * atlasPosY,\r\n texX2 = texX1 + (1 / atlasWidth * tilesetwidth),\r\n texY2 = texY1 + (1 / atlasHeight * tilesetheight);\r\n verticesBufferData.push(\r\n vecX1, vecY1,\r\n vecX2, vecY1,\r\n vecX1, vecY2,\r\n vecX1, vecY2,\r\n vecX2, vecY1,\r\n vecX2, vecY2);\r\n texturesBufferData.push(\r\n texX1, texY1,\r\n texX2, texY1,\r\n texX1, texY2,\r\n texX1, texY2,\r\n texX2, texY1,\r\n texX2, texY2\r\n );\r\n if (setBoundaries) {\r\n // if boundary is set in tilesetData\r\n let isBoundaryPreset = false;\r\n if (hasBoundaries && tilesetBoundaries.size > 0) {\r\n const tilesetBoundary = tilesetBoundaries.get(tile);\r\n if (tilesetBoundary) {\r\n isBoundaryPreset = true;\r\n const objectGroup = tilesetBoundary,\r\n objects = objectGroup.objects;\r\n \r\n objects.forEach((object) => {\r\n const baseX = mapPosX + object.x, \r\n baseY = mapPosY + object.y,\r\n rotation = object.rotation;\r\n if (rotation !== 0) {\r\n Warning(\"tilesetData.tiles.rotation property is not supported yet\");\r\n }\r\n if (object.polygon) {\r\n object.polygon.forEach(\r\n (point, idx) => {\r\n const next = object.polygon[idx + 1];\r\n if (next) {\r\n boundaries.push([point.x + baseX, point.y + baseY, next.x + baseX, next.y + baseY]);\r\n } else {\r\n // last point -> link to the first\r\n const first = object.polygon[0];\r\n boundaries.push([point.x + baseX, point.y + baseY, first.x + baseX, first.y + baseY]);\r\n }\r\n });\r\n } else if (object.point) {\r\n // x/y coordinate\r\n pointBoundaries.push([baseX, baseY]);\r\n } else if (object.ellipse) {\r\n const radX = object.width / 2,\r\n radY = object.height / 2;\r\n ellipseBoundaries.push([baseX + radX, baseY + radY, radX, radY]);\r\n } else {\r\n // object is rect\r\n const width = object.width,\r\n height = object.height,\r\n x2 = width + baseX,\r\n y2 = height + baseY;\r\n boundaries.push([baseX, baseY, x2, baseY]);\r\n boundaries.push([x2, baseY, x2, y2]);\r\n boundaries.push([x2, y2, baseX, y2]);\r\n boundaries.push([baseX, y2, baseX, baseY]);\r\n }\r\n });\r\n }\r\n\r\n // extract rect boundary for the whole tile\r\n }\r\n if (isBoundaryPreset === false) {\r\n\r\n let rightLine = [ mapPosX + tilesetwidth, mapPosY, mapPosX + tilesetwidth, mapPosY + tilesetheight ],\r\n bottomLine = [ mapPosX + tilesetwidth, mapPosY + tilesetheight, mapPosX, mapPosY + tilesetheight ],\r\n topLine = [ mapPosX, mapPosY, mapPosX + tilesetwidth, mapPosY],\r\n leftLine = [ mapPosX, mapPosY + tilesetheight, mapPosX, mapPosY ],\r\n currentAddedCellIndexes = [null, null, null, null];\r\n \r\n const topRow = row !== 0 ? boundariesRowsIndexes.get(row - 1) : undefined;\r\n if (topRow ) {\r\n const topCellIndexes = topRow.get(col);\r\n if (topCellIndexes) {\r\n //remove double lines from top\r\n const bottomTopCellIndex = topCellIndexes[INDEX_BOTTOM_LINE],\r\n bottomTopCell = boundaries[bottomTopCellIndex];\r\n if (bottomTopCell) {\r\n const bottomTopCellX1 = bottomTopCell[INDEX_X1],\r\n bottomTopCellY1 = bottomTopCell[INDEX_Y1],\r\n bottomTopCellX2 = bottomTopCell[INDEX_X2],\r\n bottomTopCellY2 = bottomTopCell[INDEX_Y2],\r\n topX1 = topLine[INDEX_X1],\r\n topY1 = topLine[INDEX_Y1],\r\n topX2 = topLine[INDEX_X2],\r\n topY2 = topLine[INDEX_Y2];\r\n \r\n if (topX1 === bottomTopCellX2 && topY1 === bottomTopCellY2 &&\r\n topX2 === bottomTopCellX1 && topY2 === bottomTopCellY1) {\r\n boundaries[bottomTopCellIndex] = undefined;\r\n topLine = undefined;\r\n }\r\n }\r\n\r\n // merge line from top right\r\n const rightTopCellIndex = topCellIndexes[INDEX_RIGHT_LINE],\r\n rightTopCell = boundaries[rightTopCellIndex];\r\n if (rightTopCell) {\r\n const rightTopCellX1 = rightTopCell[INDEX_X1],\r\n rightTopCellY1 = rightTopCell[INDEX_Y1],\r\n rightTopCellX2 = rightTopCell[INDEX_X2],\r\n rightX1 = rightLine[INDEX_X1],\r\n rightX2 = rightLine[INDEX_X2];\r\n if (rightTopCellX1 === rightX2 && rightTopCellX2 === rightX1) {\r\n boundaries[rightTopCellIndex] = undefined;\r\n rightLine[INDEX_X1] = rightTopCellX1;\r\n rightLine[INDEX_Y1] = rightTopCellY1;\r\n }\r\n }\r\n // merge line from top left\r\n const leftTopCellIndex = topCellIndexes[INDEX_LEFT_LINE],\r\n leftTopCell = boundaries[leftTopCellIndex];\r\n if (leftTopCell) {\r\n const leftTopCellX1 = leftTopCell[INDEX_X1],\r\n leftTopCellX2 = leftTopCell[INDEX_X2],\r\n leftTopCellY2 = leftTopCell[INDEX_Y2],\r\n leftX1 = leftLine[INDEX_X1],\r\n leftX2 = leftLine[INDEX_X2];\r\n if (leftTopCellX1 === leftX2 && leftTopCellX2 === leftX1) {\r\n boundaries[leftTopCellIndex] = undefined;\r\n leftLine[INDEX_X2] = leftTopCellX2;\r\n leftLine[INDEX_Y2] = leftTopCellY2;\r\n }\r\n }\r\n }\r\n }\r\n const leftCellIndexes = col !== 0 ? currentRowIndexes.get(col - 1) : undefined;\r\n if (leftCellIndexes) {\r\n\r\n //remove double lines from left\r\n const rightLeftCellIndex = leftCellIndexes[INDEX_RIGHT_LINE],\r\n rightLeftCell = boundaries[rightLeftCellIndex],\r\n rightLeftCellX1 = rightLeftCell[INDEX_X1],\r\n rightLeftCellY1 = rightLeftCell[INDEX_Y1],\r\n rightLeftCellX2 = rightLeftCell[INDEX_X2],\r\n rightLeftCellY2 = rightLeftCell[INDEX_Y2],\r\n leftX1 = leftLine[INDEX_X1],\r\n leftY1 = leftLine[INDEX_Y1],\r\n leftX2 = leftLine[INDEX_X2],\r\n leftY2 = leftLine[INDEX_Y2];\r\n\r\n if (leftX1 === rightLeftCellX2 && leftY1 === rightLeftCellY2 &&\r\n leftX2 === rightLeftCellX1 && leftY2 === rightLeftCellY1) {\r\n boundaries[rightLeftCellIndex] = undefined;\r\n leftLine = undefined;\r\n }\r\n\r\n //merge long lines from left top\r\n const topLeftCellIndex = leftCellIndexes[INDEX_TOP_LINE],\r\n topLeftCell = boundaries[topLeftCellIndex];\r\n if (topLeftCell && topLine) {\r\n const topLeftCellX1 = topLeftCell[INDEX_X1],\r\n topLeftCellY1 = topLeftCell[INDEX_Y1],\r\n topLeftCellY2 = topLeftCell[INDEX_Y2],\r\n topY1 = topLine[INDEX_Y1],\r\n topY2 = topLine[INDEX_Y2];\r\n if (topLeftCellY1 === topY2 && topLeftCellY2 === topY1 ) {\r\n boundaries[topLeftCellIndex] = undefined;\r\n topLine[INDEX_X1] = topLeftCellX1;\r\n topLine[INDEX_Y1] = topLeftCellY1;\r\n }\r\n }\r\n\r\n // merge long lines from left bottom\r\n const bottomLeftCellIndex = leftCellIndexes[INDEX_BOTTOM_LINE],\r\n bottomLeftCell = boundaries[bottomLeftCellIndex];\r\n if (bottomLeftCell) {\r\n const bottomLeftCellY1 = bottomLeftCell[INDEX_Y1],\r\n bottomLeftCellX2 = bottomLeftCell[INDEX_X2],\r\n bottomLeftCellY2 = bottomLeftCell[INDEX_Y2],\r\n bottomY1 = bottomLine[INDEX_Y1],\r\n bottomY2 = bottomLine[INDEX_Y2];\r\n if (bottomLeftCellY1 === bottomY2 && bottomLeftCellY2 === bottomY1 ) {\r\n boundaries[bottomLeftCellIndex] = undefined;\r\n //opposite direction\r\n bottomLine[INDEX_X2] = bottomLeftCellX2;\r\n bottomLine[INDEX_Y2] = bottomLeftCellY2;\r\n }\r\n }\r\n\r\n }\r\n\r\n if (topLine) {\r\n boundaries.push(topLine);\r\n currentAddedCellIndexes[INDEX_TOP_LINE] = boundaries.length - 1;\r\n }\r\n boundaries.push(rightLine);\r\n currentAddedCellIndexes[INDEX_RIGHT_LINE] = boundaries.length - 1;\r\n boundaries.push(bottomLine);\r\n currentAddedCellIndexes[INDEX_BOTTOM_LINE] = boundaries.length - 1;\r\n if (leftLine) {\r\n boundaries.push(leftLine);\r\n currentAddedCellIndexes[INDEX_LEFT_LINE] = boundaries.length - 1;\r\n }\r\n //save values indexes cols info\r\n currentRowIndexes.set(col, currentAddedCellIndexes);\r\n }\r\n }\r\n }\r\n mapIndex++;\r\n }\r\n if (currentRowIndexes.size > 0) {\r\n //save values indexes rows info\r\n boundariesRowsIndexes.set(row, currentRowIndexes);\r\n }\r\n mapIndex += skipColsRight;\r\n }\r\n //this.#bindTileImages(verticesBufferData, texturesBufferData, atlasImage, tilesetData.name, renderLayer._maskId);\r\n tileImagesData.push([new Float32Array(verticesBufferData), new Float32Array(texturesBufferData), tilesetData.name, atlasImage]);\r\n }\r\n \r\n if (setBoundaries) {\r\n // filter undefined value\r\n const filtered = boundaries.filter(array => array);\r\n pageData._addBoundariesArray(filtered);\r\n if (ellipseBoundaries.length > 0) {\r\n pageData._addEllipseBoundaries(ellipseBoundaries);\r\n }\r\n if (pointBoundaries.length > 0) {\r\n pageData._addPointBoundaries(pointBoundaries);\r\n }\r\n }\r\n resolve(tileImagesData);\r\n });\r\n }\r\n\r\n #prepareRenderLayerOld(renderLayer, pageData) {\r\n return new Promise((resolve, reject) => {\r\n const tilemap = renderLayer.tilemap,\r\n tilesets = renderLayer.tilesets,\r\n tilesetImages = renderLayer.tilesetImages,\r\n layerData = renderLayer.layerData,\r\n { tileheight:dtheight, tilewidth:dtwidth } = tilemap,\r\n tilewidth = dtwidth,\r\n tileheight = dtheight,\r\n setBoundaries = renderLayer.setBoundaries,\r\n [ settingsWorldWidth, settingsWorldHeight ] = pageData.worldDimensions,\r\n [ canvasW, canvasH ] = pageData.canvasDimensions,\r\n [ xOffset, yOffset ] = renderLayer.isOffsetTurnedOff === true ? [0,0] : pageData.worldOffset;\r\n \r\n let tileImagesData = [];\r\n if (!layerData) {\r\n Warning(WARNING_CODES.NOT_FOUND, \"check tilemap and layers name\");\r\n reject();\r\n }\r\n for (let i = 0; i <= tilesets.length - 1; i++) {\r\n const tilesetData = tilesets[i].data,\r\n firstgid = tilesets[i].firstgid,\r\n nextTileset = tilesets[i + 1],\r\n nextgid = nextTileset ? nextTileset.firstgid : 1_000_000_000, // a workaround to avoid multiple conditions\r\n //tilesetImages = this.iLoader.getTilesetImageArray(tilesetData.name),\r\n tilesetwidth = tilesetData.tilewidth,\r\n tilesetheight = tilesetData.tileheight,\r\n //atlasRows = tilesetData.imageheight / tileheight,\r\n //atlasColumns = tilesetData.imagewidth / tilewidth,\r\n atlasColumns = tilesetData.columns,\r\n layerCols = layerData.width,\r\n layerRows = layerData.height,\r\n worldW = tilewidth * layerCols,\r\n worldH = tileheight * layerRows,\r\n visibleCols = Math.ceil(canvasW / tilewidth),\r\n visibleRows = Math.ceil(canvasH / tileheight),\r\n atlasImage = tilesetImages[i],\r\n atlasWidth = atlasImage.width,\r\n atlasHeight = atlasImage.height,\r\n cellSpacing = tilesetData.spacing,\r\n cellMargin = tilesetData.margin;\r\n \r\n let mapIndex = 0,\r\n verticesBufferData = [],\r\n texturesBufferData = [];\r\n\r\n if (worldW !== settingsWorldWidth || worldH !== settingsWorldHeight) {\r\n Warning(WARNING_CODES.UNEXPECTED_WORLD_SIZE, \" World size from tilemap is different than settings one, fixing...\");\r\n pageData._setWorldDimensions(worldW, worldH);\r\n }\r\n for (let row = 0; row < layerRows; row++) {\r\n for (let col = 0; col < layerCols; col++) {\r\n let tile = layerData.data[mapIndex];\r\n \r\n if (tile >= firstgid && (tile < nextgid)) {\r\n\r\n tile -= firstgid;\r\n const colNum = tile % atlasColumns,\r\n rowNum = Math.floor(tile / atlasColumns),\r\n atlasPosX = colNum * tilesetwidth + (colNum * cellSpacing),\r\n atlasPosY = rowNum * tilesetheight + (rowNum * cellSpacing),\r\n vecX1 = col * dtwidth - xOffset,\r\n vecY1 = row * dtheight - yOffset,\r\n vecX2 = vecX1 + tilesetwidth,\r\n vecY2 = vecY1 + tilesetheight,\r\n texX1 = 1 / atlasWidth * atlasPosX,\r\n texY1 = 1 / atlasHeight * atlasPosY,\r\n texX2 = texX1 + (1 / atlasWidth * tilesetwidth),\r\n texY2 = texY1 + (1 / atlasHeight * tilesetheight);\r\n \r\n verticesBufferData.push(\r\n vecX1, vecY1,\r\n vecX2, vecY1,\r\n vecX1, vecY2,\r\n vecX1, vecY2,\r\n vecX2, vecY1,\r\n vecX2, vecY2);\r\n texturesBufferData.push(\r\n texX1, texY1,\r\n texX2, texY1,\r\n texX1, texY2,\r\n texX1, texY2,\r\n texX2, texY1,\r\n texX2, texY2\r\n );\r\n\r\n }\r\n mapIndex++;\r\n }\r\n }\r\n const v = new Float32Array(verticesBufferData);\r\n const t = new Float32Array(texturesBufferData);\r\n tileImagesData.push([v, t, tilesetData.name, atlasImage]);\r\n }\r\n resolve(tileImagesData);\r\n });\r\n }\r\n\r\n /**\r\n * \r\n * @param {DrawTiledLayer} renderLayer \r\n * @param {GameStageData} pageData\r\n * @returns {Promise}\r\n */\r\n #prepareRenderLayerWM = (renderLayer, pageData) => {\r\n return new Promise((resolve, reject) => {\r\n const tilemap = renderLayer.tilemap,\r\n tilesets = tilemap.tilesets,\r\n tilesetImages = renderLayer.tilesetImages,\r\n layerData = renderLayer.layerData,\r\n { tileheight:dtheight, tilewidth:dtwidth } = tilemap,\r\n tilewidth = dtwidth,\r\n tileheight = dtheight,\r\n offsetDataItemsFullNum = layerData.data.length,\r\n offsetDataItemsFilteredNum = layerData.data.filter((item) => item !== 0).length,\r\n setBoundaries = false, //renderLayer.setBoundaries,\r\n [ settingsWorldWidth, settingsWorldHeight ] = pageData.worldDimensions,\r\n //[ canvasW, canvasH ] = this.stageData.drawDimensions,\r\n [ xOffset, yOffset ] = renderLayer.isOffsetTurnedOff === true ? [0,0] : pageData.worldOffset;\r\n const tileImagesData = [];\r\n // clear data\r\n // this.layerDataFloat32.fill(0);\r\n // set data for webgl processing\r\n this.layerDataFloat32.set(layerData.data);\r\n if (!layerData) {\r\n Warning(WARNING_CODES.NOT_FOUND, \"check tilemap and layers name\");\r\n reject();\r\n }\r\n \r\n for (let i = 0; i < tilesets.length; i++) {\r\n const tilesetData = tilesets[i].data,\r\n firstgid = tilesets[i].firstgid,\r\n nextTileset = tilesets[i + 1],\r\n nextgid = nextTileset ? nextTileset.firstgid : 1_000_000_000, // a workaround to avoid multiple conditions\r\n //tilesetImages = this.iLoader.getTilesetImageArray(tilesetData.name),\r\n tilesetwidth = tilesetData.tilewidth,\r\n tilesetheight = tilesetData.tileheight,\r\n //atlasRows = tilesetData.imageheight / tileheight,\r\n atlasColumns = tilesetData.columns,\r\n layerCols = layerData.width,\r\n layerRows = layerData.height,\r\n //visibleCols = Math.ceil(canvasW / tilewidth),\r\n //visibleRows = Math.ceil(canvasH / tileheight),\r\n //offsetCols = layerCols - visibleCols,\r\n //offsetRows = layerRows - visibleRows,\r\n worldW = tilewidth * layerCols,\r\n worldH = tileheight * layerRows,\r\n atlasImage = tilesetImages[i],\r\n atlasWidth = atlasImage.width,\r\n atlasHeight = atlasImage.height,\r\n items = layerRows * layerCols,\r\n dataCellSizeBytes = 4,\r\n vectorCoordsItemsNum = 12,\r\n texturesCoordsItemsNum = 12,\r\n vectorDataItemsNum = offsetDataItemsFilteredNum * vectorCoordsItemsNum,\r\n texturesDataItemsNum = offsetDataItemsFilteredNum * texturesCoordsItemsNum,\r\n cellSpacing = tilesetData.spacing,\r\n cellMargin = tilesetData.margin;\r\n \r\n if (worldW !== settingsWorldWidth || worldH !== settingsWorldHeight) {\r\n Warning(WARNING_CODES.UNEXPECTED_WORLD_SIZE, \" World size from tilemap is different than settings one, fixing...\");\r\n pageData._setWorldDimensions(worldW, worldH);\r\n }\r\n\r\n //if (this.canvas.width !== worldW || this.canvas.height !== worldH) {\r\n // this._setCanvasSize(worldW, worldH);\r\n //}\r\n // boundaries cleanups every draw cycles, we need to set world boundaries again\r\n if (this.#gameOptions.render.boundaries.mapBoundariesEnabled) {\r\n pageData._setMapBoundaries();\r\n }\r\n const itemsProcessed = this.calculateBufferData(dataCellSizeBytes, offsetDataItemsFullNum, vectorDataItemsNum, layerRows, layerCols, dtwidth, dtheight, tilesetwidth, tilesetheight, atlasColumns, atlasWidth, atlasHeight, xOffset, yOffset, firstgid, nextgid, cellSpacing, setBoundaries);\r\n \r\n const verticesBufferData = itemsProcessed > 0 ? this.layerDataFloat32.slice(offsetDataItemsFullNum, vectorDataItemsNum + offsetDataItemsFullNum) : [],\r\n texturesBufferData = itemsProcessed > 0 ? this.layerDataFloat32.slice(vectorDataItemsNum + offsetDataItemsFullNum, vectorDataItemsNum + texturesDataItemsNum + offsetDataItemsFullNum) : [];\r\n \r\n tileImagesData.push([verticesBufferData, texturesBufferData, tilesetData.name, atlasImage]);\r\n if (setBoundaries) {\r\n pageData._mergeBoundaries();\r\n renderLayer.setBoundaries = false;\r\n }\r\n }\r\n resolve(tileImagesData);\r\n });\r\n };\r\n\r\n /**\r\n * \r\n * @param {string} rgbaColor \r\n * @returns {number[]}\r\n */\r\n #rgbaToArray (rgbaColor) {\r\n return rgbaColor.replace(\"rgba(\", \"\").replace(\")\", \"\").split(\",\").map((/** @param {string} */item) => Number(item.trim()));\r\n }\r\n\r\n #triangulatePolygon(vertices) {\r\n return this.#triangulate(vertices);\r\n }\r\n\r\n /**\r\n * \r\n * @param {Array>} polygonVertices \r\n * @param {Array} triangulatedPolygon \r\n * @returns {Array}\r\n */\r\n #triangulate (polygonVertices, triangulatedPolygon = []) {\r\n const len = polygonVertices.length,\r\n vectorsCS = (a, b, c) => crossProduct({x:c[0] - a[0], y: c[1] - a[1]}, {x:b[0] - a[0], y: b[1] - a[1]});\r\n\r\n if (len <= 3) {\r\n polygonVertices.forEach(vertex => {\r\n triangulatedPolygon.push(vertex[0]);\r\n triangulatedPolygon.push(vertex[1]);\r\n });\r\n return triangulatedPolygon;\r\n }\r\n const verticesSortedByY = [...polygonVertices].sort((curr, next) => next[1] - curr[1]);\r\n const topVertexIndex = polygonVertices.indexOf(verticesSortedByY[0]),\r\n startVertexIndex = topVertexIndex !== len - 1 ? topVertexIndex + 1 : 0;\r\n \r\n let processedVertices = polygonVertices,\r\n processedVerticesLen = processedVertices.length,\r\n skipCount = 0,\r\n i = startVertexIndex;\r\n \r\n while(processedVertices.length > 2) {\r\n // if overflowed, start from beginning\r\n const currLen = processedVertices.length;\r\n if (i >= currLen) {\r\n i -= currLen;\r\n }\r\n \r\n const prevVertex = i === 0 ? processedVertices[currLen - 1] : processedVertices[i - 1],\r\n currentVertex = processedVertices[i],\r\n nextVertex = currLen === i + 1 ? processedVertices[0] : processedVertices[i + 1];\r\n \r\n \r\n const cs = vectorsCS(prevVertex, currentVertex, nextVertex);\r\n \r\n if (cs < 0) {\r\n triangulatedPolygon.push(prevVertex[0]);\r\n triangulatedPolygon.push(prevVertex[1]);\r\n triangulatedPolygon.push(currentVertex[0]);\r\n triangulatedPolygon.push(currentVertex[1]);\r\n triangulatedPolygon.push(nextVertex[0]);\r\n triangulatedPolygon.push(nextVertex[1]);\r\n processedVertices = processedVertices.filter((val, index) => index !== i);\r\n } else {\r\n skipCount += 1;\r\n if (skipCount > processedVerticesLen) {\r\n // sometimes fails\r\n Warning(WARNING_CODES.TRIANGULATE_ISSUE, \"Can't extract all triangles vertices.\");\r\n return triangulatedPolygon;\r\n }\r\n i++;\r\n }\r\n // if (cs < 0): it's jumping over next vertex, maybe not a good solution? Moving up\r\n // i++;\r\n }\r\n \r\n return triangulatedPolygon;\r\n }\r\n\r\n #bindPolygon(vertices) {\r\n this.#gl.bufferData(\r\n this.#gl.ARRAY_BUFFER, \r\n new Float32Array(vertices),\r\n this.#gl.STATIC_DRAW);\r\n }\r\n\r\n #setSingleRectangle(width, height) {\r\n const x1 = 0,\r\n x2 = 0 + width,\r\n y1 = 0,\r\n y2 = 0 + height;\r\n this.#gl.bufferData(this.#gl.ARRAY_BUFFER, \r\n new Float32Array([\r\n x1, y1,\r\n x2, y1,\r\n x1, y2,\r\n x1, y2,\r\n x2, y1,\r\n x2, y2]), this.#gl.STATIC_DRAW);\r\n }\r\n /*------------------------------------\r\n * End of Predefined Drawing programs\r\n -------------------------------------*/\r\n\r\n /**-----------------------------------\r\n * Textures\r\n ------------------------------------*/\r\n #updateWebGlTexture(gl, texture, textureImage, textureNum = 0, useMipMaps = false) {\r\n this.#bindTexture(gl, texture, textureNum);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureImage);\r\n // LINEAR filtering is better for images and tiles, but for texts it produces a small blur\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\r\n // for textures not power of 2 (texts for example)\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, useMipMaps ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);\r\n }\r\n\r\n #updateTextWebGlTexture(gl, texture, textureImage, textureNum = 0) {\r\n this.#bindTexture(gl, texture, textureNum);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureImage);\r\n // LINEAR filtering is better for images and tiles, but for texts it produces a small blur\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n // for textures not power of 2 (texts for example)\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n }\r\n\r\n #bindTexture(gl, texture, textureNum = 0) {\r\n gl.activeTexture(gl.TEXTURE0 + textureNum);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n }\r\n\r\n #removeTexture(gl, texture) {\r\n gl.deleteTexture(texture);\r\n }\r\n /*------------------------------------\r\n * End Textures\r\n --------------------------------------*/\r\n\r\n isPowerOfTwo(value) {\r\n return (value & (value - 1)) === 0;\r\n }\r\n\r\n nextHighestPowerOfTwo(x) {\r\n --x;\r\n for (var i = 1; i < 32; i <<= 1) {\r\n x = x | x >> i;\r\n }\r\n return x + 1;\r\n }\r\n}","import { CONST } from \"./constants.js\";\n/**\n * Settings object, should be passed as a parameter to System.constructor().\n */\nexport class SystemSettings {\n /**\n * @hideconstructor\n */\n constructor(){}\n /**\n * DEBUG/PRODUCTION, for debug mode system Logger will show debug information in the console\n */\n static mode = CONST.MODE.DEBUG;\n\n static gameOptions = {\n // no other variants only WEBGL for now\n library: CONST.LIBRARY.WEBGL,\n optimization: CONST.OPTIMIZATION.NATIVE_JS.OPTIMIZED,\n optimizationWASMUrl: \"./src/wa/calculateBufferDataWat.wasm\",\n optimizationAssemblyUrl: \"/src/wa/calculateBufferDataAssembly.wasm\",\n loadingScreen: {\n backgroundColor: \"rgba(128, 128, 128, 0.6)\",\n loadingBarBg: \"rgba(128, 128, 128, 1)\",\n loadingBarProgress: \"rgba(128, 128, 128, 0.2)\",\n },\n render: {\n minCycleTime: 16.666, //ms which is ~60 FPS\n cyclesTimeCalc: {\n check: CONST.OPTIMIZATION.CYCLE_TIME_CALC.AVERAGES,\n averageFPStime: 10000\n },\n boundaries: {\n mapBoundariesEnabled: true,\n realtimeCalculations: true,\n wholeWorldPrecalculations: false\n },\n \n },\n debug: {\n checkWebGlErrors: false,\n debugMobileTouch: false,\n boundaries: {\n drawLayerBoundaries: false,\n drawObjectBoundaries: false,\n boundariesColor: \"rgba(224, 12, 21, 0.6)\",\n boundariesWidth: 2\n },\n delayBetweenObjectRender: false, // 1 sec delay for debug proposes\n }\n };\n \n\n static network = {\n // disable INetwork by default\n enabled: false,\n address: \"https://gameserver.reslc.ru:9009\",\n gatherRoomsInfoInterval: 5000\n };\n\n static canvasMaxSize = {\n width: 1800,\n height: 1800\n };\n\n static worldSize = {\n width: 960,\n height: 960\n };\n\n static defaultCanvasKey = \"default\";\n\n static customSettings = {};\n}","export const CONST = {\r\n MODE: {\r\n DEBUG: \"DEBUG\",\r\n PRODUCTION: \"PRODUCTION\"\r\n },\r\n SCREENS: {},\r\n AUDIO: {},\r\n CONNECTION_STATUS: {\r\n DISCONNECTED: \"disconnected\",\r\n CONNECTED: \"connected\",\r\n CONNECTION_LOST: \"connection lost\"\r\n },\r\n EVENTS: {\r\n SYSTEM: {\r\n START_PAGE:\"START_PAGE\",\r\n STOP_PAGE: \"STOP_PAGE\",\r\n RENDER: {\r\n START: \"start\",\r\n END: \"end\"\r\n }\r\n },\r\n GAME: {\r\n BOUNDARIES_COLLISION: \"BOUNDARIES_COLLISION\",\r\n OBJECTS_COLLISION: \"OBJECTS_COLLISION\"\r\n },\r\n WEBSOCKET: {\r\n SERVER_CLIENT: {\r\n CONNECTION_STATUS_CHANGED: \"CONNECTION_STATUS_CHANGED\",\r\n ROOMS_INFO: \"roomsInfo\",\r\n CREATED: \"created\",\r\n JOINED: \"joined\",\r\n FULL: \"full\",\r\n DISCONNECTED: \"disconnected\",\r\n SERVER_MESSAGE: \"message\",\r\n RESTARTED: \"restarted\",\r\n },\r\n CLIENT_SERVER: {\r\n ROOMS_INFO_REQUEST: \"gatherRoomsInfo\",\r\n CREATE_OR_JOIN: \"create or join\",\r\n RESTART_REQUEST: \"restart\",\r\n CLIENT_MESSAGE: \"message\"\r\n }\r\n }\r\n },\r\n WEBGL: {\r\n DRAW_PROGRAMS: {\r\n PRIMITIVES: \"drawPrimitives\",\r\n IMAGES: \"drawImages\"\r\n }\r\n },\r\n DRAW_TYPE: {\r\n RECTANGLE: \"rect\",\r\n CONUS: \"conus\",\r\n CIRCLE: \"circle\",\r\n POLYGON: \"polygon\",\r\n LINE: \"line\",\r\n TEXT: \"text\",\r\n IMAGE: \"image\"\r\n },\r\n LAYERS: {\r\n DEFAULT: \"default-view-layer\",\r\n BOUNDARIES: \"boundaries-view-layer\"\r\n },\r\n GAME_OPTIONS: {},\r\n LIBRARY: {\r\n WEBGL: \"webgl\"\r\n },\r\n OPTIMIZATION: {\r\n CYCLE_TIME_CALC: {\r\n AVERAGES: \"AVERAGES\",\r\n CURRENT: \"CURRENT\"\r\n },\r\n NATIVE_JS: {\r\n NOT_OPTIMIZED: \"NOT_OPTIMIZED\",\r\n OPTIMIZED: \"OPTIMIZED\"\r\n },\r\n WEB_ASSEMBLY: {\r\n ASSEMBLY_SCRIPT: \"ASSEMBLY_SCRIPT\",\r\n NATIVE_WAT: \"WASM\"\r\n }\r\n }\r\n};\r\n\r\nexport const ERROR_CODES = {\r\n CREATE_INSTANCE_ERROR: \"CREATE_INSTANCE_ERROR\",\r\n VIEW_NOT_EXIST: \"VIEW_NOT_EXIST\",\r\n ELEMENT_NOT_EXIST: \"ELEMENT_NOT_EXIST\",\r\n FILE_NOT_EXIST: \"FILE_NOT_EXIST\",\r\n CANT_GET_THE_IMAGE: \"CANT_GET_THE_IMAGE\",\r\n UNEXPECTED_INPUT_PARAMS: \"UNEXPECTED_INPUT_PARAMS\",\r\n UNHANDLED_EXCEPTION: \"UNHANDLED_EXCEPTION\",\r\n CANVAS_KEY_NOT_SPECIFIED: \"CANVAS_KEY_NOT_SPECIFIED\",\r\n CANVAS_WITH_KEY_NOT_EXIST: \"CANVAS_WITH_KEY_NOT_EXIST\",\r\n WRONG_TYPE_ERROR: \"WRONG_TYPE_ERROR\",\r\n UNEXPECTED_WS_MESSAGE: \"UNEXPECTED_WS_MESSAGE\",\r\n UNEXPECTED_PLAYER_ID: \"UNEXPECTED_PLAYER_ID\",\r\n UNEXPECTED_BULLET_ID: \"UNEXPECTED_BULLET_ID\",\r\n UNEXPECTED_EVENT_NAME: \"UNEXPECTED_EVENT_NAME\",\r\n WEBGL_ERROR: \"WEBGL_ERROR\",\r\n DRAW_PREPARE_ERROR: \"DRAW_PREPARE_ERROR\",\r\n UNEXPECTED_TILE_ID: \"UNEXPECTED_TILE_ID\",\r\n UNEXPECTED_TOUCH_AREA: \"UNEXPECTED TOUCH AREA\",\r\n UNEXPECTED_METHOD_TYPE: \"UNEXPECTED METHOD TYPE\"\r\n};\r\n\r\nexport const WARNING_CODES = {\r\n FILE_LOADING_ISSUE: \"FILE_LOADING_ISSUE\",\r\n ASSETS_NOT_READY: \"ASSETS_NOT_READY\",\r\n NOT_FOUND: \"NOT_FOUND\",\r\n NOT_TESTED: \"NOT_TESTED\",\r\n WORLD_DIMENSIONS_NOT_SET: \"WORLD_DIMENSIONS_NOT_SET\",\r\n INCORRECT_RENDER_TYPE: \"INCORRECT_RENDER_TYPE\",\r\n UNHANDLED_DRAW_ISSUE: \"UNHANDLED_DRAW_ISSUE\",\r\n UNEXPECTED_WORLD_SIZE: \"UNEXPECTED_WORLD_SIZE\",\r\n AUDIO_ALREADY_REGISTERED: \"AUDIO_ALREADY_REGISTERED\",\r\n AUDIO_NOT_REGISTERED: \"AUDIO_NOT_REGISTERED\",\r\n AUDIO_NOT_LOADED: \"AUDIO_NOT_LOADED\",\r\n UNKNOWN_DRAW_OBJECT: \"UNKNOWN_DRAW_OBJECT\",\r\n METHOD_NOT_IMPLEMENTED: \"METHOD_NOT_IMPLEMENTED\",\r\n POLYGON_VERTICES_NOT_CORRECT: \"POLYGON_VERTICES_NOT_CORRECT\",\r\n MODULE_ALREADY_INSTALLED: \"MODULE_ALREADY_INSTALLED\",\r\n DEPRECATED_PARAMETER: \"DEPRECATED_PARAMETER\",\r\n NEW_BEHAVIOR_INTRODUCED: \"NEW_BEHAVIOR_INTRODUCED\",\r\n TEXTURE_IMAGE_TEMP_OVERFLOW: \"TEXTURE_IMAGE_TEMP_OVERFLOW\",\r\n TRIANGULATE_ISSUE: \"TRIANGULATE_ISSUE\"\r\n};","import { GameStage } from \"../base/GameStage.js\";\n\nexport class LoadingStage extends GameStage {\n #total = 0;\n #loaded = 0;\n #barWidth = 0;\n register() {\n //this.iLoader.addImage(logoKey, \"./images/icon.png\");\n }\n\n init() {\n const [w, h] = this.stageData.canvasDimensions,\n barWidth = w/3,\n barHeight = 20;\n //this.logo = this.draw.image(w/2, h/2, 300, 200, logoKey);\n this.background = this.draw.rect(0, 0, w, h, this.systemSettings.gameOptions.loadingScreen.backgroundColor); \n this.loadingBarBg = this.draw.rect(w/2 - (barWidth/2), h/2 - (barHeight/2), barWidth, barHeight, this.systemSettings.gameOptions.loadingScreen.loadingBarBg);\n this.loadingBarProgress = this.draw.rect(w/2 - (barWidth/2), h/2 - (barHeight/2), barWidth, barHeight, this.systemSettings.gameOptions.loadingScreen.loadingBarProgress);\n this.text = this.draw.text(w/2 - 20, h/2 - 2 * barHeight, \"JsGE\", \"24px sans-serif\", \"black\");\n this.#barWidth = barWidth;\n }\n\n _progress = (loaded) => {\n const widthPart = this.#barWidth / this.#total;\n\n this.#loaded = loaded;\n const newWidth = widthPart * this.#loaded;\n // sometimes additional items are added to queue in load process\n // to avoid bar width overflow additional check added below:\n const applyWidth = loaded > this.#total ? this.#barWidth : newWidth;\n\n this.loadingBarProgress.width = applyWidth;\n };\n\n start(options) {\n this.#total = options.total;\n }\n\n // a workaround for checking upload progress before render\n //get iLoader() {\n // return ({filesWaitingForUpload:0});\n //}\n} ","import { System } from \"./base/System.js\";\nimport { GameStage } from \"./base/GameStage.js\";\nimport { DrawImageObject } from \"./base/DrawImageObject.js\";\nimport { ISystemAudio } from \"./base/ISystemAudio.js\";\nimport * as Primitives from \"./base/Primitives.js\";\nimport { SystemSettings } from \"./configs.js\";\nimport { CONST } from \"./constants.js\";\nimport * as utils from \"./utils.js\";\n\nexport { System, SystemSettings, CONST, GameStage, DrawImageObject, ISystemAudio, Primitives, utils };","import { Vector } from \"./base/Primitives.js\";\r\n\r\nfunction isMobile() {\r\n return /Android|webOS|iPhone|iPad|iPod|Opera Mini/i.test(navigator.userAgent) ;\r\n}\r\n\r\nfunction isSafari() {\r\n return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\r\n}\r\n\r\nfunction pointToCircleDistance(x, y, circle) {\r\n const pointToCircleCenterDistance = new Vector(x, y, circle.x, circle.y).length;\r\n return pointToCircleCenterDistance - circle.r;\r\n}\r\n\r\nfunction countClosestTraversal(line, sight) {\r\n const x1 = sight.x1,\r\n y1 = sight.y1,\r\n x2 = sight.x2,\r\n y2 = sight.y2;\r\n const x3 = line.x1,\r\n y3 = line.y1,\r\n x4 = line.x2,\r\n y4 = line.y2;\r\n\r\n const r_px = x1,\r\n r_py = y1,\r\n r_dx = x2-x1,\r\n r_dy = y2-y1;\r\n\r\n const s_px = x3,\r\n s_py = y3,\r\n s_dx = x4-x3,\r\n s_dy = y4-y3;\r\n\r\n const r_mag = Math.sqrt(r_dx*r_dx+r_dy*r_dy),\r\n s_mag = Math.sqrt(s_dx*s_dx+s_dy*s_dy);\r\n if(r_dx/r_mag==s_dx/s_mag && r_dy/r_mag==s_dy/s_mag){\r\n return null;\r\n }\r\n\r\n const T2 = (r_dx*(s_py-r_py) + r_dy*(r_px-s_px))/(s_dx*r_dy - s_dy*r_dx),\r\n T1 = (s_px+s_dx*T2-r_px)/r_dx;\r\n\r\n if(T1<0 || isNaN(T1)) return null;\r\n if(T2<0 || T2>1) return null;\r\n\r\n return {\r\n x: r_px+r_dx*T1,\r\n y: r_py+r_dy*T1,\r\n p: T1\r\n };\r\n}\r\n\r\n/**\r\n * \r\n * @param {{x1:number, y1:number, x2:number, y2:number}} line1 \r\n * @param {{x1:number, y1:number, x2:number, y2:number}} line2 \r\n * @returns {{x:number, y:number, p:number} | undefined}\r\n * @ignore\r\n */\r\nfunction countClosestTraversal2(line1, line2) {\r\n const x1 = line2.x1,\r\n y1 = line2.y1,\r\n x2 = line2.x2,\r\n y2 = line2.y2;\r\n const x3 = line1.x1,\r\n y3 = line1.y1,\r\n x4 = line1.x2,\r\n y4 = line1.y2;\r\n\r\n const det = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);\r\n // lines are parallel, or coincident\r\n if (det === 0){\r\n return;\r\n }\r\n let x = ((x1*y2 - y1*x2) * (x3 - x4) - (x1 - x2) * (x3*y4 - y3*x4)) / det;\r\n let y = ((x1*y2 - y1*x2) * (y3 - y4) - (y1 - y2) * (x3*y4 - y3*x4)) / det;\r\n const point = {x, y};\r\n \r\n if (isPointOnTheLine(point, line1, 0.0000000000001) && isPointOnTheLine(point, line2, 0.0000000000001)) {\r\n const p = Math.sqrt(Math.pow((x - x1), 2) + Math.pow((y - y1), 2));\r\n return {x, y, p};\r\n } else {\r\n return;\r\n }\r\n}\r\n\r\nfunction angle_2points(x1, y1, x2, y2) {\r\n return Math.atan2(y2 - y1, x2 - x1);\r\n}\r\n\r\nfunction angle_3points(a, b, c) {\r\n const x1 = a.x - b.x,\r\n x2 = c.x - b.x,\r\n y1 = a.y - b.y,\r\n y2 = c.y - b.y,\r\n d1 = Math.sqrt(x1 * x1 + y1 * y1),\r\n d2 = Math.sqrt(x2 * x2 + y2 * y2);\r\n //console.log(\"angle: \", (Math.acos((x1* x2 + y1 * y2) / (d1 * d2))* 180) / Math.PI);\r\n return Math.acos((x1* x2 + y1 * y2) / (d1 * d2));\r\n}\r\n\r\nfunction dotProductWithAngle(lenA, lenB, angle) {\r\n return lenA * lenB * Math.cos(angle);\r\n}\r\n\r\nfunction dotProduct(vec1, vec2) {\r\n return vec1.x * vec2.x + vec1.y * vec2.y;\r\n}\r\n\r\nfunction crossProduct(a, b) {\r\n return (a.x * b.y - b.x * a.y);\r\n}\r\n\r\nfunction isPointOnTheLine(point, line, m_error = 0) {\r\n return (\r\n ((point.x >= (line.x1 - m_error)) && (point.x <= (line.x2 + m_error))) || \r\n ((point.x <= (line.x1 + m_error)) && (point.x >= (line.x2 - m_error)))\r\n ) && (\r\n ((point.y >= (line.y1 - m_error)) && (point.y <= (line.y2 + m_error))) || \r\n ((point.y <= (line.y1 + m_error)) && (point.y >= (line.y2 - m_error)))\r\n );\r\n}\r\n\r\nfunction countDistance(obj1, obj2) {\r\n return new Vector(obj1.x, obj1.y, obj2.x, obj2.y).length;\r\n}\r\n\r\nfunction isLineShorter(line1, line2) {\r\n return (new Vector(line1.x1, line1.y1, line1.x2, line1.y2)).length < (new Vector(line2.x1, line2.y1, line2.x2, line2.y2)).length;\r\n}\r\n\r\nfunction isPointLineIntersect(point, line) {\r\n const lineL = new Vector(line.x1, line.y1, line.x2, line.y2).length,\r\n lengthAB = new Vector(line.x1, line.y1, point.x, point.y).length + new Vector(line.x2, line.y2, point.x, point.y).length;\r\n\r\n if (lengthAB <= lineL + 0.2) {\r\n //console.log(\"point to line intersect. line len: \" + lineL + \", line AB len: \" + lengthAB);\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * \r\n * @param {Array>} polygon \r\n * @param {{x1:number, y1:number, x2:number, y2:number}} line \r\n * @returns {{x:number, y:number, p:number} | null}\r\n * @ignore\r\n */\r\nfunction isPolygonLineIntersect(polygon, line) {\r\n const len = polygon.length;\r\n for (let i = 0; i < len; i+=1) {\r\n let curr = polygon[i],\r\n next = polygon[i+1];\r\n //if next item not exist and current is not first\r\n if (!next) {\r\n // if current vertex is not the first one\r\n if (!(curr[0] === polygon[0][0] && curr[1] === polygon[0][1])) {\r\n next = polygon[0];\r\n } else {\r\n continue;\r\n }\r\n }\r\n const edge = { x1: curr[0], y1: curr[1], x2: next[0], y2: next[1] };\r\n const intersection = countClosestTraversal2(edge, line);\r\n if (intersection) {\r\n return intersection;\r\n }\r\n }\r\n if (polygon[len-1][0] !== polygon[0][0] && polygon[len-1][1] !== polygon[0][1]) {\r\n //check one last item\r\n const curr = polygon[len - 1],\r\n next = polygon[0];\r\n const edge = { x1: curr[0], y1: curr[1], x2: next[0], y2: next[1] };\r\n const intersection = countClosestTraversal2(edge, line);\r\n if (intersection) {\r\n return intersection;\r\n }\r\n }\r\n return null;\r\n}\r\n\r\nfunction isPointPolygonIntersect(x, y, polygon) {\r\n const len = polygon.length;\r\n \r\n for (let i = 0; i < len; i+=1) {\r\n let vertex1 = polygon[i],\r\n vertex2 = polygon[i + 1];\r\n\r\n // if last vertex, set vertex2 as the first\r\n if (!vertex2) {\r\n vertex2 = polygon[0];\r\n }\r\n\r\n if (isPointLineIntersect({x,y}, {x1: vertex1[0], y1: vertex1[1], x2: vertex2[0], y2: vertex2[1]})) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\nfunction isPointInsidePolygon(x, y, polygon) {\r\n const len = polygon.length;\r\n let intersections = 0;\r\n\r\n for (let i = 0; i < len; i++) {\r\n let vertex1 = polygon[i],\r\n vertex2 = polygon[i + 1] ? polygon[i + 1] : polygon[0],\r\n x1 = vertex1[0],\r\n y1 = vertex1[1],\r\n x2 = vertex2[0],\r\n y2 = vertex2[1];\r\n \r\n if (y < y1 !== y < y2 && \r\n x < (x2 - x1) * (y - y1) / (y2 - y1) + x1) {\r\n intersections++;\r\n }\r\n }\r\n \r\n if (intersections > 0) {\r\n if (intersections % 2 === 0) {\r\n return false;\r\n } else {\r\n return true;\r\n }\r\n } else {\r\n return false;\r\n }\r\n}\r\n\r\nfunction isPointRectIntersect(x, y, rect) {\r\n if (x >= rect.x && x <= rect.width + rect.x && y >= rect.y && y <= rect.y + rect.height) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * \r\n * @param {number} x \r\n * @param {number} y \r\n * @param {{x:number, y:number, r:number}} circle \r\n * @returns {boolean}\r\n */\r\nfunction isPointCircleIntersect(x, y, circle) {\r\n const radius = circle.r,\r\n lineToCircleCenter = new Vector(x, y, circle.x, circle.y),\r\n pointCircleLineLength = lineToCircleCenter.length;\r\n \r\n if (pointCircleLineLength < radius)\r\n return true;\r\n else\r\n return false;\r\n}\r\n\r\nfunction isCircleLineIntersect(x, y, r, line) {\r\n const x1 = line.x1,\r\n y1 = line.y1,\r\n x2 = line.x2,\r\n y2 = line.y2,\r\n vec1 = {x: x1 - x, y: y1-y}, //new Vector(x, y, x1, y1),\r\n vec2 = {x: x2 - x, y: y2-y}, //new Vector(x, y, x2, y2),\r\n vec3 = {x: x2 - x1, y: y2-y1}, //new Vector(x1 ,y1, x2, y2),\r\n vec4 = {x: x1 - x2, y: y1-y2}, //new Vector(x2, y2, x1, y1),\r\n vec3Len = Math.sqrt(Math.pow(vec3.x, 2) + Math.pow(vec3.y, 2)),//vec3.length,\r\n dotP1 = dotProduct(vec1, vec4),\r\n dotP2 = dotProduct(vec2, vec3);\r\n // checks if the line is inside the circle,\r\n // max_dist = Math.max(vec1Len, vec2Len);\r\n let min_dist;\r\n \r\n if (dotP1 > 0 && dotP2 > 0) {\r\n min_dist = crossProduct(vec1,vec2)/vec3Len;\r\n if (min_dist < 0) {\r\n min_dist *= -1;\r\n }\r\n } else {\r\n min_dist = Math.min(vec1.length, vec2.length);\r\n }\r\n \r\n if (min_dist <= r) { // && max_dist >= r) {\r\n return true;\r\n } else {\r\n return false;\r\n } \r\n}\r\n\r\n/**\r\n * \r\n * @param {Array} ellipse - x,y,radX,radY\r\n * @param {Array>} line [x1,y1],[x2,y2]\r\n */\r\nfunction isEllipseLineIntersect(ellipse, line) {\r\n const x = ellipse[0],\r\n y = ellipse[1],\r\n radX = ellipse[2],\r\n radY = ellipse[3],\r\n x1 = line[0][0],\r\n y1 = line[0][1],\r\n x2 = line[1][0],\r\n y2 = line[1][1],\r\n lineAToElCenter = { x: x - x1, y: y - y1 }, //new Vector(x, y, x1, y1),\r\n lineBToElCenter = { x: x - x2, y: y - y2 }, //new Vector(x, y, x2, y2),\r\n lineAToElCenterLen = Math.sqrt(Math.pow(lineAToElCenter.x, 2) + Math.pow(lineAToElCenter.y, 2)),\r\n lineBToElCenterLen = Math.sqrt(Math.pow(lineBToElCenter.x, 2) + Math.pow(lineBToElCenter.y, 2)),\r\n lineToCenterLenMin = Math.min(lineAToElCenterLen, lineBToElCenterLen),\r\n ellipseMax = Math.max(radX, radY);\r\n \r\n if (lineToCenterLenMin > ellipseMax) {\r\n return false;\r\n }\r\n \r\n const traversalLine = lineToCenterLenMin === lineAToElCenterLen ? lineAToElCenter : lineBToElCenter,\r\n angleToAxisX = Math.atan2(traversalLine.y, traversalLine.x);\r\n \r\n const intersectX = Math.cos(angleToAxisX) * radX,\r\n intersectY = Math.sin(angleToAxisX) * radY,\r\n lineToCenter = { x: 0 - intersectX, y: 0 - intersectY },\r\n intersectLineLen = Math.sqrt(Math.pow(lineToCenter.x, 2) + Math.pow(lineToCenter.y, 2));\r\n //console.log(\"lenToCheck: \", lenToCheck);\r\n //console.log(\"x: \", intersectX);\r\n if (lineToCenterLenMin > intersectLineLen) {\r\n return false;\r\n }\r\n return true;\r\n}\r\n\r\n/**\r\n * \r\n * @param {Array} ellipse - x,y,radX,radY\r\n * @param {{x:number, y:number, r:number}} circle\r\n * @returns {{x:number, y:number, p:number} | boolean}\r\n */\r\nfunction isEllipseCircleIntersect(ellipse, circle) {\r\n const ellipseX = ellipse[0],\r\n ellipseY = ellipse[1],\r\n ellipseToCircleLine = { x: ellipseX - circle.x, y: ellipseY - circle.y },\r\n len = Math.sqrt(Math.pow(ellipseToCircleLine.x, 2) + Math.pow(ellipseToCircleLine.y, 2)),\r\n maxRad = Math.max(ellipse[2], ellipse[3]);\r\n // no collisions for sure\r\n if (len > (maxRad + circle.r)) {\r\n return false;\r\n } else {\r\n // check possible collision\r\n const angle = angle_2points(ellipseX, ellipseY, circle.x, circle.y),\r\n traversalX = ellipseX + (ellipse[2] * Math.cos(angle)),\r\n traversalY = ellipseY + (ellipse[3] * Math.sin(angle)),\r\n vecTrX = ellipseX - traversalX,\r\n vecTrY = ellipseY - traversalY,\r\n traversalLen = Math.sqrt(Math.pow(vecTrX, 2) + Math.pow(vecTrY, 2)) + circle.r;\r\n if (len <= traversalLen) {\r\n return {x: vecTrX, y: vecTrY, p:1};\r\n } else {\r\n return false;\r\n }\r\n }\r\n \r\n}\r\n\r\n/**\r\n * \r\n * @param {Array} ellipse - x,y,radX,radY\r\n * @param {Array>} polygon - x,y\r\n * @returns {boolean}\r\n */\r\nfunction isEllipsePolygonIntersect(ellipse, polygon) {\r\n const len = polygon.length;\r\n\r\n for (let i = 0; i < len; i+=1) {\r\n let vertex1 = polygon[i],\r\n vertex2 = polygon[i + 1];\r\n\r\n // if last vertex, set vertex2 as the first\r\n if (!vertex2) {\r\n vertex2 = polygon[0];\r\n }\r\n\r\n if (isEllipseLineIntersect(ellipse, [vertex1, vertex2])) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\nfunction generateUniqId() {\r\n return Math.round(Math.random() * 1000000); \r\n}\r\n\r\nfunction randomFromArray(array) {\r\n return array[Math.floor(Math.random()*array.length)];\r\n}\r\n\r\nfunction verticesArrayToArrayNumbers(array) {\r\n const len = array.length,\r\n numbers = [];\r\n for (let i = 0; i < len; i++) {\r\n const vertex = array[i];\r\n numbers.push([vertex.x, vertex.y]);\r\n }\r\n return numbers;\r\n}\r\n\r\n/**\r\n * @param {number} x\r\n * @param {number} y\r\n * @param {number} radiusX\r\n * @param {number} radiusY\r\n * @param {number} [angle = 2 * Math.PI]\r\n * @param {number} [step = Math.PI/12] \r\n * @returns {Array}\r\n */\r\nfunction calculateEllipseVertices(x = 0, y = 0, radiusX, radiusY, angle = 2*Math.PI, step = Math.PI/8) {\r\n let ellipsePolygonCoords = [];\r\n\r\n for (let r = 0; r <= angle; r += step) {\r\n let x2 = Math.cos(r) * radiusX + x,\r\n y2 = Math.sin(r) * radiusY + y;\r\n\r\n ellipsePolygonCoords.push([x2, y2]);\r\n }\r\n\r\n return ellipsePolygonCoords;\r\n}\r\n\r\nexport { \r\n isMobile, \r\n isSafari, \r\n pointToCircleDistance, \r\n countClosestTraversal, \r\n countClosestTraversal2,\r\n angle_2points,\r\n angle_3points,\r\n dotProductWithAngle,\r\n dotProduct,\r\n crossProduct,\r\n isPointOnTheLine,\r\n isLineShorter,\r\n isPointLineIntersect,\r\n isPointPolygonIntersect,\r\n isPointRectIntersect,\r\n isPointCircleIntersect,\r\n isPolygonLineIntersect,\r\n isCircleLineIntersect,\r\n isEllipseLineIntersect,\r\n isEllipseCircleIntersect,\r\n isEllipsePolygonIntersect,\r\n isPointInsidePolygon,\r\n generateUniqId,\r\n randomFromArray,\r\n verticesArrayToArrayNumbers,\r\n countDistance,\r\n calculateEllipseVertices };","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.f = {};\n// This file contains only the entry chunk.\n// The chunk loading function for additional chunks\n__webpack_require__.e = (chunkId) => {\n\treturn Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {\n\t\t__webpack_require__.f[key](chunkId, promises);\n\t\treturn promises;\n\t}, []));\n};","// This function allow to reference async chunks\n__webpack_require__.u = (chunkId) => {\n\t// return url for filenames based on template\n\treturn \"\" + chunkId + \".index.es6.js\";\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","var inProgress = {};\nvar dataWebpackPrefix = \"jsge:\";\n// loadScript function to load a script via script tag\n__webpack_require__.l = (url, done, key, chunkId) => {\n\tif(inProgress[url]) { inProgress[url].push(done); return; }\n\tvar script, needAttach;\n\tif(key !== undefined) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tfor(var i = 0; i < scripts.length; i++) {\n\t\t\tvar s = scripts[i];\n\t\t\tif(s.getAttribute(\"src\") == url || s.getAttribute(\"data-webpack\") == dataWebpackPrefix + key) { script = s; break; }\n\t\t}\n\t}\n\tif(!script) {\n\t\tneedAttach = true;\n\t\tscript = document.createElement('script');\n\t\tscript.type = \"module\";\n\t\tscript.charset = 'utf-8';\n\t\tscript.timeout = 120;\n\t\tif (__webpack_require__.nc) {\n\t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n\t\t}\n\t\tscript.setAttribute(\"data-webpack\", dataWebpackPrefix + key);\n\t\tscript.src = url;\n\t}\n\tinProgress[url] = [done];\n\tvar onScriptComplete = (prev, event) => {\n\t\t// avoid mem leaks in IE.\n\t\tscript.onerror = script.onload = null;\n\t\tclearTimeout(timeout);\n\t\tvar doneFns = inProgress[url];\n\t\tdelete inProgress[url];\n\t\tscript.parentNode && script.parentNode.removeChild(script);\n\t\tdoneFns && doneFns.forEach((fn) => (fn(event)));\n\t\tif(prev) return prev(event);\n\t};\n\tvar timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);\n\tscript.onerror = onScriptComplete.bind(null, script.onerror);\n\tscript.onload = onScriptComplete.bind(null, script.onload);\n\tneedAttach && document.head.appendChild(script);\n};","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","var scriptUrl;\nif (typeof import.meta.url === \"string\") scriptUrl = import.meta.url\n// When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration\n// or pass an empty string (\"\") and set the __webpack_public_path__ variable from your code to use your own logic.\nif (!scriptUrl) throw new Error(\"Automatic publicPath is not supported in this browser\");\nscriptUrl = scriptUrl.replace(/#.*$/, \"\").replace(/\\?.*$/, \"\").replace(/\\/[^\\/]+$/, \"/\");\n__webpack_require__.p = scriptUrl;","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t\"main\": 0\n};\n\n__webpack_require__.f.j = (chunkId, promises) => {\n\t\t// JSONP chunk loading for javascript\n\t\tvar installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;\n\t\tif(installedChunkData !== 0) { // 0 means \"already installed\".\n\n\t\t\t// a Promise means \"currently loading\".\n\t\t\tif(installedChunkData) {\n\t\t\t\tpromises.push(installedChunkData[2]);\n\t\t\t} else {\n\t\t\t\tif(true) { // all chunks have JS\n\t\t\t\t\t// setup Promise in chunk cache\n\t\t\t\t\tvar promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));\n\t\t\t\t\tpromises.push(installedChunkData[2] = promise);\n\n\t\t\t\t\t// start chunk loading\n\t\t\t\t\tvar url = __webpack_require__.p + __webpack_require__.u(chunkId);\n\t\t\t\t\t// create error before stack unwound to get useful stacktrace later\n\t\t\t\t\tvar error = new Error();\n\t\t\t\t\tvar loadingEnded = (event) => {\n\t\t\t\t\t\tif(__webpack_require__.o(installedChunks, chunkId)) {\n\t\t\t\t\t\t\tinstalledChunkData = installedChunks[chunkId];\n\t\t\t\t\t\t\tif(installedChunkData !== 0) installedChunks[chunkId] = undefined;\n\t\t\t\t\t\t\tif(installedChunkData) {\n\t\t\t\t\t\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n\t\t\t\t\t\t\t\tvar realSrc = event && event.target && event.target.src;\n\t\t\t\t\t\t\t\terror.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';\n\t\t\t\t\t\t\t\terror.name = 'ChunkLoadError';\n\t\t\t\t\t\t\t\terror.type = errorType;\n\t\t\t\t\t\t\t\terror.request = realSrc;\n\t\t\t\t\t\t\t\tinstalledChunkData[1](error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\t__webpack_require__.l(url, loadingEnded, \"chunk-\" + chunkId, chunkId);\n\t\t\t\t} else installedChunks[chunkId] = 0;\n\t\t\t}\n\t\t}\n};\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n// no on chunks loaded\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = (parentChunkLoadingFunction, data) => {\n\tvar [chunkIds, moreModules, runtime] = data;\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some((id) => (installedChunks[id] !== 0))) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunkjsge\"] = self[\"webpackChunkjsge\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(\"./src/index.js\");\n",""],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/dist/index.es6.min.js b/dist/index.es6.min.js index 1f678a5..a5004de 100644 --- a/dist/index.es6.min.js +++ b/dist/index.es6.min.js @@ -1 +1 @@ -var e,t,i={},s={};function n(e){var t=s[e];if(void 0!==t)return t.exports;var r=s[e]={exports:{}};return i[e](r,r.exports,n),r.exports}n.m=i,n.d=(e,t)=>{for(var i in t)n.o(t,i)&&!n.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},n.f={},n.e=e=>Promise.all(Object.keys(n.f).reduce(((t,i)=>(n.f[i](e,t),t)),[])),n.u=e=>e+".index.es6.min.js",n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),e={},t="jsge:",n.l=(i,s,r,a)=>{if(e[i])e[i].push(s);else{var o,l;if(void 0!==r)for(var h=document.getElementsByTagName("script"),c=0;c{o.onerror=o.onload=null,clearTimeout(g);var n=e[i];if(delete e[i],o.parentNode&&o.parentNode.removeChild(o),n&&n.forEach((e=>e(s))),t)return t(s)},g=setTimeout(u.bind(null,void 0,{type:"timeout",target:o}),12e4);o.onerror=u.bind(null,o.onerror),o.onload=u.bind(null,o.onload),l&&document.head.appendChild(o)}},n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{var e;if("string"==typeof import.meta.url&&(e=import.meta.url),!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),n.p=e})(),(()=>{var e={179:0};n.f.j=(t,i)=>{var s=n.o(e,t)?e[t]:void 0;if(0!==s)if(s)i.push(s[2]);else{var r=new Promise(((i,n)=>s=e[t]=[i,n]));i.push(s[2]=r);var a=n.p+n.u(t),o=new Error;n.l(a,(i=>{if(n.o(e,t)&&(0!==(s=e[t])&&(e[t]=void 0),s)){var r=i&&("load"===i.type?"missing":i.type),a=i&&i.target&&i.target.src;o.message="Loading chunk "+t+" failed.\n("+r+": "+a+")",o.name="ChunkLoadError",o.type=r,o.request=a,s[1](o)}}),"chunk-"+t,t)}};var t=(t,i)=>{var s,r,[a,o,l]=i,h=0;if(a.some((t=>0!==e[t]))){for(s in o)n.o(o,s)&&(n.m[s]=o[s]);l&&l(n)}for(t&&t(i);hl,QD:()=>Y,T_:()=>We,uw:()=>ee,xl:()=>a,xP:()=>ke,bq:()=>Z,P6:()=>o});var a={};n.r(a),n.d(a,{Rectangle:()=>F,Vector:()=>k,Vertex:()=>G});var o={};n.r(o),n.d(o,{angle_2points:()=>ae,angle_3points:()=>oe,calculateEllipseVertices:()=>be,countClosestTraversal:()=>ne,countClosestTraversal2:()=>re,countDistance:()=>ue,crossProduct:()=>ce,dotProduct:()=>he,dotProductWithAngle:()=>le,generateUniqId:()=>ye,isCircleLineIntersect:()=>pe,isEllipseCircleIntersect:()=>Re,isEllipseLineIntersect:()=>Se,isEllipsePolygonIntersect:()=>xe,isLineShorter:()=>ge,isMobile:()=>te,isPointCircleIntersect:()=>Te,isPointInsidePolygon:()=>_e,isPointLineIntersect:()=>me,isPointOnTheLine:()=>de,isPointPolygonIntersect:()=>Ee,isPointRectIntersect:()=>Ae,isPolygonLineIntersect:()=>fe,isSafari:()=>ie,pointToCircleDistance:()=>se,randomFromArray:()=>ve,verticesArrayToArrayNumbers:()=>we});const l={MODE:{DEBUG:"DEBUG",PRODUCTION:"PRODUCTION"},SCREENS:{},AUDIO:{},CONNECTION_STATUS:{DISCONNECTED:"disconnected",CONNECTED:"connected",CONNECTION_LOST:"connection lost"},EVENTS:{SYSTEM:{START_PAGE:"START_PAGE",STOP_PAGE:"STOP_PAGE",RENDER:{START:"start",END:"end"}},GAME:{BOUNDARIES_COLLISION:"BOUNDARIES_COLLISION",OBJECTS_COLLISION:"OBJECTS_COLLISION"},WEBSOCKET:{SERVER_CLIENT:{CONNECTION_STATUS_CHANGED:"CONNECTION_STATUS_CHANGED",ROOMS_INFO:"roomsInfo",CREATED:"created",JOINED:"joined",FULL:"full",DISCONNECTED:"disconnected",SERVER_MESSAGE:"message",RESTARTED:"restarted"},CLIENT_SERVER:{ROOMS_INFO_REQUEST:"gatherRoomsInfo",CREATE_OR_JOIN:"create or join",RESTART_REQUEST:"restart",CLIENT_MESSAGE:"message"}}},WEBGL:{DRAW_PROGRAMS:{PRIMITIVES:"drawPrimitives",IMAGES:"drawImages"}},DRAW_TYPE:{RECTANGLE:"rect",CONUS:"conus",CIRCLE:"circle",POLYGON:"polygon",LINE:"line",TEXT:"text",IMAGE:"image"},LAYERS:{DEFAULT:"default-view-layer",BOUNDARIES:"boundaries-view-layer"},GAME_OPTIONS:{},LIBRARY:{WEBGL:"webgl"},OPTIMIZATION:{CYCLE_TIME_CALC:{AVERAGES:"AVERAGES",CURRENT:"CURRENT"},NATIVE_JS:{NOT_OPTIMIZED:"NOT_OPTIMIZED",OPTIMIZED:"OPTIMIZED"},WEB_ASSEMBLY:{ASSEMBLY_SCRIPT:"ASSEMBLY_SCRIPT",NATIVE_WAT:"WASM"}}},h="CREATE_INSTANCE_ERROR",c="VIEW_NOT_EXIST",d="CANT_GET_THE_IMAGE",u="UNEXPECTED_INPUT_PARAMS",g="WEBGL_ERROR",m="NOT_FOUND",f="WORLD_DIMENSIONS_NOT_SET",E="UNHANDLED_DRAW_ISSUE",_="UNEXPECTED_WORLD_SIZE",A="AUDIO_NOT_REGISTERED",T="AUDIO_NOT_LOADED",p="POLYGON_VERTICES_NOT_CORRECT";function S(e,t){throw new Error(e+": "+t)}function R(e,t){console.warn(e,t)}class x{#e;#t;#i;#s;#n=0;#r=0;#a=0;#o=0;#l=0;#h=[];#c=[];#d=[];#u=[];#g=[];#m;#f=!1;isOffsetTurnedOff(){return this.#m}set mapRotate(e){this.#l=e}#E(e){this.#h.push([e.x1,e.y1,e.x2,e.y2])}_addBoundariesArray(e){this.#h.push(...e)}_addEllipseBoundaries(e){this.#c.push(...e)}_addPointBoundaries(e){this.#d.push(...e)}_clearBoundaries(){this.#h=[],this.#c=[],this.#d=[]}_setWorldDimensions(e,t){this.#e=e,this.#t=t}_setCanvasDimensions(e,t){this.#i=e,this.#s=t}_setMapBoundaries(){const[e,t]=[this.#e,this.#t],[i,s]=[this.#n,this.#r],n=e-i,r=t-s;e&&t||R(f,"Can't set map boundaries."),this.#E({x1:0,y1:0,x2:n,y2:0}),this.#E({x1:n,y1:0,x2:n,y2:r}),this.#E({x1:n,y1:r,x2:0,y2:r}),this.#E({x1:0,y1:r,x2:0,y2:0})}_setWholeWorldMapBoundaries(){const[e,t]=[this.#e,this.#t];e&&t||R(f,"Can't set map boundaries."),this.#u.push([0,0,e,0]),this.#u.push([e,0,e,t]),this.#u.push([e,t,0,t]),this.#u.push([0,t,0,0])}_mergeBoundaries(e=!1){const t=e?this.getWholeWorldBoundaries():this.getBoundaries(),i=new Set(t);for(const e of i.values()){const t=e[0],s=e[1],n=e[2],r=e[3];for(const a of i.values()){const o=a[0],l=a[1],h=a[2],c=a[3];t===h&&s===c&&n===o&&r===l&&(i.delete(e),i.delete(a)),n!==o||r!==l||t!==h&&s!==c||(a[0]=t,a[1]=s,i.delete(e))}}e?this.#h=Array.from(i):this.#u=Array.from(i),i.clear()}_setWholeMapBoundaries(e){this.#u.push(...e)}_enableMapBoundaries(){this.#f=!0}getBoundaries(){return this.#h}getEllipseBoundaries(){return this.#c}getPointBoundaries(){return this.#d}getWholeWorldBoundaries(){return this.#u}get isWorldBoundariesEnabled(){return this.#f}get canvasDimensions(){return[this.#i,this.#s]}get worldDimensions(){return[this.#e,this.#t]}get worldOffset(){return[this.#n,this.#r]}get mapCenter(){return[this.#a,this.#o]}get mapRotate(){return this.#l}centerCameraPosition=(e,t)=>{let[i,s]=this.worldOffset;const[n,r]=this.canvasDimensions,[a,o]=this.worldDimensions,l=n/2,h=r/2,c=h-s;if(l-i=0&&(this.#n=Math.round(t))}else if(a>n){const e=a-n;this.#n=Math.round(e)}if(c=0&&(this.#r=Math.round(e))}else if(o>r){const e=o-r;this.#r=Math.round(e)}this.#a=e,this.#o=t};personRotatedCenterCamera=(e,t,i)=>{console.log("new centering algorithm")};get renderObjects(){return this.#g}getObjectsByInstance(e){return this.#g.filter((t=>t instanceof e))}_sortRenderObjectsBySortIndex(){this.#g=this.#g.sort(((e,t)=>e.sortIndex-t.sortIndex))}set _renderObject(e){this.#g.push(e)}set _renderObjects(e){this.#g=e}}const y={loadstart:"loadstart",progress:"progress",abort:"abort",error:"error",load:"load",timeout:"timeout"},v=" loader is not registered.",w="Too much recursion. Stop iteration.",b="uploadMethod should be instance of Promise and return upload result value",I=" AtlasXML file extension is incorrect, only .xml file supported",O=" tileset file extension is not correct, only .tsj or .json files are supported",P=" tilemap file extension is not correct, only .tmj or .json files are supported",C=" fileKey and url should be provided";class M{#_;#A;#T=new Map;#p=new Map;constructor(e,t){this.#_=e,this.#A=(e,i,...s)=>{const n=t(e,i,...s);if(n instanceof Promise)return n.then((t=>this.#S(t,e)));throw new TypeError(b)}}#S=(e,t)=>new Promise(((i,s)=>{e||null===e||B("AssetsManager: uploadMethod for "+this.#_+" returns incorrect value"),this.#R(t,e),this.#x(t),i()}));#R(e,t){this.#p.set(e,t)}#x(e){this.#T.delete(e)}get filesWaitingForUpload(){return this.#T.size}get loadingQueue(){return this.#T}get uploadMethod(){return this.#A}_addFile=(e,t)=>{this.#T.has(e)&&B("AssetsManager: File "+this.#_+" with key "+e+" is already added"),this.#T.set(e,t)};_isFileInQueue=e=>this.#T.has(e);_getFile=e=>this.#p.get(e)}class D{#y=5;#v=new EventTarget;#w=new Map;#b=0;constructor(){this.registerLoader("Audio",this._loadAudio),this.registerLoader("Image",this._loadImage),this.registerLoader("TileMap",this._loadTileMap),this.registerLoader("TileSet",this._loadTileSet),this.registerLoader("AtlasImageMap",this._loadAtlasImage),this.registerLoader("AtlasXML",this._loadAtlasXml)}get filesWaitingForUpload(){let e=0;return Array.from(this.#w.values()).map((t=>e+=t.filesWaitingForUpload)),e}registerLoader=(e,t=this._defaultUploadMethod)=>{this["add"+e]=(t,i,...s)=>{this.addFile(e,t,i,...s)},this["get"+e]=t=>this.getFile(e,t),this["is"+e+["InQueue"]]=t=>this.isFileInQueue(e,t);const i=this.#w.get(e)||new M(e,t);this.#w.set(e,i)};preload(){return this.#I(),new Promise((async(e,t)=>{this.#O().then((()=>{this.#P(),e()})).catch((e=>{t(e)}))}))}#O(e=0){return this.#C().then((t=>{if(0===this.filesWaitingForUpload)return Promise.resolve(t);if(++e>this.#y){const e=new Error(w);return this.#M(e),Promise.reject(new Error(w))}return this.#O(e)}))}#C(){return new Promise(((e,t)=>{let i=[];Array.from(this.#w.values()).forEach((e=>{Array.from(e.loadingQueue.entries()).forEach((t=>{const s=new Promise(((i,s)=>e.uploadMethod(t[0],...t[1]).then((e=>i(e)))));i.push(s)}))})),Promise.allSettled(i).then((i=>{for(const s of i){if("rejected"===s.status){const e=s.reason;this.#D(e)?t(e):(B("AssetsManager: "+e.message),this.#M(e))}e(i)}}))}))}addEventListener(e,t,...i){y[e]?this.#v.addEventListener(e,t,...i):B("AssetsManager: Event type should be one of the ProgressEvent.type")}removeEventListener(e,t,...i){this.#v.removeEventListener(e,t,...i)}_loadAtlasXml=(e,t)=>(this.#L(t),fetch(t).then((e=>e.text())).then((e=>(new window.DOMParser).parseFromString(e,"text/xml"))).then((i=>{const s=i.documentElement||i.activeElement,n=s.attributes.getNamedItem("imagePath"),r=s.children;if(n){const i=this.#B(t);return this.addAtlasImageMap(e,i+n.value,r,i),Promise.resolve(s)}{const t=new Error(e+" XML format is not correct.");return this.#M(t),Promise.resolve(t)}})));_loadAtlasImage=(e,t,i,s="anonymous")=>new Promise(((e,n)=>{const r=new Image,a=new Map,o=document.createElement("canvas"),l=o.getContext("2d");r.crossOrigin=s,r.onload=()=>{const t=[];let s=[];o.width=r.width,o.height=r.height,l.drawImage(r,0,0);for(let e of i){const i=e.attributes,n=i.getNamedItem("name").value,r=n.includes(".")?n.split(".")[0]:n,a=i.getNamedItem("x").value,o=i.getNamedItem("y").value,h=i.getNamedItem("width").value,c=i.getNamedItem("height").value;t.push(createImageBitmap(l.getImageData(a,o,h,c),{premultiplyAlpha:"premultiply"})),s.push(r)}this.#N(),Promise.all(t).then((t=>{t.forEach(((e,t)=>{const i=s[t];a.set(i,e),this.addImage(i,"empty url",e)})),o.remove(),e(a)}))},r.onerror=()=>{const i=new Error("Error loading atlas image "+t);this.#M(i),e(null)},r.src=t}));_loadTileSet=(e,t,i=1,s)=>(this.#W(t),fetch(s?s+t:t).then((e=>e.json())).then((e=>{const{name:t,image:n,spacing:r,margin:a,tilewidth:o,tileheight:l}=e;return t&&n&&!this.isFileInQueue("Image",t)&&this.addImage(t,s?s+n:n),e.gid=i,Promise.resolve(e)})).catch((()=>{const e=new Error("Error loading related tileset "+t);return this.#M(e),Promise.resolve(null)})));_defaultUploadMethod=(e,t)=>fetch(t);_loadTileMap=(e,t,i=!0)=>(this.#G(t),fetch(t).then((e=>e.json())).then((e=>{const s=this.#B(t);if(!0===i&&e.tilesets&&e.tilesets.length>0){const t=[];return e.tilesets.forEach(((e,i)=>{const{firstgid:n,source:r}=e,a=this._loadTileSet("default-"+n,r,n,s).then((e=>(this.#N(),Promise.resolve(e))));t.push(a)})),Promise.all(t).then((t=>{for(let i=0;i(e.message.includes("JSON.parse:")&&(e=new Error("Error loading tilemap "+t)),this.#M(e),Promise.resolve(null)))));_loadAudio=(e,t)=>new Promise((e=>{const i=new Audio(t);i.addEventListener("loadeddata",(()=>{this.#N(),e(i)})),i.addEventListener("error",(()=>{const i=new Error("Error loading audio "+t);this.#M(i),e(null)}))}));_loadImage=(e,t,i,s="anonymous")=>new Promise(((e,n)=>{if(i)e(i);else{const i=new Image;i.crossOrigin=s,i.onload=()=>{createImageBitmap(i,{premultiplyAlpha:"premultiply"}).then((t=>{this.#N(),e(t)}))},i.onerror=()=>{const i=new Error("Error loading image "+t);this.#M(i),e(null)},i.src=t}}));#L(e){e.includes(".xml")||L(e+I)}#W(e){e.includes(".tsj")||e.includes(".json")||L(e+O)}#G(e){e.includes(".tmj")||e.includes(".json")||L(e+P)}#D(e){return e.message.includes(b)||e.message.includes(I)||e.message.includes(O)||e.message.includes(P)||e.message.includes(C)||e.message.includes(v)}#B(e){let t=e.split("/"),i=t.length,s="/";return t[i-1].includes(".tmj")||t[i-1].includes(".xml")||t[i-1].includes(".json")?(t.pop(),s=t.join("/")+"/"):(t[i-2].includes(".tmj")||t[i-2].includes(".xml")||t[i-2].includes(".json"))&&(t.splice(i-2,2),s=t.join("/")+"/"),s}addFile(e,t,i,...s){const n=this.#w.get(e);n?(this.#F(t,i,e),n._addFile(t,[i,...s])):L(e+v)}isFileInQueue(e,t){const i=this.#w.get(e);if(i)return i._isFileInQueue(t);L("Loader for "+e+" is not registered!")}getFile(e,t){const i=this.#w.get(e);if(i)return i._getFile(t);L("Loader for "+e+" is not registered!")}#F(e,t,i){const s=C;e&&0!==e.trim().length||L("add"+i+"()"+s),t&&0!==t.trim().length||L("add"+i+"()"+s)}#I(){let e=this.filesWaitingForUpload;this.#v.dispatchEvent(new ProgressEvent(y.loadstart,{total:e}))}#P(){this.#v.dispatchEvent(new ProgressEvent(y.load))}#N(){const e=this.filesWaitingForUpload;this.#b+=1,this.#v.dispatchEvent(new ProgressEvent(y.progress,{lengthComputable:!0,loaded:this.#b,total:e}))}#M(e){B("AssetsManger: "+e.message),this.#v.dispatchEvent(new ErrorEvent(y.error,{error:e}))}}function L(e){throw new Error(e)}function B(e){console.warn(e)}class N{#k;#j;#U;#V;#Y;#z=0;#X=0;#H=ye();#K=!1;#q;#Z;#m=!1;#J=!1;constructor(e,t,i,s){this.#k=t,this.#j=i,this.#U=s,this.#V=e}get bgColor(){return this.#U}set bgColor(e){this.#U=e}get type(){return this.#V}get x(){return this.#k}get y(){return this.#j}set x(e){this.#k=e}set y(e){this.#j=e}get sortIndex(){return this.#z}set sortIndex(e){this.#z=e}get blendFunc(){return this.#Y}set blendFunc(e){this.#Y=e}get rotation(){return this.#X}set rotation(e){this.#X=e}get id(){return this.#H}get isRemoved(){return this.#K}destroy(){this.#K=!0}get isMaskAttached(){return!!this.#q}get _maskId(){return this.#q}setMask(e){e._isMask=!0,this.#q=e.id}removeMask(){this.#q=null}set _isMask(e){this.#Z=e}get _isMask(){return this.#Z}get isOffsetTurnedOff(){return this.#m}turnOffOffset(){this.#m=!0}_calculateRectVertices=(e,t)=>{const i=e/2,s=t/2;return[[-i,-s],[i,-s],[i,s],[-i,s]]};_interpolateConus(e,t=2*Math.PI,i=Math.PI/14){let s=[0,0];for(let n=0;n<=t;n+=i){let t=Math.cos(n)*e,i=Math.sin(n)*e;s.push(t,i)}return s}_calculateConusBoundaries(e,t=2*Math.PI,i=Math.PI/14){let s=[];for(let n=0;n<=t;n+=i){let t=Math.cos(n)*e,i=Math.sin(n)*e;s.push([t,i])}return s}_convertVerticesArray(e){return void 0!==e[0].x&&void 0!==e[0].y?we(e):e}}class W extends N{#Q;#I;#$;constructor(e,t,i,s,n){super(l.DRAW_TYPE.RECTANGLE,e,t,n),this.#Q=i,this.#I=s,this.#$=this._calculateRectVertices(i,s)}get vertices(){return this.#$}get width(){return this.#Q}get height(){return this.#I}set width(e){this.#Q=e}set height(e){this.#I=e}}class G{#k;#j;constructor(e,t){this.#k=e,this.#j=t}get x(){return this.#k}get y(){return this.#j}}class F{#k;#j;#Q;#I;constructor(e,t,i,s){this.#k=e,this.#j=t,this.#Q=i,this.#I=s}get x(){return this.#k}get y(){return this.#j}get width(){return this.#Q}get height(){return this.#I}}class k{#k;#j;constructor(e,t,i,s){this.#k=i-e,this.#j=s-t}get x(){return this.#k}get y(){return this.#j}get length(){return Math.sqrt(Math.pow(this.#k,2)+Math.pow(this.#j,2))}get tetaAngle(){return Math.atan2(this.#j,this.#k)}}class j extends N{#ee;#te;#ie;#se;#ne;#re;#ae;#oe=document.createElement("canvas");#le;constructor(e,t,i,s,n){super(l.DRAW_TYPE.TEXT,e,t),this.#re=i,this.#ee=s,this.#se=n,this.#ae,this.#he()}get boundariesBox(){const e=this.textMetrics?Math.floor(this.textMetrics.width):300,t=this.textMetrics?Math.floor(this.textMetrics.fontBoundingBoxAscent+this.textMetrics.fontBoundingBoxDescent):30;return new F(this.x,this.y-t,e,t)}get vertices(){const e=this.boundariesBox;return this._calculateRectVertices(e.width,e.height)}get text(){return this.#re}set text(e){e!==this.#re&&(this.#re=e,this.#he())}get font(){return this.#ee}set font(e){e!==this.#ee&&(this.#ee=e,this.#he())}get textAlign(){return this.#te}set textAlign(e){e!==this.#te&&(this.#te=e,this.#he())}get textBaseline(){return this.#ie}set textBaseline(e){e!==this.#ie&&(this.#ie=e,this.#he())}get fillStyle(){return this.#se}set fillStyle(e){e!==this.#se&&(this.#se=e,this.#he())}get strokeStyle(){return this.#ne}set strokeStyle(e){e!==this.#ne&&(this.#ne=e,this.#he())}get textMetrics(){return this.#ae}set _textMetrics(e){this.#ae=e}get _textureStorage(){return this.#le}set _textureStorage(e){this.#le=e}get _textureCanvas(){return this.#oe}#he(){const e=this.#oe.getContext("2d",{willReadFrequently:!0});if(e){e.font=this.font,this._textMetrics=e.measureText(this.text);const t=this.boundariesBox.width,i=this.boundariesBox.height;e.canvas.width=t,e.canvas.height=i,e.clearRect(0,0,t,i),e.font=this.font,e.textBaseline="bottom",this.fillStyle&&(e.fillStyle=this.fillStyle,e.fillText(this.text,0,i)),this.strokeStyle&&(e.strokeStyle=this.strokeStyle,e.strokeText(this.text,0,i)),this.#le&&(this.#le._isTextureRecalculated=!0)}else S("UNHANDLED_EXCEPTION","can't getContext('2d')")}}class U extends N{#ce;#de;#$;#ue;constructor(e,t,i,s,n,r=0){super(l.DRAW_TYPE.CONUS,e,t,s),this.#ce=i,this.#de=n,this.#ue=r,this.#$=this._interpolateConus(i,n)}get vertices(){return this.#$}set vertices(e){this.#$=e}get radius(){return this.#ce}get angle(){return this.#de}get fade_min(){return this.#ue}set fade_min(e){this.#ue=e}}class V{#ge;#me=100;#fe;#Ee;#_e;#Ae;#Te;constructor(e,t,i=!1,s,n=!1){this.#ge=e,this.#fe=this.#pe(t),this.#Ee=s||0,this.#_e=n,this.#Ae=i}get name(){return this.#ge}get isActive(){return this.#_e}get currentSprite(){return this.#fe[this.#Ee][0]}get _isLastSprite(){return this.#fe.length-1===this.#Ee}iterateAnimationIndex(){const e=this.#Ee;this.#fe[e][1]{this.#_e=!0,this.#Ee=0,this.#Te=Date.now()};deactivateAnimation=()=>{this.#_e=!1};#pe(e){let t=[];return e.forEach((e=>{"number"==typeof e.id&&"number"==typeof e.duration?t.push([e.id,e.duration]):t.push([e,this.#me])})),t}}class Y extends N{#Q;#I;#Se;#Re;#xe;#ye;#ve;#we;#be=0;#$;#Ie;#le;constructor(e,t,i,s,n,r=0,a,o,h=0){super(l.DRAW_TYPE.IMAGE,e,t),this.#Se=n,this.#xe=new EventTarget,this.#ye=new Map,this.image=o,this.#we=r,this.#be=h,this.#Q=i,this.#I=s,this.#$=a&&!a.r?this._convertVerticesArray(a):a&&a.r?this._calculateConusBoundaries(a.r):this._calculateRectVertices(i,s),this.#Ie=a&&void 0!==a.r?a:null}get width(){return this.#Q}get height(){return this.#I}set width(e){this.#Q=e}set height(e){this.#I=e}get key(){return this.#Se}get image(){return this.#Re}set image(e){this.#le&&(this.#le._isTextureRecalculated=!0),this.#Re=e}get imageIndex(){return this.#we}set imageIndex(e){this.#we=e}get spacing(){return this.#be}get hasAnimations(){return this.#ye.size>0}get activeAnimation(){return this.#ve}get boundaries(){return this.#$}get vertices(){return this.#$}get circleBoundaries(){return this.#Ie}_processActiveAnimations(){const e=this.#ve;if(e){const t=this.#ye.get(e);t.iterateAnimationIndex(),this.#we=t.currentSprite}}get _textureStorage(){return this.#le}set _textureStorage(e){this.#le=e}emit(e,...t){const i=new Event(e);i.data=[...t],this.#xe.dispatchEvent(i)}addEventListener(e,t,i){this.#xe.addEventListener(e,t,i)}removeEventListener(e,t,i){this.#xe.removeEventListener(e,t,i)}addAnimation(e,t,i){this.#Oe(t)||S(u," animationSpriteIndexes should be Array of indexes, or Array of objects {duration:number, id:number}");const s=new V(e,t,i);this.#ye.set(e,s),this.addEventListener(e,this.#Pe)}#Oe(e){let t=!0;return e.forEach((e=>{"number"!=typeof e&&("number"==typeof e.duration&&"number"==typeof e.id||(t=!1))})),t}#Pe=e=>{const t=e.type,i=this.#ye.get(t);this.#ve&&this.#ve!==t&&this.stopRepeatedAnimation(this.#ve),i.activateAnimation(),this.#ve=t,this.#we=i.currentSprite};stopRepeatedAnimation(e){this.#ye.get(e).deactivateAnimation(),this.#ve=null}removeAllAnimations(){for(let[e,t]of this.#ye.entries())this.removeEventListener(e,t.activateAnimation),t.deactivateAnimation();this.#ye.clear(),this.#ye=void 0}destroy(){this.removeAllAnimations(),super.destroy()}}class z extends N{#$;constructor(e,t){super(l.DRAW_TYPE.LINE,e[0][0],e[0][1],t),this.#$=e}get vertices(){return this.#$}set vertices(e){this.#$=e}}class X extends N{#$;constructor(e,t){super(l.DRAW_TYPE.POLYGON,e[0].x,e[0].y,t),this.#$=this._convertVerticesArray(e)}get vertices(){return this.#$}set vertices(e){this.#$=e}}class H extends N{#ce;#$;constructor(e,t,i,s){super(l.DRAW_TYPE.CIRCLE,e,t,s),this.#ce=i,this.#$=this._interpolateConus(i)}get vertices(){return this.#$}set vertices(e){this.#$=e}get radius(){return this.#ce}}class K{#Ce;#Me;#De;#Le;#Be="-#-";#Ne;#We;#Ge;#Fe;#ke;#q;#z=0;#ye=new Map;#m;constructor(e,t,i,s,n,r,a=!1,o){this.#Ce=e,this.#Me=t,this.#De=i,this.#Le=s,this.#We=[],this.#Ne=n,this.#Ge=r,this.#Fe=a,this.#ke=a||!1,o&&this.setMask(o),this.#je(s)}get layerKey(){return this.#Ce}get tileMapKey(){return this.#Me}get tilemap(){return this.#De}get tilesets(){return this.#Le}get tilesetImages(){return this.#Ne}get layerData(){return this.#Ge}get setBoundaries(){return this.#Fe}get drawBoundaries(){return this.#ke}set drawBoundaries(e){this.#ke=e}get _maskId(){return this.#q}setMask(e){e._isMask=!0,this.#q=e.id}removeMask(){this.#q=null}get sortIndex(){return this.#z}set sortIndex(e){this.#z=e}get isOffsetTurnedOff(){return this.#m}turnOffOffset(){this.#m=!0}get hasAnimations(){return this.#ye.size>0}get _textureStorages(){return this.#We}_setTextureStorage(e,t){this.#We[e]=t}#je(e){for(let t of e){const e=t.data.tiles,i=t.data.name;if(e)for(let s of e){const e=s.animation,n=s.objectgroup,r=s.id;if(e){const s=i+this.#Be+r,n=this.#Ue(e),a=new V(s,n,!0);this.#ye.set(s,a),t.data._hasAnimations||(t.data._hasAnimations=!0,t.data._animations=new Map,t.data._animations.set(r,n[0][0])),this.#Pe(a)}n&&(t.data._hasBoundaries||(t.data._hasBoundaries=!0,t.data._boundaries=new Map),t.data._boundaries.set(r,n))}}}#Ue(e){return e.map((e=>({duration:e.duration,id:e.tileid})))}_processActiveAnimations(){for(let e of this.#ye.values())e.isActive&&(e.iterateAnimationIndex(),this.#Ve(e))}#Pe=e=>{e.activateAnimation(),this.#Ve(e)};#Ve=e=>{const[t,i]=e.name.split(this.#Be),s=this.#Le.findIndex((e=>e.data.name===t));this.#Le[s].data._animations.set(parseInt(i),e.currentSprite)};stopRepeatedAnimation(e){this.#ye.get(e).deactivateAnimation()}removeAllAnimations(){for(let[e,t]of this.#ye.entries())this.removeEventListener(e,t.activateAnimation),t.deactivateAnimation();this.#ye.clear(),this.#ye=void 0}destroy(){this.removeAllAnimations(),super.destroy()}}class q{#Ye;#ze;constructor(e){this.#Ye=e}get stageData(){return this.#ze}#Xe(e){return this.#ze._renderObject=e,this.#ze._sortRenderObjectsBySortIndex(),e}rect(e,t,i,s,n){const r=new W(e,t,i,s,n);return this.#Xe(r),r}text(e,t,i,s,n){const r=new j(e,t,i,s,n);return this.#Xe(r),r}conus(e,t,i,s,n,r=0){const a=new U(e,t,i,s,n,r);return this.#Xe(a),a}circle(e,t,i,s){const n=new H(e,t,i,s);return this.#Xe(n),n}image(e,t,i,s,n,r=0,a,o=0){const l=this.#Ye.getImage(n);l||S(d,"iLoader can't get the image with key: "+n);const h=new Y(e,t,i,s,n,r,a,l,o);return this.#Xe(h),h}line(e,t){const i=new z(e,t);return this.#Xe(i),i}polygon(e,t){const i=new X(e,t);return this.#Xe(i),i}tiledLayer(e,t,i,s){const n=this.#Ye.getTileMap(t),r=n.tilesets,a=r.map((e=>this.#Ye.getImage(e.data.name))),o=n.layers.find((t=>t.name===e)),l=new K(e,t,n,r,a,o,i,s);return this.#Xe(l),l}_registerNewObjectMethod=(e,t)=>{this[e]=(...e)=>this.#He(t,...e)};#He=(e,...t)=>{const i=e(...t);return this.#Xe(i),i};_attachPageData=e=>{this.#ze=e};_detachPageData=()=>{this.#ze=null}}class Z{constructor(){}static mode=l.MODE.DEBUG;static gameOptions={library:l.LIBRARY.WEBGL,optimization:l.OPTIMIZATION.NATIVE_JS.OPTIMIZED,optimizationWASMUrl:"/src/wa/calculateBufferDataWat.wasm",optimizationAssemblyUrl:"/src/wa/calculateBufferDataAssembly.wasm",loadingScreen:{backgroundColor:"rgba(128, 128, 128, 0.6)",loadingBarBg:"rgba(128, 128, 128, 1)",loadingBarProgress:"rgba(128, 128, 128, 0.2)"},render:{minCycleTime:16.666,cyclesTimeCalc:{check:l.OPTIMIZATION.CYCLE_TIME_CALC.AVERAGES,averageFPStime:1e4},boundaries:{mapBoundariesEnabled:!0,realtimeCalculations:!0,wholeWorldPrecalculations:!1}},debug:{checkWebGlErrors:!1,debugMobileTouch:!1,boundaries:{drawLayerBoundaries:!1,drawObjectBoundaries:!1,boundariesColor:"rgba(224, 12, 21, 0.6)",boundariesWidth:2},delayBetweenObjectRender:!1}};static network={address:"https://gameserver.reslc.ru:9009",gatherRoomsInfoInterval:5e3};static canvasMaxSize={width:1800,height:1800};static worldSize={width:960,height:960};static defaultCanvasKey="default";static customSettings={}}class J{static debug(...e){Z.mode===l.MODE.DEBUG&&e.forEach((e=>console.log(e)))}}class Q extends Event{#Ke;constructor(e,t){super(e),this.#qe(e)||S("UNEXPECTED_EVENT_NAME",", Please check if event is exist"),this.#Ke=t}#qe(e){return Object.values(l.EVENTS.WEBSOCKET.SERVER_CLIENT).find((t=>t===e))}get data(){return this.#Ke}}class $ extends EventTarget{#Ze;#Je;constructor(e){super(),e||S(h,"systemSettings should be passed to class instance"),this.#Ze=e}init(){n.e(319).then(n.bind(n,319)).then((e=>{this.#Je=e.io(this.#Ze.network.address,{withCredentials:!0}),this.#Qe()}))}get isServerConnected(){return!(!this.#Je||!this.#Je.connected)}get playerId(){return this.#Je.id}sendGatherRoomsInfo(){this.#Je.emit(l.EVENTS.WEBSOCKET.CLIENT_SERVER.ROOMS_INFO_REQUEST)}sendCreateOrJoinRoom(e,t){this.#Je.emit(l.EVENTS.WEBSOCKET.CLIENT_SERVER.CREATE_OR_JOIN,e,t)}sendMessage(e){this.#Je.emit(l.EVENTS.WEBSOCKET.CLIENT_SERVER.CLIENT_MESSAGE,e)}#$e=()=>{J.debug("connected, socket id: "+this.#Je.id),this.dispatchEvent(new Event(l.EVENTS.WEBSOCKET.SERVER_CLIENT.CONNECTION_STATUS_CHANGED))};#et=e=>{J.debug("server disconnected, reason: "+e),this.dispatchEvent(new Event(l.EVENTS.WEBSOCKET.SERVER_CLIENT.CONNECTION_STATUS_CHANGED))};#tt=e=>{console.warn("server data: ",e)};#it=e=>{J.debug("received new message from server: "+e),this.dispatchEvent(new Q(l.EVENTS.WEBSOCKET.SERVER_CLIENT.SERVER_MESSAGE,e))};#st=e=>{J.debug("received roomsInfo "+e),this.dispatchEvent(new Q(l.EVENTS.WEBSOCKET.SERVER_CLIENT.ROOMS_INFO,e))};#nt=(e,t)=>{J.debug("CLIENT SOCKET: Created room "+e),this.dispatchEvent(new Q(l.EVENTS.WEBSOCKET.SERVER_CLIENT.CREATED,{room:e,map:t}))};#rt=e=>{J.debug("CLIENT SOCKET: Room is full, can't join: "+e),this.dispatchEvent(new Q(l.EVENTS.WEBSOCKET.SERVER_CLIENT.FULL,{room:e}))};#at=(e,t)=>{J.debug("CLIENT SOCKET: Joined to room: "+e,", map: ",t),this.dispatchEvent(new Q(l.EVENTS.WEBSOCKET.SERVER_CLIENT.JOINED,{room:e,map:t}))};#ot=e=>{this.dispatchEvent(new Q(l.EVENTS.WEBSOCKET.SERVER_CLIENT.DISCONNECTED,{playerId:e}))};#Qe(){this.#Je.on("connect",this.#$e),this.#Je.on("disconnect",this.#et),this.#Je.on("data",this.#tt),this.#Je.on("roomsInfo",this.#st),this.#Je.on("created",this.#nt),this.#Je.on("full",this.#rt),this.#Je.on("joined",this.#at),this.#Je.on("log",(function(e){console.log.apply(console,e)})),this.#Je.on("message",this.#it),this.#Je.on("removed",(function(e){console.log("removed message"),console.log(e)})),this.#Je.on("disconnected",this.#ot),addEventListener("beforeunload",this.#lt)}#lt=()=>{this.#Je.disconnect()}}class ee{#ht=.5;#ct=new Map;#dt;constructor(e){this.#dt=e}getAudio=e=>{const t=this.#ct.get(e);return null===t?(R(T,"Audio with key "+e+" exists, but not actually loaded"),t):t||(R(A,""),null)};getAudioCloned=e=>{const t=this.#ct.get(e);if(null===t)return R(T,"Audio with key "+e+" exists, but not actually loaded"),t;if(t){const e=t.cloneNode();return e.volume=this.#ht,e}return R(A),null};set volume(e){this.#ht=e,this.#ut(e)}get volume(){return this.#ht}#ut(e){for(const t of this.#ct.values())t&&(t.volume=e)}registerAudio(e){let t=this.#dt.getAudio(e);this.#ct.set(e,t)}}function te(){return/Android|webOS|iPhone|iPad|iPod|Opera Mini/i.test(navigator.userAgent)}function ie(){return/^((?!chrome|android).)*safari/i.test(navigator.userAgent)}function se(e,t,i){return new k(e,t,i.x,i.y).length-i.r}function ne(e,t){const i=t.x1,s=t.y1,n=t.x2,r=t.y2,a=e.x1,o=e.y1,l=i,h=s,c=n-i,d=r-s,u=a,g=o,m=e.x2-a,f=e.y2-o,E=Math.sqrt(c*c+d*d),_=Math.sqrt(m*m+f*f);if(c/E==m/_&&d/E==f/_)return null;const A=(c*(g-h)+d*(l-u))/(m*d-f*c),T=(u+m*A-l)/c;return T<0||isNaN(T)||A<0||A>1?null:{x:l+c*T,y:h+d*T,p:T}}function re(e,t){const i=t.x1,s=t.y1,n=t.x2,r=t.y2,a=e.x1,o=e.y1,l=e.x2,h=e.y2,c=(i-n)*(o-h)-(s-r)*(a-l);if(0===c)return;let d=((i*r-s*n)*(a-l)-(i-n)*(a*h-o*l))/c,u=((i*r-s*n)*(o-h)-(s-r)*(a*h-o*l))/c;const g={x:d,y:u};return de(g,e,1e-13)&&de(g,t,1e-13)?{x:d,y:u,p:Math.sqrt(Math.pow(d-i,2)+Math.pow(u-s,2))}:void 0}function ae(e,t,i,s){return Math.atan2(s-t,i-e)}function oe(e,t,i){const s=e.x-t.x,n=i.x-t.x,r=e.y-t.y,a=i.y-t.y,o=Math.sqrt(s*s+r*r),l=Math.sqrt(n*n+a*a);return Math.acos((s*n+r*a)/(o*l))}function le(e,t,i){return e*t*Math.cos(i)}function he(e,t){return e.x*t.x+e.y*t.y}function ce(e,t){return e.x*t.y-t.x*e.y}function de(e,t,i=0){return(e.x>=t.x1-i&&e.x<=t.x2+i||e.x<=t.x1+i&&e.x>=t.x2-i)&&(e.y>=t.y1-i&&e.y<=t.y2+i||e.y<=t.y1+i&&e.y>=t.y2-i)}function ue(e,t){return new k(e.x,e.y,t.x,t.y).length}function ge(e,t){return new k(e.x1,e.y1,e.x2,e.y2).length0&&n%2!=0}function Ae(e,t,i){return e>=i.x&&e<=i.width+i.x&&t>=i.y&&t<=i.y+i.height}function Te(e,t,i){const s=i.r;return new k(e,t,i.x,i.y).length0&&m>0?(f=ce(l,h)/u,f<0&&(f*=-1)):f=Math.min(l.length,h.length),f<=i}function Se(e,t){const i=e[0],s=e[1],n=e[2],r=e[3],a={x:i-t[0][0],y:s-t[0][1]},o={x:i-t[1][0],y:s-t[1][1]},l=Math.sqrt(Math.pow(a.x,2)+Math.pow(a.y,2)),h=Math.sqrt(Math.pow(o.x,2)+Math.pow(o.y,2)),c=Math.min(l,h);if(c>Math.max(n,r))return!1;const d=c===l?a:o,u=Math.atan2(d.y,d.x),g={x:0-Math.cos(u)*n,y:0-Math.sin(u)*r};return!(c>Math.sqrt(Math.pow(g.x,2)+Math.pow(g.y,2)))}function Re(e,t){const i=e[0],s=e[1],n={x:i-t.x,y:s-t.y},r=Math.sqrt(Math.pow(n.x,2)+Math.pow(n.y,2));if(r>Math.max(e[2],e[3])+t.r)return!1;{const n=ae(i,s,t.x,t.y),a=i-(i+e[2]*Math.cos(n)),o=s-(s+e[3]*Math.sin(n));return r<=Math.sqrt(Math.pow(a,2)+Math.pow(o,2))+t.r&&{x:a,y:o,p:1}}}function xe(e,t){const i=t.length;for(let s=0;s{const e=this.#Et;return e.enable(e.BLEND),e.enable(e.STENCIL_TEST),e.stencilFunc(e.ALWAYS,1,255),e.stencilOp(e.KEEP,e.KEEP,e.REPLACE),Promise.resolve()};_initiateWasm=()=>{const e=this.#Tt.optimization===l.OPTIMIZATION.WEB_ASSEMBLY.NATIVE_WAT?this.#Tt.optimizationWASMUrl:this.#Tt.optimizationAssemblyUrl;return new Promise(((t,i)=>{this.layerData=new WebAssembly.Memory({initial:1e3}),this.layerDataFloat32=new Float32Array(this.layerData.buffer);const s={env:{memory:this.layerData,logi:console.log,logf:console.log}};fetch(e).then((e=>e.arrayBuffer())).then((e=>WebAssembly.instantiate(e,s))).then((e=>{this.calculateBufferData=e.instance.exports.calculateBufferData,t()}))}))};_clearView(){const e=this.#Et;e.clearColor(0,0,0,0),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT|e.STENCIL_BUFFER_BIT)}_render(e,t,i=0){const s=this.#Et,n=this.#At?s.getError():0;if(0!==n)throw console.error(n),new Error("Error num: "+n);return s.drawArrays(t,i,e),s.stencilFunc(s.ALWAYS,1,255),new Promise(((e,t)=>{this.#Tt.debug.delayBetweenObjectRender?setTimeout((()=>{e()}),1e3):e()}))}_registerAndCompileWebGlProgram(e,t,i,s,n){const r=this.#yt(t,i),a=this.#vt(r,s,n);return this.#Rt.set(e,r),this.#xt.set(e,a),Promise.resolve()}#yt(e,t){const i=this.#Et,s=i.createProgram();if(s){const n=this.#wt(i,e,i.VERTEX_SHADER);n?i.attachShader(s,n):S(g,"#compileShader(vertexShaderSource) is null");const r=this.#wt(i,t,i.FRAGMENT_SHADER);if(r?i.attachShader(s,r):S(g,"#compileShader(fragmentShaderSource) is null"),i.linkProgram(s),!i.getProgramParameter(s,i.LINK_STATUS)){const e=i.getProgramInfoLog(s);S(g,`Could not compile WebGL program. \n\n${e}`)}}else S(g,"gl.createProgram() is null");return s}#vt(e,t,i){const s=this.#Et;let n={};return t.forEach((t=>{n[t]=s.getUniformLocation(e,t)})),i.forEach((t=>{n[t]=s.getAttribLocation(e,t)})),n}#wt(e,t,i){const s=e.createShader(i);if(s){if(e.shaderSource(s,t),e.compileShader(s),!e.getShaderParameter(s,e.COMPILE_STATUS)){const t=e.getShaderInfoLog(s);S(g,"Couldn't compile webGl program. \n\n"+t)}}else S(g,`gl.createShader(${i}) is null`);return s}_bindPrimitives=(e,t,i,s,n)=>{const[r,a]=!0===e.isOffsetTurnedOff?[0,0]:i.worldOffset,o=e.x-r,h=e.y-a,c=[1,1],d=e.rotation,u=e.blendFunc?e.blendFunc:[t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA],{u_translation:g,u_rotation:m,u_scale:f,u_resolution:E,u_color:_,a_position:A,u_fade_min:T}=n;let S=0;switch(t.useProgram(s),t.uniform2f(E,t.canvas.width,t.canvas.height),t.uniform2f(g,o,h),t.uniform2f(f,c[0],c[1]),t.uniform1f(m,d),t.uniform1f(T,0),t.enableVertexAttribArray(A),t.bindBuffer(t.ARRAY_BUFFER,this.#pt),e.type){case l.DRAW_TYPE.RECTANGLE:this.#bt(e.width,e.height),S+=6;break;case l.DRAW_TYPE.TEXT:break;case l.DRAW_TYPE.CIRCLE:{const i=e.vertices;t.bufferData(t.ARRAY_BUFFER,new Float32Array(i),t.STATIC_DRAW),S+=i.length/2;break}case l.DRAW_TYPE.POLYGON:{const t=this.#It(e.vertices);this.#Ot(t);const i=t.length;if(i%3!=0)return R(p,`polygons ${e.id}, vertices are not correct, skip drawing`),Promise.reject();S+=i/2;break}}const x=t.FLOAT;t.vertexAttribPointer(A,2,x,!1,0,0);const y=this.#Pt(e.bgColor);return t.uniform4f(_,y[0]/255,y[1]/255,y[2]/255,y[3]),u&&t.blendFunc(u[0],u[1]),e.isMaskAttached?t.stencilFunc(t.EQUAL,e._maskId,255):e._isMask&&t.stencilFunc(t.ALWAYS,e.id,255),Promise.resolve([S,t.TRIANGLES])};_bindConus=(e,t,i,s,n)=>{const[r,a]=!0===e.isOffsetTurnedOff?[0,0]:i.worldOffset,o=e.x-r,l=e.y-a,h=[1,1],c=e.rotation,{u_translation:d,u_rotation:u,u_scale:g,u_resolution:m,u_color:f,a_position:E,u_fade_max:_,u_fade_min:A}=n,T=e.vertices,p=e.bgColor,S=e.fade_min,R=e.radius,x=e.blendFunc?e.blendFunc:[t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA];let y=0;t.useProgram(s),t.uniform2f(m,t.canvas.width,t.canvas.height),t.uniform2f(d,o,l),t.uniform2f(g,h[0],h[1]),t.uniform1f(u,c),t.uniform1f(A,S),t.uniform1f(_,R),t.bindBuffer(t.ARRAY_BUFFER,this.#pt),t.bufferData(t.ARRAY_BUFFER,new Float32Array(T),t.STATIC_DRAW),t.enableVertexAttribArray(E);const v=t.FLOAT;t.vertexAttribPointer(E,2,v,!1,0,0),y+=T.length/2,x&&t.blendFunc(x[0],x[1]);const w=this.#Pt(p);return t.uniform4f(f,w[0]/255,w[1]/255,w[2]/255,w[3]),e.isMaskAttached?t.stencilFunc(t.EQUAL,e._maskId,255):e._isMask&&t.stencilFunc(t.ALWAYS,e.id,255),Promise.resolve([y,t.TRIANGLE_FAN])};_bindText=(e,t,i,s,n)=>{const{u_translation:r,u_rotation:a,u_scale:o,u_resolution:l,a_position:h,a_texCoord:c,u_image:d}=n,{width:u,height:g}=e.boundariesBox,[m,f]=(e.text,!0===e.isOffsetTurnedOff?[0,0]:i.worldOffset),E=e.x-m,_=e.y-f-g,A=e.blendFunc?e.blendFunc:[t.ONE,t.ONE_MINUS_SRC_ALPHA],T=[1,1],p=E+u,S=_+g,R=[E,_,p,_,E,S,E,S,p,_,p,S];let x=0;t.useProgram(s),t.uniform2f(l,t.canvas.width,t.canvas.height),t.uniform2f(r,E,_),t.uniform2f(o,T[0],T[1]),t.uniform1f(a,0),t.bindBuffer(t.ARRAY_BUFFER,this.#pt),t.bufferData(t.ARRAY_BUFFER,new Float32Array(R),t.STATIC_DRAW),t.enableVertexAttribArray(h);const y=t.FLOAT;t.vertexAttribPointer(h,2,y,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,this.#St),t.bufferData(t.ARRAY_BUFFER,new Float32Array([0,0,1,0,0,1,0,1,1,0,1,1]),t.STATIC_DRAW),t.enableVertexAttribArray(c),t.vertexAttribPointer(c,2,t.FLOAT,!1,0,0),x+=6,t.blendFunc(A[0],A[1]);let v=e._textureStorage;return v||(v=new Ie(t.createTexture()),e._textureStorage=v),!0===v._isTextureRecalculated?(this.#Ct(t,v._texture,e._textureCanvas),v._isTextureRecalculated=!1):this.#Mt(t,v._texture),t.uniform1i(d,v._textureIndex),t.depthMask(!1),Promise.resolve([6,t.TRIANGLES])};_bindImage=(e,t,i,s,n)=>{const{u_translation:r,u_rotation:a,u_scale:o,u_resolution:l,a_position:h,a_texCoord:c,u_image:d}=n,[u,g]=!0===e.isOffsetTurnedOff?[0,0]:i.worldOffset,m=e.x-u,f=e.y-g,E=e.image,_=e.imageIndex,A=(e.key,e._maskId),T=e.spacing,p=e.blendFunc?e.blendFunc:[t.ONE,t.ONE_MINUS_SRC_ALPHA],S=[1,1];let R=0,x=0,y=0,v=0,w=0;if(0!==_){const t=(E.width+T)/(e.width+T);y=_%t,v=Math.floor(_/t),R=y*e.width+y*T,x=v*e.height+v*T}const b=m-e.width/2,I=f-e.height/2,O=b+e.width,P=I+e.height,C=1/E.width*R,M=1/E.height*x,D=C+1/E.width*e.width,L=M+1/E.height*e.height,B=[b,I,O,I,b,P,b,P,O,I,O,P],N=[C,M,D,M,C,L,C,L,D,M,D,L];t.useProgram(s),t.uniform2f(l,t.canvas.width,t.canvas.height),t.uniform2f(r,m,f),t.uniform2f(o,S[0],S[1]),t.uniform1f(a,e.rotation),t.bindBuffer(t.ARRAY_BUFFER,this.#pt),t.bufferData(t.ARRAY_BUFFER,new Float32Array(B),t.STATIC_DRAW),w+=B.length/2,t.enableVertexAttribArray(h);const W=t.FLOAT;t.vertexAttribPointer(h,2,W,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,this.#St),t.bufferData(t.ARRAY_BUFFER,new Float32Array(N),t.STATIC_DRAW),t.enableVertexAttribArray(c),t.vertexAttribPointer(c,2,t.FLOAT,!1,0,0);let G=e._textureStorage;return G||(G=new Ie(t.createTexture()),e._textureStorage=G),!0===G._isTextureRecalculated?(this.#Dt(t,G._texture,e.image),G._isTextureRecalculated=!1):this.#Mt(t,G._texture),t.uniform1i(d,G._textureIndex),t.blendFunc(p[0],p[1]),A&&t.stencilFunc(t.EQUAL,A,255),Promise.resolve([w,t.TRIANGLES])};_bindTileImages=async(e,t,i,s,n)=>{const{u_translation:r,u_rotation:a,u_scale:o,u_resolution:h,a_position:c,a_texCoord:d,u_image:u}=n;let g;switch(t.useProgram(s),this.#Tt.optimization){case l.OPTIMIZATION.NATIVE_JS.NOT_OPTIMIZED:g=await this.#Lt(e,i);break;case l.OPTIMIZATION.WEB_ASSEMBLY.ASSEMBLY_SCRIPT:case l.OPTIMIZATION.WEB_ASSEMBLY.NATIVE_WAT:g=await this.#Bt(e,i);break;case l.OPTIMIZATION.NATIVE_JS.OPTIMIZED:default:g=await this.#Nt(e,i)}const m=[0,0],f=[1,1],E=["ONE","ONE_MINUS_SRC_ALPHA"],_=e._maskId;let A=0,T=!1;for(let i=0;i0&&l.length>0){T&&await this._render(A,t.TRIANGLES),t.uniform2f(h,t.canvas.width,t.canvas.height),t.uniform2f(r,m[0],m[1]),t.uniform2f(o,f[0],f[1]),t.uniform1f(a,0),t.bindBuffer(t.ARRAY_BUFFER,this.#pt),t.bufferData(t.ARRAY_BUFFER,n,t.STATIC_DRAW),t.enableVertexAttribArray(c);const s=2,g=t.FLOAT,S=!1,R=0,x=0;t.vertexAttribPointer(c,s,g,S,R,x),t.bindBuffer(t.ARRAY_BUFFER,this.#St),t.bufferData(t.ARRAY_BUFFER,l,t.STATIC_DRAW),t.enableVertexAttribArray(d),t.vertexAttribPointer(d,2,t.FLOAT,!1,0,x);let y=e._textureStorages[i];y||(y=new Ie(t.createTexture(),i),e._setTextureStorage(i,y)),!0===y._isTextureRecalculated?(this.#Dt(t,y._texture,p,y._textureIndex),y._isTextureRecalculated=!1):this.#Mt(t,y._texture,y._textureIndex),t.uniform1i(u,y._textureIndex),t.blendFunc(t[E[0]],t[E[1]]),A=n.length/2,_&&t.stencilFunc(t.EQUAL,_,255),T=!0}}return Promise.resolve([A,t.TRIANGLES])};_drawPolygon(e,t){const[i,s]=!0===e.isOffsetTurnedOff?[0,0]:t.worldOffset,n=e.x-i,r=e.y-s,a=e.rotation||0,o=e.vertices,h=this.#Tt.debug.boundaries.boundariesColor,c=this.getProgram(l.WEBGL.DRAW_PROGRAMS.PRIMITIVES),{u_translation:d,u_rotation:u,u_scale:g,u_resolution:m,u_color:f,a_position:E,u_fade_max:_,u_fade_min:A}=this.getProgramVarLocations(l.WEBGL.DRAW_PROGRAMS.PRIMITIVES),T=this.#Et;let S=0;T.useProgram(c),T.uniform2f(m,T.canvas.width,T.canvas.height),T.uniform2f(d,n,r),T.uniform2f(g,1,1),T.uniform1f(u,a),T.uniform1f(A,0),T.enableVertexAttribArray(E),T.bindBuffer(T.ARRAY_BUFFER,this.#pt);const x=this.#It(o),y=x.length;if(y%3!=0)return void R(p,"polygon boundaries vertices are not correct, skip drawing");this.#Ot(x),S+=y/2;const v=T.FLOAT;T.vertexAttribPointer(E,2,v,!1,0,0);const w=this.#Pt(h);T.uniform4f(f,w[0]/255,w[1]/255,w[2]/255,w[3]),this._render(S,T.TRIANGLES)}_bindLine=(e,t,i,s,n)=>{const[r,a]=!0===e.isOffsetTurnedOff?[0,0]:i.worldOffset,o=e.x-r,l=e.y-a,h=e.rotation,{u_translation:c,u_rotation:d,u_scale:u,u_resolution:g,u_color:m,a_position:f,u_fade_max:E,u_fade_min:_}=n,A=e.vertices,T=e.bgColor,p=(e.fade_min,e.radius,this.#Tt.debug.boundaries.boundariesWidth);let S=0;t.useProgram(s),t.uniform2f(g,t.canvas.width,t.canvas.height),t.uniform2f(c,o,l),t.uniform2f(u,1,1),t.uniform1f(d,h),t.uniform1f(_,0),t.enableVertexAttribArray(f),t.bindBuffer(t.ARRAY_BUFFER,this.#pt),t.bufferData(t.ARRAY_BUFFER,new Float32Array(A),t.STATIC_DRAW),S+=A.length/2;const R=t.FLOAT;t.vertexAttribPointer(f,2,R,!1,0,0);const x=this.#Pt(T);return t.uniform4f(m,x[0]/255,x[1]/255,x[2]/255,x[3]),t.lineWidth(p),Promise.resolve([0,t.LINES])};_drawLines(e,t,i=1,s=0,n=[0,0]){const r=this.getProgram(l.WEBGL.DRAW_PROGRAMS.PRIMITIVES),{u_translation:a,u_rotation:o,u_scale:h,u_resolution:c,u_color:d,a_position:u,u_fade_max:g,u_fade_min:m}=this.getProgramVarLocations(l.WEBGL.DRAW_PROGRAMS.PRIMITIVES),f=this.#Et;let E=0;f.useProgram(r),f.uniform2f(c,f.canvas.width,f.canvas.height),f.uniform2f(a,n[0],n[1]),f.uniform2f(h,1,1),f.uniform1f(o,s),f.uniform1f(m,0),f.enableVertexAttribArray(u),f.bindBuffer(f.ARRAY_BUFFER,this.#pt),f.bufferData(f.ARRAY_BUFFER,new Float32Array(e),f.STATIC_DRAW),E+=e.length/2;const _=f.FLOAT;f.vertexAttribPointer(u,2,_,!1,0,0);const A=this.#Pt(t);f.uniform4f(d,A[0]/255,A[1]/255,A[2]/255,A[3]),f.lineWidth(i),this._render(E,f.LINES)}#Nt(e,t){return new Promise(((i,s)=>{const n=e.tilemap,r=e.tilesets,a=e.tilesetImages,o=e.layerData,{tileheight:l,tilewidth:h}=n,c=h,d=l,[u,g]=t.worldDimensions,[f,E]=t.canvasDimensions,[A,T]=!0===e.isOffsetTurnedOff?[0,0]:t.worldOffset,p=(this.#Tt.render.boundaries.realtimeCalculations,e.setBoundaries);let S=new Map,x=[],y=[],v=[],w=[];o||(R(m,"check tilemap and layers name"),s());for(let e=0;eE?Math.ceil(E/d)+1:L,U=B>f?Math.ceil(f/c)+1:D,V=D-U-k,Y=i.spacing,z=(i.margin,i._hasAnimations),X=[],H=[],K=i._hasBoundaries,q=i._boundaries;B===u&&N===g||(R(_," World size from tilemap is different than settings one, fixing..."),t._setWorldDimensions(B,N)),p&&this.#Tt.render.boundaries.mapBoundariesEnabled&&t._setMapBoundaries();let Z=F*D;for(let e=0;e=s&&r0){const e=q.get(r);e&&(i=!0,e.objects.forEach((e=>{const t=a+e.x,i=o+e.y;if(0!==e.rotation&&R("tilesetData.tiles.rotation property is not supported yet"),e.polygon)e.polygon.forEach(((s,n)=>{const r=e.polygon[n+1];if(r)x.push([s.x+t,s.y+i,r.x+t,r.y+i]);else{const n=e.polygon[0];x.push([s.x+t,s.y+i,n.x+t,n.y+i])}}));else if(e.point)v.push([t,i]);else if(e.ellipse){const s=e.width/2,n=e.height/2;y.push([t+s,i+n,s,n])}else{const s=e.width,n=e.height,r=s+t,a=n+i;x.push([t,i,r,i]),x.push([r,i,r,a]),x.push([r,a,t,a]),x.push([t,a,t,i])}})))}if(!1===i){let i=[a+b,o,a+b,o+I],s=[a+b,o+I,a,o+I],r=[a,o,a+b,o],l=[a,o+I,a,o],h=[null,null,null,null];const c=0!==e?S.get(e-1):void 0;if(c){const e=c.get(n);if(e){const t=e[2],s=x[t];if(s){const e=s[0],i=s[1],n=s[2],a=s[3],o=r[0],l=r[1],h=r[2],c=r[3];o===n&&l===a&&h===e&&c===i&&(x[t]=void 0,r=void 0)}const n=e[1],a=x[n];if(a){const e=a[0],t=a[1],s=a[2],r=i[0];e===i[2]&&s===r&&(x[n]=void 0,i[0]=e,i[1]=t)}const o=e[3],h=x[o];if(h){const e=h[0],t=h[2],i=h[3],s=l[0];e===l[2]&&t===s&&(x[o]=void 0,l[2]=t,l[3]=i)}}}const d=0!==n?t.get(n-1):void 0;if(d){const e=d[1],t=x[e],i=t[0],n=t[1],a=t[2],o=t[3],h=l[0],c=l[1],u=l[2],g=l[3];h===a&&c===o&&u===i&&g===n&&(x[e]=void 0,l=void 0);const m=d[0],f=x[m];if(f&&r){const e=f[0],t=f[1],i=f[3],s=r[1];t===r[3]&&i===s&&(x[m]=void 0,r[0]=e,r[1]=t)}const E=d[2],_=x[E];if(_){const e=_[1],t=_[2],i=_[3],n=s[1];e===s[3]&&i===n&&(x[E]=void 0,s[2]=t,s[3]=i)}}r&&(x.push(r),h[0]=x.length-1),x.push(i),h[1]=x.length-1,x.push(s),h[2]=x.length-1,l&&(x.push(l),h[3]=x.length-1),t.set(n,h)}}}Z++}t.size>0&&S.set(e,t),Z+=V}w.push([new Float32Array(X),new Float32Array(H),i.name,O])}if(p){const e=x.filter((e=>e));t._addBoundariesArray(e),y.length>0&&t._addEllipseBoundaries(y),v.length>0&&t._addPointBoundaries(v)}i(w)}))}#Lt(e,t){return new Promise(((i,s)=>{const n=e.tilemap,r=e.tilesets,a=e.tilesetImages,o=e.layerData,{tileheight:l,tilewidth:h}=n,c=h,d=l,[u,g]=(e.setBoundaries,t.worldDimensions),[f,E]=t.canvasDimensions,[A,T]=!0===e.isOffsetTurnedOff?[0,0]:t.worldOffset;let p=[];o||(R(m,"check tilemap and layers name"),s());for(let e=0;e<=r.length-1;e++){const i=r[e].data,s=r[e].firstgid,n=r[e+1],m=n?n.firstgid:1e9,S=i.tilewidth,x=i.tileheight,y=i.columns,v=o.width,w=o.height,b=c*v,I=d*w,O=(Math.ceil(f/c),Math.ceil(E/d),a[e]),P=O.width,C=O.height,M=i.spacing;i.margin;let D=0,L=[],B=[];b===u&&I===g||(R(_," World size from tilemap is different than settings one, fixing..."),t._setWorldDimensions(b,I));for(let e=0;e=s&&inew Promise(((i,s)=>{const n=e.tilemap,r=n.tilesets,a=e.tilesetImages,o=e.layerData,{tileheight:l,tilewidth:h}=n,c=h,d=l,u=o.data.length,g=o.data.filter((e=>0!==e)).length,[f,E]=t.worldDimensions,[A,T]=!0===e.isOffsetTurnedOff?[0,0]:t.worldOffset,p=[];this.layerDataFloat32.set(o.data),o||(R(m,"check tilemap and layers name"),s());for(let e=0;e0?this.layerDataFloat32.slice(u,D+u):[],G=N>0?this.layerDataFloat32.slice(D+u,D+L+u):[];p.push([W,G,i.name,O])}i(p)}));#Pt(e){return e.replace("rgba(","").replace(")","").split(",").map((e=>Number(e.trim())))}#It(e){return this.#Wt(e)}#Wt(e,t=[]){const i=e.length;if(i<=3)return e.forEach((e=>{t.push(e[0]),t.push(e[1])})),t;const s=[...e].sort(((e,t)=>t[1]-e[1])),n=e.indexOf(s[0]),r=n!==i-1?n+1:0;let a=e,o=a.length,l=0,h=r;for(;a.length>2;){const e=a.length;h>=e&&(h-=e);const i=0===h?a[e-1]:a[h-1],s=a[h],n=e===h+1?a[0]:a[h+1];if(c=i,d=s,ce({x:(u=n)[0]-c[0],y:u[1]-c[1]},{x:d[0]-c[0],y:d[1]-c[1]})<0)t.push(i[0]),t.push(i[1]),t.push(s[0]),t.push(s[1]),t.push(n[0]),t.push(n[1]),a=a.filter(((e,t)=>t!==h));else{if(l+=1,l>o)return R("TRIANGULATE_ISSUE","Can't extract all triangles vertices."),t;h++}}var c,d,u;return t}#Ot(e){this.#Et.bufferData(this.#Et.ARRAY_BUFFER,new Float32Array(e),this.#Et.STATIC_DRAW)}#bt(e,t){const i=0+e,s=0+t;this.#Et.bufferData(this.#Et.ARRAY_BUFFER,new Float32Array([0,0,i,0,0,s,0,s,i,0,i,s]),this.#Et.STATIC_DRAW)}#Dt(e,t,i,s=0,n=!1){this.#Mt(e,t,s),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,i),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,n?e.LINEAR_MIPMAP_LINEAR:e.LINEAR)}#Ct(e,t,i,s=0){this.#Mt(e,t,s),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,i),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST)}#Mt(e,t,i=0){e.activeTexture(e.TEXTURE0+i),e.bindTexture(e.TEXTURE_2D,t)}#Gt(e,t){e.deleteTexture(t)}isPowerOfTwo(e){return!(e&e-1)}nextHighestPowerOfTwo(e){--e;for(var t=1;t<32;t<<=1)e|=e>>t;return e+1}}const Pe=["u_translation","u_rotation","u_scale","u_resolution","u_image"],Ce=["a_position","a_texCoord"],Me=["u_translation","u_rotation","u_scale","u_resolution","u_fade_min","u_fade_max","u_color"],De=["a_position"];class Le{#Ft;#kt;#jt;#_e;#Ut;#Vt;#Yt;#dt;#zt;#Xt;#Ht=!1;#Kt;#xe=new EventTarget;#qt;#Zt=new Map;#Jt=[];constructor(e,t,i){this.#jt=!1,this.#Ft=document.createElement("canvas"),i.appendChild(this.#Ft),this.#kt=this.#Ft.getContext("webgl",{stencil:!0}),this.#Yt=e,this.#dt=t,this.#zt=[],this.#Kt=this.systemSettings.gameOptions.render.minCycleTime,this.#Ht=this.systemSettings.gameOptions.render.boundaries.wholeWorldPrecalculations,this.#Ut=new Oe(this.#kt,this.#Yt.gameOptions),this.systemSettings.gameOptions.optimization!==l.OPTIMIZATION.WEB_ASSEMBLY.NATIVE_WAT&&this.systemSettings.gameOptions.optimization!==l.OPTIMIZATION.WEB_ASSEMBLY.ASSEMBLY_SCRIPT||this._registerRenderInit(this.#Ut._initiateWasm),this._registerRenderInit(this.fixCanvasSize),this._registerRenderInit((()=>this._registerAndCompileWebGlProgram(l.WEBGL.DRAW_PROGRAMS.IMAGES,"\n attribute vec2 a_texCoord;\n\n attribute vec2 a_position;\n\n uniform vec2 u_translation;\n uniform float u_rotation;\n uniform vec2 u_scale;\n\n uniform vec2 u_resolution;\n\n varying vec2 v_texCoord;\n\n void main(void) {\n float c = cos(u_rotation);\n float s = sin(u_rotation);\n\n mat3 translationMatrix1 = mat3(\n 1, 0, 0,\n 0, 1, 0,\n u_translation.x, u_translation.y, 1\n );\n\n mat3 translationMatrix2 = mat3(\n 1, 0, 0,\n 0, 1, 0,\n -u_translation.x, -u_translation.y, 1\n );\n \n mat3 rotationMatrix = mat3(\n c, s, 0,\n -s, c, 0,\n 0, 0, 1\n );\n\n mat3 scalingMatrix = mat3(\n u_scale.x, 0, 0,\n 0, u_scale.y, 0,\n 0, 0, 1\n );\n\n mat3 matrix = translationMatrix1 * rotationMatrix * translationMatrix2 * scalingMatrix;\n \n vec2 position = (matrix * vec3(a_position, 1)).xy;\n\n vec2 clipSpace = position / u_resolution * 2.0 - 1.0;\n\n gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);\n \n v_texCoord = a_texCoord;\n }","\n precision mediump float;\n\n uniform sampler2D u_image;\n\n //texCoords passed in from the vertex shader\n varying vec2 v_texCoord;\n void main() {\n vec4 color = texture2D(u_image, v_texCoord);\n gl_FragColor = color;\n }",Pe,Ce))),this._registerRenderInit((()=>this._registerAndCompileWebGlProgram(l.WEBGL.DRAW_PROGRAMS.PRIMITIVES,"\n precision mediump float;\n\n attribute vec2 a_position;\n\n uniform vec2 u_translation;\n uniform float u_rotation;\n uniform vec2 u_scale;\n\n uniform vec2 u_resolution;\n\n void main(void) {\n float c = cos(u_rotation);\n float s = sin(u_rotation);\n\n mat3 translationMatrix1 = mat3(\n 1, 0, 0,\n 0, 1, 0,\n u_translation.x, u_translation.y, 1\n );\n\n //mat3 translationMatrix2 = mat3(\n // 1, 0, 0,\n // 0, 1, 0,\n // -u_translation.x, -u_translation.y, 1\n //);\n \n mat3 rotationMatrix = mat3(\n c, s, 0,\n -s, c, 0,\n 0, 0, 1\n );\n\n mat3 scalingMatrix = mat3(\n u_scale.x, 0, 0,\n 0, u_scale.y, 0,\n 0, 0, 1\n );\n \n mat3 matrix = translationMatrix1 * rotationMatrix * scalingMatrix;\n\n vec2 position = (matrix * vec3(a_position, 1)).xy;\n\n vec2 clipSpace = position / u_resolution * 2.0 - 1.0;\n\n gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);\n }\n","\n precision mediump float;\n\n uniform vec4 u_color;\n uniform float u_fade_min; \n uniform float u_fade_max;\n uniform vec2 u_resolution;\n uniform vec2 u_translation;\n\n void main(void) {\n vec4 p = u_color;\n if (u_fade_min > 0.0) {\n vec2 fix_tr = vec2(u_translation.x, u_resolution.y - u_translation.y); \n float distance = distance(fix_tr.xy, gl_FragCoord.xy);\n if (u_fade_min <= distance && distance <= u_fade_max) {\n float percent = ((distance - u_fade_max) / (u_fade_min - u_fade_max)) * 100.0;\n p.a = u_color.a * (percent / 100.0);\n }\n }\n\n gl_FragColor = p;\n }\n",Me,De))),this._registerRenderInit(this.#Ut._initWebGlAttributes),this._registerObjectRender(j.name,this.#Ut._bindText,l.WEBGL.DRAW_PROGRAMS.IMAGES),this._registerObjectRender(W.name,this.#Ut._bindPrimitives,l.WEBGL.DRAW_PROGRAMS.PRIMITIVES),this._registerObjectRender(X.name,this.#Ut._bindPrimitives,l.WEBGL.DRAW_PROGRAMS.PRIMITIVES),this._registerObjectRender(H.name,this.#Ut._bindConus,l.WEBGL.DRAW_PROGRAMS.PRIMITIVES),this._registerObjectRender(U.name,this.#Ut._bindConus,l.WEBGL.DRAW_PROGRAMS.PRIMITIVES),this._registerObjectRender(K.name,this.#Ut._bindTileImages,l.WEBGL.DRAW_PROGRAMS.IMAGES),this._registerObjectRender(z.name,this.#Ut._bindLine,l.WEBGL.DRAW_PROGRAMS.PRIMITIVES)}addEventListener=(e,t,i)=>{this.#xe.addEventListener(e,t,i)};removeEventListener=(e,t,i)=>{this.#xe.removeEventListener(e,t,i)};get stageData(){return this.#Vt}get systemSettings(){return this.#Yt}get iLoader(){return this.#dt}get canvas(){return this.#Ft}get drawContext(){return this.#kt}emit=(e,...t)=>{const i=new Event(e);i.data=[...t],this.#xe.dispatchEvent(i)};isAllFilesLoaded=()=>0===this.iLoader.filesWaitingForUpload;initiateContext=()=>Promise.all(this.#Jt.map((e=>e())));clearContext(){this.#Ut._clearView()}setCanvasSize(e,t){this.#Ft.width=e,this.#Ft.height=t,this.#Ut&&this.#Ut._fixCanvasSize(e,t)}fixCanvasSize=()=>{const e=this.systemSettings,t=e.canvasMaxSize.width&&e.canvasMaxSize.widthPromise.reject(e)));e.push(n)}this.systemSettings.gameOptions.debug.boundaries.drawLayerBoundaries&&e.push(this.#Qt().catch((e=>Promise.reject(e))))}return(await Promise.allSettled(e)).forEach((e=>{"rejected"===e.status&&(Promise.reject(e.reason),i=!0,t.push(e.reason))})),this.#$t(),this._isCleared=!1,!1===i?Promise.resolve():Promise.reject(t)}set _isCleared(e){this.#jt=e}get _isCleared(){return this.#jt}_createBoundariesPrecalculations(){}#$t(){}#ei(e){return new Promise(((t,i)=>{if(e.setBoundaries){const s=this.iLoader.getTileMap(e.tileMapKey),n=s.tilesets,r=s.layers.find((t=>t.name===e.layerKey)),{tileheight:a,tilewidth:o}=s,l=o,h=a,[c,d]=this.stageData.worldDimensions;let u=[];r||(R(m,"check tilemap and layers name"),i());for(let t=0;tthis.#Ut._render(e[0],e[1])))}return i.method(e,this.drawContext,this.stageData)}if(e.type===l.DRAW_TYPE.IMAGE){const t=this.#Ut.getProgram(l.WEBGL.DRAW_PROGRAMS.IMAGES),i=this.#Ut.getProgramVarLocations(l.WEBGL.DRAW_PROGRAMS.IMAGES);if(!e.image){const t=this.iLoader.getImage(e.key);t?e.image=t:S(d,"iLoader can't get the image with key: "+e.key)}return this.#Ut._bindImage(e,this.drawContext,this.stageData,t,i).then((e=>this.#Ut._render(e[0],e[1]))).then((()=>e.vertices&&this.systemSettings.gameOptions.debug.boundaries.drawObjectBoundaries?this.#Ut._drawPolygon(e,this.stageData):Promise.resolve()))}return console.warn("no registered draw object method for "+t+" skip draw"),Promise.resolve()}#Qt(){return new Promise((e=>{const t=this.stageData.getBoundaries(),i=this.stageData.getEllipseBoundaries(),s=this.stageData.getPointBoundaries(),n=(t.length,i.length),r=s.length;this.#Ut._drawLines(t.flat(),this.systemSettings.gameOptions.debug.boundaries.boundariesColor,this.systemSettings.gameOptions.debug.boundaries.boundariesWidth),n&&i.forEach((e=>{const t=be(e[0],e[1],e[2],e[3]);this.#Ut._drawPolygon({x:0,y:0,vertices:t,isOffsetTurnedOff:!0},this.stageData)})),r&&s.forEach((e=>{const t=e[0],i=e[1],s=[t,i,t+1,i+1];this.#Ut._drawLines(s,this.systemSettings.gameOptions.debug.boundaries.boundariesColor,this.systemSettings.gameOptions.debug.boundaries.boundariesWidth)})),e()}))}#ti(){const e=this.systemSettings.gameOptions.render.cyclesTimeCalc.averageFPStime,t=this.#zt.length;let i=0;for(let e=0;e{const t=this.systemSettings.gameOptions;this.#_e=!0,this.#Vt=e,this.fixCanvasSize(),t.library===l.LIBRARY.WEBGL&&(await this.#ii(),this.timeStart=Date.now(),setTimeout((()=>requestAnimationFrame(this.#si)))),t.render.cyclesTimeCalc.check===l.OPTIMIZATION.CYCLE_TIME_CALC.AVERAGES&&(this.#Xt=setInterval((()=>this.#ti()),t.render.cyclesTimeCalc.averageFPStime))};_stopRender=()=>{this.#_e=!1,this.#Vt=null,this.#zt=[],clearInterval(this.#Xt),this.#Xt=null};#ii(){return new Promise(((e,t)=>{let i=[];const s=this.#Ht;i.push(this.initiateContext()),s&&console.warn("isBoundariesPrecalculations() is turned off"),Promise.allSettled(i).then((i=>{i.forEach((e=>{if("rejected"===e.status){const i=e.reason;R(E,i),t(i)}})),e()}))}))}#si=async()=>{const e=performance.now(),t=this.#Kt,i=this.systemSettings.gameOptions.render.cyclesTimeCalc.check===l.OPTIMIZATION.CYCLE_TIME_CALC.CURRENT;this.emit(l.EVENTS.SYSTEM.RENDER.START),this.stageData._clearBoundaries(),this.clearContext(),this.render().then((()=>{const s=performance.now()-e,n=t-s,r=n>0?n:0,a=s+r;i&&s>t&&console.log("current draw take: ",s," ms"),this.emit(l.EVENTS.SYSTEM.RENDER.END),a>0&&this.#zt.push(a),this.#_e&&setTimeout((()=>requestAnimationFrame(this.#si)),r)})).catch((e=>{e.forEach?e.forEach((e=>{R(E,e)})):R(E,e.message),this._stopRender()}))}}class Be{#ni;constructor(e){this.#ni=e}registerDrawObject(e,t){this.#ni.drawObjectFactory._registerNewObjectMethod(e,t)}registerAndCompileWebGlProgram(e,t,i,s,n){return this.#ni.iRender._registerAndCompileWebGlProgram(e,t,i,s,n)}registerRenderInit(e){this.#ni.iRender._registerRenderInit(e)}registerObjectRender(e,t,i){this.#ni.iRender._registerObjectRender(e,t,i)}}class Ne{#Ze;#ri;#ai;#oi;#Ye=new D;#li;#hi=new q(this.#Ye);#ci=new Map;#di;#xe=new EventTarget;constructor(e,t,i){e||S(h,"systemSettings should be passed to class instance"),this.#Ze=e,this.#oi=new ee(this.iLoader),this.#ai=new $(e),this.#li=new Le(this.systemSettings,this.iLoader,i),this.#ri=new Be(this,this.#li),this.#di=t,this.#li.addEventListener(l.EVENTS.SYSTEM.RENDER.START,(()=>this.emit(l.EVENTS.SYSTEM.RENDER.START))),this.#li.addEventListener(l.EVENTS.SYSTEM.RENDER.END,(()=>this.emit(l.EVENTS.SYSTEM.RENDER.END)))}emit=(e,...t)=>{const i=new Event(e);i.data=[...t],this.#xe.dispatchEvent(i)};addEventListener=(e,t,i)=>{this.#xe.addEventListener(e,t,i)};removeEventListener=(e,t,i)=>{this.#xe.removeEventListener(e,t,i)};get iNetwork(){return this.#ai}get systemSettings(){return this.#Ze}get audio(){return this.#oi}get iLoader(){return this.#Ye}get iRender(){return this.#li}get drawObjectFactory(){return this.#hi}get iExtension(){return this.#ri}get modules(){return this.#ci}installModule=(e,t,...i)=>{const s=new t(this,...i);return this.#ci.has(e)?(R("MODULE_ALREADY_INSTALLED","module "+e+" is already installed"),this.#ci.get(e)):(this.#ci.set(e,s),s)};startGameStage=(e,t)=>{if(this.#di.has(e)){const i=this.#di.get(e),s=i.stageData;this.#hi._attachPageData(s),!1===i.isInitiated&&i._init(),i._start(t),this.emit(l.EVENTS.SYSTEM.START_PAGE),this.#li._startRender(s)}else S(c,"View "+e+" is not registered!")};stopGameStage=e=>{this.#di.has(e)?(this.emit(l.EVENTS.SYSTEM.STOP_PAGE),this.drawObjectFactory._detachPageData(),this.#li._stopRender(),this.#di.get(e)._stop()):S(c,"View "+e+" is not registered!")}}class We{#ui;#gi=!1;#_e;#mi;#fi;constructor(){this.#_e=!1,this.#fi=new x}_register(e,t){this.#ui=e,this.#mi=t,this.#Ei(),this.#_i(),this.register()}_init(){this.init(),this.#gi=!0}register(){}init(){}start(e){}stop(){}resize(){}get iLoader(){return this.#mi.iLoader}get draw(){return this.#mi.drawObjectFactory}_attachCanvasToContainer(e){this.#Ai(this.canvasHtmlElement,e)}addRenderObject=e=>{const t=this.stageData;-1!==t.renderObjects.indexOf(e)?R("NEW_BEHAVIOR_INTRODUCED","stage.draw methods add objects to pageData, no need to call addRenderObject"):(t._renderObject=e,t._sortRenderObjectsBySortIndex())};get isActive(){return this.#_e}get isInitiated(){return this.#gi}get name(){return this.#ui}get stageData(){return this.#fi}get systemSettings(){return this.#mi.systemSettings}get audio(){return this.#mi.audio}get iSystem(){return this.#mi}get canvasHtmlElement(){return document.getElementsByTagName("canvas")[0]}addEventListener=(e,t,i)=>{this.iSystem.addEventListener(e,t,i)};removeEventListener=(e,t,i)=>{this.iSystem.removeEventListener(e,t,i)};_start(e){this.start(e),this.#_e=!0,window.addEventListener("resize",this._resize),this._resize()}_stop(){this.#_e=!1,window.removeEventListener("resize",this._resize),this.stop()}_resize=()=>{this.#_i(),this.resize()};#Ai(e,t){t.appendChild(e)}#Ei(){const e=this.systemSettings.worldSize?this.systemSettings.worldSize.width:0,t=this.systemSettings.worldSize?this.systemSettings.worldSize.height:0;this.stageData._setWorldDimensions(e,t)}isBoundariesCollision=(e,t,i)=>{const s=i.type,n=i.vertices,r=i.circleBoundaries;switch(s){case l.DRAW_TYPE.TEXT:case l.DRAW_TYPE.RECTANGLE:case l.DRAW_TYPE.CONUS:case l.DRAW_TYPE.IMAGE:return r?this.#Ti(e,t,i.circleBoundaries.r):this.#pi(e,t,n,i.rotation);case l.DRAW_TYPE.CIRCLE:R(l.WARNING_CODES.METHOD_NOT_IMPLEMENTED,"isObjectCollision.circle check is not implemented yet!");break;case l.DRAW_TYPE.LINE:R(l.WARNING_CODES.METHOD_NOT_IMPLEMENTED,"isObjectCollision.line check is not implemented yet, please use .rect instead line!");break;default:R(l.WARNING_CODES.UNKNOWN_DRAW_OBJECT,"unknown object type!")}return!1};isObjectsCollision=(e,t,i,s)=>{const n=i.type,r=i.vertices,a=i.circleBoundaries;switch(n){case l.DRAW_TYPE.TEXT:case l.DRAW_TYPE.RECTANGLE:case l.DRAW_TYPE.CONUS:case l.DRAW_TYPE.IMAGE:return a?this.#Si(e,t,a,s):this.#Ri(e,t,r,i.rotation,s);case l.DRAW_TYPE.CIRCLE:R(l.WARNING_CODES.METHOD_NOT_IMPLEMENTED,"isObjectCollision.circle check is not implemented yet!");break;case l.DRAW_TYPE.LINE:R(l.WARNING_CODES.METHOD_NOT_IMPLEMENTED,"isObjectCollision.line check is not implemented yet, please use .rect instead line!");break;default:R(l.WARNING_CODES.UNKNOWN_DRAW_OBJECT,"unknown object type!")}return!1};#Ri(e,t,i,s,n){const r=n.length;let a=[];for(let o=0;o0?this.#yi(a):null}#Si(e,t,i,s){const n=i.r,r=s.length;let a=[];for(let i=0;i0?this.#yi(a):null}#yi(e){return e.sort(((e,t)=>e.p0)}#xi(e,t,i,s,n){const[r,a]=this.stageData.worldOffset,o=e-r,l=t-a,h=n.x-r,c=n.y-a,d=n.vertices,u=n.rotation,g=i.map((e=>this.#bi(e,o,l,s))),m=d.length;for(let e=0;e0)for(let e=0;e0)for(let e=0;ethis.#bi(e,h,c,s))),u=n.length,g=r.length,m=a.length;for(let e=0;e0)for(let e=0;e0)for(let e=0;e{const t=this.#Pi/this.#Ii;this.#Oi=e;const i=t*this.#Oi,s=e>this.#Ii?this.#Pi:i;this.loadingBarProgress.width=s};start(e){this.#Ii=e.total}}const Fe="loadingPage";class ke{#Ci;#Mi;constructor(e,t){e||S(h,"iSystemSettings should be passed to class instance"),this.#Ci=new Map,t||(t=document.createElement("div"),document.body.appendChild(t)),this.#Mi=new Ne(e,this.#Ci,t),this.registerStage(Fe,Ge),this.#Mi.iLoader.addEventListener("loadstart",this.#Di),this.#Mi.iLoader.addEventListener("progress",this.#Li),this.#Mi.iLoader.addEventListener("load",this.#Bi)}get iSystem(){return this.#Mi}registerStage(e,t){if(e&&"string"==typeof e&&e.trim().length>0){const i=new t;i._register(e,this.iSystem),this.#Ci.set(e,i)}else S(h,"valid class name should be provided")}preloadAllData(){return this.#Mi.iLoader.preload()}#Di=e=>{this.#Mi.startGameStage(Fe,{total:e.total})};#Li=e=>{const t=e.loaded,i=e.total;this.#Ci.get(Fe)._progress(t,i)};#Bi=()=>{this.#Mi.stopGameStage(Fe)}}var je=r.oX,Ue=r.QD,Ve=r.T_,Ye=r.uw,ze=r.xl,Xe=r.xP,He=r.bq,Ke=r.P6;export{je as CONST,Ue as DrawImageObject,Ve as GameStage,Ye as ISystemAudio,ze as Primitives,Xe as System,He as SystemSettings,Ke as utils}; \ No newline at end of file +var e,t,i={},s={};function n(e){var t=s[e];if(void 0!==t)return t.exports;var r=s[e]={exports:{}};return i[e](r,r.exports,n),r.exports}n.m=i,n.d=(e,t)=>{for(var i in t)n.o(t,i)&&!n.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},n.f={},n.e=e=>Promise.all(Object.keys(n.f).reduce(((t,i)=>(n.f[i](e,t),t)),[])),n.u=e=>e+".index.es6.min.js",n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),e={},t="jsge:",n.l=(i,s,r,a)=>{if(e[i])e[i].push(s);else{var o,l;if(void 0!==r)for(var h=document.getElementsByTagName("script"),c=0;c{o.onerror=o.onload=null,clearTimeout(g);var n=e[i];if(delete e[i],o.parentNode&&o.parentNode.removeChild(o),n&&n.forEach((e=>e(s))),t)return t(s)},g=setTimeout(u.bind(null,void 0,{type:"timeout",target:o}),12e4);o.onerror=u.bind(null,o.onerror),o.onload=u.bind(null,o.onload),l&&document.head.appendChild(o)}},n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{var e;if("string"==typeof import.meta.url&&(e=import.meta.url),!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),n.p=e})(),(()=>{var e={179:0};n.f.j=(t,i)=>{var s=n.o(e,t)?e[t]:void 0;if(0!==s)if(s)i.push(s[2]);else{var r=new Promise(((i,n)=>s=e[t]=[i,n]));i.push(s[2]=r);var a=n.p+n.u(t),o=new Error;n.l(a,(i=>{if(n.o(e,t)&&(0!==(s=e[t])&&(e[t]=void 0),s)){var r=i&&("load"===i.type?"missing":i.type),a=i&&i.target&&i.target.src;o.message="Loading chunk "+t+" failed.\n("+r+": "+a+")",o.name="ChunkLoadError",o.type=r,o.request=a,s[1](o)}}),"chunk-"+t,t)}};var t=(t,i)=>{var s,r,[a,o,l]=i,h=0;if(a.some((t=>0!==e[t]))){for(s in o)n.o(o,s)&&(n.m[s]=o[s]);l&&l(n)}for(t&&t(i);hl,QD:()=>Y,T_:()=>We,uw:()=>ee,xl:()=>a,xP:()=>ke,bq:()=>Z,P6:()=>o});var a={};n.r(a),n.d(a,{Rectangle:()=>F,Vector:()=>k,Vertex:()=>G});var o={};n.r(o),n.d(o,{angle_2points:()=>ae,angle_3points:()=>oe,calculateEllipseVertices:()=>be,countClosestTraversal:()=>ne,countClosestTraversal2:()=>re,countDistance:()=>ue,crossProduct:()=>ce,dotProduct:()=>he,dotProductWithAngle:()=>le,generateUniqId:()=>ye,isCircleLineIntersect:()=>pe,isEllipseCircleIntersect:()=>Re,isEllipseLineIntersect:()=>Se,isEllipsePolygonIntersect:()=>xe,isLineShorter:()=>ge,isMobile:()=>te,isPointCircleIntersect:()=>Te,isPointInsidePolygon:()=>_e,isPointLineIntersect:()=>me,isPointOnTheLine:()=>de,isPointPolygonIntersect:()=>Ee,isPointRectIntersect:()=>Ae,isPolygonLineIntersect:()=>fe,isSafari:()=>ie,pointToCircleDistance:()=>se,randomFromArray:()=>ve,verticesArrayToArrayNumbers:()=>we});const l={MODE:{DEBUG:"DEBUG",PRODUCTION:"PRODUCTION"},SCREENS:{},AUDIO:{},CONNECTION_STATUS:{DISCONNECTED:"disconnected",CONNECTED:"connected",CONNECTION_LOST:"connection lost"},EVENTS:{SYSTEM:{START_PAGE:"START_PAGE",STOP_PAGE:"STOP_PAGE",RENDER:{START:"start",END:"end"}},GAME:{BOUNDARIES_COLLISION:"BOUNDARIES_COLLISION",OBJECTS_COLLISION:"OBJECTS_COLLISION"},WEBSOCKET:{SERVER_CLIENT:{CONNECTION_STATUS_CHANGED:"CONNECTION_STATUS_CHANGED",ROOMS_INFO:"roomsInfo",CREATED:"created",JOINED:"joined",FULL:"full",DISCONNECTED:"disconnected",SERVER_MESSAGE:"message",RESTARTED:"restarted"},CLIENT_SERVER:{ROOMS_INFO_REQUEST:"gatherRoomsInfo",CREATE_OR_JOIN:"create or join",RESTART_REQUEST:"restart",CLIENT_MESSAGE:"message"}}},WEBGL:{DRAW_PROGRAMS:{PRIMITIVES:"drawPrimitives",IMAGES:"drawImages"}},DRAW_TYPE:{RECTANGLE:"rect",CONUS:"conus",CIRCLE:"circle",POLYGON:"polygon",LINE:"line",TEXT:"text",IMAGE:"image"},LAYERS:{DEFAULT:"default-view-layer",BOUNDARIES:"boundaries-view-layer"},GAME_OPTIONS:{},LIBRARY:{WEBGL:"webgl"},OPTIMIZATION:{CYCLE_TIME_CALC:{AVERAGES:"AVERAGES",CURRENT:"CURRENT"},NATIVE_JS:{NOT_OPTIMIZED:"NOT_OPTIMIZED",OPTIMIZED:"OPTIMIZED"},WEB_ASSEMBLY:{ASSEMBLY_SCRIPT:"ASSEMBLY_SCRIPT",NATIVE_WAT:"WASM"}}},h="CREATE_INSTANCE_ERROR",c="VIEW_NOT_EXIST",d="CANT_GET_THE_IMAGE",u="UNEXPECTED_INPUT_PARAMS",g="WEBGL_ERROR",m="NOT_FOUND",f="WORLD_DIMENSIONS_NOT_SET",E="UNHANDLED_DRAW_ISSUE",_="UNEXPECTED_WORLD_SIZE",A="AUDIO_NOT_REGISTERED",T="AUDIO_NOT_LOADED",p="POLYGON_VERTICES_NOT_CORRECT";function S(e,t){throw new Error(e+": "+t)}function R(e,t){console.warn(e,t)}class x{#e;#t;#i;#s;#n=0;#r=0;#a=0;#o=0;#l=0;#h=[];#c=[];#d=[];#u=[];#g=[];#m;#f=!1;isOffsetTurnedOff(){return this.#m}set mapRotate(e){this.#l=e}#E(e){this.#h.push([e.x1,e.y1,e.x2,e.y2])}_addBoundariesArray(e){this.#h.push(...e)}_addEllipseBoundaries(e){this.#c.push(...e)}_addPointBoundaries(e){this.#d.push(...e)}_clearBoundaries(){this.#h=[],this.#c=[],this.#d=[]}_setWorldDimensions(e,t){this.#e=e,this.#t=t}_setCanvasDimensions(e,t){this.#i=e,this.#s=t}_setMapBoundaries(){const[e,t]=[this.#e,this.#t],[i,s]=[this.#n,this.#r],n=e-i,r=t-s;e&&t||R(f,"Can't set map boundaries."),this.#E({x1:0,y1:0,x2:n,y2:0}),this.#E({x1:n,y1:0,x2:n,y2:r}),this.#E({x1:n,y1:r,x2:0,y2:r}),this.#E({x1:0,y1:r,x2:0,y2:0})}_setWholeWorldMapBoundaries(){const[e,t]=[this.#e,this.#t];e&&t||R(f,"Can't set map boundaries."),this.#u.push([0,0,e,0]),this.#u.push([e,0,e,t]),this.#u.push([e,t,0,t]),this.#u.push([0,t,0,0])}_mergeBoundaries(e=!1){const t=e?this.getWholeWorldBoundaries():this.getBoundaries(),i=new Set(t);for(const e of i.values()){const t=e[0],s=e[1],n=e[2],r=e[3];for(const a of i.values()){const o=a[0],l=a[1],h=a[2],c=a[3];t===h&&s===c&&n===o&&r===l&&(i.delete(e),i.delete(a)),n!==o||r!==l||t!==h&&s!==c||(a[0]=t,a[1]=s,i.delete(e))}}e?this.#h=Array.from(i):this.#u=Array.from(i),i.clear()}_setWholeMapBoundaries(e){this.#u.push(...e)}_enableMapBoundaries(){this.#f=!0}getBoundaries(){return this.#h}getEllipseBoundaries(){return this.#c}getPointBoundaries(){return this.#d}getWholeWorldBoundaries(){return this.#u}get isWorldBoundariesEnabled(){return this.#f}get canvasDimensions(){return[this.#i,this.#s]}get worldDimensions(){return[this.#e,this.#t]}get worldOffset(){return[this.#n,this.#r]}get mapCenter(){return[this.#a,this.#o]}get mapRotate(){return this.#l}centerCameraPosition=(e,t)=>{let[i,s]=this.worldOffset;const[n,r]=this.canvasDimensions,[a,o]=this.worldDimensions,l=n/2,h=r/2,c=h-s;if(l-i=0&&(this.#n=Math.round(t))}else if(a>n){const e=a-n;this.#n=Math.round(e)}if(c=0&&(this.#r=Math.round(e))}else if(o>r){const e=o-r;this.#r=Math.round(e)}this.#a=e,this.#o=t};personRotatedCenterCamera=(e,t,i)=>{console.log("new centering algorithm")};get renderObjects(){return this.#g}getObjectsByInstance(e){return this.#g.filter((t=>t instanceof e))}_sortRenderObjectsBySortIndex(){this.#g=this.#g.sort(((e,t)=>e.sortIndex-t.sortIndex))}set _renderObject(e){this.#g.push(e)}set _renderObjects(e){this.#g=e}}const y={loadstart:"loadstart",progress:"progress",abort:"abort",error:"error",load:"load",timeout:"timeout"},v=" loader is not registered.",w="Too much recursion. Stop iteration.",b="uploadMethod should be instance of Promise and return upload result value",I=" AtlasXML file extension is incorrect, only .xml file supported",O=" tileset file extension is not correct, only .tsj or .json files are supported",P=" tilemap file extension is not correct, only .tmj or .json files are supported",C=" fileKey and url should be provided";class M{#_;#A;#T=new Map;#p=new Map;constructor(e,t){this.#_=e,this.#A=(e,i,...s)=>{const n=t(e,i,...s);if(n instanceof Promise)return n.then((t=>this.#S(t,e)));throw new TypeError(b)}}#S=(e,t)=>new Promise(((i,s)=>{e||null===e||B("AssetsManager: uploadMethod for "+this.#_+" returns incorrect value"),this.#R(t,e),this.#x(t),i()}));#R(e,t){this.#p.set(e,t)}#x(e){this.#T.delete(e)}get filesWaitingForUpload(){return this.#T.size}get loadingQueue(){return this.#T}get uploadMethod(){return this.#A}_addFile=(e,t)=>{this.#T.has(e)&&B("AssetsManager: File "+this.#_+" with key "+e+" is already added"),this.#T.set(e,t)};_isFileInQueue=e=>this.#T.has(e);_getFile=e=>this.#p.get(e)}class D{#y=5;#v=new EventTarget;#w=new Map;#b=0;constructor(){this.registerLoader("Audio",this._loadAudio),this.registerLoader("Image",this._loadImage),this.registerLoader("TileMap",this._loadTileMap),this.registerLoader("TileSet",this._loadTileSet),this.registerLoader("AtlasImageMap",this._loadAtlasImage),this.registerLoader("AtlasXML",this._loadAtlasXml)}get filesWaitingForUpload(){let e=0;return Array.from(this.#w.values()).map((t=>e+=t.filesWaitingForUpload)),e}registerLoader=(e,t=this._defaultUploadMethod)=>{this["add"+e]=(t,i,...s)=>{this.addFile(e,t,i,...s)},this["get"+e]=t=>this.getFile(e,t),this["is"+e+["InQueue"]]=t=>this.isFileInQueue(e,t);const i=this.#w.get(e)||new M(e,t);this.#w.set(e,i)};preload(){return this.#I(),new Promise((async(e,t)=>{this.#O().then((()=>{this.#P(),e()})).catch((e=>{t(e)}))}))}#O(e=0){return this.#C().then((t=>{if(0===this.filesWaitingForUpload)return Promise.resolve(t);if(++e>this.#y){const e=new Error(w);return this.#M(e),Promise.reject(new Error(w))}return this.#O(e)}))}#C(){return new Promise(((e,t)=>{let i=[];Array.from(this.#w.values()).forEach((e=>{Array.from(e.loadingQueue.entries()).forEach((t=>{const s=new Promise(((i,s)=>e.uploadMethod(t[0],...t[1]).then((e=>i(e)))));i.push(s)}))})),Promise.allSettled(i).then((i=>{for(const s of i){if("rejected"===s.status){const e=s.reason;this.#D(e)?t(e):(B("AssetsManager: "+e.message),this.#M(e))}e(i)}}))}))}addEventListener(e,t,...i){y[e]?this.#v.addEventListener(e,t,...i):B("AssetsManager: Event type should be one of the ProgressEvent.type")}removeEventListener(e,t,...i){this.#v.removeEventListener(e,t,...i)}_loadAtlasXml=(e,t)=>(this.#L(t),fetch(t).then((e=>e.text())).then((e=>(new window.DOMParser).parseFromString(e,"text/xml"))).then((i=>{const s=i.documentElement||i.activeElement,n=s.attributes.getNamedItem("imagePath"),r=s.children;if(n){const i=this.#B(t);return this.addAtlasImageMap(e,i+n.value,r,i),Promise.resolve(s)}{const t=new Error(e+" XML format is not correct.");return this.#M(t),Promise.resolve(t)}})));_loadAtlasImage=(e,t,i,s="anonymous")=>new Promise(((e,n)=>{const r=new Image,a=new Map,o=document.createElement("canvas"),l=o.getContext("2d");r.crossOrigin=s,r.onload=()=>{const t=[];let s=[];o.width=r.width,o.height=r.height,l.drawImage(r,0,0);for(let e of i){const i=e.attributes,n=i.getNamedItem("name").value,r=n.includes(".")?n.split(".")[0]:n,a=i.getNamedItem("x").value,o=i.getNamedItem("y").value,h=i.getNamedItem("width").value,c=i.getNamedItem("height").value;t.push(createImageBitmap(l.getImageData(a,o,h,c),{premultiplyAlpha:"premultiply"})),s.push(r)}this.#N(),Promise.all(t).then((t=>{t.forEach(((e,t)=>{const i=s[t];a.set(i,e),this.addImage(i,"empty url",e)})),o.remove(),e(a)}))},r.onerror=()=>{const i=new Error("Error loading atlas image "+t);this.#M(i),e(null)},r.src=t}));_loadTileSet=(e,t,i=1,s)=>(this.#W(t),fetch(s?s+t:t).then((e=>e.json())).then((e=>{const{name:t,image:n,spacing:r,margin:a,tilewidth:o,tileheight:l}=e;return t&&n&&!this.isFileInQueue("Image",t)&&this.addImage(t,s?s+n:n),e.gid=i,Promise.resolve(e)})).catch((()=>{const e=new Error("Error loading related tileset "+t);return this.#M(e),Promise.resolve(null)})));_defaultUploadMethod=(e,t)=>fetch(t);_loadTileMap=(e,t,i=!0)=>(this.#G(t),fetch(t).then((e=>e.json())).then((e=>{const s=this.#B(t);if(!0===i&&e.tilesets&&e.tilesets.length>0){const t=[];return e.tilesets.forEach(((e,i)=>{const{firstgid:n,source:r}=e,a=this._loadTileSet("default-"+n,r,n,s).then((e=>(this.#N(),Promise.resolve(e))));t.push(a)})),Promise.all(t).then((t=>{for(let i=0;i(e.message.includes("JSON.parse:")&&(e=new Error("Error loading tilemap "+t)),this.#M(e),Promise.resolve(null)))));_loadAudio=(e,t)=>new Promise((e=>{const i=new Audio(t);i.addEventListener("loadeddata",(()=>{this.#N(),e(i)})),i.addEventListener("error",(()=>{const i=new Error("Error loading audio "+t);this.#M(i),e(null)}))}));_loadImage=(e,t,i,s="anonymous")=>new Promise(((e,n)=>{if(i)e(i);else{const i=new Image;i.crossOrigin=s,i.onload=()=>{createImageBitmap(i,{premultiplyAlpha:"premultiply"}).then((t=>{this.#N(),e(t)}))},i.onerror=()=>{const i=new Error("Error loading image "+t);this.#M(i),e(null)},i.src=t}}));#L(e){e.includes(".xml")||L(e+I)}#W(e){e.includes(".tsj")||e.includes(".json")||L(e+O)}#G(e){e.includes(".tmj")||e.includes(".json")||L(e+P)}#D(e){return e.message.includes(b)||e.message.includes(I)||e.message.includes(O)||e.message.includes(P)||e.message.includes(C)||e.message.includes(v)}#B(e){let t=e.split("/"),i=t.length,s="/";return t[i-1].includes(".tmj")||t[i-1].includes(".xml")||t[i-1].includes(".json")?(t.pop(),s=t.join("/")+"/"):(t[i-2].includes(".tmj")||t[i-2].includes(".xml")||t[i-2].includes(".json"))&&(t.splice(i-2,2),s=t.join("/")+"/"),s}addFile(e,t,i,...s){const n=this.#w.get(e);n?(this.#F(t,i,e),n._addFile(t,[i,...s])):L(e+v)}isFileInQueue(e,t){const i=this.#w.get(e);if(i)return i._isFileInQueue(t);L("Loader for "+e+" is not registered!")}getFile(e,t){const i=this.#w.get(e);if(i)return i._getFile(t);L("Loader for "+e+" is not registered!")}#F(e,t,i){const s=C;e&&0!==e.trim().length||L("add"+i+"()"+s),t&&0!==t.trim().length||L("add"+i+"()"+s)}#I(){let e=this.filesWaitingForUpload;this.#v.dispatchEvent(new ProgressEvent(y.loadstart,{total:e}))}#P(){this.#v.dispatchEvent(new ProgressEvent(y.load))}#N(){const e=this.filesWaitingForUpload;this.#b+=1,this.#v.dispatchEvent(new ProgressEvent(y.progress,{lengthComputable:!0,loaded:this.#b,total:e}))}#M(e){B("AssetsManger: "+e.message),this.#v.dispatchEvent(new ErrorEvent(y.error,{error:e}))}}function L(e){throw new Error(e)}function B(e){console.warn(e)}class N{#k;#j;#U;#V;#Y;#z=0;#X=0;#H=ye();#K=!1;#q;#Z;#m=!1;#J=!1;constructor(e,t,i,s){this.#k=t,this.#j=i,this.#U=s,this.#V=e}get bgColor(){return this.#U}set bgColor(e){this.#U=e}get type(){return this.#V}get x(){return this.#k}get y(){return this.#j}set x(e){this.#k=e}set y(e){this.#j=e}get sortIndex(){return this.#z}set sortIndex(e){this.#z=e}get blendFunc(){return this.#Y}set blendFunc(e){this.#Y=e}get rotation(){return this.#X}set rotation(e){this.#X=e}get id(){return this.#H}get isRemoved(){return this.#K}destroy(){this.#K=!0}get isMaskAttached(){return!!this.#q}get _maskId(){return this.#q}setMask(e){e._isMask=!0,this.#q=e.id}removeMask(){this.#q=null}set _isMask(e){this.#Z=e}get _isMask(){return this.#Z}get isOffsetTurnedOff(){return this.#m}turnOffOffset(){this.#m=!0}_calculateRectVertices=(e,t)=>{const i=e/2,s=t/2;return[[-i,-s],[i,-s],[i,s],[-i,s]]};_interpolateConus(e,t=2*Math.PI,i=Math.PI/14){let s=[0,0];for(let n=0;n<=t;n+=i){let t=Math.cos(n)*e,i=Math.sin(n)*e;s.push(t,i)}return s}_calculateConusBoundaries(e,t=2*Math.PI,i=Math.PI/14){let s=[];for(let n=0;n<=t;n+=i){let t=Math.cos(n)*e,i=Math.sin(n)*e;s.push([t,i])}return s}_convertVerticesArray(e){return void 0!==e[0].x&&void 0!==e[0].y?we(e):e}}class W extends N{#Q;#I;#$;constructor(e,t,i,s,n){super(l.DRAW_TYPE.RECTANGLE,e,t,n),this.#Q=i,this.#I=s,this.#$=this._calculateRectVertices(i,s)}get vertices(){return this.#$}get width(){return this.#Q}get height(){return this.#I}set width(e){this.#Q=e}set height(e){this.#I=e}}class G{#k;#j;constructor(e,t){this.#k=e,this.#j=t}get x(){return this.#k}get y(){return this.#j}}class F{#k;#j;#Q;#I;constructor(e,t,i,s){this.#k=e,this.#j=t,this.#Q=i,this.#I=s}get x(){return this.#k}get y(){return this.#j}get width(){return this.#Q}get height(){return this.#I}}class k{#k;#j;constructor(e,t,i,s){this.#k=i-e,this.#j=s-t}get x(){return this.#k}get y(){return this.#j}get length(){return Math.sqrt(Math.pow(this.#k,2)+Math.pow(this.#j,2))}get tetaAngle(){return Math.atan2(this.#j,this.#k)}}class j extends N{#ee;#te;#ie;#se;#ne;#re;#ae;#oe=document.createElement("canvas");#le;constructor(e,t,i,s,n){super(l.DRAW_TYPE.TEXT,e,t),this.#re=i,this.#ee=s,this.#se=n,this.#ae,this.#he()}get boundariesBox(){const e=this.textMetrics?Math.floor(this.textMetrics.width):300,t=this.textMetrics?Math.floor(this.textMetrics.fontBoundingBoxAscent+this.textMetrics.fontBoundingBoxDescent):30;return new F(this.x,this.y-t,e,t)}get vertices(){const e=this.boundariesBox;return this._calculateRectVertices(e.width,e.height)}get text(){return this.#re}set text(e){e!==this.#re&&(this.#re=e,this.#he())}get font(){return this.#ee}set font(e){e!==this.#ee&&(this.#ee=e,this.#he())}get textAlign(){return this.#te}set textAlign(e){e!==this.#te&&(this.#te=e,this.#he())}get textBaseline(){return this.#ie}set textBaseline(e){e!==this.#ie&&(this.#ie=e,this.#he())}get fillStyle(){return this.#se}set fillStyle(e){e!==this.#se&&(this.#se=e,this.#he())}get strokeStyle(){return this.#ne}set strokeStyle(e){e!==this.#ne&&(this.#ne=e,this.#he())}get textMetrics(){return this.#ae}set _textMetrics(e){this.#ae=e}get _textureStorage(){return this.#le}set _textureStorage(e){this.#le=e}get _textureCanvas(){return this.#oe}#he(){const e=this.#oe.getContext("2d",{willReadFrequently:!0});if(e){e.font=this.font,this._textMetrics=e.measureText(this.text);const t=this.boundariesBox.width,i=this.boundariesBox.height;e.canvas.width=t,e.canvas.height=i,e.clearRect(0,0,t,i),e.font=this.font,e.textBaseline="bottom",this.fillStyle&&(e.fillStyle=this.fillStyle,e.fillText(this.text,0,i)),this.strokeStyle&&(e.strokeStyle=this.strokeStyle,e.strokeText(this.text,0,i)),this.#le&&(this.#le._isTextureRecalculated=!0)}else S("UNHANDLED_EXCEPTION","can't getContext('2d')")}}class U extends N{#ce;#de;#$;#ue;constructor(e,t,i,s,n,r=0){super(l.DRAW_TYPE.CONUS,e,t,s),this.#ce=i,this.#de=n,this.#ue=r,this.#$=this._interpolateConus(i,n)}get vertices(){return this.#$}set vertices(e){this.#$=e}get radius(){return this.#ce}get angle(){return this.#de}get fade_min(){return this.#ue}set fade_min(e){this.#ue=e}}class V{#ge;#me=100;#fe;#Ee;#_e;#Ae;#Te;constructor(e,t,i=!1,s,n=!1){this.#ge=e,this.#fe=this.#pe(t),this.#Ee=s||0,this.#_e=n,this.#Ae=i}get name(){return this.#ge}get isActive(){return this.#_e}get currentSprite(){return this.#fe[this.#Ee][0]}get _isLastSprite(){return this.#fe.length-1===this.#Ee}iterateAnimationIndex(){const e=this.#Ee;this.#fe[e][1]{this.#_e=!0,this.#Ee=0,this.#Te=Date.now()};deactivateAnimation=()=>{this.#_e=!1};#pe(e){let t=[];return e.forEach((e=>{"number"==typeof e.id&&"number"==typeof e.duration?t.push([e.id,e.duration]):t.push([e,this.#me])})),t}}class Y extends N{#Q;#I;#Se;#Re;#xe;#ye;#ve;#we;#be=0;#$;#Ie;#le;constructor(e,t,i,s,n,r=0,a,o,h=0){super(l.DRAW_TYPE.IMAGE,e,t),this.#Se=n,this.#xe=new EventTarget,this.#ye=new Map,this.image=o,this.#we=r,this.#be=h,this.#Q=i,this.#I=s,this.#$=a&&!a.r?this._convertVerticesArray(a):a&&a.r?this._calculateConusBoundaries(a.r):this._calculateRectVertices(i,s),this.#Ie=a&&void 0!==a.r?a:null}get width(){return this.#Q}get height(){return this.#I}set width(e){this.#Q=e}set height(e){this.#I=e}get key(){return this.#Se}get image(){return this.#Re}set image(e){this.#le&&(this.#le._isTextureRecalculated=!0),this.#Re=e}get imageIndex(){return this.#we}set imageIndex(e){this.#we=e}get spacing(){return this.#be}get hasAnimations(){return this.#ye.size>0}get activeAnimation(){return this.#ve}get boundaries(){return this.#$}get vertices(){return this.#$}get circleBoundaries(){return this.#Ie}_processActiveAnimations(){const e=this.#ve;if(e){const t=this.#ye.get(e);t.iterateAnimationIndex(),this.#we=t.currentSprite}}get _textureStorage(){return this.#le}set _textureStorage(e){this.#le=e}emit(e,...t){const i=new Event(e);i.data=[...t],this.#xe.dispatchEvent(i)}addEventListener(e,t,i){this.#xe.addEventListener(e,t,i)}removeEventListener(e,t,i){this.#xe.removeEventListener(e,t,i)}addAnimation(e,t,i){this.#Oe(t)||S(u," animationSpriteIndexes should be Array of indexes, or Array of objects {duration:number, id:number}");const s=new V(e,t,i);this.#ye.set(e,s),this.addEventListener(e,this.#Pe)}#Oe(e){let t=!0;return e.forEach((e=>{"number"!=typeof e&&("number"==typeof e.duration&&"number"==typeof e.id||(t=!1))})),t}#Pe=e=>{const t=e.type,i=this.#ye.get(t);this.#ve&&this.#ve!==t&&this.stopRepeatedAnimation(this.#ve),i.activateAnimation(),this.#ve=t,this.#we=i.currentSprite};stopRepeatedAnimation(e){this.#ye.get(e).deactivateAnimation(),this.#ve=null}removeAllAnimations(){for(let[e,t]of this.#ye.entries())this.removeEventListener(e,t.activateAnimation),t.deactivateAnimation();this.#ye.clear(),this.#ye=void 0}destroy(){this.removeAllAnimations(),super.destroy()}}class z extends N{#$;constructor(e,t){super(l.DRAW_TYPE.LINE,e[0][0],e[0][1],t),this.#$=e}get vertices(){return this.#$}set vertices(e){this.#$=e}}class X extends N{#$;constructor(e,t){super(l.DRAW_TYPE.POLYGON,e[0].x,e[0].y,t),this.#$=this._convertVerticesArray(e)}get vertices(){return this.#$}set vertices(e){this.#$=e}}class H extends N{#ce;#$;constructor(e,t,i,s){super(l.DRAW_TYPE.CIRCLE,e,t,s),this.#ce=i,this.#$=this._interpolateConus(i)}get vertices(){return this.#$}set vertices(e){this.#$=e}get radius(){return this.#ce}}class K{#Ce;#Me;#De;#Le;#Be="-#-";#Ne;#We;#Ge;#Fe;#ke;#q;#z=0;#ye=new Map;#m;constructor(e,t,i,s,n,r,a=!1,o){this.#Ce=e,this.#Me=t,this.#De=i,this.#Le=s,this.#We=[],this.#Ne=n,this.#Ge=r,this.#Fe=a,this.#ke=a||!1,o&&this.setMask(o),this.#je(s)}get layerKey(){return this.#Ce}get tileMapKey(){return this.#Me}get tilemap(){return this.#De}get tilesets(){return this.#Le}get tilesetImages(){return this.#Ne}get layerData(){return this.#Ge}get setBoundaries(){return this.#Fe}get drawBoundaries(){return this.#ke}set drawBoundaries(e){this.#ke=e}get _maskId(){return this.#q}setMask(e){e._isMask=!0,this.#q=e.id}removeMask(){this.#q=null}get sortIndex(){return this.#z}set sortIndex(e){this.#z=e}get isOffsetTurnedOff(){return this.#m}turnOffOffset(){this.#m=!0}get hasAnimations(){return this.#ye.size>0}get _textureStorages(){return this.#We}_setTextureStorage(e,t){this.#We[e]=t}#je(e){for(let t of e){const e=t.data.tiles,i=t.data.name;if(e)for(let s of e){const e=s.animation,n=s.objectgroup,r=s.id;if(e){const s=i+this.#Be+r,n=this.#Ue(e),a=new V(s,n,!0);this.#ye.set(s,a),t.data._hasAnimations||(t.data._hasAnimations=!0,t.data._animations=new Map,t.data._animations.set(r,n[0][0])),this.#Pe(a)}n&&(t.data._hasBoundaries||(t.data._hasBoundaries=!0,t.data._boundaries=new Map),t.data._boundaries.set(r,n))}}}#Ue(e){return e.map((e=>({duration:e.duration,id:e.tileid})))}_processActiveAnimations(){for(let e of this.#ye.values())e.isActive&&(e.iterateAnimationIndex(),this.#Ve(e))}#Pe=e=>{e.activateAnimation(),this.#Ve(e)};#Ve=e=>{const[t,i]=e.name.split(this.#Be),s=this.#Le.findIndex((e=>e.data.name===t));this.#Le[s].data._animations.set(parseInt(i),e.currentSprite)};stopRepeatedAnimation(e){this.#ye.get(e).deactivateAnimation()}removeAllAnimations(){for(let[e,t]of this.#ye.entries())this.removeEventListener(e,t.activateAnimation),t.deactivateAnimation();this.#ye.clear(),this.#ye=void 0}destroy(){this.removeAllAnimations(),super.destroy()}}class q{#Ye;#ze;constructor(e){this.#Ye=e}get stageData(){return this.#ze}#Xe(e){return this.#ze._renderObject=e,this.#ze._sortRenderObjectsBySortIndex(),e}rect(e,t,i,s,n){const r=new W(e,t,i,s,n);return this.#Xe(r),r}text(e,t,i,s,n){const r=new j(e,t,i,s,n);return this.#Xe(r),r}conus(e,t,i,s,n,r=0){const a=new U(e,t,i,s,n,r);return this.#Xe(a),a}circle(e,t,i,s){const n=new H(e,t,i,s);return this.#Xe(n),n}image(e,t,i,s,n,r=0,a,o=0){const l=this.#Ye.getImage(n);l||S(d,"iLoader can't get the image with key: "+n);const h=new Y(e,t,i,s,n,r,a,l,o);return this.#Xe(h),h}line(e,t){const i=new z(e,t);return this.#Xe(i),i}polygon(e,t){const i=new X(e,t);return this.#Xe(i),i}tiledLayer(e,t,i,s){const n=this.#Ye.getTileMap(t),r=n.tilesets,a=r.map((e=>this.#Ye.getImage(e.data.name))),o=n.layers.find((t=>t.name===e)),l=new K(e,t,n,r,a,o,i,s);return this.#Xe(l),l}_registerNewObjectMethod=(e,t)=>{this[e]=(...e)=>this.#He(t,...e)};#He=(e,...t)=>{const i=e(...t);return this.#Xe(i),i};_attachPageData=e=>{this.#ze=e};_detachPageData=()=>{this.#ze=null}}class Z{constructor(){}static mode=l.MODE.DEBUG;static gameOptions={library:l.LIBRARY.WEBGL,optimization:l.OPTIMIZATION.NATIVE_JS.OPTIMIZED,optimizationWASMUrl:"./src/wa/calculateBufferDataWat.wasm",optimizationAssemblyUrl:"/src/wa/calculateBufferDataAssembly.wasm",loadingScreen:{backgroundColor:"rgba(128, 128, 128, 0.6)",loadingBarBg:"rgba(128, 128, 128, 1)",loadingBarProgress:"rgba(128, 128, 128, 0.2)"},render:{minCycleTime:16.666,cyclesTimeCalc:{check:l.OPTIMIZATION.CYCLE_TIME_CALC.AVERAGES,averageFPStime:1e4},boundaries:{mapBoundariesEnabled:!0,realtimeCalculations:!0,wholeWorldPrecalculations:!1}},debug:{checkWebGlErrors:!1,debugMobileTouch:!1,boundaries:{drawLayerBoundaries:!1,drawObjectBoundaries:!1,boundariesColor:"rgba(224, 12, 21, 0.6)",boundariesWidth:2},delayBetweenObjectRender:!1}};static network={enabled:!1,address:"https://gameserver.reslc.ru:9009",gatherRoomsInfoInterval:5e3};static canvasMaxSize={width:1800,height:1800};static worldSize={width:960,height:960};static defaultCanvasKey="default";static customSettings={}}class J{static debug(...e){Z.mode===l.MODE.DEBUG&&e.forEach((e=>console.log(e)))}}class Q extends Event{#Ke;constructor(e,t){super(e),this.#qe(e)||S("UNEXPECTED_EVENT_NAME",", Please check if event is exist"),this.#Ke=t}#qe(e){return Object.values(l.EVENTS.WEBSOCKET.SERVER_CLIENT).find((t=>t===e))}get data(){return this.#Ke}}class $ extends EventTarget{#Ze;#Je;constructor(e){super(),e||S(h,"systemSettings should be passed to class instance"),this.#Ze=e}init(){n.e(319).then(n.bind(n,319)).then((e=>{this.#Je=e.io(this.#Ze.network.address,{withCredentials:!0}),this.#Qe()}))}get isServerConnected(){return!(!this.#Je||!this.#Je.connected)}get playerId(){return this.#Je.id}sendGatherRoomsInfo(){this.#Je.emit(l.EVENTS.WEBSOCKET.CLIENT_SERVER.ROOMS_INFO_REQUEST)}sendCreateOrJoinRoom(e,t){this.#Je.emit(l.EVENTS.WEBSOCKET.CLIENT_SERVER.CREATE_OR_JOIN,e,t)}sendMessage(e){this.#Je.emit(l.EVENTS.WEBSOCKET.CLIENT_SERVER.CLIENT_MESSAGE,e)}#$e=()=>{J.debug("connected, socket id: "+this.#Je.id),this.dispatchEvent(new Event(l.EVENTS.WEBSOCKET.SERVER_CLIENT.CONNECTION_STATUS_CHANGED))};#et=e=>{J.debug("server disconnected, reason: "+e),this.dispatchEvent(new Event(l.EVENTS.WEBSOCKET.SERVER_CLIENT.CONNECTION_STATUS_CHANGED))};#tt=e=>{console.warn("server data: ",e)};#it=e=>{J.debug("received new message from server: "+e),this.dispatchEvent(new Q(l.EVENTS.WEBSOCKET.SERVER_CLIENT.SERVER_MESSAGE,e))};#st=e=>{J.debug("received roomsInfo "+e),this.dispatchEvent(new Q(l.EVENTS.WEBSOCKET.SERVER_CLIENT.ROOMS_INFO,e))};#nt=(e,t)=>{J.debug("CLIENT SOCKET: Created room "+e),this.dispatchEvent(new Q(l.EVENTS.WEBSOCKET.SERVER_CLIENT.CREATED,{room:e,map:t}))};#rt=e=>{J.debug("CLIENT SOCKET: Room is full, can't join: "+e),this.dispatchEvent(new Q(l.EVENTS.WEBSOCKET.SERVER_CLIENT.FULL,{room:e}))};#at=(e,t)=>{J.debug("CLIENT SOCKET: Joined to room: "+e,", map: ",t),this.dispatchEvent(new Q(l.EVENTS.WEBSOCKET.SERVER_CLIENT.JOINED,{room:e,map:t}))};#ot=e=>{this.dispatchEvent(new Q(l.EVENTS.WEBSOCKET.SERVER_CLIENT.DISCONNECTED,{playerId:e}))};#Qe(){this.#Je.on("connect",this.#$e),this.#Je.on("disconnect",this.#et),this.#Je.on("data",this.#tt),this.#Je.on("roomsInfo",this.#st),this.#Je.on("created",this.#nt),this.#Je.on("full",this.#rt),this.#Je.on("joined",this.#at),this.#Je.on("log",(function(e){console.log.apply(console,e)})),this.#Je.on("message",this.#it),this.#Je.on("removed",(function(e){console.log("removed message"),console.log(e)})),this.#Je.on("disconnected",this.#ot),addEventListener("beforeunload",this.#lt)}#lt=()=>{this.#Je.disconnect()}}class ee{#ht=.5;#ct=new Map;#dt;constructor(e){this.#dt=e}getAudio=e=>{const t=this.#ct.get(e);return null===t?(R(T,"Audio with key "+e+" exists, but not actually loaded"),t):t||(R(A,""),null)};getAudioCloned=e=>{const t=this.#ct.get(e);if(null===t)return R(T,"Audio with key "+e+" exists, but not actually loaded"),t;if(t){const e=t.cloneNode();return e.volume=this.#ht,e}return R(A),null};set volume(e){this.#ht=e,this.#ut(e)}get volume(){return this.#ht}#ut(e){for(const t of this.#ct.values())t&&(t.volume=e)}registerAudio(e){let t=this.#dt.getAudio(e);this.#ct.set(e,t)}}function te(){return/Android|webOS|iPhone|iPad|iPod|Opera Mini/i.test(navigator.userAgent)}function ie(){return/^((?!chrome|android).)*safari/i.test(navigator.userAgent)}function se(e,t,i){return new k(e,t,i.x,i.y).length-i.r}function ne(e,t){const i=t.x1,s=t.y1,n=t.x2,r=t.y2,a=e.x1,o=e.y1,l=i,h=s,c=n-i,d=r-s,u=a,g=o,m=e.x2-a,f=e.y2-o,E=Math.sqrt(c*c+d*d),_=Math.sqrt(m*m+f*f);if(c/E==m/_&&d/E==f/_)return null;const A=(c*(g-h)+d*(l-u))/(m*d-f*c),T=(u+m*A-l)/c;return T<0||isNaN(T)||A<0||A>1?null:{x:l+c*T,y:h+d*T,p:T}}function re(e,t){const i=t.x1,s=t.y1,n=t.x2,r=t.y2,a=e.x1,o=e.y1,l=e.x2,h=e.y2,c=(i-n)*(o-h)-(s-r)*(a-l);if(0===c)return;let d=((i*r-s*n)*(a-l)-(i-n)*(a*h-o*l))/c,u=((i*r-s*n)*(o-h)-(s-r)*(a*h-o*l))/c;const g={x:d,y:u};return de(g,e,1e-13)&&de(g,t,1e-13)?{x:d,y:u,p:Math.sqrt(Math.pow(d-i,2)+Math.pow(u-s,2))}:void 0}function ae(e,t,i,s){return Math.atan2(s-t,i-e)}function oe(e,t,i){const s=e.x-t.x,n=i.x-t.x,r=e.y-t.y,a=i.y-t.y,o=Math.sqrt(s*s+r*r),l=Math.sqrt(n*n+a*a);return Math.acos((s*n+r*a)/(o*l))}function le(e,t,i){return e*t*Math.cos(i)}function he(e,t){return e.x*t.x+e.y*t.y}function ce(e,t){return e.x*t.y-t.x*e.y}function de(e,t,i=0){return(e.x>=t.x1-i&&e.x<=t.x2+i||e.x<=t.x1+i&&e.x>=t.x2-i)&&(e.y>=t.y1-i&&e.y<=t.y2+i||e.y<=t.y1+i&&e.y>=t.y2-i)}function ue(e,t){return new k(e.x,e.y,t.x,t.y).length}function ge(e,t){return new k(e.x1,e.y1,e.x2,e.y2).length0&&n%2!=0}function Ae(e,t,i){return e>=i.x&&e<=i.width+i.x&&t>=i.y&&t<=i.y+i.height}function Te(e,t,i){const s=i.r;return new k(e,t,i.x,i.y).length0&&m>0?(f=ce(l,h)/u,f<0&&(f*=-1)):f=Math.min(l.length,h.length),f<=i}function Se(e,t){const i=e[0],s=e[1],n=e[2],r=e[3],a={x:i-t[0][0],y:s-t[0][1]},o={x:i-t[1][0],y:s-t[1][1]},l=Math.sqrt(Math.pow(a.x,2)+Math.pow(a.y,2)),h=Math.sqrt(Math.pow(o.x,2)+Math.pow(o.y,2)),c=Math.min(l,h);if(c>Math.max(n,r))return!1;const d=c===l?a:o,u=Math.atan2(d.y,d.x),g={x:0-Math.cos(u)*n,y:0-Math.sin(u)*r};return!(c>Math.sqrt(Math.pow(g.x,2)+Math.pow(g.y,2)))}function Re(e,t){const i=e[0],s=e[1],n={x:i-t.x,y:s-t.y},r=Math.sqrt(Math.pow(n.x,2)+Math.pow(n.y,2));if(r>Math.max(e[2],e[3])+t.r)return!1;{const n=ae(i,s,t.x,t.y),a=i-(i+e[2]*Math.cos(n)),o=s-(s+e[3]*Math.sin(n));return r<=Math.sqrt(Math.pow(a,2)+Math.pow(o,2))+t.r&&{x:a,y:o,p:1}}}function xe(e,t){const i=t.length;for(let s=0;s{const e=this.#Et;return e.enable(e.BLEND),e.enable(e.STENCIL_TEST),e.stencilFunc(e.ALWAYS,1,255),e.stencilOp(e.KEEP,e.KEEP,e.REPLACE),Promise.resolve()};_initiateWasm=()=>{const e=this.#Tt.optimization===l.OPTIMIZATION.WEB_ASSEMBLY.NATIVE_WAT?this.#Tt.optimizationWASMUrl:this.#Tt.optimizationAssemblyUrl;return new Promise(((t,i)=>{this.layerData=new WebAssembly.Memory({initial:1e3}),this.layerDataFloat32=new Float32Array(this.layerData.buffer);const s={env:{memory:this.layerData,logi:console.log,logf:console.log}};fetch(e).then((e=>e.arrayBuffer())).then((e=>WebAssembly.instantiate(e,s))).then((e=>{this.calculateBufferData=e.instance.exports.calculateBufferData,t()}))}))};_clearView(){const e=this.#Et;e.clearColor(0,0,0,0),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT|e.STENCIL_BUFFER_BIT)}_render(e,t,i=0){const s=this.#Et,n=this.#At?s.getError():0;if(0!==n)throw console.error(n),new Error("Error num: "+n);return s.drawArrays(t,i,e),s.stencilFunc(s.ALWAYS,1,255),new Promise(((e,t)=>{this.#Tt.debug.delayBetweenObjectRender?setTimeout((()=>{e()}),1e3):e()}))}_registerAndCompileWebGlProgram(e,t,i,s,n){const r=this.#yt(t,i),a=this.#vt(r,s,n);return this.#Rt.set(e,r),this.#xt.set(e,a),Promise.resolve()}#yt(e,t){const i=this.#Et,s=i.createProgram();if(s){const n=this.#wt(i,e,i.VERTEX_SHADER);n?i.attachShader(s,n):S(g,"#compileShader(vertexShaderSource) is null");const r=this.#wt(i,t,i.FRAGMENT_SHADER);if(r?i.attachShader(s,r):S(g,"#compileShader(fragmentShaderSource) is null"),i.linkProgram(s),!i.getProgramParameter(s,i.LINK_STATUS)){const e=i.getProgramInfoLog(s);S(g,`Could not compile WebGL program. \n\n${e}`)}}else S(g,"gl.createProgram() is null");return s}#vt(e,t,i){const s=this.#Et;let n={};return t.forEach((t=>{n[t]=s.getUniformLocation(e,t)})),i.forEach((t=>{n[t]=s.getAttribLocation(e,t)})),n}#wt(e,t,i){const s=e.createShader(i);if(s){if(e.shaderSource(s,t),e.compileShader(s),!e.getShaderParameter(s,e.COMPILE_STATUS)){const t=e.getShaderInfoLog(s);S(g,"Couldn't compile webGl program. \n\n"+t)}}else S(g,`gl.createShader(${i}) is null`);return s}_bindPrimitives=(e,t,i,s,n)=>{const[r,a]=!0===e.isOffsetTurnedOff?[0,0]:i.worldOffset,o=e.x-r,h=e.y-a,c=[1,1],d=e.rotation,u=e.blendFunc?e.blendFunc:[t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA],{u_translation:g,u_rotation:m,u_scale:f,u_resolution:E,u_color:_,a_position:A,u_fade_min:T}=n;let S=0;switch(t.useProgram(s),t.uniform2f(E,t.canvas.width,t.canvas.height),t.uniform2f(g,o,h),t.uniform2f(f,c[0],c[1]),t.uniform1f(m,d),t.uniform1f(T,0),t.enableVertexAttribArray(A),t.bindBuffer(t.ARRAY_BUFFER,this.#pt),e.type){case l.DRAW_TYPE.RECTANGLE:this.#bt(e.width,e.height),S+=6;break;case l.DRAW_TYPE.TEXT:break;case l.DRAW_TYPE.CIRCLE:{const i=e.vertices;t.bufferData(t.ARRAY_BUFFER,new Float32Array(i),t.STATIC_DRAW),S+=i.length/2;break}case l.DRAW_TYPE.POLYGON:{const t=this.#It(e.vertices);this.#Ot(t);const i=t.length;if(i%3!=0)return R(p,`polygons ${e.id}, vertices are not correct, skip drawing`),Promise.reject();S+=i/2;break}}const x=t.FLOAT;t.vertexAttribPointer(A,2,x,!1,0,0);const y=this.#Pt(e.bgColor);return t.uniform4f(_,y[0]/255,y[1]/255,y[2]/255,y[3]),u&&t.blendFunc(u[0],u[1]),e.isMaskAttached?t.stencilFunc(t.EQUAL,e._maskId,255):e._isMask&&t.stencilFunc(t.ALWAYS,e.id,255),Promise.resolve([S,t.TRIANGLES])};_bindConus=(e,t,i,s,n)=>{const[r,a]=!0===e.isOffsetTurnedOff?[0,0]:i.worldOffset,o=e.x-r,l=e.y-a,h=[1,1],c=e.rotation,{u_translation:d,u_rotation:u,u_scale:g,u_resolution:m,u_color:f,a_position:E,u_fade_max:_,u_fade_min:A}=n,T=e.vertices,p=e.bgColor,S=e.fade_min,R=e.radius,x=e.blendFunc?e.blendFunc:[t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA];let y=0;t.useProgram(s),t.uniform2f(m,t.canvas.width,t.canvas.height),t.uniform2f(d,o,l),t.uniform2f(g,h[0],h[1]),t.uniform1f(u,c),t.uniform1f(A,S),t.uniform1f(_,R),t.bindBuffer(t.ARRAY_BUFFER,this.#pt),t.bufferData(t.ARRAY_BUFFER,new Float32Array(T),t.STATIC_DRAW),t.enableVertexAttribArray(E);const v=t.FLOAT;t.vertexAttribPointer(E,2,v,!1,0,0),y+=T.length/2,x&&t.blendFunc(x[0],x[1]);const w=this.#Pt(p);return t.uniform4f(f,w[0]/255,w[1]/255,w[2]/255,w[3]),e.isMaskAttached?t.stencilFunc(t.EQUAL,e._maskId,255):e._isMask&&t.stencilFunc(t.ALWAYS,e.id,255),Promise.resolve([y,t.TRIANGLE_FAN])};_bindText=(e,t,i,s,n)=>{const{u_translation:r,u_rotation:a,u_scale:o,u_resolution:l,a_position:h,a_texCoord:c,u_image:d}=n,{width:u,height:g}=e.boundariesBox,[m,f]=(e.text,!0===e.isOffsetTurnedOff?[0,0]:i.worldOffset),E=e.x-m,_=e.y-f-g,A=e.blendFunc?e.blendFunc:[t.ONE,t.ONE_MINUS_SRC_ALPHA],T=[1,1],p=E+u,S=_+g,R=[E,_,p,_,E,S,E,S,p,_,p,S];let x=0;t.useProgram(s),t.uniform2f(l,t.canvas.width,t.canvas.height),t.uniform2f(r,E,_),t.uniform2f(o,T[0],T[1]),t.uniform1f(a,0),t.bindBuffer(t.ARRAY_BUFFER,this.#pt),t.bufferData(t.ARRAY_BUFFER,new Float32Array(R),t.STATIC_DRAW),t.enableVertexAttribArray(h);const y=t.FLOAT;t.vertexAttribPointer(h,2,y,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,this.#St),t.bufferData(t.ARRAY_BUFFER,new Float32Array([0,0,1,0,0,1,0,1,1,0,1,1]),t.STATIC_DRAW),t.enableVertexAttribArray(c),t.vertexAttribPointer(c,2,t.FLOAT,!1,0,0),x+=6,t.blendFunc(A[0],A[1]);let v=e._textureStorage;return v||(v=new Ie(t.createTexture()),e._textureStorage=v),!0===v._isTextureRecalculated?(this.#Ct(t,v._texture,e._textureCanvas),v._isTextureRecalculated=!1):this.#Mt(t,v._texture),t.uniform1i(d,v._textureIndex),t.depthMask(!1),Promise.resolve([6,t.TRIANGLES])};_bindImage=(e,t,i,s,n)=>{const{u_translation:r,u_rotation:a,u_scale:o,u_resolution:l,a_position:h,a_texCoord:c,u_image:d}=n,[u,g]=!0===e.isOffsetTurnedOff?[0,0]:i.worldOffset,m=e.x-u,f=e.y-g,E=e.image,_=e.imageIndex,A=(e.key,e._maskId),T=e.spacing,p=e.blendFunc?e.blendFunc:[t.ONE,t.ONE_MINUS_SRC_ALPHA],S=[1,1];let R=0,x=0,y=0,v=0,w=0;if(0!==_){const t=(E.width+T)/(e.width+T);y=_%t,v=Math.floor(_/t),R=y*e.width+y*T,x=v*e.height+v*T}const b=m-e.width/2,I=f-e.height/2,O=b+e.width,P=I+e.height,C=1/E.width*R,M=1/E.height*x,D=C+1/E.width*e.width,L=M+1/E.height*e.height,B=[b,I,O,I,b,P,b,P,O,I,O,P],N=[C,M,D,M,C,L,C,L,D,M,D,L];t.useProgram(s),t.uniform2f(l,t.canvas.width,t.canvas.height),t.uniform2f(r,m,f),t.uniform2f(o,S[0],S[1]),t.uniform1f(a,e.rotation),t.bindBuffer(t.ARRAY_BUFFER,this.#pt),t.bufferData(t.ARRAY_BUFFER,new Float32Array(B),t.STATIC_DRAW),w+=B.length/2,t.enableVertexAttribArray(h);const W=t.FLOAT;t.vertexAttribPointer(h,2,W,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,this.#St),t.bufferData(t.ARRAY_BUFFER,new Float32Array(N),t.STATIC_DRAW),t.enableVertexAttribArray(c),t.vertexAttribPointer(c,2,t.FLOAT,!1,0,0);let G=e._textureStorage;return G||(G=new Ie(t.createTexture()),e._textureStorage=G),!0===G._isTextureRecalculated?(this.#Dt(t,G._texture,e.image),G._isTextureRecalculated=!1):this.#Mt(t,G._texture),t.uniform1i(d,G._textureIndex),t.blendFunc(p[0],p[1]),A&&t.stencilFunc(t.EQUAL,A,255),Promise.resolve([w,t.TRIANGLES])};_bindTileImages=async(e,t,i,s,n)=>{const{u_translation:r,u_rotation:a,u_scale:o,u_resolution:h,a_position:c,a_texCoord:d,u_image:u}=n;let g;switch(t.useProgram(s),this.#Tt.optimization){case l.OPTIMIZATION.NATIVE_JS.NOT_OPTIMIZED:g=await this.#Lt(e,i);break;case l.OPTIMIZATION.WEB_ASSEMBLY.ASSEMBLY_SCRIPT:case l.OPTIMIZATION.WEB_ASSEMBLY.NATIVE_WAT:g=await this.#Bt(e,i);break;case l.OPTIMIZATION.NATIVE_JS.OPTIMIZED:default:g=await this.#Nt(e,i)}const m=[0,0],f=[1,1],E=["ONE","ONE_MINUS_SRC_ALPHA"],_=e._maskId;let A=0,T=!1;for(let i=0;i0&&l.length>0){T&&await this._render(A,t.TRIANGLES),t.uniform2f(h,t.canvas.width,t.canvas.height),t.uniform2f(r,m[0],m[1]),t.uniform2f(o,f[0],f[1]),t.uniform1f(a,0),t.bindBuffer(t.ARRAY_BUFFER,this.#pt),t.bufferData(t.ARRAY_BUFFER,n,t.STATIC_DRAW),t.enableVertexAttribArray(c);const s=2,g=t.FLOAT,S=!1,R=0,x=0;t.vertexAttribPointer(c,s,g,S,R,x),t.bindBuffer(t.ARRAY_BUFFER,this.#St),t.bufferData(t.ARRAY_BUFFER,l,t.STATIC_DRAW),t.enableVertexAttribArray(d),t.vertexAttribPointer(d,2,t.FLOAT,!1,0,x);let y=e._textureStorages[i];y||(y=new Ie(t.createTexture(),i),e._setTextureStorage(i,y)),!0===y._isTextureRecalculated?(this.#Dt(t,y._texture,p,y._textureIndex),y._isTextureRecalculated=!1):this.#Mt(t,y._texture,y._textureIndex),t.uniform1i(u,y._textureIndex),t.blendFunc(t[E[0]],t[E[1]]),A=n.length/2,_&&t.stencilFunc(t.EQUAL,_,255),T=!0}}return Promise.resolve([A,t.TRIANGLES])};_drawPolygon(e,t){const[i,s]=!0===e.isOffsetTurnedOff?[0,0]:t.worldOffset,n=e.x-i,r=e.y-s,a=e.rotation||0,o=e.vertices,h=this.#Tt.debug.boundaries.boundariesColor,c=this.getProgram(l.WEBGL.DRAW_PROGRAMS.PRIMITIVES),{u_translation:d,u_rotation:u,u_scale:g,u_resolution:m,u_color:f,a_position:E,u_fade_max:_,u_fade_min:A}=this.getProgramVarLocations(l.WEBGL.DRAW_PROGRAMS.PRIMITIVES),T=this.#Et;let S=0;T.useProgram(c),T.uniform2f(m,T.canvas.width,T.canvas.height),T.uniform2f(d,n,r),T.uniform2f(g,1,1),T.uniform1f(u,a),T.uniform1f(A,0),T.enableVertexAttribArray(E),T.bindBuffer(T.ARRAY_BUFFER,this.#pt);const x=this.#It(o),y=x.length;if(y%3!=0)return void R(p,"polygon boundaries vertices are not correct, skip drawing");this.#Ot(x),S+=y/2;const v=T.FLOAT;T.vertexAttribPointer(E,2,v,!1,0,0);const w=this.#Pt(h);T.uniform4f(f,w[0]/255,w[1]/255,w[2]/255,w[3]),this._render(S,T.TRIANGLES)}_bindLine=(e,t,i,s,n)=>{const[r,a]=!0===e.isOffsetTurnedOff?[0,0]:i.worldOffset,o=e.x-r,l=e.y-a,h=e.rotation,{u_translation:c,u_rotation:d,u_scale:u,u_resolution:g,u_color:m,a_position:f,u_fade_max:E,u_fade_min:_}=n,A=e.vertices,T=e.bgColor,p=(e.fade_min,e.radius,this.#Tt.debug.boundaries.boundariesWidth);let S=0;t.useProgram(s),t.uniform2f(g,t.canvas.width,t.canvas.height),t.uniform2f(c,o,l),t.uniform2f(u,1,1),t.uniform1f(d,h),t.uniform1f(_,0),t.enableVertexAttribArray(f),t.bindBuffer(t.ARRAY_BUFFER,this.#pt),t.bufferData(t.ARRAY_BUFFER,new Float32Array(A),t.STATIC_DRAW),S+=A.length/2;const R=t.FLOAT;t.vertexAttribPointer(f,2,R,!1,0,0);const x=this.#Pt(T);return t.uniform4f(m,x[0]/255,x[1]/255,x[2]/255,x[3]),t.lineWidth(p),Promise.resolve([0,t.LINES])};_drawLines(e,t,i=1,s=0,n=[0,0]){const r=this.getProgram(l.WEBGL.DRAW_PROGRAMS.PRIMITIVES),{u_translation:a,u_rotation:o,u_scale:h,u_resolution:c,u_color:d,a_position:u,u_fade_max:g,u_fade_min:m}=this.getProgramVarLocations(l.WEBGL.DRAW_PROGRAMS.PRIMITIVES),f=this.#Et;let E=0;f.useProgram(r),f.uniform2f(c,f.canvas.width,f.canvas.height),f.uniform2f(a,n[0],n[1]),f.uniform2f(h,1,1),f.uniform1f(o,s),f.uniform1f(m,0),f.enableVertexAttribArray(u),f.bindBuffer(f.ARRAY_BUFFER,this.#pt),f.bufferData(f.ARRAY_BUFFER,new Float32Array(e),f.STATIC_DRAW),E+=e.length/2;const _=f.FLOAT;f.vertexAttribPointer(u,2,_,!1,0,0);const A=this.#Pt(t);f.uniform4f(d,A[0]/255,A[1]/255,A[2]/255,A[3]),f.lineWidth(i),this._render(E,f.LINES)}#Nt(e,t){return new Promise(((i,s)=>{const n=e.tilemap,r=e.tilesets,a=e.tilesetImages,o=e.layerData,{tileheight:l,tilewidth:h}=n,c=h,d=l,[u,g]=t.worldDimensions,[f,E]=t.canvasDimensions,[A,T]=!0===e.isOffsetTurnedOff?[0,0]:t.worldOffset,p=(this.#Tt.render.boundaries.realtimeCalculations,e.setBoundaries);let S=new Map,x=[],y=[],v=[],w=[];o||(R(m,"check tilemap and layers name"),s());for(let e=0;eE?Math.ceil(E/d)+1:L,U=B>f?Math.ceil(f/c)+1:D,V=D-U-k,Y=i.spacing,z=(i.margin,i._hasAnimations),X=[],H=[],K=i._hasBoundaries,q=i._boundaries;B===u&&N===g||(R(_," World size from tilemap is different than settings one, fixing..."),t._setWorldDimensions(B,N)),p&&this.#Tt.render.boundaries.mapBoundariesEnabled&&t._setMapBoundaries();let Z=F*D;for(let e=0;e=s&&r0){const e=q.get(r);e&&(i=!0,e.objects.forEach((e=>{const t=a+e.x,i=o+e.y;if(0!==e.rotation&&R("tilesetData.tiles.rotation property is not supported yet"),e.polygon)e.polygon.forEach(((s,n)=>{const r=e.polygon[n+1];if(r)x.push([s.x+t,s.y+i,r.x+t,r.y+i]);else{const n=e.polygon[0];x.push([s.x+t,s.y+i,n.x+t,n.y+i])}}));else if(e.point)v.push([t,i]);else if(e.ellipse){const s=e.width/2,n=e.height/2;y.push([t+s,i+n,s,n])}else{const s=e.width,n=e.height,r=s+t,a=n+i;x.push([t,i,r,i]),x.push([r,i,r,a]),x.push([r,a,t,a]),x.push([t,a,t,i])}})))}if(!1===i){let i=[a+b,o,a+b,o+I],s=[a+b,o+I,a,o+I],r=[a,o,a+b,o],l=[a,o+I,a,o],h=[null,null,null,null];const c=0!==e?S.get(e-1):void 0;if(c){const e=c.get(n);if(e){const t=e[2],s=x[t];if(s){const e=s[0],i=s[1],n=s[2],a=s[3],o=r[0],l=r[1],h=r[2],c=r[3];o===n&&l===a&&h===e&&c===i&&(x[t]=void 0,r=void 0)}const n=e[1],a=x[n];if(a){const e=a[0],t=a[1],s=a[2],r=i[0];e===i[2]&&s===r&&(x[n]=void 0,i[0]=e,i[1]=t)}const o=e[3],h=x[o];if(h){const e=h[0],t=h[2],i=h[3],s=l[0];e===l[2]&&t===s&&(x[o]=void 0,l[2]=t,l[3]=i)}}}const d=0!==n?t.get(n-1):void 0;if(d){const e=d[1],t=x[e],i=t[0],n=t[1],a=t[2],o=t[3],h=l[0],c=l[1],u=l[2],g=l[3];h===a&&c===o&&u===i&&g===n&&(x[e]=void 0,l=void 0);const m=d[0],f=x[m];if(f&&r){const e=f[0],t=f[1],i=f[3],s=r[1];t===r[3]&&i===s&&(x[m]=void 0,r[0]=e,r[1]=t)}const E=d[2],_=x[E];if(_){const e=_[1],t=_[2],i=_[3],n=s[1];e===s[3]&&i===n&&(x[E]=void 0,s[2]=t,s[3]=i)}}r&&(x.push(r),h[0]=x.length-1),x.push(i),h[1]=x.length-1,x.push(s),h[2]=x.length-1,l&&(x.push(l),h[3]=x.length-1),t.set(n,h)}}}Z++}t.size>0&&S.set(e,t),Z+=V}w.push([new Float32Array(X),new Float32Array(H),i.name,O])}if(p){const e=x.filter((e=>e));t._addBoundariesArray(e),y.length>0&&t._addEllipseBoundaries(y),v.length>0&&t._addPointBoundaries(v)}i(w)}))}#Lt(e,t){return new Promise(((i,s)=>{const n=e.tilemap,r=e.tilesets,a=e.tilesetImages,o=e.layerData,{tileheight:l,tilewidth:h}=n,c=h,d=l,[u,g]=(e.setBoundaries,t.worldDimensions),[f,E]=t.canvasDimensions,[A,T]=!0===e.isOffsetTurnedOff?[0,0]:t.worldOffset;let p=[];o||(R(m,"check tilemap and layers name"),s());for(let e=0;e<=r.length-1;e++){const i=r[e].data,s=r[e].firstgid,n=r[e+1],m=n?n.firstgid:1e9,S=i.tilewidth,x=i.tileheight,y=i.columns,v=o.width,w=o.height,b=c*v,I=d*w,O=(Math.ceil(f/c),Math.ceil(E/d),a[e]),P=O.width,C=O.height,M=i.spacing;i.margin;let D=0,L=[],B=[];b===u&&I===g||(R(_," World size from tilemap is different than settings one, fixing..."),t._setWorldDimensions(b,I));for(let e=0;e=s&&inew Promise(((i,s)=>{const n=e.tilemap,r=n.tilesets,a=e.tilesetImages,o=e.layerData,{tileheight:l,tilewidth:h}=n,c=h,d=l,u=o.data.length,g=o.data.filter((e=>0!==e)).length,[f,E]=t.worldDimensions,[A,T]=!0===e.isOffsetTurnedOff?[0,0]:t.worldOffset,p=[];this.layerDataFloat32.set(o.data),o||(R(m,"check tilemap and layers name"),s());for(let e=0;e0?this.layerDataFloat32.slice(u,D+u):[],G=N>0?this.layerDataFloat32.slice(D+u,D+L+u):[];p.push([W,G,i.name,O])}i(p)}));#Pt(e){return e.replace("rgba(","").replace(")","").split(",").map((e=>Number(e.trim())))}#It(e){return this.#Wt(e)}#Wt(e,t=[]){const i=e.length;if(i<=3)return e.forEach((e=>{t.push(e[0]),t.push(e[1])})),t;const s=[...e].sort(((e,t)=>t[1]-e[1])),n=e.indexOf(s[0]),r=n!==i-1?n+1:0;let a=e,o=a.length,l=0,h=r;for(;a.length>2;){const e=a.length;h>=e&&(h-=e);const i=0===h?a[e-1]:a[h-1],s=a[h],n=e===h+1?a[0]:a[h+1];if(c=i,d=s,ce({x:(u=n)[0]-c[0],y:u[1]-c[1]},{x:d[0]-c[0],y:d[1]-c[1]})<0)t.push(i[0]),t.push(i[1]),t.push(s[0]),t.push(s[1]),t.push(n[0]),t.push(n[1]),a=a.filter(((e,t)=>t!==h));else{if(l+=1,l>o)return R("TRIANGULATE_ISSUE","Can't extract all triangles vertices."),t;h++}}var c,d,u;return t}#Ot(e){this.#Et.bufferData(this.#Et.ARRAY_BUFFER,new Float32Array(e),this.#Et.STATIC_DRAW)}#bt(e,t){const i=0+e,s=0+t;this.#Et.bufferData(this.#Et.ARRAY_BUFFER,new Float32Array([0,0,i,0,0,s,0,s,i,0,i,s]),this.#Et.STATIC_DRAW)}#Dt(e,t,i,s=0,n=!1){this.#Mt(e,t,s),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,i),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,n?e.LINEAR_MIPMAP_LINEAR:e.LINEAR)}#Ct(e,t,i,s=0){this.#Mt(e,t,s),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,i),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST)}#Mt(e,t,i=0){e.activeTexture(e.TEXTURE0+i),e.bindTexture(e.TEXTURE_2D,t)}#Gt(e,t){e.deleteTexture(t)}isPowerOfTwo(e){return!(e&e-1)}nextHighestPowerOfTwo(e){--e;for(var t=1;t<32;t<<=1)e|=e>>t;return e+1}}const Pe=["u_translation","u_rotation","u_scale","u_resolution","u_image"],Ce=["a_position","a_texCoord"],Me=["u_translation","u_rotation","u_scale","u_resolution","u_fade_min","u_fade_max","u_color"],De=["a_position"];class Le{#Ft;#kt;#jt;#_e;#Ut;#Vt;#Yt;#dt;#zt;#Xt;#Ht=!1;#Kt;#xe=new EventTarget;#qt;#Zt=new Map;#Jt=[];constructor(e,t,i){this.#jt=!1,this.#Ft=document.createElement("canvas"),i.appendChild(this.#Ft),this.#kt=this.#Ft.getContext("webgl",{stencil:!0}),this.#Yt=e,this.#dt=t,this.#zt=[],this.#Kt=this.systemSettings.gameOptions.render.minCycleTime,this.#Ht=this.systemSettings.gameOptions.render.boundaries.wholeWorldPrecalculations,this.#Ut=new Oe(this.#kt,this.#Yt.gameOptions),this.systemSettings.gameOptions.optimization!==l.OPTIMIZATION.WEB_ASSEMBLY.NATIVE_WAT&&this.systemSettings.gameOptions.optimization!==l.OPTIMIZATION.WEB_ASSEMBLY.ASSEMBLY_SCRIPT||this._registerRenderInit(this.#Ut._initiateWasm),this._registerRenderInit(this.fixCanvasSize),this._registerRenderInit((()=>this._registerAndCompileWebGlProgram(l.WEBGL.DRAW_PROGRAMS.IMAGES,"\n attribute vec2 a_texCoord;\n\n attribute vec2 a_position;\n\n uniform vec2 u_translation;\n uniform float u_rotation;\n uniform vec2 u_scale;\n\n uniform vec2 u_resolution;\n\n varying vec2 v_texCoord;\n\n void main(void) {\n float c = cos(u_rotation);\n float s = sin(u_rotation);\n\n mat3 translationMatrix1 = mat3(\n 1, 0, 0,\n 0, 1, 0,\n u_translation.x, u_translation.y, 1\n );\n\n mat3 translationMatrix2 = mat3(\n 1, 0, 0,\n 0, 1, 0,\n -u_translation.x, -u_translation.y, 1\n );\n \n mat3 rotationMatrix = mat3(\n c, s, 0,\n -s, c, 0,\n 0, 0, 1\n );\n\n mat3 scalingMatrix = mat3(\n u_scale.x, 0, 0,\n 0, u_scale.y, 0,\n 0, 0, 1\n );\n\n mat3 matrix = translationMatrix1 * rotationMatrix * translationMatrix2 * scalingMatrix;\n \n vec2 position = (matrix * vec3(a_position, 1)).xy;\n\n vec2 clipSpace = position / u_resolution * 2.0 - 1.0;\n\n gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);\n \n v_texCoord = a_texCoord;\n }","\n precision mediump float;\n\n uniform sampler2D u_image;\n\n //texCoords passed in from the vertex shader\n varying vec2 v_texCoord;\n void main() {\n vec4 color = texture2D(u_image, v_texCoord);\n gl_FragColor = color;\n }",Pe,Ce))),this._registerRenderInit((()=>this._registerAndCompileWebGlProgram(l.WEBGL.DRAW_PROGRAMS.PRIMITIVES,"\n precision mediump float;\n\n attribute vec2 a_position;\n\n uniform vec2 u_translation;\n uniform float u_rotation;\n uniform vec2 u_scale;\n\n uniform vec2 u_resolution;\n\n void main(void) {\n float c = cos(u_rotation);\n float s = sin(u_rotation);\n\n mat3 translationMatrix1 = mat3(\n 1, 0, 0,\n 0, 1, 0,\n u_translation.x, u_translation.y, 1\n );\n\n //mat3 translationMatrix2 = mat3(\n // 1, 0, 0,\n // 0, 1, 0,\n // -u_translation.x, -u_translation.y, 1\n //);\n \n mat3 rotationMatrix = mat3(\n c, s, 0,\n -s, c, 0,\n 0, 0, 1\n );\n\n mat3 scalingMatrix = mat3(\n u_scale.x, 0, 0,\n 0, u_scale.y, 0,\n 0, 0, 1\n );\n \n mat3 matrix = translationMatrix1 * rotationMatrix * scalingMatrix;\n\n vec2 position = (matrix * vec3(a_position, 1)).xy;\n\n vec2 clipSpace = position / u_resolution * 2.0 - 1.0;\n\n gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);\n }\n","\n precision mediump float;\n\n uniform vec4 u_color;\n uniform float u_fade_min; \n uniform float u_fade_max;\n uniform vec2 u_resolution;\n uniform vec2 u_translation;\n\n void main(void) {\n vec4 p = u_color;\n if (u_fade_min > 0.0) {\n vec2 fix_tr = vec2(u_translation.x, u_resolution.y - u_translation.y); \n float distance = distance(fix_tr.xy, gl_FragCoord.xy);\n if (u_fade_min <= distance && distance <= u_fade_max) {\n float percent = ((distance - u_fade_max) / (u_fade_min - u_fade_max)) * 100.0;\n p.a = u_color.a * (percent / 100.0);\n }\n }\n\n gl_FragColor = p;\n }\n",Me,De))),this._registerRenderInit(this.#Ut._initWebGlAttributes),this._registerObjectRender(j.name,this.#Ut._bindText,l.WEBGL.DRAW_PROGRAMS.IMAGES),this._registerObjectRender(W.name,this.#Ut._bindPrimitives,l.WEBGL.DRAW_PROGRAMS.PRIMITIVES),this._registerObjectRender(X.name,this.#Ut._bindPrimitives,l.WEBGL.DRAW_PROGRAMS.PRIMITIVES),this._registerObjectRender(H.name,this.#Ut._bindConus,l.WEBGL.DRAW_PROGRAMS.PRIMITIVES),this._registerObjectRender(U.name,this.#Ut._bindConus,l.WEBGL.DRAW_PROGRAMS.PRIMITIVES),this._registerObjectRender(K.name,this.#Ut._bindTileImages,l.WEBGL.DRAW_PROGRAMS.IMAGES),this._registerObjectRender(z.name,this.#Ut._bindLine,l.WEBGL.DRAW_PROGRAMS.PRIMITIVES)}addEventListener=(e,t,i)=>{this.#xe.addEventListener(e,t,i)};removeEventListener=(e,t,i)=>{this.#xe.removeEventListener(e,t,i)};get stageData(){return this.#Vt}get systemSettings(){return this.#Yt}get iLoader(){return this.#dt}get canvas(){return this.#Ft}get drawContext(){return this.#kt}emit=(e,...t)=>{const i=new Event(e);i.data=[...t],this.#xe.dispatchEvent(i)};isAllFilesLoaded=()=>0===this.iLoader.filesWaitingForUpload;initiateContext=()=>Promise.all(this.#Jt.map((e=>e())));clearContext(){this.#Ut._clearView()}setCanvasSize(e,t){this.#Ft.width=e,this.#Ft.height=t,this.#Ut&&this.#Ut._fixCanvasSize(e,t)}fixCanvasSize=()=>{const e=this.systemSettings,t=e.canvasMaxSize.width&&e.canvasMaxSize.widthPromise.reject(e)));e.push(n)}this.systemSettings.gameOptions.debug.boundaries.drawLayerBoundaries&&e.push(this.#Qt().catch((e=>Promise.reject(e))))}return(await Promise.allSettled(e)).forEach((e=>{"rejected"===e.status&&(Promise.reject(e.reason),i=!0,t.push(e.reason))})),this.#$t(),this._isCleared=!1,!1===i?Promise.resolve():Promise.reject(t)}set _isCleared(e){this.#jt=e}get _isCleared(){return this.#jt}_createBoundariesPrecalculations(){}#$t(){}#ei(e){return new Promise(((t,i)=>{if(e.setBoundaries){const s=this.iLoader.getTileMap(e.tileMapKey),n=s.tilesets,r=s.layers.find((t=>t.name===e.layerKey)),{tileheight:a,tilewidth:o}=s,l=o,h=a,[c,d]=this.stageData.worldDimensions;let u=[];r||(R(m,"check tilemap and layers name"),i());for(let t=0;tthis.#Ut._render(e[0],e[1])))}return i.method(e,this.drawContext,this.stageData)}if(e.type===l.DRAW_TYPE.IMAGE){const t=this.#Ut.getProgram(l.WEBGL.DRAW_PROGRAMS.IMAGES),i=this.#Ut.getProgramVarLocations(l.WEBGL.DRAW_PROGRAMS.IMAGES);if(!e.image){const t=this.iLoader.getImage(e.key);t?e.image=t:S(d,"iLoader can't get the image with key: "+e.key)}return this.#Ut._bindImage(e,this.drawContext,this.stageData,t,i).then((e=>this.#Ut._render(e[0],e[1]))).then((()=>e.vertices&&this.systemSettings.gameOptions.debug.boundaries.drawObjectBoundaries?this.#Ut._drawPolygon(e,this.stageData):Promise.resolve()))}return console.warn("no registered draw object method for "+t+" skip draw"),Promise.resolve()}#Qt(){return new Promise((e=>{const t=this.stageData.getBoundaries(),i=this.stageData.getEllipseBoundaries(),s=this.stageData.getPointBoundaries(),n=(t.length,i.length),r=s.length;this.#Ut._drawLines(t.flat(),this.systemSettings.gameOptions.debug.boundaries.boundariesColor,this.systemSettings.gameOptions.debug.boundaries.boundariesWidth),n&&i.forEach((e=>{const t=be(e[0],e[1],e[2],e[3]);this.#Ut._drawPolygon({x:0,y:0,vertices:t,isOffsetTurnedOff:!0},this.stageData)})),r&&s.forEach((e=>{const t=e[0],i=e[1],s=[t,i,t+1,i+1];this.#Ut._drawLines(s,this.systemSettings.gameOptions.debug.boundaries.boundariesColor,this.systemSettings.gameOptions.debug.boundaries.boundariesWidth)})),e()}))}#ti(){const e=this.systemSettings.gameOptions.render.cyclesTimeCalc.averageFPStime,t=this.#zt.length;let i=0;for(let e=0;e{const t=this.systemSettings.gameOptions;this.#_e=!0,this.#Vt=e,this.fixCanvasSize(),t.library===l.LIBRARY.WEBGL&&(await this.#ii(),this.timeStart=Date.now(),setTimeout((()=>requestAnimationFrame(this.#si)))),t.render.cyclesTimeCalc.check===l.OPTIMIZATION.CYCLE_TIME_CALC.AVERAGES&&(this.#Xt=setInterval((()=>this.#ti()),t.render.cyclesTimeCalc.averageFPStime))};_stopRender=()=>{this.#_e=!1,this.#Vt=null,this.#zt=[],clearInterval(this.#Xt),this.#Xt=null};#ii(){return new Promise(((e,t)=>{let i=[];const s=this.#Ht;i.push(this.initiateContext()),s&&console.warn("isBoundariesPrecalculations() is turned off"),Promise.allSettled(i).then((i=>{i.forEach((e=>{if("rejected"===e.status){const i=e.reason;R(E,i),t(i)}})),e()}))}))}#si=async()=>{const e=performance.now(),t=this.#Kt,i=this.systemSettings.gameOptions.render.cyclesTimeCalc.check===l.OPTIMIZATION.CYCLE_TIME_CALC.CURRENT;this.emit(l.EVENTS.SYSTEM.RENDER.START),this.stageData._clearBoundaries(),this.clearContext(),this.render().then((()=>{const s=performance.now()-e,n=t-s,r=n>0?n:0,a=s+r;i&&s>t&&console.log("current draw take: ",s," ms"),this.emit(l.EVENTS.SYSTEM.RENDER.END),a>0&&this.#zt.push(a),this.#_e&&setTimeout((()=>requestAnimationFrame(this.#si)),r)})).catch((e=>{e.forEach?e.forEach((e=>{R(E,e)})):R(E,e.message),this._stopRender()}))}}class Be{#ni;constructor(e){this.#ni=e}registerDrawObject(e,t){this.#ni.drawObjectFactory._registerNewObjectMethod(e,t)}registerAndCompileWebGlProgram(e,t,i,s,n){return this.#ni.iRender._registerAndCompileWebGlProgram(e,t,i,s,n)}registerRenderInit(e){this.#ni.iRender._registerRenderInit(e)}registerObjectRender(e,t,i){this.#ni.iRender._registerObjectRender(e,t,i)}}class Ne{#Ze;#ri;#ai;#oi;#Ye=new D;#li;#hi=new q(this.#Ye);#ci=new Map;#di;#xe=new EventTarget;constructor(e,t,i){e||S(h,"systemSettings should be passed to class instance"),this.#Ze=e,this.#oi=new ee(this.iLoader),this.#ai=e.network.enabled?new $(e):null,this.#li=new Le(this.systemSettings,this.iLoader,i),this.#ri=new Be(this,this.#li),this.#di=t,this.#li.addEventListener(l.EVENTS.SYSTEM.RENDER.START,(()=>this.emit(l.EVENTS.SYSTEM.RENDER.START))),this.#li.addEventListener(l.EVENTS.SYSTEM.RENDER.END,(()=>this.emit(l.EVENTS.SYSTEM.RENDER.END)))}emit=(e,...t)=>{const i=new Event(e);i.data=[...t],this.#xe.dispatchEvent(i)};addEventListener=(e,t,i)=>{this.#xe.addEventListener(e,t,i)};removeEventListener=(e,t,i)=>{this.#xe.removeEventListener(e,t,i)};get iNetwork(){return this.#ai}get systemSettings(){return this.#Ze}get audio(){return this.#oi}get iLoader(){return this.#Ye}get iRender(){return this.#li}get drawObjectFactory(){return this.#hi}get iExtension(){return this.#ri}get modules(){return this.#ci}installModule=(e,t,...i)=>{const s=new t(this,...i);return this.#ci.has(e)?(R("MODULE_ALREADY_INSTALLED","module "+e+" is already installed"),this.#ci.get(e)):(this.#ci.set(e,s),s)};startGameStage=(e,t)=>{if(this.#di.has(e)){const i=this.#di.get(e),s=i.stageData;this.#hi._attachPageData(s),!1===i.isInitiated&&i._init(),i._start(t),this.emit(l.EVENTS.SYSTEM.START_PAGE),this.#li._startRender(s)}else S(c,"View "+e+" is not registered!")};stopGameStage=e=>{this.#di.has(e)?(this.emit(l.EVENTS.SYSTEM.STOP_PAGE),this.drawObjectFactory._detachPageData(),this.#li._stopRender(),this.#di.get(e)._stop()):S(c,"View "+e+" is not registered!")}}class We{#ui;#gi=!1;#_e;#mi;#fi;constructor(){this.#_e=!1,this.#fi=new x}_register(e,t){this.#ui=e,this.#mi=t,this.#Ei(),this.#_i(),this.register()}_init(){this.init(),this.#gi=!0}register(){}init(){}start(e){}stop(){}resize(){}get iLoader(){return this.#mi.iLoader}get draw(){return this.#mi.drawObjectFactory}_attachCanvasToContainer(e){this.#Ai(this.canvasHtmlElement,e)}addRenderObject=e=>{const t=this.stageData;-1!==t.renderObjects.indexOf(e)?R("NEW_BEHAVIOR_INTRODUCED","stage.draw methods add objects to pageData, no need to call addRenderObject"):(t._renderObject=e,t._sortRenderObjectsBySortIndex())};get isActive(){return this.#_e}get isInitiated(){return this.#gi}get name(){return this.#ui}get stageData(){return this.#fi}get systemSettings(){return this.#mi.systemSettings}get audio(){return this.#mi.audio}get iSystem(){return this.#mi}get canvasHtmlElement(){return document.getElementsByTagName("canvas")[0]}addEventListener=(e,t,i)=>{this.iSystem.addEventListener(e,t,i)};removeEventListener=(e,t,i)=>{this.iSystem.removeEventListener(e,t,i)};_start(e){this.start(e),this.#_e=!0,window.addEventListener("resize",this._resize),this._resize()}_stop(){this.#_e=!1,window.removeEventListener("resize",this._resize),this.stop()}_resize=()=>{this.#_i(),this.resize()};#Ai(e,t){t.appendChild(e)}#Ei(){const e=this.systemSettings.worldSize?this.systemSettings.worldSize.width:0,t=this.systemSettings.worldSize?this.systemSettings.worldSize.height:0;this.stageData._setWorldDimensions(e,t)}isBoundariesCollision=(e,t,i)=>{const s=i.type,n=i.vertices,r=i.circleBoundaries;switch(s){case l.DRAW_TYPE.TEXT:case l.DRAW_TYPE.RECTANGLE:case l.DRAW_TYPE.CONUS:case l.DRAW_TYPE.IMAGE:return r?this.#Ti(e,t,i.circleBoundaries.r):this.#pi(e,t,n,i.rotation);case l.DRAW_TYPE.CIRCLE:R(l.WARNING_CODES.METHOD_NOT_IMPLEMENTED,"isObjectCollision.circle check is not implemented yet!");break;case l.DRAW_TYPE.LINE:R(l.WARNING_CODES.METHOD_NOT_IMPLEMENTED,"isObjectCollision.line check is not implemented yet, please use .rect instead line!");break;default:R(l.WARNING_CODES.UNKNOWN_DRAW_OBJECT,"unknown object type!")}return!1};isObjectsCollision=(e,t,i,s)=>{const n=i.type,r=i.vertices,a=i.circleBoundaries;switch(n){case l.DRAW_TYPE.TEXT:case l.DRAW_TYPE.RECTANGLE:case l.DRAW_TYPE.CONUS:case l.DRAW_TYPE.IMAGE:return a?this.#Si(e,t,a,s):this.#Ri(e,t,r,i.rotation,s);case l.DRAW_TYPE.CIRCLE:R(l.WARNING_CODES.METHOD_NOT_IMPLEMENTED,"isObjectCollision.circle check is not implemented yet!");break;case l.DRAW_TYPE.LINE:R(l.WARNING_CODES.METHOD_NOT_IMPLEMENTED,"isObjectCollision.line check is not implemented yet, please use .rect instead line!");break;default:R(l.WARNING_CODES.UNKNOWN_DRAW_OBJECT,"unknown object type!")}return!1};#Ri(e,t,i,s,n){const r=n.length;let a=[];for(let o=0;o0?this.#yi(a):null}#Si(e,t,i,s){const n=i.r,r=s.length;let a=[];for(let i=0;i0?this.#yi(a):null}#yi(e){return e.sort(((e,t)=>e.p0)}#xi(e,t,i,s,n){const[r,a]=this.stageData.worldOffset,o=e-r,l=t-a,h=n.x-r,c=n.y-a,d=n.vertices,u=n.rotation,g=i.map((e=>this.#bi(e,o,l,s))),m=d.length;for(let e=0;e0)for(let e=0;e0)for(let e=0;ethis.#bi(e,h,c,s))),u=n.length,g=r.length,m=a.length;for(let e=0;e0)for(let e=0;e0)for(let e=0;e{const t=this.#Pi/this.#Ii;this.#Oi=e;const i=t*this.#Oi,s=e>this.#Ii?this.#Pi:i;this.loadingBarProgress.width=s};start(e){this.#Ii=e.total}}const Fe="loadingPage";class ke{#Ci;#Mi;constructor(e,t){e||S(h,"iSystemSettings should be passed to class instance"),this.#Ci=new Map,t||(t=document.createElement("div"),document.body.appendChild(t)),this.#Mi=new Ne(e,this.#Ci,t),this.registerStage(Fe,Ge),this.#Mi.iLoader.addEventListener("loadstart",this.#Di),this.#Mi.iLoader.addEventListener("progress",this.#Li),this.#Mi.iLoader.addEventListener("load",this.#Bi)}get iSystem(){return this.#Mi}registerStage(e,t){if(e&&"string"==typeof e&&e.trim().length>0){const i=new t;i._register(e,this.iSystem),this.#Ci.set(e,i)}else S(h,"valid class name should be provided")}preloadAllData(){return this.#Mi.iLoader.preload()}#Di=e=>{this.#Mi.startGameStage(Fe,{total:e.total})};#Li=e=>{const t=e.loaded,i=e.total;this.#Ci.get(Fe)._progress(t,i)};#Bi=()=>{this.#Mi.stopGameStage(Fe)}}var je=r.oX,Ue=r.QD,Ve=r.T_,Ye=r.uw,ze=r.xl,Xe=r.xP,He=r.bq,Ke=r.P6;export{je as CONST,Ue as DrawImageObject,Ve as GameStage,Ye as ISystemAudio,ze as Primitives,Xe as System,He as SystemSettings,Ke as utils}; \ No newline at end of file diff --git a/docs/templates/custom/tmpl/layout.tmpl b/docs/templates/custom/tmpl/layout.tmpl index 5ec27e4..12ad7c0 100644 --- a/docs/templates/custom/tmpl/layout.tmpl +++ b/docs/templates/custom/tmpl/layout.tmpl @@ -2,6 +2,7 @@ + JSDoc: <?js= title ?> @@ -22,7 +23,7 @@ diff --git a/examples/main.js b/examples/main.js index 54454f6..9b3adc4 100644 --- a/examples/main.js +++ b/examples/main.js @@ -7,6 +7,7 @@ import { SpinePage } from "./spine/spinePage.js"; import { BigMap } from "./big_map/bigMap.js"; import { Tanks } from "./tanks/tanks.js"; import { Strategy } from "./strategy/strategy.js"; +import { Primitives } from "./primitives/primitives.js"; import { CustomWebGlTestPage } from "./testCustomWebGl/index.js"; import { CustomDrawObject, createCustomDrawObjectInstance, drawCustomObject } from "./testCustomWebGl/TestDrawObject.js"; @@ -20,7 +21,8 @@ const START_PAGE_NAME = "start", BIG_MAP = "big_map", STRATEGY_GAME = "strategy_game", CUSTOM_WEBGL_PAGE = "custom_webgl", - TANKS_PAGE = "tanks"; + TANKS_PAGE = "tanks", + PRIMITIVES_PAGE = "primitives"; const TEST_WEBGL_PROGRAM_KEY = "test", TEST_CUSTOM_DRAW_OBJECT_KEY = "customDrawObject"; @@ -218,6 +220,7 @@ function runApp(settings) { app.registerStage(STRATEGY_GAME, Strategy); app.registerStage(CUSTOM_WEBGL_PAGE, CustomWebGlTestPage); app.registerStage(TANKS_PAGE, Tanks); + app.registerStage(PRIMITIVES_PAGE, Primitives) // пробуем пользовательскую webgl программу app.iSystem.iExtension.registerAndCompileWebGlProgram(TEST_WEBGL_PROGRAM_KEY, testVertexShader, testFragmentShader, testUniforms, testAttributes); diff --git a/examples/primitives/primitives.js b/examples/primitives/primitives.js new file mode 100644 index 0000000..08be9cb --- /dev/null +++ b/examples/primitives/primitives.js @@ -0,0 +1,98 @@ +import { GameStage, CONST, System, SystemSettings } from "../../src/index.js"; + +export class Primitives extends GameStage { + #keyPressed = { ArrowUp: false, KeyW: false, ArrowLeft: false, KeyA: false, ArrowRight: false, KeyD: false, ArrowDown: false, KeyS: false }; + register() { + } + init() { + } + start() { + this.registerListeners(); + } + + stop() { + this.unregisterListeners(); + } + + registerListeners() { + this.#registerMouseListeners(); + this.#registerKeyboardListeners(); + this.#registerSystemEventsListeners(); + } + + unregisterListeners() { + this.#unregisterMouseListeners(); + this.#unregisterKeyboardListeners(); + this.#unregisterSystemEventsListeners(); + } + + #registerKeyboardListeners() { + document.addEventListener("keydown", this.#pressKeyAction); + document.addEventListener("keyup", this.#removeKeyAction); + } + + #unregisterKeyboardListeners() { + document.removeEventListener("keydown", this.#pressKeyAction); + document.removeEventListener("keyup", this.#removeKeyAction); + } + + #registerMouseListeners() { + document.addEventListener("mousemove", this.#mouseMoveAction); + document.addEventListener("click", this.#mouseClickAction); + } + + #unregisterMouseListeners() { + document.removeEventListener("mousemove", this.#mouseMoveAction); + document.removeEventListener("click", this.#mouseClickAction); + } + + #pressKeyAction = (event) => { + const code = event.code; + let keyPressed = this.#keyPressed; + + keyPressed[code] = true; + }; + #removeKeyAction = (event) => { + const code = event.code; + this.#keyPressed[code] = false; + }; + + #mouseMoveAction = (e) => { + const [xOffset, yOffset] = this.stageData.worldOffset, + x = e.offsetX, + y = e.offsetY, + cursorPosX = x + xOffset, + cursorPosY = y + yOffset; + }; + + + #mouseClickAction = (e) => { + + } + + + #render = () => { + const keyPressed = this.#keyPressed; + + if (keyPressed["ArrowUp"] || keyPressed["KeyW"]){ + //this.stepMove("forward"); + } + if (keyPressed["ArrowLeft"] || keyPressed["KeyA"]) { + //this.stepMove("turn_left"); + } + if (keyPressed["ArrowRight"] || keyPressed["KeyD"]) { + //this.stepMove("turn_right"); + } + if (keyPressed["ArrowDown"] || keyPressed["KeyS"]){ + //this.stepMove("backward"); + } + + } + #registerSystemEventsListeners() { + this.iSystem.addEventListener(CONST.EVENTS.SYSTEM.RENDER.START, this.#render); + } + + #unregisterSystemEventsListeners() { + this.iSystem.removeEventListener(CONST.EVENTS.SYSTEM.RENDER.START, this.#render); + } +} diff --git a/examples/startPage.js b/examples/startPage.js index 39db30a..05f2afc 100644 --- a/examples/startPage.js +++ b/examples/startPage.js @@ -14,7 +14,8 @@ const START_PAGE_NAME = "start", BIG_MAP = "big_map", STRATEGY_GAME = "strategy_game", CUSTOM_WEBGL_PAGE = "custom_webgl", - TANKS_PAGE = "tanks"; + TANKS_PAGE = "tanks", + PRIMITIVES_PAGE = "primitives"; const SPINE = { SpineTexture: "spineTexture", @@ -55,6 +56,7 @@ export class StartPage extends GameStage { this.navItemBigMap = this.draw.text(w/2 + LEFT_SHIFT, h/2 + 70, "Big map", "20px sans-serif", "black"); this.navItemTestCustomWebGl = this.draw.text(w/2 + LEFT_SHIFT, h/2 + 100, "Custom WebGl program", "20px sans-serif", "black"); this.navTanksGame = this.draw.text(w/2 + LEFT_SHIFT, h/2 + 130, "Tanks game", "20px sans-serif", "black"); + this.navPrimitivesGame = this.draw.text(w/2 + LEFT_SHIFT, h/2 + 160, "Primitives draw", "20px sans-serif", "black"); //this.#createOptionsBlock(); this.audio.registerAudio(MENU_CLICK_AUDIO_NAME); @@ -86,7 +88,8 @@ export class StartPage extends GameStage { isNav5T = isPointRectIntersect(event.offsetX, event.offsetY, this.navItemBigMap.boundariesBox), isNav6T = isPointRectIntersect(event.offsetX, event.offsetY, this.navItemTestCustomWebGl.boundariesBox), isNav7T = isPointRectIntersect(event.offsetX, event.offsetY, this.navTanksGame.boundariesBox), - isNav8T = isPointRectIntersect(event.offsetX, event.offsetY, this.navItemStrategy.boundariesBox); + isNav8T = isPointRectIntersect(event.offsetX, event.offsetY, this.navItemStrategy.boundariesBox), + isNav9T = isPointRectIntersect(event.offsetX, event.offsetY, this.navPrimitivesGame.boundariesBox); if (isNav1Traversed) { this.navItemDun.strokeStyle = "rgba(0, 0, 0, 0.3)"; @@ -136,7 +139,13 @@ export class StartPage extends GameStage { this.navItemStrategy.strokeStyle = undefined; } - if (isNav1Traversed || isNavP2PTraversed || isNav3Traversed || isNav4Traversed || isNav5T || isNav6T || isNav7T || isNav8T) { + if (isNav9T) { + this.navPrimitivesGame.strokeStyle = "rgba(0, 0, 0, 0.3)"; + } else if (this.navPrimitivesGame.strokeStyle) { + this.navPrimitivesGame.strokeStyle = undefined; + } + + if (isNav1Traversed || isNavP2PTraversed || isNav3Traversed || isNav4Traversed || isNav5T || isNav6T || isNav7T || isNav8T || isNav9T) { canvas.style.cursor = "pointer"; } else { canvas.style.cursor = "default"; @@ -195,6 +204,13 @@ export class StartPage extends GameStage { this.iSystem.startGameStage(STRATEGY_GAME); } + + if (isPointRectIntersect(event.offsetX, event.offsetY, this.navPrimitivesGame.boundariesBox)) { + this.#menuClickMediaElement.play(); + this.iSystem.stopGameStage(START_PAGE_NAME); + this.iSystem.startGameStage(PIRATES_GAME); + + } }; #loaderErrorHandler = (error) => { diff --git a/history/history-roadmap.txt b/history/history-roadmap.txt index 70b2e95..8264fcc 100644 --- a/history/history-roadmap.txt +++ b/history/history-roadmap.txt @@ -4,6 +4,9 @@ r: code refactoring f: fixed defects # History +1.4.4: + r: disable iNetwork interface by default + 1.4.32: f: Mobile Chrome@125.0.6422.147 issue: "Name conflicts between an uniform and an attribute: a_position" f: registerStage() type issue diff --git a/package.json b/package.json index 598539f..17e0f76 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jsge", - "version": "1.4.32", + "version": "1.4.4", "description": "Javascript Game Engine", "main": "src/index.js", "type": "module", diff --git a/src/base/IExtension.js b/src/base/IExtension.js index 210575a..bee7617 100644 --- a/src/base/IExtension.js +++ b/src/base/IExtension.js @@ -51,7 +51,7 @@ export class IExtension { * Register render method for class. * @param {string} objectClassName - object name registered to DrawObjectFactory * @param {function(renderObject, gl, pageData, program, vars):Promise} objectRenderMethod - should be promise based returns vertices number and draw program - * @param {string=} objectWebGlDrawProgram - a webgl program name previously registered with iExtension.registerAndCompileWebGlProgram() + * @param {string} objectWebGlDrawProgram - a webgl program name previously registered with iExtension.registerAndCompileWebGlProgram() */ registerObjectRender(objectClassName, objectRenderMethod, objectWebGlDrawProgram) { this.#systemReference.iRender._registerObjectRender(objectClassName, objectRenderMethod, objectWebGlDrawProgram); diff --git a/src/base/INetwork.js b/src/base/INetwork.js index a350f7c..a5504e0 100644 --- a/src/base/INetwork.js +++ b/src/base/INetwork.js @@ -5,6 +5,9 @@ import { SystemEvent } from "./Events/SystemEvent.js"; /** * Represents Socket connection + * + * From 1.4.4 disabled by default, + * to enable, set settings.network.enabled to true */ export class INetwork extends EventTarget { #systemSettings; diff --git a/src/base/ISystem.js b/src/base/ISystem.js index 3d410ae..8fd9118 100644 --- a/src/base/ISystem.js +++ b/src/base/ISystem.js @@ -28,7 +28,7 @@ export class ISystem { */ #iExtension; /** - * @type {INetwork} + * @type {INetwork | null} */ #systemServerConnection; /** @@ -67,7 +67,7 @@ export class ISystem { this.#systemSettings = systemSettings; this.#systemAudioInterface = new ISystemAudio(this.iLoader); - this.#systemServerConnection = new INetwork(systemSettings); + this.#systemServerConnection = systemSettings.network.enabled ? new INetwork(systemSettings) : null; this.#iRender = new IRender(this.systemSettings, this.iLoader, canvasContainer); this.#iExtension = new IExtension(this, this.#iRender); this.#registeredStagesReference = registeredStages; @@ -108,7 +108,7 @@ export class ISystem { }; /** - * @type { INetwork } + * @type { INetwork | null } */ get iNetwork () { return this.#systemServerConnection; diff --git a/src/base/System.js b/src/base/System.js index 40f5867..4bf71de 100644 --- a/src/base/System.js +++ b/src/base/System.js @@ -57,7 +57,7 @@ export class System { * A main factory method for create GameStage instances,
* register them in a System and call GameStage.register() stage * @param {string} screenPageName - * @param {typeof GameStage} stage + * @param {GameStage} stage */ registerStage(screenPageName, stage) { if (screenPageName && typeof screenPageName === "string" && screenPageName.trim().length > 0) { diff --git a/src/configs.js b/src/configs.js index 5279882..a13f1ac 100644 --- a/src/configs.js +++ b/src/configs.js @@ -16,7 +16,7 @@ export class SystemSettings { // no other variants only WEBGL for now library: CONST.LIBRARY.WEBGL, optimization: CONST.OPTIMIZATION.NATIVE_JS.OPTIMIZED, - optimizationWASMUrl: "/src/wa/calculateBufferDataWat.wasm", + optimizationWASMUrl: "./src/wa/calculateBufferDataWat.wasm", optimizationAssemblyUrl: "/src/wa/calculateBufferDataAssembly.wasm", loadingScreen: { backgroundColor: "rgba(128, 128, 128, 0.6)", @@ -51,6 +51,8 @@ export class SystemSettings { static network = { + // disable INetwork by default + enabled: false, address: "https://gameserver.reslc.ru:9009", gatherRoomsInfoInterval: 5000 };