@galacean/effects-plugin-alipay-downgrade 2.0.0-alpha.0 → 2.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.min.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * Description: Galacean Effects player downgrade plugin for Alipay
4
4
  * Author: Ant Group CO., Ltd.
5
5
  * Contributors: 燃然,意绮
6
- * Version: v2.0.0-alpha.0
6
+ * Version: v2.0.0-alpha.1
7
7
  */
8
- !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("@galacean/effects")):"function"==typeof define&&define.amd?define(["exports","@galacean/effects"],n):n(((e="undefined"!=typeof globalThis?globalThis:e||self).ge=e.ge||{},e.ge.alipayDowngradePlugin={}),e.ge)}(this,(function(e,n){"use strict";var r=function(e,n){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,n){e.__proto__=n}||function(e,n){for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])},r(e,n)};function t(e,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function t(){this.constructor=e}r(e,n),e.prototype=null===n?Object.create(n):(t.prototype=n.prototype,new t)}function o(e,n,r,t){return new(r||(r=Promise))((function(o,i){function a(e){try{l(t.next(e))}catch(e){i(e)}}function c(e){try{l(t.throw(e))}catch(e){i(e)}}function l(e){var n;e.done?o(e.value):(n=e.value,n instanceof r?n:new r((function(e){e(n)}))).then(a,c)}l((t=t.apply(e,n||[])).next())}))}function i(e,n){var r,t,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:c(0),throw:c(1),return:c(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function c(c){return function(l){return function(c){if(r)throw new TypeError("Generator is already executing.");for(;i&&(i=0,c[0]&&(a=0)),a;)try{if(r=1,t&&(o=2&c[0]?t.return:c[0]?t.throw||((o=t.return)&&o.call(t),0):t.next)&&!(o=o.call(t,c[1])).done)return o;switch(t=0,o&&(c=[2&c[0],o.value]),c[0]){case 0:case 1:o=c;break;case 4:return a.label++,{value:c[1],done:!1};case 5:a.label++,t=c[1],c=[0];continue;case 7:c=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==c[0]&&2!==c[0])){a=0;continue}if(3===c[0]&&(!o||c[1]>o[0]&&c[1]<o[3])){a.label=c[1];break}if(6===c[0]&&a.label<o[1]){a.label=o[1],o=c;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(c);break}o[2]&&a.ops.pop(),a.trys.pop();continue}c=n.call(e,a)}catch(e){c=[6,e],t=0}finally{r=o=0}if(5&c[0])throw c[1];return{value:c[0]?c[1]:void 0,done:!0}}([c,l])}}}function a(e,n){var r="function"==typeof Symbol&&e[Symbol.iterator];if(!r)return e;var t,o,i=r.call(e),a=[];try{for(;(void 0===n||n-- >0)&&!(t=i.next()).done;)a.push(t.value)}catch(e){o={error:e}}finally{try{t&&!t.done&&(r=i.return)&&r.call(i)}finally{if(o)throw o.error}}return a}function c(e,n,r){if(r||2===arguments.length)for(var t,o=0,i=n.length;o<i;o++)!t&&o in n||(t||(t=Array.prototype.slice.call(n,0,o)),t[o]=n[o]);return e.concat(t||Array.prototype.slice.call(n))}"function"==typeof SuppressedError&&SuppressedError;var l,u,s="low",d="middle",f="high",p="DESKTOP_DEBUG",v=!1;function g(){return o(this,void 0,void 0,(function(){return i(this,(function(e){return l||(l=function(){return o(this,void 0,void 0,(function(){return i(this,(function(e){return[2,new Promise((function(e,n){var r=window.AlipayJSBridge;r?r.call("getSystemInfo",(function(r){r.error?n(r):e(r)})):n("no ap")}))]}))}))}().then((function(e){var n=e.performance,r=e.platform,t=e.model;if(u||(u=n),v="iOS"===r,/iPhone(\d+),/.test(p=void 0===t?"UNKNOWN_DEVICE":t)&&!u){var o=+RegExp.$1;u=o<=9?s:o<10?d:f}return 0===p.indexOf(e.brand)&&(p=p.replace(e.brand,"").trim()),p}),(function(e){}))),[2,l.then((function(){return p}),(function(){return p}))]}))}))}function y(e){return"auto"!==e&&e?/[ABS]/.test(e)?e:n.spec.RenderLevel.S:u===f?n.spec.RenderLevel.S:u===d?n.spec.RenderLevel.A:u===s?n.spec.RenderLevel.B:v?n.spec.RenderLevel.S:n.spec.RenderLevel.B}var h="mock-fail";function w(e,r){return void 0===r&&(r={}),o(this,void 0,void 0,(function(){var t,o;return i(this,(function(i){return e===h||"mock-pass"===e?[2,Promise.resolve({downgrade:e===h,reason:"mock"})]:(t=window.AlipayJSBridge)?(o=performance.now(),[2,g().then((function(){return new Promise((function(i){var l,p=["mars"],v=r.techPoint;v&&p.push.apply(p,c([],a(v),!1)),(null!==(l=r.callBridge)&&void 0!==l?l:t.call)("getDowngradeResult",{bizId:e,scene:0,ext:{techPoint:p}},(function(e){var r=void 0;if(console.info("downgrade time: ".concat(performance.now()-o,"ms")),e.error)i({downgrade:4!==e.error,reason:"api error:"+e.error});else try{var t=n.isString(e)?JSON.parse(e):e;if("downgradeResultType"in t?r=t.downgradeResultType:"resultType"in t&&(r=t.resultType),e.context){var a=e.context.deviceInfo;if(a){var c=a.deviceLevel;c===f||c===s?u=c:"medium"===c&&(u=d)}}}catch(e){console.error(e)}i(void 0===r?{downgrade:!0,reason:"call downgrade fail"}:{reason:r,downgrade:1===r})}))}))}))]):[2,Promise.resolve({downgrade:!1,reason:"no AP env"})]}))}))}var m=function(e){function n(){return null!==e&&e.apply(this,arguments)||this}return t(n,e),n.onPlayerCreated=function(e){return o(this,void 0,void 0,(function(){return i(this,(function(r){switch(r.label){case 0:return n.glLostOccurred?(console.warn("gl lost happened, new player will be destroyed."),[2,e.dispose()]):n.currentBizId?[4,w(n.currentBizId)]:[3,2];case 1:r.sent().downgrade&&(console.warn("automatically destroy downgraded player."),e.dispose()),r.label=2;case 2:return[2]}}))}))},n.processRawJSON=function(e,r){var t,a;return void 0===r&&(r={}),o(this,void 0,void 0,(function(){var e;return i(this,(function(o){switch(o.label){case 0:return n.glLostOccurred?[2,Promise.reject("gl lost happened")]:[4,w(null!==(a=null===(t=r.pluginData)||void 0===t?void 0:t.alipayBizId)&&void 0!==a?a:n.currentBizId)];case 1:if((e=o.sent()).downgrade)throw new Error("downgraded, reason: ".concat(e.reason));return r.renderLevel||(r.renderLevel=y(r.renderLevel)),[2]}}))}))},n.currentBizId="",n.glLostOccurred=!1,n}(n.AbstractPlugin),b=function(e){function n(){return null!==e&&e.apply(this,arguments)||this}return t(n,e),n}(n.VFXItem);function P(e,n){for(var r=[],t=2;t<arguments.length;t++)r[t-2]=arguments[t];try{var o=window.AlipayJSBridge,i=S.apply(void 0,c([e,n],a(r),!1));null==o||o.call("H5APLog",{content:i})}catch(e){console.error(e)}}function L(e,n){for(var r=[],t=2;t<arguments.length;t++)r[t-2]=arguments[t];try{var o=window.AlipayJSBridge;null==o||o.call("localLog",{anr_info:"mars",message:n+r.join(""),level:e})}catch(e){console.error(e)}}function S(e,n){for(var r=[],t=2;t<arguments.length;t++)r[t-2]=arguments[t];var o=["<MARS_PLAYER>","(".concat(e,"):"),n];return r.forEach((function(e){o.push(e+"")})),o.join(" ")}n.logger.register((function(e,r){for(var t=[],o=2;o<arguments.length;o++)t[o-2]=arguments[o];n.isAndroid()?L.apply(void 0,c([e,"".concat("[Galacean Effects]"," ").concat(r)],a(t),!1)):n.isIOS()&&P.apply(void 0,c([e,r],a(t),!1))}));var A=!1;var E=Symbol("@@_inter_pause");function B(e){e.target===document&&(n.logger.info("Auto pause all players with data offloaded"),n.getActivePlayers().forEach((function(e){e.paused||(e.pause({offloadTexture:!0}),e[E]=!0)})))}function x(e){e.target===document&&(n.logger.info("auto resume all players"),n.getActivePlayers().forEach((function(e){e[E]&&(e.resume(),e[E]=!1)})))}var O="2.0.0-alpha.0";n.logger.info("plugin alipay downgrade version: "+O),e.checkDowngrade=w,e.getAlipayDowngradeBizId=function(){return m.currentBizId},e.getDeviceName=g,e.getRenderLevelByDevice=y,e.resetDevicePending=function(){l=void 0},e.setAlipayDowngradeBizId=function(e,r){void 0===r&&(r={});var t=r.ignoreGLLost,o=r.autoPause,i=!0!==t;m.currentBizId=e,A||(n.registerPlugin("alipay-downgrade",m,b,!0),window.addEventListener("unload",(function(){n.getActivePlayers().forEach((function(e){return e.dispose()}))})),window.addEventListener("webglcontextlost",(function(e){n.isCanvasUsedByPlayer(e.target)&&(m.glLostOccurred=!0,console.error("webgl lost occur"),i&&(console.warn("webgl lost occur, all players will be downgraded from now on"),n.disableAllPlayer(!0),n.getActivePlayers().forEach((function(e){return e.dispose()}))))}),!0),o&&(document.addEventListener("pause",B),document.addEventListener("resume",x)),A=!0,g())},e.version=O,Object.defineProperty(e,"__esModule",{value:!0})}));
8
+ !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("@galacean/effects")):"function"==typeof define&&define.amd?define(["exports","@galacean/effects"],n):n(((e="undefined"!=typeof globalThis?globalThis:e||self).ge=e.ge||{},e.ge.alipayDowngradePlugin={}),e.ge)}(this,(function(e,n){"use strict";var r=function(e,n){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,n){e.__proto__=n}||function(e,n){for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])},r(e,n)};function o(e,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function o(){this.constructor=e}r(e,n),e.prototype=null===n?Object.create(n):(o.prototype=n.prototype,new o)}function t(e,n,r,o){return new(r||(r=Promise))((function(t,i){function a(e){try{l(o.next(e))}catch(e){i(e)}}function c(e){try{l(o.throw(e))}catch(e){i(e)}}function l(e){var n;e.done?t(e.value):(n=e.value,n instanceof r?n:new r((function(e){e(n)}))).then(a,c)}l((o=o.apply(e,n||[])).next())}))}function i(e,n){var r,o,t,i,a={label:0,sent:function(){if(1&t[0])throw t[1];return t[1]},trys:[],ops:[]};return i={next:c(0),throw:c(1),return:c(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function c(c){return function(l){return function(c){if(r)throw new TypeError("Generator is already executing.");for(;i&&(i=0,c[0]&&(a=0)),a;)try{if(r=1,o&&(t=2&c[0]?o.return:c[0]?o.throw||((t=o.return)&&t.call(o),0):o.next)&&!(t=t.call(o,c[1])).done)return t;switch(o=0,t&&(c=[2&c[0],t.value]),c[0]){case 0:case 1:t=c;break;case 4:return a.label++,{value:c[1],done:!1};case 5:a.label++,o=c[1],c=[0];continue;case 7:c=a.ops.pop(),a.trys.pop();continue;default:if(!(t=a.trys,(t=t.length>0&&t[t.length-1])||6!==c[0]&&2!==c[0])){a=0;continue}if(3===c[0]&&(!t||c[1]>t[0]&&c[1]<t[3])){a.label=c[1];break}if(6===c[0]&&a.label<t[1]){a.label=t[1],t=c;break}if(t&&a.label<t[2]){a.label=t[2],a.ops.push(c);break}t[2]&&a.ops.pop(),a.trys.pop();continue}c=n.call(e,a)}catch(e){c=[6,e],o=0}finally{r=t=0}if(5&c[0])throw c[1];return{value:c[0]?c[1]:void 0,done:!0}}([c,l])}}}function a(e,n){var r="function"==typeof Symbol&&e[Symbol.iterator];if(!r)return e;var o,t,i=r.call(e),a=[];try{for(;(void 0===n||n-- >0)&&!(o=i.next()).done;)a.push(o.value)}catch(e){t={error:e}}finally{try{o&&!o.done&&(r=i.return)&&r.call(i)}finally{if(t)throw t.error}}return a}function c(e,n,r){if(r||2===arguments.length)for(var o,t=0,i=n.length;t<i;t++)!o&&t in n||(o||(o=Array.prototype.slice.call(n,0,t)),o[t]=n[t]);return e.concat(o||Array.prototype.slice.call(n))}"function"==typeof SuppressedError&&SuppressedError;var l=function(e){function n(){return null!==e&&e.apply(this,arguments)||this}return o(n,e),n}(n.VFXItem),s="mock-fail",u="high",d="medium",f="low",v=!1;function p(){return t(this,void 0,void 0,(function(){return i(this,(function(e){return[2,new Promise((function(e,n){var r=window.AlipayJSBridge;r?r.call("getSystemInfo",(function(r){r.error?n(r):e(r)})):n("no ap")}))]}))}))}var g=new(function(){function e(){this.isIOS=!1,this.model="DESKTOP_DEBUG",this.deviceLevel="none",this.isDowngrade=!1}return e.prototype.getRenderLevel=function(){return this.deviceLevel===u?n.spec.RenderLevel.S:this.deviceLevel===d?n.spec.RenderLevel.A:this.deviceLevel===f?n.spec.RenderLevel.B:this.isIOS?n.spec.RenderLevel.S:n.spec.RenderLevel.B},e.prototype.hasDeviceLevel=function(){return m(this.deviceLevel)},e.prototype.setBySystemInfo=function(e){var n=e.performance,r=e.platform,o=e.model,t=void 0===o?"UNKNOWN_DEVICE":o;this.isIOS="iOS"===r,this.model=t,n&&!this.hasDeviceLevel()&&(this.deviceLevel=n)},e.prototype.updateDeviceLevel=function(){if(!this.hasDeviceLevel()&&/iPhone(\d+),/.test(this.model)){var e=+RegExp.$1;this.deviceLevel=e<=9?f:e<10?d:u}},e.prototype.getDeviceInfo=function(){return{isIOS:this.isIOS,model:this.model,deviceLevel:this.deviceLevel}},e}());function y(e){if(e.mock){var r=e.mock,o=r.downgrade,t=r.deviceLevel,i=void 0===t?u:t;return g.deviceLevel=i,{downgrade:o,reason:"mock"}}return e.noAlipayEnv?{downgrade:!1,reason:"no AP env"}:e.systemInfo?e.downgradeResult?(g.setBySystemInfo(e.systemInfo),function(e){var r=void 0,o=void 0;if(e.error)return{downgrade:4!==e.error,reason:"api error: "+e.error};try{var t=n.isString(e)?JSON.parse(e):e;if("downgradeResultType"in t?r=t.downgradeResultType:"resultType"in t&&(r=t.resultType,o=t.resultReason),e.context){var i=e.context.deviceInfo;if(i){var a=i.deviceLevel;m(a)&&(g.deviceLevel=a)}}g.updateDeviceLevel()}catch(e){console.error(e)}return void 0===r?{downgrade:!0,reason:"call downgrade fail"}:1===r?{downgrade:!0,reason:h(o)}:{downgrade:!1,reason:r}}(e.downgradeResult)):{downgrade:!1,reason:"downgradeResult is required"}:{downgrade:!1,reason:"systemInfo is required"}}function h(e){return-1===e?"".concat(e,"-no config"):0===e?"".concat(e,"-none"):1===e?"".concat(e,"-downgrade by memory"):2===e?"".concat(e,"-downgrade by crash"):3===e?"".concat(e,"-downgrade by device"):4===e?"".concat(e,"-downgrade by force"):"".concat(e)}function w(e){return e?/[ABS]/.test(e)?e:n.spec.RenderLevel.S:g.getRenderLevel()}function m(e){return e===u||e===d||e===f}var L=Symbol("@@_inter_pause");function b(e){e.target===document&&(n.logger.info("Auto pause all players with data offloaded"),n.getActivePlayers().forEach((function(e){e.paused||(e.pause({offloadTexture:!0}),e[L]=!0)})))}function S(e){e.target===document&&(n.logger.info("auto resume all players"),n.getActivePlayers().forEach((function(e){e[L]&&(e.resume(),e[L]=!1)})))}var P=function(e){function n(){return null!==e&&e.apply(this,arguments)||this}return o(n,e),n.onPlayerCreated=function(e){return t(this,void 0,void 0,(function(){return i(this,(function(r){return n.glLostOccurred?(console.warn("gl lost happened, new player will be destroyed."),[2,e.dispose()]):[2]}))}))},n.processRawJSON=function(e,r){var o;return void 0===r&&(r={}),t(this,void 0,void 0,(function(){var e,t;return i(this,(function(i){if(n.glLostOccurred)return[2,Promise.reject("gl lost happened")];if(e=null===(o=r.pluginData)||void 0===o?void 0:o.downgrade){if((t=y(e)).downgrade)throw new Error("downgraded, reason: ".concat(t.reason))}else console.warn("No downgrade result in pluginData of SceneLoadOptions");return r.renderLevel||(r.renderLevel=w(r.renderLevel)),[2]}))}))},n.glLostOccurred=!1,n}(n.AbstractPlugin);function A(e,n){for(var r=[],o=2;o<arguments.length;o++)r[o-2]=arguments[o];try{var t=window.AlipayJSBridge,i=R.apply(void 0,c([e,n],a(r),!1));null==t||t.call("H5APLog",{content:i})}catch(e){console.error(e)}}function E(e,n){for(var r=[],o=2;o<arguments.length;o++)r[o-2]=arguments[o];try{var t=window.AlipayJSBridge;null==t||t.call("localLog",{anr_info:"mars",message:n+r.join(""),level:e})}catch(e){console.error(e)}}function R(e,n){for(var r=[],o=2;o<arguments.length;o++)r[o-2]=arguments[o];var t=["<MARS_PLAYER>","(".concat(e,"):"),n];return r.forEach((function(e){t.push(e+"")})),t.join(" ")}n.logger.register((function(e,r){for(var o=[],t=2;t<arguments.length;t++)o[t-2]=arguments[t];n.isAndroid()?E.apply(void 0,c([e,"".concat("[Galacean Effects]"," ").concat(r)],a(o),!1)):n.isIOS()&&A.apply(void 0,c([e,r],a(o),!1))}));var O="2.0.0-alpha.1";n.registerPlugin("alipay-downgrade",P,l,!0),n.logger.info("plugin alipay downgrade version: "+O),e.checkDowngradeResult=y,e.getDowngradeResult=function(e,r){return void 0===r&&(r={}),t(this,void 0,void 0,(function(){var o,t;return i(this,(function(i){return v||(!function(e){var r=e.ignoreGLLost,o=e.autoPause,t=!0!==r;window.addEventListener("unload",(function(){n.getActivePlayers().forEach((function(e){return e.dispose()}))})),window.addEventListener("webglcontextlost",(function(e){n.isCanvasUsedByPlayer(e.target)&&(P.glLostOccurred=!0,console.error("webgl lost occur"),t&&(console.warn("webgl lost occur, all players will be downgraded from now on"),n.disableAllPlayer(!0),n.getActivePlayers().forEach((function(e){return e.dispose()}))))}),!0),o&&(document.addEventListener("pause",b),document.addEventListener("resume",S))}(r),v=!0),e===s||"mock-pass"===e?[2,Promise.resolve({mock:{downgrade:e===s}})]:(o=window.AlipayJSBridge)?(t=performance.now(),[2,p().then((function(n){return new Promise((function(i){var l,s=["mars"],u=r.techPoint;u&&s.push.apply(s,c([],a(u),!1));var d={bizId:e,scene:0,ext:{techPoint:s}};(null!==(l=r.callBridge)&&void 0!==l?l:o.call)("getDowngradeResult",d,(function(r){var o=performance.now()-t;console.info("downgrade time: ".concat(o,"ms")),i({bizId:e,systemInfo:n,downgradeResult:r,totalTime:o})}))}))}))]):[2,Promise.resolve({noAlipayEnv:!0})]}))}))},e.getRenderLevelByDevice=w,e.version=O,Object.defineProperty(e,"__esModule",{value:!0})}));
9
9
  //# sourceMappingURL=index.min.js.map
package/dist/index.mjs CHANGED
@@ -3,10 +3,10 @@
3
3
  * Description: Galacean Effects player downgrade plugin for Alipay
4
4
  * Author: Ant Group CO., Ltd.
5
5
  * Contributors: 燃然,意绮
6
- * Version: v2.0.0-alpha.0
6
+ * Version: v2.0.0-alpha.1
7
7
  */
8
8
 
9
- import { spec, isString, AbstractPlugin, VFXItem, logger, isAndroid, isIOS as isIOS$1, registerPlugin, getActivePlayers, isCanvasUsedByPlayer, disableAllPlayer } from '@galacean/effects';
9
+ import { VFXItem, isString, spec, getActivePlayers, isCanvasUsedByPlayer, disableAllPlayer, logger, AbstractPlugin, isAndroid, isIOS, registerPlugin } from '@galacean/effects';
10
10
 
11
11
  /******************************************************************************
12
12
  Copyright (c) Microsoft Corporation.
@@ -109,86 +109,37 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
109
109
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
110
110
  };
111
111
 
112
- var DEVICE_PERFORMANCE_LOW = 'low';
113
- var DEVICE_PERFORMANCE_MIDDLE = 'middle';
114
- var DEVICE_PERFORMANCE_HIGH = 'high';
115
- var devicePending;
116
- var devicePerformance;
117
- var deviceName = 'DESKTOP_DEBUG';
118
- var isIOS = false;
119
- function getDeviceName() {
120
- return __awaiter(this, void 0, void 0, function () {
121
- return __generator(this, function (_a) {
122
- if (!devicePending) {
123
- devicePending = getSystemInfo().then(function (info) {
124
- var performance = info.performance, platform = info.platform, _a = info.model, model = _a === void 0 ? 'UNKNOWN_DEVICE' : _a;
125
- if (!devicePerformance) {
126
- devicePerformance = performance;
127
- }
128
- isIOS = platform === 'iOS';
129
- deviceName = model;
130
- if (/iPhone(\d+),/.test(deviceName) && !devicePerformance) {
131
- var gen = +RegExp.$1;
132
- // https://gist.github.com/adamawolf/3048717 device code
133
- if (gen <= 9) { // iphone 7,iphone 7p
134
- devicePerformance = DEVICE_PERFORMANCE_LOW;
135
- }
136
- else if (gen < 10) {
137
- devicePerformance = DEVICE_PERFORMANCE_MIDDLE;
138
- }
139
- else {
140
- devicePerformance = DEVICE_PERFORMANCE_HIGH;
141
- }
142
- }
143
- if (deviceName.indexOf(info.brand) === 0) {
144
- deviceName = deviceName.replace(info.brand, '').trim();
145
- }
146
- return deviceName;
147
- }, function (e) {
148
- });
149
- }
150
- return [2 /*return*/, devicePending.then(function () { return deviceName; }, function () { return deviceName; })];
151
- });
152
- });
153
- }
154
- function getRenderLevelByDevice(renderLevel) {
155
- if (renderLevel === 'auto' || !renderLevel) {
156
- if (devicePerformance === DEVICE_PERFORMANCE_HIGH) {
157
- return spec.RenderLevel.S;
158
- }
159
- else if (devicePerformance === DEVICE_PERFORMANCE_MIDDLE) {
160
- return spec.RenderLevel.A;
161
- }
162
- else if (devicePerformance === DEVICE_PERFORMANCE_LOW) {
163
- return spec.RenderLevel.B;
164
- }
165
- return isIOS ? spec.RenderLevel.S : spec.RenderLevel.B;
112
+ var DowngradeVFXItem = /** @class */ (function (_super) {
113
+ __extends(DowngradeVFXItem, _super);
114
+ function DowngradeVFXItem() {
115
+ return _super !== null && _super.apply(this, arguments) || this;
166
116
  }
167
- return /[ABS]/.test(renderLevel) ? renderLevel : spec.RenderLevel.S;
168
- }
169
- function resetDevicePending() {
170
- devicePending = undefined;
171
- }
117
+ return DowngradeVFXItem;
118
+ }(VFXItem));
119
+
172
120
  var mockIdPass = 'mock-pass';
173
121
  var mockIdFail = 'mock-fail';
174
- /**
175
- *
176
- * @param bizId
177
- * @param options
178
- * @returns
179
- */
180
- function checkDowngrade(bizId, options) {
122
+ var DEVICE_LEVEL_HIGH = 'high';
123
+ var DEVICE_LEVEL_MEDIUM = 'medium';
124
+ var DEVICE_LEVEL_LOW = 'low';
125
+ var DEVICE_LEVEL_NONE = 'none';
126
+ var hasRegisterEvent = false;
127
+ function getDowngradeResult(bizId, options) {
181
128
  if (options === void 0) { options = {}; }
182
129
  return __awaiter(this, void 0, void 0, function () {
183
130
  var ap, now_1;
184
131
  return __generator(this, function (_a) {
132
+ if (!hasRegisterEvent) {
133
+ registerEvent(options);
134
+ hasRegisterEvent = true;
135
+ }
185
136
  if (bizId === mockIdFail || bizId === mockIdPass) {
186
- return [2 /*return*/, Promise.resolve({ downgrade: bizId === mockIdFail, reason: 'mock' })];
137
+ return [2 /*return*/, Promise.resolve({ mock: { downgrade: bizId === mockIdFail } })];
187
138
  }
188
139
  ap = window.AlipayJSBridge;
189
140
  if (ap) {
190
141
  now_1 = performance.now();
191
- return [2 /*return*/, getDeviceName().then(function () {
142
+ return [2 /*return*/, getSystemInfo().then(function (systemInfo) {
192
143
  return new Promise(function (resolve) {
193
144
  var _a;
194
145
  var techPoint = ['mars'];
@@ -196,60 +147,51 @@ function checkDowngrade(bizId, options) {
196
147
  if (tc) {
197
148
  techPoint.push.apply(techPoint, __spreadArray([], __read(tc), false));
198
149
  }
199
- var callBridge = (_a = options.callBridge) !== null && _a !== void 0 ? _a : ap.call;
200
- callBridge('getDowngradeResult', {
150
+ var downgradeOptions = {
201
151
  bizId: bizId,
202
152
  scene: 0,
203
153
  ext: {
204
154
  techPoint: techPoint,
205
155
  },
206
- }, function (result) {
207
- var reason = undefined;
208
- console.info("downgrade time: ".concat(performance.now() - now_1, "ms"));
209
- if (!result.error) {
210
- try {
211
- var ret = isString(result) ? JSON.parse(result) : result;
212
- if ('downgradeResultType' in ret) {
213
- reason = ret.downgradeResultType;
214
- }
215
- else if ('resultType' in ret) {
216
- reason = ret.resultType;
217
- }
218
- if (result.context) {
219
- var deviceInfo = result.context.deviceInfo;
220
- if (deviceInfo) {
221
- var level = deviceInfo.deviceLevel;
222
- if (level === DEVICE_PERFORMANCE_HIGH || level === DEVICE_PERFORMANCE_LOW) {
223
- devicePerformance = level;
224
- }
225
- else if (level === 'medium') {
226
- devicePerformance = DEVICE_PERFORMANCE_MIDDLE;
227
- }
228
- }
229
- }
230
- }
231
- catch (ex) {
232
- console.error(ex);
233
- }
234
- }
235
- else {
236
- // 无权调用的情况下不降级
237
- resolve({ downgrade: result.error !== 4, reason: 'api error:' + result.error });
238
- }
239
- if (reason === undefined) {
240
- resolve({ downgrade: true, reason: 'call downgrade fail' });
241
- }
242
- else {
243
- resolve({ reason: reason, downgrade: reason === 1 });
244
- }
245
- });
156
+ };
157
+ var downgradeCallback = function (result) {
158
+ var totalTime = performance.now() - now_1;
159
+ console.info("downgrade time: ".concat(totalTime, "ms"));
160
+ resolve({ bizId: bizId, systemInfo: systemInfo, downgradeResult: result, totalTime: totalTime });
161
+ };
162
+ var callBridge = (_a = options.callBridge) !== null && _a !== void 0 ? _a : ap.call;
163
+ callBridge('getDowngradeResult', downgradeOptions, downgradeCallback);
246
164
  });
247
165
  })];
248
166
  }
249
- return [2 /*return*/, Promise.resolve({ downgrade: false, reason: 'no AP env' })];
167
+ else {
168
+ return [2 /*return*/, Promise.resolve({ noAlipayEnv: true })];
169
+ }
250
170
  });
251
171
  });
252
172
  }
173
+ function registerEvent(options) {
174
+ var ignoreGLLost = options.ignoreGLLost, autoPause = options.autoPause;
175
+ var downgradeWhenGLLost = ignoreGLLost !== true;
176
+ window.addEventListener('unload', function () {
177
+ getActivePlayers().forEach(function (player) { return player.dispose(); });
178
+ });
179
+ window.addEventListener('webglcontextlost', function (e) {
180
+ if (isCanvasUsedByPlayer(e.target)) {
181
+ AlipayDowngradePlugin.glLostOccurred = true;
182
+ console.error('webgl lost occur');
183
+ if (downgradeWhenGLLost) {
184
+ console.warn('webgl lost occur, all players will be downgraded from now on');
185
+ disableAllPlayer(true);
186
+ getActivePlayers().forEach(function (player) { return player.dispose(); });
187
+ }
188
+ }
189
+ }, true);
190
+ if (autoPause) {
191
+ document.addEventListener('pause', pauseAllActivePlayers);
192
+ document.addEventListener('resume', resumePausedPlayers);
193
+ }
194
+ }
253
195
  function getSystemInfo() {
254
196
  return __awaiter(this, void 0, void 0, function () {
255
197
  return __generator(this, function (_a) {
@@ -272,6 +214,191 @@ function getSystemInfo() {
272
214
  });
273
215
  });
274
216
  }
217
+ var DeviceProxy = /** @class */ (function () {
218
+ function DeviceProxy() {
219
+ this.isIOS = false;
220
+ this.model = 'DESKTOP_DEBUG';
221
+ this.deviceLevel = DEVICE_LEVEL_NONE;
222
+ this.isDowngrade = false;
223
+ }
224
+ DeviceProxy.prototype.getRenderLevel = function () {
225
+ if (this.deviceLevel === DEVICE_LEVEL_HIGH) {
226
+ return spec.RenderLevel.S;
227
+ }
228
+ else if (this.deviceLevel === DEVICE_LEVEL_MEDIUM) {
229
+ return spec.RenderLevel.A;
230
+ }
231
+ else if (this.deviceLevel === DEVICE_LEVEL_LOW) {
232
+ return spec.RenderLevel.B;
233
+ }
234
+ else {
235
+ return this.isIOS ? spec.RenderLevel.S : spec.RenderLevel.B;
236
+ }
237
+ };
238
+ DeviceProxy.prototype.hasDeviceLevel = function () {
239
+ return isDeviceLevel(this.deviceLevel);
240
+ };
241
+ DeviceProxy.prototype.setBySystemInfo = function (systemInfo) {
242
+ var performance = systemInfo.performance, platform = systemInfo.platform, _a = systemInfo.model, model = _a === void 0 ? 'UNKNOWN_DEVICE' : _a;
243
+ this.isIOS = platform === 'iOS';
244
+ this.model = model;
245
+ if (performance && !this.hasDeviceLevel()) {
246
+ this.deviceLevel = performance;
247
+ }
248
+ };
249
+ DeviceProxy.prototype.updateDeviceLevel = function () {
250
+ if (this.hasDeviceLevel()) {
251
+ return;
252
+ }
253
+ if (/iPhone(\d+),/.test(this.model)) {
254
+ var gen = +RegExp.$1;
255
+ if (gen <= 9) {
256
+ this.deviceLevel = DEVICE_LEVEL_LOW;
257
+ }
258
+ else if (gen < 10) {
259
+ this.deviceLevel = DEVICE_LEVEL_MEDIUM;
260
+ }
261
+ else {
262
+ this.deviceLevel = DEVICE_LEVEL_HIGH;
263
+ }
264
+ }
265
+ };
266
+ DeviceProxy.prototype.getDeviceInfo = function () {
267
+ return {
268
+ isIOS: this.isIOS,
269
+ model: this.model,
270
+ deviceLevel: this.deviceLevel,
271
+ };
272
+ };
273
+ return DeviceProxy;
274
+ }());
275
+ var device = new DeviceProxy();
276
+ function checkDowngradeResult(result) {
277
+ if (result.mock) {
278
+ var _a = result.mock, downgrade = _a.downgrade, _b = _a.deviceLevel, deviceLevel = _b === void 0 ? DEVICE_LEVEL_HIGH : _b;
279
+ device.deviceLevel = deviceLevel;
280
+ return { downgrade: downgrade, reason: 'mock' };
281
+ }
282
+ if (result.noAlipayEnv) {
283
+ return { downgrade: false, reason: 'no AP env' };
284
+ }
285
+ if (!result.systemInfo) {
286
+ return { downgrade: false, reason: 'systemInfo is required' };
287
+ }
288
+ if (!result.downgradeResult) {
289
+ return { downgrade: false, reason: 'downgradeResult is required' };
290
+ }
291
+ device.setBySystemInfo(result.systemInfo);
292
+ return parseDowngradeResult(result.downgradeResult);
293
+ }
294
+ function parseDowngradeResult(result) {
295
+ var resultType = undefined;
296
+ var resultReason = undefined;
297
+ if (!result.error) {
298
+ try {
299
+ var ret = isString(result) ? JSON.parse(result) : result;
300
+ if ('downgradeResultType' in ret) {
301
+ resultType = ret.downgradeResultType;
302
+ }
303
+ else if ('resultType' in ret) {
304
+ resultType = ret.resultType;
305
+ resultReason = ret.resultReason;
306
+ }
307
+ if (result.context) {
308
+ var deviceInfo = result.context.deviceInfo;
309
+ if (deviceInfo) {
310
+ var deviceLevel = deviceInfo.deviceLevel;
311
+ if (isDeviceLevel(deviceLevel)) {
312
+ device.deviceLevel = deviceLevel;
313
+ }
314
+ }
315
+ }
316
+ device.updateDeviceLevel();
317
+ }
318
+ catch (ex) {
319
+ console.error(ex);
320
+ }
321
+ if (resultType === undefined) {
322
+ return { downgrade: true, reason: 'call downgrade fail' };
323
+ }
324
+ else {
325
+ if (resultType === 1) {
326
+ return { downgrade: true, reason: getDowngradeReason(resultReason) };
327
+ }
328
+ else {
329
+ return { downgrade: false, reason: resultType };
330
+ }
331
+ }
332
+ }
333
+ else {
334
+ // 无权调用的情况下不降级
335
+ return { downgrade: result.error !== 4, reason: 'api error: ' + result.error };
336
+ }
337
+ }
338
+ function getDowngradeReason(reason) {
339
+ if (reason === -1) {
340
+ return "".concat(reason, "-no config");
341
+ }
342
+ else if (reason === 0) {
343
+ return "".concat(reason, "-none");
344
+ }
345
+ else if (reason === 1) {
346
+ return "".concat(reason, "-downgrade by memory");
347
+ }
348
+ else if (reason === 2) {
349
+ return "".concat(reason, "-downgrade by crash");
350
+ }
351
+ else if (reason === 3) {
352
+ return "".concat(reason, "-downgrade by device");
353
+ }
354
+ else if (reason === 4) {
355
+ return "".concat(reason, "-downgrade by force");
356
+ }
357
+ else {
358
+ return "".concat(reason);
359
+ }
360
+ }
361
+ function getRenderLevelByDevice(renderLevel) {
362
+ if (!renderLevel) {
363
+ return device.getRenderLevel();
364
+ }
365
+ else {
366
+ return /[ABS]/.test(renderLevel) ? renderLevel : spec.RenderLevel.S;
367
+ }
368
+ }
369
+ function isDeviceLevel(deviceLevel) {
370
+ return deviceLevel === DEVICE_LEVEL_HIGH
371
+ || deviceLevel === DEVICE_LEVEL_MEDIUM
372
+ || deviceLevel === DEVICE_LEVEL_LOW;
373
+ }
374
+ var internalPaused = Symbol('@@_inter_pause');
375
+ function pauseAllActivePlayers(e) {
376
+ if (e.target === document) {
377
+ logger.info('Auto pause all players with data offloaded');
378
+ var players = getActivePlayers();
379
+ players.forEach(function (player) {
380
+ if (!player.paused) {
381
+ player.pause({ offloadTexture: true });
382
+ // @ts-expect-error
383
+ player[internalPaused] = true;
384
+ }
385
+ });
386
+ }
387
+ }
388
+ function resumePausedPlayers(e) {
389
+ if (e.target === document) {
390
+ logger.info('auto resume all players');
391
+ var players = getActivePlayers();
392
+ players.forEach(function (player) {
393
+ // @ts-expect-error
394
+ if (player[internalPaused]) {
395
+ void player.resume();
396
+ // @ts-expect-error
397
+ player[internalPaused] = false;
398
+ }
399
+ });
400
+ }
401
+ }
275
402
 
276
403
  var AlipayDowngradePlugin = /** @class */ (function (_super) {
277
404
  __extends(AlipayDowngradePlugin, _super);
@@ -280,66 +407,45 @@ var AlipayDowngradePlugin = /** @class */ (function (_super) {
280
407
  }
281
408
  AlipayDowngradePlugin.onPlayerCreated = function (player) {
282
409
  return __awaiter(this, void 0, void 0, function () {
283
- var result;
284
410
  return __generator(this, function (_a) {
285
- switch (_a.label) {
286
- case 0:
287
- if (AlipayDowngradePlugin.glLostOccurred) {
288
- console.warn('gl lost happened, new player will be destroyed.');
289
- return [2 /*return*/, player.dispose()];
290
- }
291
- if (!AlipayDowngradePlugin.currentBizId) return [3 /*break*/, 2];
292
- return [4 /*yield*/, checkDowngrade(AlipayDowngradePlugin.currentBizId)];
293
- case 1:
294
- result = _a.sent();
295
- if (result.downgrade) {
296
- console.warn('automatically destroy downgraded player.');
297
- player.dispose();
298
- }
299
- _a.label = 2;
300
- case 2: return [2 /*return*/];
411
+ if (AlipayDowngradePlugin.glLostOccurred) {
412
+ console.warn('gl lost happened, new player will be destroyed.');
413
+ return [2 /*return*/, player.dispose()];
301
414
  }
415
+ return [2 /*return*/];
302
416
  });
303
417
  });
304
418
  };
305
419
  AlipayDowngradePlugin.processRawJSON = function (json, options) {
306
- var _a, _b;
420
+ var _a;
307
421
  if (options === void 0) { options = {}; }
308
422
  return __awaiter(this, void 0, void 0, function () {
309
- var result;
310
- return __generator(this, function (_c) {
311
- switch (_c.label) {
312
- case 0:
313
- if (AlipayDowngradePlugin.glLostOccurred) {
314
- return [2 /*return*/, Promise.reject('gl lost happened')];
315
- }
316
- return [4 /*yield*/, checkDowngrade((_b = (_a = options.pluginData) === null || _a === void 0 ? void 0 : _a['alipayBizId']) !== null && _b !== void 0 ? _b : AlipayDowngradePlugin.currentBizId)];
317
- case 1:
318
- result = _c.sent();
319
- if (result.downgrade) {
320
- throw new Error("downgraded, reason: ".concat(result.reason));
321
- }
322
- if (!options.renderLevel) {
323
- options.renderLevel = getRenderLevelByDevice(options.renderLevel);
324
- }
325
- return [2 /*return*/];
423
+ var downgradeResult, downgradeDecision;
424
+ return __generator(this, function (_b) {
425
+ if (AlipayDowngradePlugin.glLostOccurred) {
426
+ return [2 /*return*/, Promise.reject('gl lost happened')];
427
+ }
428
+ downgradeResult = (_a = options.pluginData) === null || _a === void 0 ? void 0 : _a['downgrade'];
429
+ if (downgradeResult) {
430
+ downgradeDecision = checkDowngradeResult(downgradeResult);
431
+ if (downgradeDecision.downgrade) {
432
+ throw new Error("downgraded, reason: ".concat(downgradeDecision.reason));
433
+ }
326
434
  }
435
+ else {
436
+ console.warn('No downgrade result in pluginData of SceneLoadOptions');
437
+ }
438
+ if (!options.renderLevel) {
439
+ options.renderLevel = getRenderLevelByDevice(options.renderLevel);
440
+ }
441
+ return [2 /*return*/];
327
442
  });
328
443
  });
329
444
  };
330
- AlipayDowngradePlugin.currentBizId = '';
331
445
  AlipayDowngradePlugin.glLostOccurred = false;
332
446
  return AlipayDowngradePlugin;
333
447
  }(AbstractPlugin));
334
448
 
335
- var DowngradeVFXItem = /** @class */ (function (_super) {
336
- __extends(DowngradeVFXItem, _super);
337
- function DowngradeVFXItem() {
338
- return _super !== null && _super.apply(this, arguments) || this;
339
- }
340
- return DowngradeVFXItem;
341
- }(VFXItem));
342
-
343
449
  var prefix = '[Galacean Effects]';
344
450
  logger.register(nativeLogger);
345
451
  function nativeLogger(type, msg) {
@@ -350,7 +456,7 @@ function nativeLogger(type, msg) {
350
456
  if (isAndroid()) {
351
457
  androidLogger.apply(void 0, __spreadArray([type, "".concat(prefix, " ").concat(msg)], __read(args), false));
352
458
  }
353
- else if (isIOS$1()) {
459
+ else if (isIOS()) {
354
460
  iOSLogger.apply(void 0, __spreadArray([type, msg], __read(args), false));
355
461
  }
356
462
  }
@@ -404,80 +510,9 @@ function formatMessage(level, msg) {
404
510
  return result.join(' ');
405
511
  }
406
512
 
407
- var registered = false;
408
- /**
409
- * 支付宝端内统一降级方案,传入降级 ID,每次加载场景前都会自动调用降级
410
- * - 如果要为某个 json 单独配置降级 ID,可以使用 `player.loadScene(url, { pluginData: { alipayBizId: '#bizId#' }})`
411
- * @param bizId - 降级 ID,如果为 `mock-pass` 将 mock 不降级场景,如果为 `mock-fail` 将 mock 降级场景,业务请不要使用这两个字符串
412
- * @param options - 优化策略
413
- */
414
- function setAlipayDowngradeBizId(bizId, options) {
415
- if (options === void 0) { options = {}; }
416
- var ignoreGLLost = options.ignoreGLLost, autoPause = options.autoPause;
417
- var downgradeWhenGLLost = ignoreGLLost !== true;
418
- AlipayDowngradePlugin.currentBizId = bizId;
419
- if (registered) {
420
- return;
421
- }
422
- registerPlugin('alipay-downgrade', AlipayDowngradePlugin, DowngradeVFXItem, true);
423
- window.addEventListener('unload', function () {
424
- getActivePlayers().forEach(function (player) { return player.dispose(); });
425
- });
426
- window.addEventListener('webglcontextlost', function (e) {
427
- if (isCanvasUsedByPlayer(e.target)) {
428
- AlipayDowngradePlugin.glLostOccurred = true;
429
- console.error('webgl lost occur');
430
- if (downgradeWhenGLLost) {
431
- console.warn('webgl lost occur, all players will be downgraded from now on');
432
- disableAllPlayer(true);
433
- getActivePlayers().forEach(function (player) { return player.dispose(); });
434
- }
435
- }
436
- }, true);
437
- if (autoPause) {
438
- document.addEventListener('pause', pauseAllActivePlayers);
439
- document.addEventListener('resume', resumePausedPlayers);
440
- }
441
- registered = true;
442
- void getDeviceName();
443
- }
444
- /**
445
- *
446
- * @returns
447
- */
448
- function getAlipayDowngradeBizId() {
449
- return AlipayDowngradePlugin.currentBizId;
450
- }
451
- var internalPaused = Symbol('@@_inter_pause');
452
- function pauseAllActivePlayers(e) {
453
- if (e.target === document) {
454
- logger.info('Auto pause all players with data offloaded');
455
- var players = getActivePlayers();
456
- players.forEach(function (player) {
457
- if (!player.paused) {
458
- player.pause({ offloadTexture: true });
459
- // @ts-expect-error
460
- player[internalPaused] = true;
461
- }
462
- });
463
- }
464
- }
465
- function resumePausedPlayers(e) {
466
- if (e.target === document) {
467
- logger.info('auto resume all players');
468
- var players = getActivePlayers();
469
- players.forEach(function (player) {
470
- // @ts-expect-error
471
- if (player[internalPaused]) {
472
- void player.resume();
473
- // @ts-expect-error
474
- player[internalPaused] = false;
475
- }
476
- });
477
- }
478
- }
479
- var version = "2.0.0-alpha.0";
513
+ var version = "2.0.0-alpha.1";
514
+ registerPlugin('alipay-downgrade', AlipayDowngradePlugin, DowngradeVFXItem, true);
480
515
  logger.info('plugin alipay downgrade version: ' + version);
481
516
 
482
- export { checkDowngrade, getAlipayDowngradeBizId, getDeviceName, getRenderLevelByDevice, resetDevicePending, setAlipayDowngradeBizId, version };
517
+ export { checkDowngradeResult, getDowngradeResult, getRenderLevelByDevice, version };
483
518
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}