[add] 3.7空專案
This commit is contained in:
		| @@ -0,0 +1,2 @@ | |||||||
|  | [InternetShortcut] | ||||||
|  | URL=https://docs.cocos.com/creator/manual/en/scripting/setup.html#custom-script-template | ||||||
							
								
								
									
										5
									
								
								.creator/default-meta.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.creator/default-meta.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | { | ||||||
|  |   "image": { | ||||||
|  |     "type": "sprite-frame" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										69
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										69
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,59 +1,24 @@ | |||||||
| #///////////////////////////////////////////////////////////////////////////// |  | ||||||
| # Fireball Projects |  | ||||||
| #///////////////////////////////////////////////////////////////////////////// |  | ||||||
|  |  | ||||||
| /library/ | #/////////////////////////// | ||||||
| /temp/ | # Cocos Creator 3D Project | ||||||
| /local/ | #/////////////////////////// | ||||||
| /build/ | library/ | ||||||
|  | temp/ | ||||||
|  | local/ | ||||||
|  | build/ | ||||||
|  | profiles/ | ||||||
| native | native | ||||||
| #///////////////////////////////////////////////////////////////////////////// | #////////////////////////// | ||||||
| # npm files | # NPM | ||||||
| #///////////////////////////////////////////////////////////////////////////// | #////////////////////////// | ||||||
|  |  | ||||||
| npm-debug.log |  | ||||||
| node_modules/ | node_modules/ | ||||||
|  |  | ||||||
| #///////////////////////////////////////////////////////////////////////////// |  | ||||||
| # Logs and databases |  | ||||||
| #///////////////////////////////////////////////////////////////////////////// |  | ||||||
|  |  | ||||||
| *.log |  | ||||||
| *.sql |  | ||||||
| *.sqlite |  | ||||||
|  |  | ||||||
| #///////////////////////////////////////////////////////////////////////////// |  | ||||||
| # files for debugger |  | ||||||
| #///////////////////////////////////////////////////////////////////////////// |  | ||||||
|  |  | ||||||
| *.sln |  | ||||||
| *.csproj |  | ||||||
| *.pidb |  | ||||||
| *.unityproj |  | ||||||
| *.suo |  | ||||||
|  |  | ||||||
| #///////////////////////////////////////////////////////////////////////////// |  | ||||||
| # OS generated files |  | ||||||
| #///////////////////////////////////////////////////////////////////////////// |  | ||||||
|  |  | ||||||
| .DS_Store |  | ||||||
| ehthumbs.db |  | ||||||
| Thumbs.db |  | ||||||
|  |  | ||||||
| #///////////////////////////////////////////////////////////////////////////// |  | ||||||
| # WebStorm files |  | ||||||
| #///////////////////////////////////////////////////////////////////////////// |  | ||||||
|  |  | ||||||
| .idea/ |  | ||||||
|  |  | ||||||
| #////////////////////////// | #////////////////////////// | ||||||
| # HotUpdate | # VSCode | ||||||
| #////////////////////////// | #////////////////////////// | ||||||
|  |  | ||||||
| remote-assets/ |  | ||||||
|  |  | ||||||
| #////////////////////////// |  | ||||||
| # VS Code files |  | ||||||
| #////////////////////////// |  | ||||||
|  |  | ||||||
| .vscode/ | .vscode/ | ||||||
|  |  | ||||||
|  | #////////////////////////// | ||||||
|  | # WebStorm | ||||||
|  | #////////////////////////// | ||||||
|  | .idea/ | ||||||
							
								
								
									
										
											BIN
										
									
								
								JMKA - 捷徑.lnk
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								JMKA - 捷徑.lnk
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -1,13 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.3", |  | ||||||
|   "uuid": "9e28a2e5-f683-4157-bfc5-f19dd02440b1", |  | ||||||
|   "importer": "folder", |  | ||||||
|   "isBundle": false, |  | ||||||
|   "bundleName": "", |  | ||||||
|   "priority": 1, |  | ||||||
|   "compressionType": {}, |  | ||||||
|   "optimizeHotUpdate": {}, |  | ||||||
|   "inlineSpriteFrames": {}, |  | ||||||
|   "isRemoteBundle": {}, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,687 +0,0 @@ | |||||||
| if (typeof rvAgentPlayer !== 'undefined') { |  | ||||||
|     throw new Error('ResponsiveVoice Website Agent is already running'); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| var rvAgentPlayer = { version : 1 }; |  | ||||||
| var rvApiKey = '8LG4XCOk'; |  | ||||||
| var rvApiEndpoint = 'https://texttospeech.responsivevoice.org/v1/text:synthesize'; |  | ||||||
|  |  | ||||||
| if (typeof responsiveVoice === 'undefined') { |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  ResponsiveVoice JS v1.8.0 |  | ||||||
|  |  | ||||||
|  (c) 2015-2020 LearnBrite |  | ||||||
|  |  | ||||||
|  License: http://responsivevoice.org/license |  | ||||||
| */ |  | ||||||
| Array.from||(Array.from=function(){var w=Object.prototype.toString,y=function(p){return"function"===typeof p||"[object Function]"===w.call(p)},C=Math.pow(2,53)-1;return function(p){var a=Object(p);if(null==p)throw new TypeError("Array.from requires an array-like object - not null or undefined");var q=1<arguments.length?arguments[1]:void 0,z;if("undefined"!==typeof q){if(!y(q))throw new TypeError("Array.from: when provided, the second argument must be a function");2<arguments.length&& |  | ||||||
| (z=arguments[2])}var t=Number(a.length);t=isNaN(t)?0:0!==t&&isFinite(t)?(0<t?1:-1)*Math.floor(Math.abs(t)):t;t=Math.min(Math.max(t,0),C);for(var b=y(this)?Object(new this(t)):Array(t),c=0,d;c<t;)d=a[c],b[c]=q?"undefined"===typeof z?q(d,c):q.call(z,d,c):d,c+=1;b.length=t;return b}}());if(!isNaN)var isNaN=function(w){w=Number(w);return w!==w}; |  | ||||||
| (function(w,y){"object"===typeof exports&&"undefined"!==typeof module?y():"function"===typeof define&&define.amd?define(y):y()})(this,function(){function w(C){w="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(p){return typeof p}:function(p){return p&&"function"===typeof Symbol&&p.constructor===Symbol&&p!==Symbol.prototype?"symbol":typeof p};return w(C)}function y(C,p){var a=this.event&&this.event.type;a="unload"===a||"beforeunload"===a;var q="XMLHttpRequest"in this?new XMLHttpRequest: |  | ||||||
| new ActiveXObject("Microsoft.XMLHTTP");q.open("POST",C,!a);q.withCredentials=!0;q.setRequestHeader("Accept","*/*");"string"===typeof p?(q.setRequestHeader("Content-Type","text/plain;charset=UTF-8"),q.responseType="text"):p instanceof Blob&&p.type&&q.setRequestHeader("Content-Type",p.type);try{q.send(p)}catch(z){return!1}return!0}(function(){"navigator"in this||(this.navigator={});"function"!==typeof this.navigator.sendBeacon&&(this.navigator.sendBeacon=y.bind(this))}).call("object"===("undefined"=== |  | ||||||
| typeof window?"undefined":w(window))?window:{})}); |  | ||||||
| if("undefined"!=typeof responsiveVoice)console.log("ResponsiveVoice already loaded"),console.log(responsiveVoice);else var ResponsiveVoice=function(){function w(b){b=b.replace(/([\n\r])+/gm,"\n");for(var c=/([,.:!\u00a1?\u00bf;()\[\]\u2014\u00ab\u00bb])+[\n\r]/gm,d=!0;d;)null===b.match(c)?d=!1:b=b.replace(c,"$1 ");return b}function y(b,c){if(!q)return b;console.log(c);var d=b;try{for(var h=0;h<q.length;h++){var e=q[h],g=!1,k=e.collectionvoices;k?(Array.isArray(k)||(k=[k]),c.collectionvoice&&c.collectionvoice.name&& |  | ||||||
| -1!=k.indexOf(c.collectionvoice.name)&&(g=!0)):g=!0;var f=!1,l=e.systemvoices;l?(Array.isArray(l)||(l=[l]),c.systemvoice&&c.systemvoice.name&&-1!=l.indexOf(c.systemvoice.name)&&(f=!0)):f=!0;(null==k||null!=k&&g)&&(null==l||null!=l&&f)&&(d=d.replace(e.searchvalue,e.newvalue))}return d}catch(u){return console.warn("ResponsiveVoice: There was an error while processing the textReplacements array"),b}}function C(){var b=document.getElementsByTagName("script"),c;for(c=0;c<b.length;++c)if(b[c].src&&t.test(b[c].src)){var d= |  | ||||||
| b[c].src;var h=document.createElement("a");var e={};h.href=d;if(h.search){var g=h.search.replace(/^\?/,"").split("&");for(d=0;d<g.length;d++)h=g[d].split("="),e[h[0]]=h[1];e=e.source?e.source:!1}else e=!1;if(e&&"wp-plugin"==e)return t.lastIndex=0,!0}return!1}function p(){var b=document.getElementsByTagName("script"),c;for(c=0;c<b.length;++c)if(b[c].src&&t.test(b[c].src))return t.lastIndex=0,!1;return!0}var a=this;a.version="1.8.0";console.log("ResponsiveVoice r"+a.version);a.responsivevoices=[{name:"UK English Female", |  | ||||||
| flag:"gb",gender:"f",lang:"en-GB",voiceIDs:[3,7,171,201,5,1,257,286,342,258,287,343,8]},{name:"UK English Male",flag:"gb",gender:"m",lang:"en-GB",voiceIDs:[0,277,202,75,4,2,256,285,341,159]},{name:"US English Female",flag:"us",gender:"f",lang:"en-US",voiceIDs:[432,433,434,40,41,42,383,205,204,43,173,235,283,339,408,44]},{name:"US English Male",flag:"us",gender:"m",lang:"en-US",voiceIDs:[431,39,234,282,338,236,284,340,2,4,0,75,195,169]},{name:"Arabic Male",flag:"ar",gender:"m",lang:"ar-SA",voiceIDs:[96, |  | ||||||
| 95,97,196,388]},{name:"Arabic Female",flag:"ar",gender:"f",lang:"ar-SA",voiceIDs:[98]},{name:"Armenian Male",flag:"hy",gender:"f",lang:"hy-AM",voiceIDs:[99]},{name:"Australian Female",flag:"au",gender:"f",lang:"en-AU",voiceIDs:[415,276,201,87,5,88]},{name:"Australian Male",flag:"au",gender:"m",lang:"en-AU",voiceIDs:[86,386]},{name:"Bangla Bangladesh Female",flag:"bd",gender:"f",lang:"bn-BD",voiceIDs:[435]},{name:"Bangla Bangladesh Male",flag:"bd",gender:"m",lang:"bn-BD",voiceIDs:[410,436]},{name:"Bangla India Female", |  | ||||||
| flag:"bd",gender:"f",lang:"bn-IN",voiceIDs:[447]},{name:"Bangla India Male",flag:"bd",gender:"m",lang:"bn-IN",voiceIDs:[411,448]},{name:"Brazilian Portuguese Female",flag:"br",gender:"f",lang:"pt-BR",voiceIDs:[245,124,123,125,186,223,126]},{name:"Brazilian Portuguese Male",flag:"br",gender:"m",lang:"pt-BR",voiceIDs:[315,332,371,399],deprecated:!0},{name:"Chinese Female",flag:"cn",gender:"f",lang:"zh-CN",voiceIDs:[249,58,59,380,281,231,155,60,191,268,297,353,269,298,354,409,61]},{name:"Chinese Male", |  | ||||||
| flag:"cn",gender:"m",lang:"zh-CN",voiceIDs:[317,334,373,389]},{name:"Chinese (Hong Kong) Female",flag:"hk",gender:"f",lang:"zh-HK",voiceIDs:[192,193,232,250,251,270,299,355,409,444,252]},{name:"Chinese (Hong Kong) Male",flag:"hk",gender:"m",lang:"zh-HK",voiceIDs:[430,318,335,374,445,390]},{name:"Chinese Taiwan Female",flag:"tw",gender:"f",lang:"zh-TW",voiceIDs:[194,233,253,254,305,322,361,384,319,336,375,409,255]},{name:"Chinese Taiwan Male",flag:"tw",gender:"m",lang:"zh-TW",voiceIDs:[320,337,376, |  | ||||||
| 391]},{name:"Czech Female",flag:"cz",gender:"f",lang:"cs-CZ",voiceIDs:[412,101,100,102,197,103]},{name:"Czech Male",flag:"cz",gender:"m",lang:"cs-CZ",voiceIDs:[161],deprecated:!0},{name:"Danish Female",flag:"dk",gender:"f",lang:"da-DK",voiceIDs:[413,105,104,106,198,107]},{name:"Danish Male",flag:"da",gender:"m",lang:"da-DK",voiceIDs:[162],deprecated:!0},{name:"Deutsch Female",flag:"de",gender:"f",lang:"de-DE",voiceIDs:[27,28,29,30,78,170,275,199,31,261,290,346,262,291,347,32]},{name:"Deutsch Male", |  | ||||||
| flag:"de",gender:"m",lang:"de-DE",voiceIDs:[307,324,363,377,393]},{name:"Dutch Female",flag:"nl",gender:"f",lang:"nl-NL",voiceIDs:[243,219,84,157,158,184,45]},{name:"Dutch Male",flag:"nl",gender:"m",lang:"nl-NL",voiceIDs:[157,220,407]},{name:"Estonian Male",flag:"ee",gender:"m",lang:"et-EE",voiceIDs:[416,446]},{name:"Filipino Female",flag:"ph",gender:"f",lang:"fil-PH",voiceIDs:[418,437]},{name:"Finnish Female",flag:"fi",gender:"f",lang:"fi-FI",voiceIDs:[417,90,89,91,209,92]},{name:"Finnish Male", |  | ||||||
| flag:"fi",gender:"m",lang:"fi-FI",voiceIDs:[160],deprecated:!0},{name:"French Female",flag:"fr",gender:"f",lang:"fr-FR",voiceIDs:[240,21,22,23,77,178,279,210,266,295,351,304,321,360,26]},{name:"French Male",flag:"fr",gender:"m",lang:"fr-FR",voiceIDs:[311,328,367,378,392]},{name:"French Canadian Female",flag:"ca",gender:"f",lang:"fr-CA",voiceIDs:[419,210,449]},{name:"French Canadian Male",flag:"ca",gender:"m",lang:"fr-CA",voiceIDs:[450]},{name:"Greek Female",flag:"gr",gender:"f",lang:"el-GR",voiceIDs:[414, |  | ||||||
| 62,63,80,200,64]},{name:"Greek Male",flag:"gr",gender:"m",lang:"el-GR",voiceIDs:[163],deprecated:!0},{name:"Hindi Female",flag:"hi",gender:"f",lang:"hi-IN",voiceIDs:[247,66,154,179,213,259,288,344,67]},{name:"Hindi Male",flag:"hi",gender:"m",lang:"hi-IN",voiceIDs:[394]},{name:"Hungarian Female",flag:"hu",gender:"f",lang:"hu-HU",voiceIDs:[420,9,10,81,214,11]},{name:"Hungarian Male",flag:"hu",gender:"m",lang:"hu-HU",voiceIDs:[164],deprecated:!0},{name:"Indonesian Female",flag:"id",gender:"f",lang:"id-ID", |  | ||||||
| voiceIDs:[241,111,112,180,215,113]},{name:"Indonesian Male",flag:"id",gender:"m",lang:"id-ID",voiceIDs:[395]},{name:"Italian Female",flag:"it",gender:"f",lang:"it-IT",voiceIDs:[242,33,34,35,36,37,79,181,216,271,300,356,38]},{name:"Italian Male",flag:"it",gender:"m",lang:"it-IT",voiceIDs:[312,329,368,406]},{name:"Japanese Female",flag:"jp",gender:"f",lang:"ja-JP",voiceIDs:[51,280,217,52,153,182,273,302,358,274,303,359,53]},{name:"Japanese Male",flag:"jp",gender:"m",lang:"ja-JP",voiceIDs:[248,50,313, |  | ||||||
| 330,369,396]},{name:"Korean Female",flag:"kr",gender:"f",lang:"ko-KR",voiceIDs:[54,55,56,156,183,218,306,323,362,384,57]},{name:"Korean Male",flag:"kr",gender:"m",lang:"ko-KR",voiceIDs:[397]},{name:"Latin Female",flag:"va",gender:"f",lang:"la",voiceIDs:[114],deprecated:!0},{name:"Latin Male",flag:"va",gender:"m",lang:"la",voiceIDs:[165]},{name:"Nepali",flag:"np",gender:"f",lang:"ne-NP",voiceIDs:[423,441]},{name:"Norwegian Female",flag:"no",gender:"f",lang:"nb-NO",voiceIDs:[422,72,73,221,74]},{name:"Norwegian Male", |  | ||||||
| flag:"no",gender:"m",lang:"nb-NO",voiceIDs:[166]},{name:"Polish Female",flag:"pl",gender:"f",lang:"pl-PL",voiceIDs:[244,120,119,121,185,222,267,296,352,122]},{name:"Polish Male",flag:"pl",gender:"m",lang:"pl-PL",voiceIDs:[314,331,370,398]},{name:"Portuguese Female",flag:"br",gender:"f",lang:"pt-BR",voiceIDs:[128,127,129,187,224,272,301,357,130]},{name:"Portuguese Male",flag:"br",gender:"m",lang:"pt-BR",voiceIDs:[400]},{name:"Romanian Female",flag:"ro",gender:"f",lang:"ro-RO",voiceIDs:[424,151,150, |  | ||||||
| 152,225,46]},{name:"Russian Female",flag:"ru",gender:"f",lang:"ru-RU",voiceIDs:[246,47,48,83,188,226,260,289,345,49]},{name:"Russian Male",flag:"ru",gender:"m",lang:"ru-RU",voiceIDs:[316,333,372,387],deprecated:!0},{name:"Sinhala",flag:"lk",gender:"f",lang:"si-LK",voiceIDs:[425,442]},{name:"Slovak Female",flag:"sk",gender:"f",lang:"sk-SK",voiceIDs:[426,133,132,134,227,135]},{name:"Slovak Male",flag:"sk",gender:"m",lang:"sk-SK",voiceIDs:[167],deprecated:!0},{name:"Spanish Female",flag:"es",gender:"f", |  | ||||||
| lang:"es-ES",voiceIDs:[19,238,16,17,18,20,76,174,207,263,292,348,264,293,349,15]},{name:"Spanish Male",flag:"es",gender:"m",lang:"es-ES",voiceIDs:[309,326,365,401],deprecated:!0},{name:"Spanish Latin American Female",flag:"es",gender:"f",lang:"es-MX",voiceIDs:[239,137,136,138,175,208,265,294,350,139]},{name:"Spanish Latin American Male",flag:"es",gender:"m",lang:"es-MX",voiceIDs:[136,310,327,366,402]},{name:"Swedish Female",flag:"sv",gender:"f",lang:"sv-SE",voiceIDs:[427,85,149,228,65]},{name:"Swedish Male", |  | ||||||
| flag:"sv",gender:"m",lang:"sv-SE",voiceIDs:[148,168]},{name:"Tamil Female",flag:"hi",gender:"m",lang:"hi-IN",voiceIDs:[451]},{name:"Tamil Male",flag:"hi",gender:"m",lang:"hi-IN",voiceIDs:[141]},{name:"Thai Female",flag:"th",gender:"f",lang:"th-TH",voiceIDs:[143,142,144,189,229,145]},{name:"Thai Male",flag:"th",gender:"m",lang:"th-TH",voiceIDs:[403]},{name:"Turkish Female",flag:"tr",gender:"f",lang:"tr-TR",voiceIDs:[69,70,82,190,230,71]},{name:"Turkish Male",flag:"tr",gender:"m",lang:"tr-TR",voiceIDs:[404]}, |  | ||||||
| {name:"Ukrainian Female",flag:"ua",gender:"f",lang:"uk-UA",voiceIDs:[428,443]},{name:"Vietnamese Female",flag:"vi",gender:"f",lang:"vi-VN",voiceIDs:[429,405]},{name:"Vietnamese Male",flag:"vi",gender:"m",lang:"vi-VN",voiceIDs:[146]},{name:"Afrikaans Male",flag:"af",gender:"m",lang:"af-ZA",voiceIDs:[93]},{name:"Albanian Male",flag:"sq",gender:"m",lang:"sq-AL",voiceIDs:[94]},{name:"Bosnian Male",flag:"bs",gender:"m",lang:"bs",voiceIDs:[14]},{name:"Catalan Male",flag:"catalonia",gender:"m",lang:"ca-ES", |  | ||||||
| voiceIDs:[68]},{name:"Croatian Male",flag:"hr",gender:"m",lang:"hr-HR",voiceIDs:[13]},{name:"Esperanto Male",flag:"eo",gender:"m",lang:"eo",voiceIDs:[108]},{name:"Icelandic Male",flag:"is",gender:"m",lang:"is-IS",voiceIDs:[110]},{name:"Latvian Male",flag:"lv",gender:"m",lang:"lv-LV",voiceIDs:[115]},{name:"Macedonian Male",flag:"mk",gender:"m",lang:"mk-MK",voiceIDs:[116]},{name:"Moldavian Female",flag:"md",gender:"f",lang:"md",voiceIDs:[117]},{name:"Moldavian Male",flag:"md",gender:"m",lang:"md",voiceIDs:[117], |  | ||||||
| deprecated:!0},{name:"Montenegrin Male",flag:"me",gender:"m",lang:"me",voiceIDs:[118]},{name:"Serbian Male",flag:"sr",gender:"m",lang:"sr-RS",voiceIDs:[12]},{name:"Serbo-Croatian Male",flag:"hr",gender:"m",lang:"hr-HR",voiceIDs:[131]},{name:"Swahili Male",flag:"sw",gender:"m",lang:"sw-KE",voiceIDs:[140]},{name:"Welsh Male",flag:"cy",gender:"m",lang:"cy",voiceIDs:[147]},{name:"Fallback UK Female",flag:"gb",gender:"f",lang:"en-GB",voiceIDs:[8]}];a.voicecollection=[{name:"Google UK English Male"},{name:"Agnes"}, |  | ||||||
| {name:"Daniel Compact"},{name:"Google UK English Female"},{name:"en-GB",rate:.25,pitch:1},{name:"en-AU",rate:.25,pitch:1},{name:"ingl\u00e9s Reino Unido"},{name:"English United Kingdom"},{name:"Fallback en-GB Female",lang:"en-GB",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Eszter Compact"},{name:"hu-HU",rate:.4},{name:"Fallback Hungarian Female",lang:"hu",fallbackvoice:!0,service:"g1"},{name:"Fallback Serbian Male",lang:"sr",fallbackvoice:!0,service:"g1",gender:"male"},{name:"Fallback Croatian Male", |  | ||||||
| lang:"hr",rate:.5,fallbackvoice:!0,service:"g1",gender:"male"},{name:"Fallback Bosnian Male",lang:"bs",fallbackvoice:!0,service:"g1",gender:"male"},{name:"Fallback Spanish Female",lang:"es",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Spanish Spain"},{name:"espa\u00f1ol Espa\u00f1a"},{name:"Diego Compact",rate:.3},{name:"Google Espa\u00f1ol"},{name:"es-ES",rate:.2},{name:"Google Fran\u00e7ais"},{name:"French France"},{name:"franc\u00e9s Francia"},{name:"Virginie Compact",rate:.5},{name:"fr-FR", |  | ||||||
| rate:.25},{name:"Fallback French Female",lang:"fr",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Google Deutsch"},{name:"German Germany"},{name:"alem\u00e1n Alemania"},{name:"Yannick Compact",rate:.5},{name:"de-DE",rate:.25},{name:"Fallback Deutsch Female",lang:"de",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Google Italiano"},{name:"Italian Italy"},{name:"italiano Italia"},{name:"Paolo Compact",rate:.5},{name:"it-IT",rate:.25},{name:"Fallback Italian Female",lang:"it",fallbackvoice:!0, |  | ||||||
| service:"g1",gender:"female"},{name:"Google US English",timerSpeed:1},{name:"English United States"},{name:"ingl\u00e9s Estados Unidos"},{name:"Vicki"},{name:"en-US",rate:.2,pitch:1,timerSpeed:1.3},{name:"Fallback US English",lang:"en-US",fallbackvoice:!0,timerSpeed:0,service:"g1",gender:"female"},{name:"Fallback Dutch Female",lang:"nl",fallbackvoice:!0,timerSpeed:0,service:"g1",gender:"female"},{name:"Fallback Romanian",lang:"ro",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Milena Compact"}, |  | ||||||
| {name:"ru-RU",rate:.25},{name:"Fallback Russian",lang:"ru",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Google \u65e5\u672c\u4eba",timerSpeed:1},{name:"Kyoko Compact"},{name:"ja-JP",rate:.25},{name:"Fallback Japanese Female",lang:"ja",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Google \ud55c\uad6d\uc758",timerSpeed:1},{name:"Narae Compact"},{name:"ko-KR",rate:.25},{name:"Fallback Korean Female",lang:"ko",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Google \u4e2d\u56fd\u7684", |  | ||||||
| timerSpeed:1},{name:"Ting-Ting Compact"},{name:"zh-CN",rate:.25},{name:"Fallback Chinese",lang:"zh-CN",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Alexandros Compact"},{name:"el-GR",rate:.25},{name:"Fallback Greek",lang:"el",fallbackvoice:!0,service:"g3",gender:"female"},{name:"Fallback Swedish",lang:"sv",fallbackvoice:!0,service:"g3",gender:"female"},{name:"hi-IN",rate:.25},{name:"Fallback Hindi Female",lang:"hi",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Fallback Catalan",lang:"ca", |  | ||||||
| fallbackvoice:!0,service:"g1",gender:"male"},{name:"Aylin Compact"},{name:"tr-TR",rate:.25},{name:"Fallback Turkish",lang:"tr",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Stine Compact"},{name:"no-NO",rate:.25},{name:"Fallback Norwegian",lang:"no",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Daniel"},{name:"Monica"},{name:"Amelie"},{name:"Anna"},{name:"Alice"},{name:"Melina"},{name:"Mariska"},{name:"Yelda"},{name:"Milena"},{name:"Xander"},{name:"Alva"},{name:"Lee Compact"},{name:"Karen"}, |  | ||||||
| {name:"Fallback Australian Female",lang:"en-AU",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Mikko Compact"},{name:"Satu"},{name:"fi-FI",rate:.25},{name:"Fallback Finnish",lang:"fi",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Fallback Afrikans",lang:"af",fallbackvoice:!0,service:"g1",gender:"male"},{name:"Fallback Albanian",lang:"sq",fallbackvoice:!0,service:"g1",gender:"male"},{name:"Maged Compact"},{name:"Tarik"},{name:"ar-SA",rate:.25},{name:"Fallback Arabic",lang:"ar",fallbackvoice:!0, |  | ||||||
| service:"g1",gender:"female"},{name:"Fallback Armenian",lang:"hy",fallbackvoice:!0,service:"g1",gender:"male"},{name:"Zuzana Compact"},{name:"Zuzana"},{name:"cs-CZ",rate:.25},{name:"Fallback Czech",lang:"cs",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Ida Compact"},{name:"Sara"},{name:"da-DK",rate:.25},{name:"Fallback Danish",lang:"da",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Fallback Esperanto",lang:"eo",fallbackvoice:!0,service:"g1",gender:"male"},{name:"Fallback Haitian Creole", |  | ||||||
| lang:"ht",fallbackvoice:!0},{name:"Fallback Icelandic",lang:"is",fallbackvoice:!0,service:"g1",gender:"male"},{name:"Damayanti"},{name:"id-ID",rate:.25},{name:"Fallback Indonesian Female",lang:"id",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Fallback Latin Female",lang:"la",fallbackvoice:!0,service:"g2",gender:"female"},{name:"Fallback Latvian Male",lang:"lv",fallbackvoice:!0,service:"g1",gender:"male"},{name:"Fallback Macedonian Male",lang:"mk",fallbackvoice:!0,service:"g1",gender:"male"}, |  | ||||||
| {name:"Fallback Moldavian Female",lang:"mo",fallbackvoice:!0,service:"g2",gender:"female"},{name:"Fallback Montenegrin Male",lang:"sr-ME",fallbackvoice:!0,service:"g1",gender:"male"},{name:"Agata Compact"},{name:"Zosia"},{name:"pl-PL",rate:.25},{name:"Fallback Polish Female",lang:"pl",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Raquel Compact"},{name:"Luciana"},{name:"pt-BR",rate:.25},{name:"Fallback Brazilian Portuguese Female",lang:"pt-BR",fallbackvoice:!0,service:"g1",gender:"female"}, |  | ||||||
| {name:"Joana Compact"},{name:"Joana"},{name:"pt-PT",rate:.25},{name:"Fallback Portuguese",lang:"pt-PT",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Fallback Serbo-Croation",lang:"sh",fallbackvoice:!0,service:"g2",gender:"male"},{name:"Laura Compact"},{name:"Laura"},{name:"sk-SK",rate:.25},{name:"Fallback Slovak",lang:"sk",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Javier Compact"},{name:"Paulina"},{name:"es-MX",rate:.25},{name:"Fallback Spanish (Latin American) Female",lang:"es-419", |  | ||||||
| fallbackvoice:!0,service:"g1",gender:"female"},{name:"Fallback Swahili",lang:"sw",fallbackvoice:!0,service:"g1",gender:"male"},{name:"Fallback Tamil",lang:"ta",fallbackvoice:!0,service:"g1",gender:"male"},{name:"Narisa Compact"},{name:"Kanya"},{name:"th-TH",rate:.25},{name:"Fallback Thai Female",lang:"th",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Fallback Vietnamese Male",lang:"vi",fallbackvoice:!0,service:"g3",gender:"male"},{name:"Fallback Welsh",lang:"cy",fallbackvoice:!0,service:"g1", |  | ||||||
| gender:"male"},{name:"Oskar Compact"},{name:"sv-SE",rate:.25},{name:"Simona Compact"},{name:"Ioana"},{name:"ro-RO",rate:.25},{name:"Kyoko"},{name:"Lekha"},{name:"Ting-Ting"},{name:"Yuna"},{name:"Xander Compact"},{name:"nl-NL",rate:.25},{name:"Fallback UK English Male",lang:"en-GB",fallbackvoice:!0,service:"g1",voicename:"rjs",gender:"male"},{name:"Finnish Male",lang:"fi",fallbackvoice:!0,service:"g3",voicename:"",gender:"male",deprecated:!0},{name:"Czech Male",lang:"cs",fallbackvoice:!0,service:"g3", |  | ||||||
| voicename:"",gender:"male",deprecated:!0},{name:"Danish Male",lang:"da",fallbackvoice:!0,service:"g3",voicename:"",gender:"male",deprecated:!0},{name:"Greek Male",lang:"el",fallbackvoice:!0,service:"g3",voicename:"",gender:"male",deprecated:!0},{name:"Hungarian Male",lang:"hu",fallbackvoice:!0,service:"g3",voicename:"",gender:"male",deprecated:!0},{name:"Latin Male",lang:"la",fallbackvoice:!0,service:"g1",voicename:"",gender:"male"},{name:"Norwegian Male",lang:"no",fallbackvoice:!0,service:"g3",voicename:"", |  | ||||||
| gender:"male"},{name:"Slovak Male",lang:"sk",fallbackvoice:!0,service:"g3",voicename:"",gender:"male",deprecated:!0},{name:"Swedish Male",lang:"sv",fallbackvoice:!0,service:"g3",voicename:"",gender:"male"},{name:"Fallback US English Male",lang:"en-US",fallbackvoice:!0,service:"g3",voicename:"",gender:"male"},{name:"German Germany",lang:"de_DE"},{name:"English United Kingdom",lang:"en_GB"},{name:"English India",lang:"en_IN"},{name:"English United States",lang:"en_US"},{name:"Spanish Spain",lang:"es_ES"}, |  | ||||||
| {name:"Spanish Mexico",lang:"es_MX"},{name:"Spanish United States",lang:"es_US"},{name:"French Belgium",lang:"fr_BE"},{name:"French France",lang:"fr_FR"},{name:"Hindi India",lang:"hi_IN"},{name:"Indonesian Indonesia",lang:"in_ID"},{name:"Italian Italy",lang:"it_IT"},{name:"Japanese Japan",lang:"ja_JP"},{name:"Korean South Korea",lang:"ko_KR"},{name:"Dutch Netherlands",lang:"nl_NL"},{name:"Polish Poland",lang:"pl_PL"},{name:"Portuguese Brazil",lang:"pt_BR"},{name:"Portuguese Portugal",lang:"pt_PT"}, |  | ||||||
| {name:"Russian Russia",lang:"ru_RU"},{name:"Thai Thailand",lang:"th_TH"},{name:"Turkish Turkey",lang:"tr_TR"},{name:"Chinese China",lang:"zh_CN_#Hans"},{name:"Chinese Hong Kong",lang:"zh_HK_#Hans"},{name:"Chinese Hong Kong",lang:"zh_HK_#Hant"},{name:"Chinese Taiwan",lang:"zh_TW_#Hant"},{name:"Alex"},{name:"Maged",lang:"ar-SA"},{name:"Zuzana",lang:"cs-CZ"},{name:"Sara",lang:"da-DK"},{name:"Anna",lang:"de-DE"},{name:"Melina",lang:"el-GR"},{name:"Karen",lang:"en-AU"},{name:"Daniel",lang:"en-GB"},{name:"Moira", |  | ||||||
| lang:"en-IE"},{name:"Samantha (Enhanced)",lang:"en-US"},{name:"Samantha",lang:"en-US"},{name:"Tessa",lang:"en-ZA"},{name:"Monica",lang:"es-ES"},{name:"Paulina",lang:"es-MX"},{name:"Satu",lang:"fi-FI"},{name:"Amelie",lang:"fr-CA"},{name:"Thomas",lang:"fr-FR"},{name:"Carmit",lang:"he-IL"},{name:"Lekha",lang:"hi-IN"},{name:"Mariska",lang:"hu-HU"},{name:"Damayanti",lang:"id-ID"},{name:"Alice",lang:"it-IT"},{name:"Kyoko",lang:"ja-JP"},{name:"Yuna",lang:"ko-KR"},{name:"Ellen",lang:"nl-BE"},{name:"Xander", |  | ||||||
| lang:"nl-NL"},{name:"Nora",lang:"no-NO"},{name:"Zosia",lang:"pl-PL"},{name:"Luciana",lang:"pt-BR"},{name:"Joana",lang:"pt-PT"},{name:"Ioana",lang:"ro-RO"},{name:"Milena",lang:"ru-RU"},{name:"Laura",lang:"sk-SK"},{name:"Alva",lang:"sv-SE"},{name:"Kanya",lang:"th-TH"},{name:"Yelda",lang:"tr-TR"},{name:"Ting-Ting",lang:"zh-CN"},{name:"Sin-Ji",lang:"zh-HK"},{name:"Mei-Jia",lang:"zh-TW"},{name:"Microsoft David Mobile - English (United States)",lang:"en-US"},{name:"Microsoft Zira Mobile - English (United States)", |  | ||||||
| lang:"en-US"},{name:"Microsoft Mark Mobile - English (United States)",lang:"en-US"},{name:"native",lang:""},{name:"Google espa\u00f1ol"},{name:"Google espa\u00f1ol de Estados Unidos"},{name:"Google fran\u00e7ais"},{name:"Google Bahasa Indonesia"},{name:"Google italiano"},{name:"Google Nederlands"},{name:"Google polski"},{name:"Google portugu\u00eas do Brasil"},{name:"Google \u0440\u0443\u0441\u0441\u043a\u0438\u0439"},{name:"Google \u0939\u093f\u0928\u094d\u0926\u0940"},{name:"Google \u65e5\u672c\u8a9e"}, |  | ||||||
| {name:"Google \u666e\u901a\u8bdd\uff08\u4e2d\u56fd\u5927\u9646\uff09"},{name:"Google \u7ca4\u8a9e\uff08\u9999\u6e2f\uff09"},{name:"zh-HK",rate:.25},{name:"Fallback Chinese (Hong Kong) Female",lang:"zh-HK",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Google \u7ca4\u8a9e\uff08\u9999\u6e2f\uff09"},{name:"zh-TW",rate:.25},{name:"Fallback Chinese (Taiwan) Female",lang:"zh-TW",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Microsoft George Mobile - English (United Kingdom)",lang:"en-GB"}, |  | ||||||
| {name:"Microsoft Susan Mobile - English (United Kingdom)",lang:"en-GB"},{name:"Microsoft Hazel Mobile - English (United Kingdom)",lang:"en-GB"},{name:"Microsoft Heera Mobile - English (India)",lang:"en-In"},{name:"Microsoft Irina Mobile - Russian (Russia)",lang:"ru-RU"},{name:"Microsoft Hedda Mobile - German (Germany)",lang:"de-DE"},{name:"Microsoft Katja Mobile - German (Germany)",lang:"de-DE"},{name:"Microsoft Helena Mobile - Spanish (Spain)",lang:"es-ES"},{name:"Microsoft Laura Mobile - Spanish (Spain)", |  | ||||||
| lang:"es-ES"},{name:"Microsoft Sabina Mobile - Spanish (Mexico)",lang:"es-MX"},{name:"Microsoft Julie Mobile - French (France)",lang:"fr-FR"},{name:"Microsoft Paulina Mobile - Polish (Poland)",lang:"pl-PL"},{name:"Microsoft Huihui Mobile - Chinese (Simplified, PRC)",lang:"zh-CN"},{name:"Microsoft Yaoyao Mobile - Chinese (Simplified, PRC)",lang:"zh-CN"},{name:"Microsoft Tracy Mobile - Chinese (Traditional, Hong Kong S.A.R.)",lang:"zh-CN"},{name:"Microsoft Elsa Mobile - Italian (Italy)",lang:"it-IT"}, |  | ||||||
| {name:"Microsoft Maria Mobile - Portuguese (Brazil)",lang:"pt-BR"},{name:"Microsoft Ayumi Mobile - Japanese (Japan)",lang:"ja-JP"},{name:"Microsoft Haruka Mobile - Japanese (Japan)",lang:"ja-JP"},{name:"Helena",lang:"de-DE"},{name:"Catherine",lang:"en-AU"},{name:"Arthur",lang:"en-GB"},{name:"Martha",lang:"en-GB"},{name:"Marie",lang:"fr-FR"},{name:"O-ren",lang:"ja-JP"},{name:"Yu-shu",lang:"zh-CN"},{name:"Microsoft David - English (United States)",lang:"en-US"},{name:"Microsoft Zira - English (United States)", |  | ||||||
| lang:"en-US"},{name:"Microsoft Mark - English (United States)",lang:"en-US"},{name:"Microsoft George - English (United Kingdom)",lang:"en-GB"},{name:"Microsoft Susan - English (United Kingdom)",lang:"en-GB"},{name:"Microsoft Hazel - English (United Kingdom)",lang:"en-GB"},{name:"Microsoft Heera - English (India)",lang:"en-In"},{name:"Microsoft Irina - Russian (Russia)",lang:"ru-RU"},{name:"Microsoft Hedda - German (Germany)",lang:"de-DE"},{name:"Microsoft Katja - German (Germany)",lang:"de-DE"},{name:"Microsoft Helena - Spanish (Spain)", |  | ||||||
| lang:"es-ES"},{name:"Microsoft Laura - Spanish (Spain)",lang:"es-ES"},{name:"Microsoft Sabina - Spanish (Mexico)",lang:"es-MX"},{name:"Microsoft Julie - French (France)",lang:"fr-FR"},{name:"Microsoft Paulina - Polish (Poland)",lang:"pl-PL"},{name:"Microsoft Huihui - Chinese (Simplified, PRC)",lang:"zh-CN"},{name:"Microsoft Yaoyao - Chinese (Simplified, PRC)",lang:"zh-CN"},{name:"Microsoft Tracy - Chinese (Traditional, Hong Kong S.A.R.)",lang:"zh-CN"},{name:"Microsoft Elsa - Italian (Italy)",lang:"it-IT"}, |  | ||||||
| {name:"Microsoft Maria - Portuguese (Brazil)",lang:"pt-BR"},{name:"Microsoft Ayumi - Japanese (Japan)",lang:"ja-JP"},{name:"Microsoft Haruka - Japanese (Japan)",lang:"ja-JP"},{name:"Microsoft Hortense - French (France)",lang:"fr-FR"},{name:"Microsoft Hanhan - Chinese (Traditional, Taiwan)",lang:"zh-TW"},{name:"Microsoft Heami - Korean (Korean)",lang:"ko-KR"},{name:"Microsoft Stefan - German (Germany)",lang:"de-DE"},{name:"Microsoft Ravi - English (India)",lang:"en-IN"},{name:"Microsoft Pablo - Spanish (Spain)", |  | ||||||
| lang:"es-ES"},{name:"Microsoft Raul - Spanish (Mexico)",lang:"es-MX"},{name:"Microsoft Paul - French (France)",lang:"fr-FR"},{name:"Microsoft Cosimo - Italian (Italy)",lang:"it-IT"},{name:"Microsoft Ichiro - Japanese (Japan)",lang:"ja-JP"},{name:"Microsoft Adam - Polish (Poland)",lang:"pl-PL"},{name:"Microsoft Daniel - Portuguese (Brazil)",lang:"pt-BR"},{name:"Microsoft Pavel - Russian (Russia)",lang:"ru-RU"},{name:"Microsoft Kangkang - Chinese (Simplified, PRC)",lang:"zh-CN"},{name:"Microsoft Danny - Chinese (Traditional, Hong Kong S.A.R.)", |  | ||||||
| lang:"zh-HK"},{name:"Microsoft Yating - Chinese (Traditional, Taiwan)",lang:"zh-TW"},{name:"Microsoft Zhiwei - Chinese (Traditional, Taiwan)",lang:"zh-TW"},{name:"Microsoft Hortense Mobile - French (France)",lang:"fr-FR"},{name:"Microsoft Hanhan Mobile - Chinese (Traditional, Taiwan)",lang:"zh-TW"},{name:"Microsoft Heami Mobile - Korean (Korean)",lang:"ko-KR"},{name:"Microsoft Stefan Mobile - German (Germany)",lang:"de-DE"},{name:"Microsoft Ravi Mobile - English (India)",lang:"en-IN"},{name:"Microsoft Pablo Mobile - Spanish (Spain)", |  | ||||||
| lang:"es-ES"},{name:"Microsoft Raul Mobile - Spanish (Mexico)",lang:"es-MX"},{name:"Microsoft Paul Mobile - French (France)",lang:"fr-FR"},{name:"Microsoft Cosimo Mobile - Italian (Italy)",lang:"it-IT"},{name:"Microsoft Ichiro Mobile - Japanese (Japan)",lang:"ja-JP"},{name:"Microsoft Adam Mobile - Polish (Poland)",lang:"pl-PL"},{name:"Microsoft Daniel Mobile - Portuguese (Brazil)",lang:"pt-BR"},{name:"Microsoft Pavel Mobile - Russian (Russia)",lang:"ru-RU"},{name:"Microsoft Kangkang Mobile - Chinese (Simplified, PRC)", |  | ||||||
| lang:"zh-CN"},{name:"Microsoft Danny Mobile - Chinese (Traditional, Hong Kong S.A.R.)",lang:"zh-HK"},{name:"Microsoft Yating Mobile - Chinese (Traditional, Taiwan)",lang:"zh-TW"},{name:"Microsoft Zhiwei Mobile - Chinese (Traditional, Taiwan)",lang:"zh-TW"},{name:"Microsoft David Desktop - English (United States)",lang:"en-US"},{name:"Microsoft Zira Desktop - English (United States)",lang:"en-US"},{name:"Microsoft Mark Desktop - English (United States)",lang:"en-US"},{name:"Microsoft George Desktop - English (United Kingdom)", |  | ||||||
| lang:"en-GB"},{name:"Microsoft Susan Desktop - English (United Kingdom)",lang:"en-GB"},{name:"Microsoft Hazel Desktop - English (United Kingdom)",lang:"en-GB"},{name:"Microsoft Heera Desktop - English (India)",lang:"en-In"},{name:"Microsoft Irina Desktop - Russian (Russia)",lang:"ru-RU"},{name:"Microsoft Hedda Desktop - German (Germany)",lang:"de-DE"},{name:"Microsoft Katja Desktop - German (Germany)",lang:"de-DE"},{name:"Microsoft Helena Desktop - Spanish (Spain)",lang:"es-ES"},{name:"Microsoft Laura Desktop - Spanish (Spain)", |  | ||||||
| lang:"es-ES"},{name:"Microsoft Sabina Desktop - Spanish (Mexico)",lang:"es-MX"},{name:"Microsoft Julie Desktop - French (France)",lang:"fr-FR"},{name:"Microsoft Paulina Desktop - Polish (Poland)",lang:"pl-PL"},{name:"Microsoft Huihui Desktop - Chinese (Simplified, PRC)",lang:"zh-CN"},{name:"Microsoft Yaoyao Desktop - Chinese (Simplified, PRC)",lang:"zh-CN"},{name:"Microsoft Tracy Desktop - Chinese (Traditional, Hong Kong S.A.R.)",lang:"zh-CN"},{name:"Microsoft Elsa Desktop - Italian (Italy)",lang:"it-IT"}, |  | ||||||
| {name:"Microsoft Maria Desktop - Portuguese (Brazil)",lang:"pt-BR"},{name:"Microsoft Ayumi Desktop - Japanese (Japan)",lang:"ja-JP"},{name:"Microsoft Haruka Desktop - Japanese (Japan)",lang:"ja-JP"},{name:"Microsoft Hortense Desktop - French (France)",lang:"fr-FR"},{name:"Microsoft Hanhan Desktop - Chinese (Traditional, Taiwan)",lang:"zh-TW"},{name:"Microsoft Heami Desktop - Korean (Korean)",lang:"ko-KR"},{name:"Microsoft Stefan Desktop - German (Germany)",lang:"de-DE"},{name:"Microsoft Ravi Desktop - English (India)", |  | ||||||
| lang:"en-IN"},{name:"Microsoft Pablo Desktop - Spanish (Spain)",lang:"es-ES"},{name:"Microsoft Raul Desktop - Spanish (Mexico)",lang:"es-MX"},{name:"Microsoft Paul Desktop - French (France)",lang:"fr-FR"},{name:"Microsoft Cosimo Desktop - Italian (Italy)",lang:"it-IT"},{name:"Microsoft Ichiro Desktop - Japanese (Japan)",lang:"ja-JP"},{name:"Microsoft Adam Desktop - Polish (Poland)",lang:"pl-PL"},{name:"Microsoft Daniel Desktop - Portuguese (Brazil)",lang:"pt-BR"},{name:"Microsoft Pavel Desktop - Russian (Russia)", |  | ||||||
| lang:"ru-RU"},{name:"Microsoft Kangkang Desktop - Chinese (Simplified, PRC)",lang:"zh-CN"},{name:"Microsoft Danny Desktop - Chinese (Traditional, Hong Kong S.A.R.)",lang:"zh-HK"},{name:"Microsoft Yating Desktop - Chinese (Traditional, Taiwan)",lang:"zh-TW"},{name:"Microsoft Zhiwei Desktop - Chinese (Traditional, Taiwan)",lang:"zh-TW"},{name:"Martin",lang:"de-DE"},{name:"Daniel",lang:"fr-FR"},{name:"Hattori",lang:"ja-JP"},{name:"Li-mu",lang:"zh-CN"},{name:"Gordon",lang:"en-AU"},{name:"Aaron",lang:"en-US"}, |  | ||||||
| {name:"Nicky",lang:"en-US"},{name:"Microsoft Hanhan Desktop - Chinese (Taiwan)",lang:"zh-TW"},{name:"Microsoft Heami Desktop - Korean",lang:"ko-KR"},{name:"Fallback Australian Male",lang:"en-AU",fallbackvoice:!0,service:"g3",gender:"male"},{name:"Fallback Russian Male",lang:"ru",fallbackvoice:!0,service:"g3",gender:"male",deprecated:!0},{name:"Fallback Arabic Male",lang:"ar",fallbackvoice:!0,service:"g3",gender:"male"},{name:"Fallback Chinese",lang:"zh-CN",fallbackvoice:!0,service:"g3",gender:"male"}, |  | ||||||
| {name:"Fallback Chinese HK",lang:"zh-HK",fallbackvoice:!0,service:"g3",gender:"male"},{name:"Fallback Chinese TW",lang:"zh-TW",fallbackvoice:!0,service:"g3",gender:"male"},{name:"Fallback French Male",lang:"fr",fallbackvoice:!0,service:"g3",gender:"male"},{name:"Fallback Deutsch Male",lang:"de",fallbackvoice:!0,service:"g3",gender:"male"},{name:"Fallback Hindi Male",lang:"hi",fallbackvoice:!0,service:"g3",gender:"male"},{name:"Fallback Indonesian Male",lang:"id",fallbackvoice:!0,service:"g3",gender:"male"}, |  | ||||||
| {name:"Fallback Japanese Male",lang:"ja",fallbackvoice:!0,service:"g3",gender:"male"},{name:"Fallback Korean Male",lang:"ko",fallbackvoice:!0,service:"g3",gender:"male"},{name:"Fallback Polish Male",lang:"pl",fallbackvoice:!0,service:"g1",gender:"male"},{name:"Fallback Brazilian Portuguese Male",lang:"pt-BR",fallbackvoice:!0,service:"g3",gender:"male",deprecated:!0},{name:"Fallback Portuguese Male",lang:"pt-PT",fallbackvoice:!0,service:"g1",gender:"male"},{name:"Fallback Spanish Male",lang:"es",fallbackvoice:!0, |  | ||||||
| service:"g3",gender:"male",deprecated:!0},{name:"Fallback Spanish (Latin American) Male",lang:"es-419",fallbackvoice:!0,service:"g3",gender:"male"},{name:"Fallback Thai Male",lang:"th",fallbackvoice:!0,service:"g3",gender:"male"},{name:"Fallback Turkish Male",lang:"tr",fallbackvoice:!0,service:"g3",gender:"male"},{name:"Fallback Vietnamese Female",lang:"vi",fallbackvoice:!0,service:"g1",gender:"female"},{name:"Fallback Italian Male",lang:"it",fallbackvoice:!0,service:"g3",gender:"male"},{name:"Fallback Dutch Male", |  | ||||||
| lang:"nl",fallbackvoice:!0,timerSpeed:0,service:"g3",gender:"male"},{name:"Microsoft Anna - English (United States)",lang:"en-US",gender:"female"},{name:"Microsoft Lili - Chinese (China)",lang:"zh-CN",gender:"female"},{name:"Bangla Bangladesh",lang:"bn_BD",gender:"male"},{name:"Bangla India",lang:"bn_IN",gender:"male"},{name:"Czech Czechia",lang:"cs_CZ",gender:"female"},{name:"Danish Denmark",lang:"da_DK",gender:"female"},{name:"Greek Greece",lang:"el_GR",gender:"female"},{name:"English Australia", |  | ||||||
| lang:"en_AU",gender:"female"},{name:"Estonian Estonia",lang:"et_EE",gender:"male"},{name:"Finnish Finland",lang:"fi_FI",gender:"female"},{name:"Filipino Philippines",lang:"fil_PH",gender:"female"},{name:"French Canada",lang:"fr_CAF",gender:"female"},{name:"Hungarian Hungary",lang:"hu_HU",gender:"female"},{name:"Khmer Cambodia",lang:"km_KH",gender:"female"},{name:"Norwegian Bokm\u00e5l Norway",lang:"nb_NO",gender:"female"},{name:"Nepali Nepal",lang:"ne_NP",gender:"female"},{name:"Romanian Romania", |  | ||||||
| lang:"ro_RO",gender:"female"},{name:"Sinhala Sri Lanka",lang:"si_LK",gender:"female"},{name:"Slovak Slovakia",lang:"sk_SK",gender:"female"},{name:"Swedish Sweden",lang:"sv_SE",gender:"female"},{name:"Ukrainian Ukraine",lang:"uk_UA",gender:"female"},{name:"Vietnamese Vietnam",lang:"vi_VN",gender:"female"},{name:"Cantonese Hong Kong",lang:"yue_HK_#Hant",gender:"female"},{name:"Microsoft Server Speech Text to Speech Voice (en-US, Guy24kRUS)",lang:"en-US",gender:"male"},{name:"Microsoft Server Speech Text to Speech Voice (en-US, Jessa24kRUS)", |  | ||||||
| lang:"en-US",gender:"female"},{name:"Microsoft Server Speech Text to Speech Voice (en-US, JessaRUS)",lang:"en-US",gender:"female"},{name:"Microsoft Server Speech Text to Speech Voice (en-US, ZiraRUS)",lang:"en-US",gender:"female"},{name:"Fallback Bangla Bangladeh Female",lang:"bn-BD",fallbackvoice:!0,timerSpeed:0,service:"g3",gender:"female"},{name:"Fallback Bangla Bangladeh Male",lang:"bn-BD",fallbackvoice:!0,timerSpeed:0,service:"g3",gender:"male"},{name:"Fallback Filipino Female",lang:"fil-PH", |  | ||||||
| fallbackvoice:!0,timerSpeed:0,service:"g3",gender:"female"},{name:"Fallback Filipino Male",lang:"fil-PH",fallbackvoice:!0,timerSpeed:0,service:"g3",gender:"male"},{name:"Fallback Cambodian Khmer Female",lang:"km-KH",fallbackvoice:!0,timerSpeed:0,service:"g3",gender:"female"},{name:"Fallback Cambodian Khmer Male",lang:"km-KH",fallbackvoice:!0,timerSpeed:0,service:"g3",gender:"male"},{name:"Fallback Nepali Female",lang:"ne-NP",fallbackvoice:!0,timerSpeed:0,service:"g3",gender:"female"},{name:"Fallback Sinhala Female", |  | ||||||
| lang:"si-LK",fallbackvoice:!0,timerSpeed:0,service:"g3",gender:"female"},{name:"Fallback Ukrainian Female",lang:"uk-UA",fallbackvoice:!0,timerSpeed:0,service:"g3",gender:"female"},{name:"Fallback Cantonese Hong Kong Female",lang:"yue-HK",fallbackvoice:!0,timerSpeed:0,service:"g3",gender:"female"},{name:"Fallback Cantonese Hong Kong Male",lang:"yue-HK",fallbackvoice:!0,timerSpeed:0,service:"g3",gender:"male"},{name:"Fallback Estonian Male",lang:"et-EE",fallbackvoice:!0,timerSpeed:0,service:"g3",gender:"male"}, |  | ||||||
| {name:"Fallback Bangla India Female",lang:"bn-IN",fallbackvoice:!0,timerSpeed:0,service:"g3",gender:"female"},{name:"Fallback Bangla India Male",lang:"bn-IN",fallbackvoice:!0,timerSpeed:0,service:"g3",gender:"male"},{name:"Fallback French Canadian Female",lang:"fr-CA",fallbackvoice:!0,timerSpeed:0,service:"g3",gender:"female"},{name:"Fallback French Canadian Male",lang:"fr-CA",fallbackvoice:!0,timerSpeed:0,service:"g3",gender:"male"},{name:"Fallback Tamil",lang:"ta",fallbackvoice:!0,service:"g1", |  | ||||||
| gender:"female"}];a.iOS=/(iPad|iPhone|iPod)/g.test(navigator.userAgent);a.iOS9=/(iphone|ipod|ipad).* os 9_/.test(navigator.userAgent.toLowerCase());a.iOS10=/(iphone|ipod|ipad).* os 10_/.test(navigator.userAgent.toLowerCase());a.iOS11=/(iphone|ipod|ipad).* os 11_/.test(navigator.userAgent.toLowerCase());a.iOS9plus=/(iphone|ipod|ipad).* os 10_/.test(navigator.userAgent.toLowerCase())||/(iphone|ipod|ipad).* os 10_/.test(navigator.userAgent.toLowerCase());a.iOS12_0=/(iphone|ipod|ipad).* os 12_0/.test(navigator.userAgent.toLowerCase()); |  | ||||||
| a.iOS12=/(iphone|ipod|ipad).* os 12_/.test(navigator.userAgent.toLowerCase());a.iOS13_0=/(iphone|ipod|ipad).* os 13_0/.test(navigator.userAgent.toLowerCase());a.iOS13=/(iphone|ipod|ipad).* os 13/.test(navigator.userAgent.toLowerCase());a.is_chrome=-1<navigator.userAgent.indexOf("Chrome");a.is_safari=-1<navigator.userAgent.indexOf("Safari");a.is_chrome&&a.is_safari&&(a.is_safari=!1);a.is_opera=!!window.opera||0<=navigator.userAgent.indexOf(" OPR/");a.is_android=-1<navigator.userAgent.toLowerCase().indexOf("android"); |  | ||||||
| a.iOS_initialized=!1;a.iOS9_initialized=!1;a.iOS10_initialized=!1;a.iOS11_initialized=!1;a.cache_ios_voices=[{name:"he-IL",voiceURI:"he-IL",lang:"he-IL"},{name:"th-TH",voiceURI:"th-TH",lang:"th-TH"},{name:"pt-BR",voiceURI:"pt-BR",lang:"pt-BR"},{name:"sk-SK",voiceURI:"sk-SK",lang:"sk-SK"},{name:"fr-CA",voiceURI:"fr-CA",lang:"fr-CA"},{name:"ro-RO",voiceURI:"ro-RO",lang:"ro-RO"},{name:"no-NO",voiceURI:"no-NO",lang:"no-NO"},{name:"fi-FI",voiceURI:"fi-FI",lang:"fi-FI"},{name:"pl-PL",voiceURI:"pl-PL",lang:"pl-PL"}, |  | ||||||
| {name:"de-DE",voiceURI:"de-DE",lang:"de-DE"},{name:"nl-NL",voiceURI:"nl-NL",lang:"nl-NL"},{name:"id-ID",voiceURI:"id-ID",lang:"id-ID"},{name:"tr-TR",voiceURI:"tr-TR",lang:"tr-TR"},{name:"it-IT",voiceURI:"it-IT",lang:"it-IT"},{name:"pt-PT",voiceURI:"pt-PT",lang:"pt-PT"},{name:"fr-FR",voiceURI:"fr-FR",lang:"fr-FR"},{name:"ru-RU",voiceURI:"ru-RU",lang:"ru-RU"},{name:"es-MX",voiceURI:"es-MX",lang:"es-MX"},{name:"zh-HK",voiceURI:"zh-HK",lang:"zh-HK"},{name:"sv-SE",voiceURI:"sv-SE",lang:"sv-SE"},{name:"hu-HU", |  | ||||||
| voiceURI:"hu-HU",lang:"hu-HU"},{name:"zh-TW",voiceURI:"zh-TW",lang:"zh-TW"},{name:"es-ES",voiceURI:"es-ES",lang:"es-ES"},{name:"zh-CN",voiceURI:"zh-CN",lang:"zh-CN"},{name:"nl-BE",voiceURI:"nl-BE",lang:"nl-BE"},{name:"en-GB",voiceURI:"en-GB",lang:"en-GB"},{name:"ar-SA",voiceURI:"ar-SA",lang:"ar-SA"},{name:"ko-KR",voiceURI:"ko-KR",lang:"ko-KR"},{name:"cs-CZ",voiceURI:"cs-CZ",lang:"cs-CZ"},{name:"en-ZA",voiceURI:"en-ZA",lang:"en-ZA"},{name:"en-AU",voiceURI:"en-AU",lang:"en-AU"},{name:"da-DK",voiceURI:"da-DK", |  | ||||||
| lang:"da-DK"},{name:"en-US",voiceURI:"en-US",lang:"en-US"},{name:"en-IE",voiceURI:"en-IE",lang:"en-IE"},{name:"hi-IN",voiceURI:"hi-IN",lang:"hi-IN"},{name:"el-GR",voiceURI:"el-GR",lang:"el-GR"},{name:"ja-JP",voiceURI:"ja-JP",lang:"ja-JP"}];a.cache_ios9_voices=[{name:"Maged",voiceURI:"com.apple.ttsbundle.Maged-compact",lang:"ar-SA",localService:!0,"default":!0},{name:"Zuzana",voiceURI:"com.apple.ttsbundle.Zuzana-compact",lang:"cs-CZ",localService:!0,"default":!0},{name:"Sara",voiceURI:"com.apple.ttsbundle.Sara-compact", |  | ||||||
| lang:"da-DK",localService:!0,"default":!0},{name:"Anna",voiceURI:"com.apple.ttsbundle.Anna-compact",lang:"de-DE",localService:!0,"default":!0},{name:"Melina",voiceURI:"com.apple.ttsbundle.Melina-compact",lang:"el-GR",localService:!0,"default":!0},{name:"Karen",voiceURI:"com.apple.ttsbundle.Karen-compact",lang:"en-AU",localService:!0,"default":!0},{name:"Daniel",voiceURI:"com.apple.ttsbundle.Daniel-compact",lang:"en-GB",localService:!0,"default":!0},{name:"Moira",voiceURI:"com.apple.ttsbundle.Moira-compact", |  | ||||||
| lang:"en-IE",localService:!0,"default":!0},{name:"Samantha (Enhanced)",voiceURI:"com.apple.ttsbundle.Samantha-premium",lang:"en-US",localService:!0,"default":!0},{name:"Samantha",voiceURI:"com.apple.ttsbundle.Samantha-compact",lang:"en-US",localService:!0,"default":!0},{name:"Tessa",voiceURI:"com.apple.ttsbundle.Tessa-compact",lang:"en-ZA",localService:!0,"default":!0},{name:"Monica",voiceURI:"com.apple.ttsbundle.Monica-compact",lang:"es-ES",localService:!0,"default":!0},{name:"Paulina",voiceURI:"com.apple.ttsbundle.Paulina-compact", |  | ||||||
| lang:"es-MX",localService:!0,"default":!0},{name:"Satu",voiceURI:"com.apple.ttsbundle.Satu-compact",lang:"fi-FI",localService:!0,"default":!0},{name:"Amelie",voiceURI:"com.apple.ttsbundle.Amelie-compact",lang:"fr-CA",localService:!0,"default":!0},{name:"Thomas",voiceURI:"com.apple.ttsbundle.Thomas-compact",lang:"fr-FR",localService:!0,"default":!0},{name:"Carmit",voiceURI:"com.apple.ttsbundle.Carmit-compact",lang:"he-IL",localService:!0,"default":!0},{name:"Lekha",voiceURI:"com.apple.ttsbundle.Lekha-compact", |  | ||||||
| lang:"hi-IN",localService:!0,"default":!0},{name:"Mariska",voiceURI:"com.apple.ttsbundle.Mariska-compact",lang:"hu-HU",localService:!0,"default":!0},{name:"Damayanti",voiceURI:"com.apple.ttsbundle.Damayanti-compact",lang:"id-ID",localService:!0,"default":!0},{name:"Alice",voiceURI:"com.apple.ttsbundle.Alice-compact",lang:"it-IT",localService:!0,"default":!0},{name:"Kyoko",voiceURI:"com.apple.ttsbundle.Kyoko-compact",lang:"ja-JP",localService:!0,"default":!0},{name:"Yuna",voiceURI:"com.apple.ttsbundle.Yuna-compact", |  | ||||||
| lang:"ko-KR",localService:!0,"default":!0},{name:"Ellen",voiceURI:"com.apple.ttsbundle.Ellen-compact",lang:"nl-BE",localService:!0,"default":!0},{name:"Xander",voiceURI:"com.apple.ttsbundle.Xander-compact",lang:"nl-NL",localService:!0,"default":!0},{name:"Nora",voiceURI:"com.apple.ttsbundle.Nora-compact",lang:"no-NO",localService:!0,"default":!0},{name:"Zosia",voiceURI:"com.apple.ttsbundle.Zosia-compact",lang:"pl-PL",localService:!0,"default":!0},{name:"Luciana",voiceURI:"com.apple.ttsbundle.Luciana-compact", |  | ||||||
| lang:"pt-BR",localService:!0,"default":!0},{name:"Joana",voiceURI:"com.apple.ttsbundle.Joana-compact",lang:"pt-PT",localService:!0,"default":!0},{name:"Ioana",voiceURI:"com.apple.ttsbundle.Ioana-compact",lang:"ro-RO",localService:!0,"default":!0},{name:"Milena",voiceURI:"com.apple.ttsbundle.Milena-compact",lang:"ru-RU",localService:!0,"default":!0},{name:"Laura",voiceURI:"com.apple.ttsbundle.Laura-compact",lang:"sk-SK",localService:!0,"default":!0},{name:"Alva",voiceURI:"com.apple.ttsbundle.Alva-compact", |  | ||||||
| lang:"sv-SE",localService:!0,"default":!0},{name:"Kanya",voiceURI:"com.apple.ttsbundle.Kanya-compact",lang:"th-TH",localService:!0,"default":!0},{name:"Yelda",voiceURI:"com.apple.ttsbundle.Yelda-compact",lang:"tr-TR",localService:!0,"default":!0},{name:"Ting-Ting",voiceURI:"com.apple.ttsbundle.Ting-Ting-compact",lang:"zh-CN",localService:!0,"default":!0},{name:"Sin-Ji",voiceURI:"com.apple.ttsbundle.Sin-Ji-compact",lang:"zh-HK",localService:!0,"default":!0},{name:"Mei-Jia",voiceURI:"com.apple.ttsbundle.Mei-Jia-compact", |  | ||||||
| lang:"zh-TW",localService:!0,"default":!0}];a.cache_ios10_voices=[{name:"Maged",voiceURI:"com.apple.ttsbundle.Maged-compact",lang:"ar-SA"},{name:"Zuzana",voiceURI:"com.apple.ttsbundle.Zuzana-compact",lang:"cs-CZ"},{name:"Sara",voiceURI:"com.apple.ttsbundle.Sara-compact",lang:"da-DK"},{name:"Anna",voiceURI:"com.apple.ttsbundle.Anna-compact",lang:"de-DE"},{name:"Helena",voiceURI:"com.apple.ttsbundle.siri_female_de-DE_compact",lang:"de-DE"},{name:"Martin",voiceURI:"com.apple.ttsbundle.siri_male_de-DE_compact", |  | ||||||
| lang:"de-DE"},{name:"Nikos (Enhanced)",voiceURI:"com.apple.ttsbundle.Nikos-premium",lang:"el-GR"},{name:"Melina",voiceURI:"com.apple.ttsbundle.Melina-compact",lang:"el-GR"},{name:"Nikos",voiceURI:"com.apple.ttsbundle.Nikos-compact",lang:"el-GR"},{name:"Catherine",voiceURI:"com.apple.ttsbundle.siri_female_en-AU_compact",lang:"en-AU"},{name:"Gordon",voiceURI:"com.apple.ttsbundle.siri_male_en-AU_compact",lang:"en-AU"},{name:"Karen",voiceURI:"com.apple.ttsbundle.Karen-compact",lang:"en-AU"},{name:"Daniel (Enhanced)", |  | ||||||
| voiceURI:"com.apple.ttsbundle.Daniel-premium",lang:"en-GB"},{name:"Arthur",voiceURI:"com.apple.ttsbundle.siri_male_en-GB_compact",lang:"en-GB"},{name:"Daniel",voiceURI:"com.apple.ttsbundle.Daniel-compact",lang:"en-GB"},{name:"Martha",voiceURI:"com.apple.ttsbundle.siri_female_en-GB_compact",lang:"en-GB"},{name:"Moira",voiceURI:"com.apple.ttsbundle.Moira-compact",lang:"en-IE"},{name:"Nicky (Enhanced)",voiceURI:"com.apple.ttsbundle.siri_female_en-US_premium",lang:"en-US"},{name:"Samantha (Enhanced)", |  | ||||||
| voiceURI:"com.apple.ttsbundle.Samantha-premium",lang:"en-US"},{name:"Aaron",voiceURI:"com.apple.ttsbundle.siri_male_en-US_compact",lang:"en-US"},{name:"Fred",voiceURI:"com.apple.speech.synthesis.voice.Fred",lang:"en-US"},{name:"Nicky",voiceURI:"com.apple.ttsbundle.siri_female_en-US_compact",lang:"en-US"},{name:"Samantha",voiceURI:"com.apple.ttsbundle.Samantha-compact",lang:"en-US"},{name:"Tessa",voiceURI:"com.apple.ttsbundle.Tessa-compact",lang:"en-ZA"},{name:"Monica",voiceURI:"com.apple.ttsbundle.Monica-compact", |  | ||||||
| lang:"es-ES"},{name:"Paulina",voiceURI:"com.apple.ttsbundle.Paulina-compact",lang:"es-MX"},{name:"Satu",voiceURI:"com.apple.ttsbundle.Satu-compact",lang:"fi-FI"},{name:"Amelie",voiceURI:"com.apple.ttsbundle.Amelie-compact",lang:"fr-CA"},{name:"Daniel",voiceURI:"com.apple.ttsbundle.siri_male_fr-FR_compact",lang:"fr-FR"},{name:"Marie",voiceURI:"com.apple.ttsbundle.siri_female_fr-FR_compact",lang:"fr-FR"},{name:"Thomas",voiceURI:"com.apple.ttsbundle.Thomas-compact",lang:"fr-FR"},{name:"Carmit",voiceURI:"com.apple.ttsbundle.Carmit-compact", |  | ||||||
| lang:"he-IL"},{name:"Lekha",voiceURI:"com.apple.ttsbundle.Lekha-compact",lang:"hi-IN"},{name:"Mariska",voiceURI:"com.apple.ttsbundle.Mariska-compact",lang:"hu-HU"},{name:"Damayanti",voiceURI:"com.apple.ttsbundle.Damayanti-compact",lang:"id-ID"},{name:"Alice",voiceURI:"com.apple.ttsbundle.Alice-compact",lang:"it-IT"},{name:"Hattori",voiceURI:"com.apple.ttsbundle.siri_male_ja-JP_compact",lang:"ja-JP"},{name:"Kyoko",voiceURI:"com.apple.ttsbundle.Kyoko-compact",lang:"ja-JP"},{name:"O-ren",voiceURI:"com.apple.ttsbundle.siri_female_ja-JP_compact", |  | ||||||
| lang:"ja-JP"},{name:"Yuna",voiceURI:"com.apple.ttsbundle.Yuna-compact",lang:"ko-KR"},{name:"Ellen",voiceURI:"com.apple.ttsbundle.Ellen-compact",lang:"nl-BE"},{name:"Xander",voiceURI:"com.apple.ttsbundle.Xander-compact",lang:"nl-NL"},{name:"Nora",voiceURI:"com.apple.ttsbundle.Nora-compact",lang:"no-NO"},{name:"Zosia",voiceURI:"com.apple.ttsbundle.Zosia-compact",lang:"pl-PL"},{name:"Luciana",voiceURI:"com.apple.ttsbundle.Luciana-compact",lang:"pt-BR"},{name:"Joana",voiceURI:"com.apple.ttsbundle.Joana-compact", |  | ||||||
| lang:"pt-PT"},{name:"Ioana",voiceURI:"com.apple.ttsbundle.Ioana-compact",lang:"ro-RO"},{name:"Milena",voiceURI:"com.apple.ttsbundle.Milena-compact",lang:"ru-RU"},{name:"Laura",voiceURI:"com.apple.ttsbundle.Laura-compact",lang:"sk-SK"},{name:"Alva",voiceURI:"com.apple.ttsbundle.Alva-compact",lang:"sv-SE"},{name:"Kanya",voiceURI:"com.apple.ttsbundle.Kanya-compact",lang:"th-TH"},{name:"Yelda",voiceURI:"com.apple.ttsbundle.Yelda-compact",lang:"tr-TR"},{name:"Li-mu",voiceURI:"com.apple.ttsbundle.siri_male_zh-CN_compact", |  | ||||||
| lang:"zh-CN"},{name:"Ting-Ting",voiceURI:"com.apple.ttsbundle.Ting-Ting-compact",lang:"zh-CN"},{name:"Yu-shu",voiceURI:"com.apple.ttsbundle.siri_female_zh-CN_compact",lang:"zh-CN"},{name:"Sin-Ji",voiceURI:"com.apple.ttsbundle.Sin-Ji-compact",lang:"zh-HK"},{name:"Mei-Jia",voiceURI:"com.apple.ttsbundle.Mei-Jia-compact",lang:"zh-TW"}];a.cache_ios11_voices=[{name:"Maged",voiceURI:"com.apple.ttsbundle.Maged-compact",lang:"ar-SA"},{name:"Zuzana",voiceURI:"com.apple.ttsbundle.Zuzana-compact",lang:"cs-CZ"}, |  | ||||||
| {name:"Sara",voiceURI:"com.apple.ttsbundle.Sara-compact",lang:"da-DK"},{name:"Anna",voiceURI:"com.apple.ttsbundle.Anna-compact",lang:"de-DE"},{name:"Helena",voiceURI:"com.apple.ttsbundle.siri_female_de-DE_compact",lang:"de-DE"},{name:"Martin",voiceURI:"com.apple.ttsbundle.siri_male_de-DE_compact",lang:"de-DE"},{name:"Melina",voiceURI:"com.apple.ttsbundle.Melina-compact",lang:"el-GR"},{name:"Catherine",voiceURI:"com.apple.ttsbundle.siri_female_en-AU_compact",lang:"en-AU"},{name:"Gordon",voiceURI:"com.apple.ttsbundle.siri_male_en-AU_compact", |  | ||||||
| lang:"en-AU"},{name:"Karen",voiceURI:"com.apple.ttsbundle.Karen-compact",lang:"en-AU"},{name:"Arthur",voiceURI:"com.apple.ttsbundle.siri_male_en-GB_compact",lang:"en-GB"},{name:"Daniel",voiceURI:"com.apple.ttsbundle.Daniel-compact",lang:"en-GB"},{name:"Martha",voiceURI:"com.apple.ttsbundle.siri_female_en-GB_compact",lang:"en-GB"},{name:"Moira",voiceURI:"com.apple.ttsbundle.Moira-compact",lang:"en-IE"},{name:"Aaron",voiceURI:"com.apple.ttsbundle.siri_male_en-US_compact",lang:"en-US"},{name:"Fred", |  | ||||||
| voiceURI:"com.apple.speech.synthesis.voice.Fred",lang:"en-US"},{name:"Nicky",voiceURI:"com.apple.ttsbundle.siri_female_en-US_compact",lang:"en-US"},{name:"Samantha",voiceURI:"com.apple.ttsbundle.Samantha-compact",lang:"en-US"},{name:"Tessa",voiceURI:"com.apple.ttsbundle.Tessa-compact",lang:"en-ZA"},{name:"Monica",voiceURI:"com.apple.ttsbundle.Monica-compact",lang:"es-ES"},{name:"Paulina",voiceURI:"com.apple.ttsbundle.Paulina-compact",lang:"es-MX"},{name:"Satu",voiceURI:"com.apple.ttsbundle.Satu-compact", |  | ||||||
| lang:"fi-FI"},{name:"Amelie",voiceURI:"com.apple.ttsbundle.Amelie-compact",lang:"fr-CA"},{name:"Daniel",voiceURI:"com.apple.ttsbundle.siri_male_fr-FR_compact",lang:"fr-FR"},{name:"Marie",voiceURI:"com.apple.ttsbundle.siri_female_fr-FR_compact",lang:"fr-FR"},{name:"Thomas",voiceURI:"com.apple.ttsbundle.Thomas-compact",lang:"fr-FR"},{name:"Carmit",voiceURI:"com.apple.ttsbundle.Carmit-compact",lang:"he-IL"},{name:"Lekha",voiceURI:"com.apple.ttsbundle.Lekha-compact",lang:"hi-IN"},{name:"Mariska",voiceURI:"com.apple.ttsbundle.Mariska-compact", |  | ||||||
| lang:"hu-HU"},{name:"Damayanti",voiceURI:"com.apple.ttsbundle.Damayanti-compact",lang:"id-ID"},{name:"Alice",voiceURI:"com.apple.ttsbundle.Alice-compact",lang:"it-IT"},{name:"Hattori",voiceURI:"com.apple.ttsbundle.siri_male_ja-JP_compact",lang:"ja-JP"},{name:"Kyoko",voiceURI:"com.apple.ttsbundle.Kyoko-compact",lang:"ja-JP"},{name:"O-ren",voiceURI:"com.apple.ttsbundle.siri_female_ja-JP_compact",lang:"ja-JP"},{name:"Yuna",voiceURI:"com.apple.ttsbundle.Yuna-compact",lang:"ko-KR"},{name:"Ellen",voiceURI:"com.apple.ttsbundle.Ellen-compact", |  | ||||||
| lang:"nl-BE"},{name:"Xander",voiceURI:"com.apple.ttsbundle.Xander-compact",lang:"nl-NL"},{name:"Nora",voiceURI:"com.apple.ttsbundle.Nora-compact",lang:"no-NO"},{name:"Zosia",voiceURI:"com.apple.ttsbundle.Zosia-compact",lang:"pl-PL"},{name:"Luciana",voiceURI:"com.apple.ttsbundle.Luciana-compact",lang:"pt-BR"},{name:"Joana",voiceURI:"com.apple.ttsbundle.Joana-compact",lang:"pt-PT"},{name:"Ioana",voiceURI:"com.apple.ttsbundle.Ioana-compact",lang:"ro-RO"},{name:"Milena",voiceURI:"com.apple.ttsbundle.Milena-compact", |  | ||||||
| lang:"ru-RU"},{name:"Laura",voiceURI:"com.apple.ttsbundle.Laura-compact",lang:"sk-SK"},{name:"Alva",voiceURI:"com.apple.ttsbundle.Alva-compact",lang:"sv-SE"},{name:"Kanya",voiceURI:"com.apple.ttsbundle.Kanya-compact",lang:"th-TH"},{name:"Yelda",voiceURI:"com.apple.ttsbundle.Yelda-compact",lang:"tr-TR"},{name:"Li-mu",voiceURI:"com.apple.ttsbundle.siri_male_zh-CN_compact",lang:"zh-CN"},{name:"Ting-Ting",voiceURI:"com.apple.ttsbundle.Ting-Ting-compact",lang:"zh-CN"},{name:"Yu-shu",voiceURI:"com.apple.ttsbundle.siri_female_zh-CN_compact", |  | ||||||
| lang:"zh-CN"},{name:"Sin-Ji",voiceURI:"com.apple.ttsbundle.Sin-Ji-compact",lang:"zh-HK"},{name:"Mei-Jia",voiceURI:"com.apple.ttsbundle.Mei-Jia-compact",lang:"zh-TW"}];a.systemvoices=null;a.CHARACTER_LIMIT=100;a.VOICESUPPORT_ATTEMPTLIMIT=5;a.voicesupport_attempts=0;a.fallbackMode=!1;a.WORDS_PER_MINUTE=130;a.fallback_audio=null;a.fallback_playbackrate=1;a.def_fallback_playbackrate=a.fallback_playbackrate;a.fallback_audiopool=[];a.msgparameters=null;a.timeoutId=null;a.OnLoad_callbacks=[];a.useTimer= |  | ||||||
| !1;a.utterances=[];a.userInteractionEvents=["mousedown","mouseup","mousewheel","keydown"];a.fallbackBufferLength=5;a.iOS&&(a.fallbackBufferLength=2);var q=null,z=1;a.tstCompiled=function(){return!/param/.test(function(b){})};a.fallbackServicePath="undefined"!=typeof rvApiEndpoint&&rvApiEndpoint?rvApiEndpoint:"https://code.responsivevoice.org/"+(a.tstCompiled()?"":"develop/")+"getvoice.php";a.default_rv=a.responsivevoices[0];a.debug=!1;a.rvsMapped=!1;a.forcedFallbackMode=!1;a.speechAllowedByUser=!0; |  | ||||||
| a.enableEstimationTimeout=!0;a.analytics={characterCount:0};a.log=function(b){a.debug&&console.log(b)};a.init=function(){a.is_wordpress=C();a.is_bundle=p();"undefined"==typeof rvApiKey&&console.error("ResponsiveVoice missing API key. See https://responsivevoice.org/register?devtools="+encodeURIComponent(window.location.href));if(a.is_android||a.iOS||a.is_safari)a.useTimer=!0;a.is_opera||"undefined"===typeof speechSynthesis?(console.log("RV: Voice synthesis not supported"),a.enableFallbackMode()): |  | ||||||
| setTimeout(function(){var b=setInterval(function(){var c=window.speechSynthesis.getVoices();0!=c.length||null!=a.systemvoices&&0!=a.systemvoices.length?(console.log("RV: Voice support ready"),a.systemVoicesReady(c),clearInterval(b)):(console.log("Voice support NOT ready"),a.voicesupport_attempts++,a.voicesupport_attempts>a.VOICESUPPORT_ATTEMPTLIMIT&&(clearInterval(b),null!=window.speechSynthesis?a.iOS?(a.iOS11||a.iOS12||a.iOS13_0||a.iOS13?a.systemVoicesReady(a.cache_ios11_voices):a.iOS10?a.systemVoicesReady(a.cache_ios10_voices): |  | ||||||
| a.iOS9?a.systemVoicesReady(a.cache_ios9_voices):a.systemVoicesReady(a.cache_ios_voices),console.log("RV: Voice support ready (cached)")):(console.log("RV: speechSynthesis present but no system voices found"),a.enableFallbackMode()):a.enableFallbackMode()))},100)},100);(a.iOS||a.is_android||a.is_safari)&&a.enableWindowClickHook();a.Dispatch("OnLoad")};a.systemVoicesReady=function(b){a.systemvoices=b;a.mapRVs();null!=a.OnVoiceReady&&a.OnVoiceReady.call();a.Dispatch("OnReady");window.hasOwnProperty("dispatchEvent")&& |  | ||||||
| window.dispatchEvent(new Event("ResponsiveVoice_OnReady"))};a.enableFallbackMode=function(){a.fallbackMode=!0;a.forcedFallbackMode=!0;console.log("RV: Enabling fallback mode");a.mapRVs();null!=a.OnVoiceReady&&a.OnVoiceReady.call();a.Dispatch("OnReady");window.hasOwnProperty("dispatchEvent")&&window.dispatchEvent(new Event("ResponsiveVoice_OnReady"));a.Dispatch("OnServiceSwitched")};a.getVoices=function(){for(var b=[],c=0;c<a.responsivevoices.length;c++){var d=a.responsivevoices[c];!0!==d.deprecated&& |  | ||||||
| b.push({name:d.name})}return b};a.speak=function(b,c,d){if(null==b)a.log("No text provided");else if(a.initializePermissionsTimeout&&clearTimeout(a.initializePermissionsTimeout),a.rvsMapped){var h=null;if(a.isPlaying())a.log("Cancelling previous speech"),a.cancel(),setTimeout(function(){a.speak(b,c,d)},50);else{function F(x){-1!=x.search(/[\u3002]/gm)?x.split(/[\u3002]/).filter(function(r){r&&k.push(r)}):k.push(x)}if(null==c){var e=a.default_rv;a.setDefaultVoice(e.name)}else e=a.getResponsiveVoice(c); |  | ||||||
| if(e){!0===e.deprecated&&console.warn('ResponsiveVoice: Voice "'+e.name+'" is deprecated; it might not always be the right gender, and could be removed in future releases');var g={};if(null!=e.mappedProfile)g=e.mappedProfile;else if(g.systemvoice=a.getMatchedVoice(e),g.collectionvoice={},null==g.systemvoice){console.log("RV: ERROR: No voice found for: "+c);return}b=y(b,g);b=b.replace(/["`]/gm,"'");a.msgparameters=d||{};a.msgtext=b;a.msgvoicename=c;a.onstartFired=!1;var k=[];if(b.length>a.CHARACTER_LIMIT){for(var f= |  | ||||||
| b=w(b);f.length>a.CHARACTER_LIMIT;){e=f.search(/([\u3002:!\u00a1?\u00bf;\(\)\[\]\u2014\u00ab\u00bb\n]+|\.[^0-9]+)/);var l="";if(-1==e||e>=a.CHARACTER_LIMIT)e=f.search(/,[^0-9]+/);if((-1==e||e>=a.CHARACTER_LIMIT)&&-1!=f.search(" ")){var u=f.split(" ");for(e=0;e<u.length;e++){if(l.length+u[e].length+1>a.CHARACTER_LIMIT){u[e].length>=a.CHARACTER_LIMIT&&(l+=u[e].substr(0,a.CHARACTER_LIMIT-l.length-1));break}l+=(0!=e?" ":"")+u[e]}}else{if(-1==e||e>=a.CHARACTER_LIMIT)e=a.CHARACTER_LIMIT-1;l=f.substr(0, |  | ||||||
| e+1)}f=f.substr(l.length,f.length-l.length);k.push(l)}0<f.length&&F(f)}else F(b);console.log(k);a.multipartText=k;if(a.checkSpeechAllowed()){a.fallbackMode&&0<a.fallback_audiopool.length&&a.clearFallbackPool();a.msgprofile=g;a.log("Voice picked: "+a.msgprofile.systemvoice.name);a.utterances=[];a.fallbackChunks=[];for(e=0;e<k.length;e++)if(!a.fallbackMode&&a.getServiceEnabled(a.services.NATIVE_TTS))a.log("Using SpeechSynthesis"),h=a.services.NATIVE_TTS,f=new SpeechSynthesisUtterance,f.voiceURI=g.systemvoice.voiceURI, |  | ||||||
| f.volume=a.selectBest([g.collectionvoice.volume,g.systemvoice.volume,1]),f.rate=a.selectBest([a.iOS9plus?1:null,g.collectionvoice.rate,g.systemvoice.rate,z]),f.pitch=a.selectBest([g.collectionvoice.pitch,g.systemvoice.pitch,1]),f.text=k[e],f.lang=a.selectBest([g.collectionvoice.lang,g.systemvoice.lang]),f.rvIndex=e,f.rvTotal=k.length,0==e&&(f.onstart=a.speech_onstart),a.msgparameters.onendcalled=!1,null!=d?(f.voice="undefined"!==typeof d.voice?d.voice:g.systemvoice,e<k.length-1&&1<k.length?(f.onend= |  | ||||||
| a.onPartEnd,f.hasOwnProperty("addEventListener")&&f.addEventListener("end",a.onPartEnd)):(f.onend=a.speech_onend,f.hasOwnProperty("addEventListener")&&f.addEventListener("end",a.speech_onend)),f.onerror=d.onerror||function(x){a.log("RV: Unknown Error");a.log(x);"not-allowed"===x.error&&(a.speechSynthesisNotAllowedError=!0,a.speak(b,c,d))},d.rate=a.validateParameters(d,"rate"),d.pitch=a.validateParameters(d,"pitch"),d.volume=a.validateParameters(d,"volume"),f.onpause=d.onpause,f.onresume=d.onresume, |  | ||||||
| f.onmark=d.onmark,f.onboundary=d.onboundary||a.onboundary,f.pitch=null!=d.pitch?d.pitch:f.pitch,f.rate=a.iOS?(null!=d.rate?d.rate*d.rate:1)*f.rate:(null!=d.rate?d.rate:z)*f.rate,f.volume=null!=d.volume?d.volume:f.volume):(a.log("No Params received for current Utterance"),f.voice=g.systemvoice,d=d||{},f.onend=a.speech_onend,f.onboundary=a.onboundary,f.onerror=function(x){a.log("RV: Unknown Error");a.log(x);"not-allowed"===x.error&&(a.speechSynthesisNotAllowedError=!0,a.speak(b,c,d))}),a.utterances.push(f), |  | ||||||
| 0==e&&(a.currentMsg=f),console.log(f),a.tts_speak(f);else if(a.fallbackMode&&a.getServiceEnabled(a.services.FALLBACK_AUDIO)){h=a.services.FALLBACK_AUDIO;a.fallback_playbackrate=a.def_fallback_playbackrate;f=a.selectBest([g.collectionvoice.pitch,g.systemvoice.pitch,1]);l=a.selectBest([a.iOS9plus?1:null,g.collectionvoice.rate,g.systemvoice.rate,1]);u=a.selectBest([g.collectionvoice.volume,g.systemvoice.volume,1]);if(null!=d){f*=null!=d.pitch?d.pitch:1;l*=null!=d.rate?d.rate:1;u*=null!=d.volume?d.volume: |  | ||||||
| 1;var D=d.extraParams||null}f/=2;l/=2;u*=2;f=Math.min(Math.max(f,0),1);l=Math.min(Math.max(l,0),1);u=Math.min(Math.max(u,0),1);var G="?t="+encodeURIComponent(k[e])+"&tl="+(g.collectionvoice.lang||g.systemvoice.lang||"en-US")+"&sv="+(g.collectionvoice.service||g.systemvoice.service||"")+"&vn="+(g.collectionvoice.voicename||g.systemvoice.voicename||"")+"&pitch="+f.toString()+"&rate="+l.toString()+"&vol="+u.toString();"undefined"!=typeof rvApiEndpoint&&rvApiEndpoint&&(G="?text="+encodeURIComponent(k[e])+ |  | ||||||
| "&lang="+(g.collectionvoice.lang||g.systemvoice.lang||"en-US")+"&engine="+(g.collectionvoice.service||g.systemvoice.service||"")+"&name="+(g.collectionvoice.voicename||g.systemvoice.voicename||"")+"&pitch="+f.toString()+"&rate="+l.toString()+"&volume="+u.toString());f=a.fallbackServicePath+G;"undefined"!=typeof rvApiKey&&(f+="&key="+rvApiKey);"undefined"==typeof rvApiKey&&a.is_bundle&&(f+="&key=FQ9r4hgY");"undefined"==typeof rvApiKey&&a.is_wordpress&&(f+="&key=HY7lTyiS");void 0!==g.collectionvoice.gender&& |  | ||||||
| (f+="&gender="+g.collectionvoice.gender);D&&(f+="&extraParams="+JSON.stringify(D));a.fallbackChunks.push({text:k[e],url:f,audio:null})}a.fallbackMode&&a.getServiceEnabled(a.services.FALLBACK_AUDIO)&&(a.fallbackChunkIndex=0,a.fallback_startPart());a.log("Service used: "+h)}else a.scheduledSpeak={text:b,voicename:c,parameters:d}}else console.error("Selected voice does not exist: "+c),a.Dispatch("OnMissingVoiceError",{voice:c})}}else setTimeout(function(){a.speak(b,c,d)},15)};a.startTimeout=function(b, |  | ||||||
| c){var d=a.msgprofile.collectionvoice.timerSpeed;null==a.msgprofile.collectionvoice.timerSpeed&&(d=1);0>=d||(a.timeoutId=setTimeout(c,a.getEstimatedTimeLength(b,d)),a.log("Timeout ID: "+a.timeoutId))};a.checkAndCancelTimeout=function(){null!=a.timeoutId&&(clearTimeout(a.timeoutId),a.timeoutId=null)};a.speech_timedout=function(){a.cancel();a.cancelled=!1;a.speech_onend()};a.speech_onend=function(){a.checkAndCancelTimeout();!0===a.cancelled?a.cancelled=!1:(a.log("on end fired"),null!=a.msgparameters&& |  | ||||||
| null!=a.msgparameters.onend&&1!=a.msgparameters.onendcalled&&(a.log("Speech on end called  -"+a.msgtext),a.msgparameters.onendcalled=!0,a.msgparameters.onend()))};a.speech_onstart=function(){if(!a.onstartFired&&(a.onstartFired=!0,a.log("Speech start"),a.enableEstimationTimeout&&a.useTimer&&(a.fallbackMode||a.startTimeout(a.msgtext,a.speech_timedout)),a.msgparameters.onendcalled=!1,null!=a.msgparameters&&null!=a.msgparameters.onstart))a.msgparameters.onstart()};a.fallback_startPart=function(){0==a.fallbackChunkIndex&& |  | ||||||
| a.speech_onstart();a.fallback_updateChunksBuffer();a.fallback_audio=a.fallbackChunks[a.fallbackChunkIndex].audio;null==a.fallback_audio?a.log("RV: Fallback Audio is not available"):(function(){var b=a.fallback_audio;setTimeout(function(){b.playbackRate=a.fallback_playbackrate},50);b.onloadedmetadata=function(){b.playbackRate=a.fallback_playbackrate};var c=function(h){setTimeout(function(){if(0==h.currentTime){a.log("Audio chunk not playing. Trying to recover. Disabling time estimation");a.enableEstimationTimeout= |  | ||||||
| !1;a.checkAndCancelTimeout();h.load();var e=function(){h.play();h.removeEventListener("canplaythrough",e)};h.addEventListener("canplaythrough",e,!1)}},700)};if(2<=b.readyState)b.play(),c(b);else{var d=function(){b.play();b.removeEventListener("canplaythrough",d)};b.addEventListener("canplaythrough",d,!1)}}(),a.fallback_audio.onerror=function(b){function c(){if(this.readyState==this.DONE&&200!==this.status)switch(this.status){case 400:console.error("ResponsiveVoice audio could not be loaded. Invalid parameters."); |  | ||||||
| break;case 403:console.error("ResponsiveVoice invalid API key. See https://responsivevoice.org/register?devtools="+encodeURIComponent(window.location.href));break;default:console.error("ResponsiveVoice audio could not be loaded. There is an issue connecting your browser to the API endpoint.")}}switch(b.target.error.code){case b.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED:var d=new XMLHttpRequest;d.open("GET",b.target.src,!0);d.send();d.onreadystatechange=c;break;default:console.error("ResponsiveVoice: an unknown error occurred.")}}, |  | ||||||
| a.fallback_audio.addEventListener("ended",a.fallback_finishPart),a.enableEstimationTimeout&&a.useTimer&&a.startTimeout(a.multipartText[a.fallbackChunkIndex],a.fallback_finishPart))};a.isFallbackAudioPlaying=function(){var b;for(b=0;b<a.fallback_audiopool.length;b++){var c=a.fallback_audiopool[b];if(!c.paused&&!c.ended&&c.currentTime!=c.duration)return!0}return!1};a.fallback_finishPart=function(b){a.isFallbackAudioPlaying()?(a.checkAndCancelTimeout(),a.timeoutId=setTimeout(a.fallback_finishPart,1E3* |  | ||||||
| (a.fallback_audio.duration-a.fallback_audio.currentTime))):(a.checkAndCancelTimeout(),a.fallbackChunkIndex<a.fallbackChunks.length-1?(a.fallbackChunkIndex++,a.fallback_startPart()):a.speech_onend())};a.cancel=function(){a.checkAndCancelTimeout();a.fallbackMode?(null!=a.fallback_audio&&a.fallback_audio.pause(),a.clearFallbackPool()):(a.cancelled=!0,speechSynthesis.cancel())};a.voiceSupport=function(){return"speechSynthesis"in window};a.OnFinishedPlaying=function(b){if(null!=a.msgparameters&&null!= |  | ||||||
| a.msgparameters.onend)a.msgparameters.onend()};a.setDefaultVoice=function(b){if(a.rvsMapped){var c=a.getResponsiveVoice(b);null!=c&&(a.default_rv=c)}else setTimeout(function(){a.setDefaultVoice(b)},15)};a.setDefaultRate=function(b){var c=b;b=parseFloat(b);isNaN(b)?console.error("[responsiveVoice.setDefaultRate] invalid argument: "+c.toString()):0===b?console.error("[responsiveVoice.setDefaultRate] rate must be > 0"):1.5<b?console.error("[responsiveVoice.setDefaultRate] rate must be <= 1.5"):z=b}; |  | ||||||
| a.mapRVs=function(){if("object"==typeof navigator){var b,c="anguage";var d=navigator;d=(b=d["l"+c+"s"],b&&b.length?b:(c=d["l"+c]||d["browserL"+c]||d["userL"+c])?[c]:c)}else d=void 0;b=d[0];for(c=0;c<a.responsivevoices.length;c++){d=a.responsivevoices[c];for(var h=0;h<d.voiceIDs.length;h++){var e=a.voicecollection[d.voiceIDs[h]];if(1!=e.fallbackvoice){var g=a.getSystemVoice(e.name);a.forcedFallbackMode&&(g=null);a.iOS12_0&&d.lang.toLowerCase()!=b.toLowerCase()&&d.lang.toLowerCase().split("-")[0]!= |  | ||||||
| b.toLowerCase()&&(g=null);if(null!=g){d.mappedProfile={systemvoice:g,collectionvoice:e};break}}else{d.mappedProfile={systemvoice:{},collectionvoice:e};break}}}a.rvsMapped=!0};a.getMatchedVoice=function(b){for(var c=0;c<b.voiceIDs.length;c++){var d=a.getSystemVoice(a.voicecollection[b.voiceIDs[c]].name);if(null!=d)return d}return null};a.getSystemVoice=function(b){var c=String.fromCharCode(160);var d=b.replace(new RegExp("\\s+|"+c,"g"),"");if("undefined"===typeof a.systemvoices||null===a.systemvoices)return null; |  | ||||||
| for(var h=0;h<a.systemvoices.length;h++)if(0===a.systemvoices[h].name.localeCompare(b)||0===a.systemvoices[h].name.replace(new RegExp("\\s+|"+c,"g"),"").replace(/ *\([^)]*\) */g,"").localeCompare(d))return a.systemvoices[h];return null};a.getResponsiveVoice=function(b){for(var c=0;c<a.responsivevoices.length;c++)if(a.responsivevoices[c].name==b)return b=a.fallbackMode,a.fallbackMode=!0===a.responsivevoices[c].mappedProfile.collectionvoice.fallbackvoice||!0===a.forcedFallbackMode?!0:!1,b!=a.fallbackMode&& |  | ||||||
| (a.mapRVs(),a.Dispatch("OnServiceSwitched")),a.responsivevoices[c];return null};a.Dispatch=function(b,c){c=void 0!==c?c:null;if(a.hasOwnProperty(b+"_callbacks")&&null!=a[b+"_callbacks"]&&0<a[b+"_callbacks"].length){for(var d=a[b+"_callbacks"],h=0;h<d.length;h++)d[h](c);return!0}var e=b+"_callbacks_timeout",g=b+"_callbacks_timeoutCount";a.hasOwnProperty(e)||(a[g]=10,a[e]=setInterval(function(){--a[g];(a.Dispatch(b,c)||0>a[g])&&clearTimeout(a[e])},50));return!1};a.AddEventListener=function(b,c){a.hasOwnProperty(b+ |  | ||||||
| "_callbacks")||(a[b+"_callbacks"]=[]);a[b+"_callbacks"].push(c)};a.addEventListener=a.AddEventListener;a.RemoveEventListener=function(b,c){a[b+"_callbacks"]&&-1!=a[b+"_callbacks"].indexOf(c)&&a[b+"_callbacks"].splice(a[b+"_callbacks"].indexOf(c),1)};a.clickEvent=function(){a.log("Click event");a.click_event_detected=!0;a.initializePermissionsTimeout=setTimeout(a.initializePermissions,5);a.userInteractionEvents.forEach(function(b){window.removeEventListener(b,a.clickEvent,!1)});a.Dispatch("OnClickEvent")}; |  | ||||||
| a.initializePermissions=function(){if(a.iOS&&!a.iOS_initialized){a.log("Initializing iOS click event");if("undefined"!==typeof speechSynthesis){var b=new SpeechSynthesisUtterance(" ");speechSynthesis.speak(b)}a.iOS_initialized=!0}a.is_android&&!a.android_initialized&&(a.log("Initializing Android click event"),"undefined"!==typeof speechSynthesis&&(b=new SpeechSynthesisUtterance(" "),speechSynthesis.speak(b)),a.android_initialized=!0);a.initFallbackPool()};a.isPlaying=function(){return a.fallbackMode? |  | ||||||
| null!=a.fallback_audio&&!a.fallback_audio.ended&&!a.fallback_audio.paused:"undefined"!=typeof speechSynthesis?speechSynthesis.speaking:!1};a.clearFallbackPool=function(){for(var b=0;b<a.fallback_audiopool.length;b++)null!=a.fallback_audiopool[b]&&a.fallback_audiopool[b].pause();a.fallback_audiopool_index=0;a.fallbackChunks=[]};a.initFallbackPool=function(){if(!a.fallback_audiopool||0==a.fallback_audiopool.length){for(var b=0;10>b;b++){var c=b,d=document.createElement("AUDIO");d.preload="auto";a.is_android&& |  | ||||||
| (d.src="data:audio/mpeg;base64,/+NIxAAAAAAAAAAAAFhpbmcAAAAPAAAAEwAACZAAIiIiIiIqKioqKjMzMzMzRERERERETExMTExdXV1dXWZmZmZmd3d3d3d3gICAgICRkZGRkZmZmZmZqqqqqqqqs7Ozs7PExMTExMzMzMzM3d3d3d3d5ubm5ub39/f39///////AAAAUExBTUUzLjEwMAQoAAAAAAAAAAAVCCQCQCEAAeAAAAmQ/qJL7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+NIxAAGkAJAGAAAAABn///////////////6w//L/IeGCGc//+U61QAP/4LmWycNjPzmXtEL0VxbXSoQaadV7pSNs2X6hJ3Ok1a9yNRtf7ddPJrLR2nyP/p/30b0OdF6Su29GKp9Ls6LORkWRJ1sOsGr4mUADf9n/P+9v/FR5t08rK1UubPiChtJS2Yoop4MH48ec+PjR01tJJOmX8O3Mvmf//nf6s7pnCzO5wl8y7aVyzX5lLGdCKJYgd6S33q26FtBZVczczydHIbM6oMQuaUADf9n/9v//js/ijDGj7uNKCaLVPLY2TzXwmkzHCZrHdGypjNcBdIf+cssK+/f4397ez1JaRw1aI3FlV5ubTY1LQIWVb2m7K89qpjxLf5g/+MYxPgS5FZAeADFKNGO6mh1fMqEEQGWqWYmg3FqAA2vQlp77/uffWS702wqfv8vFD5PuNitqPG8p77pLmWf/+/HA5ryUlu7/+MYxOcXRFo8eAGHKS//vwnLX//6HPNCIzXla56JRuFPNdKV2pety8ID4VN+uRuoU+VV8zTMMfXYUQ4eh9ZoGKKlPHBCqgAN/+MoxMUX3CY8eAGHKbdmn+OeVJTGIlzpdOsUYwaXtdxnHOiuHjAFIU+ZnMzIo2eVWlxPy//y8rD9GK8OTKZXL6Wply47bXzyeYUcuXSE5qSwGGPcoJv2DchBu8Jw8gGwmW09AA23RXO3nb6WmOopONBSqNIeqnXWiAz7K4XEHwmcIdATmzwV0jJ9s4V/k////+MYxOgYlGo4eAGHLO/5f9nlL8kDpHZv+mbMu4mH7HHuyyqHq6TeK5/8aMjm1eRixEgQJqGo+0p5lQAN/0f477nlU9IqLh3g/+MoxMAV6+48eABHIXO7Otw9wgTCohOLjxNDi9CJZRx1mRayrbDuUE9K1/pzV12nzc/+fe9/4ZerXKtVHrfdcl3Snkp5pGPb7DmYQNJNSh9zwUw9UvZi6fQYM8eKDZqHEZhiAA3/Y/3//e/ncbwBH455AViDJuJXNlQhwMiabt6ZEy6bRZ0EyOvDkSz2KvaZ/+MYxOsWVDY8eAFHJX7d09JbPf7UcpGYFU4MK/TuiMtVI3U+7sa9XVlqveysYtTVmOxmQruJCGeRFdkDcQANv0P3v3+7/3v8/+MoxMwY7F48eAIHLXy7nE/l1671KjRcnSXttqsdJjz2h+kezUHiUdTRuwjpGa8vMy/+f55c7D+2xUlyOfmTv66UvLp0GeRl5WIljlTvLXeKT5Jwvad3F1mByDEbg4DVAA33Y/siOm/FK0CDQEmy6l1gwcQJgyQLX8QIFrg8G8A8hcy4q8OF+ZHkb0p5fP/K/+MYxOsXRCo8eAGFKUPMFnky0+ddOU/S++kPVj1z5qq55m56zXyFmmU0V3mwIsuiUKchEUZjC1y1AA33Y+///fv+5GmZj12N/+MoxMkXhGI8eAGHKcORvd5V0ztA0tUM1d+s21a+e6KTMnBOORPRyKWf/+1Of+f5OxsW9IyZ2uy3M/mef1/vzuZZ1+5S4ttla/eWHjROLbPed0N/NGppAxUqAA33YL08vVo7VkuqIZR2GbZVHBO0MUUIGSGq5ID2e8wpwECpKV8878nSmv//S/Ms5dUdI5Hm/+MYxO4W3F48eABHIQiMTfh86Vs7nfvC9Uz8pZcymIeTPMKyUIcIsjkcyeKlrzc2k0CVAA3/Y+Pr/fn//7zv3OWUiaOhGM2//+MoxM0Wy+48eAGHKRjF4VTgSyzCCRr9P73Jc005wH9MiLp5G/2/Kn+yf/86jUqeNwFTqP5fqU4xMbl/8SdmZ/NtnZjdrWFF6UKjAWGFTDC2EeELBAvBAA2vI/f7nm2z7j8yZbGhowotlks7nfrmUdf4x2L/eGdHO1CiZMbZmtjJ08Rr/e+YzL1v///y7/3O/+MYxPQW3G48eAAGPNpFgkl87qjOVlLOrn9vCSGL5fOHCRe/Unm5gbFu+VQFRSCPW4kxnBUHAA2/R//35++f7/8f5UFOi5dp/+MoxNMXs/48eAGHKeb7ShEhrRrJ7ox2Dwom6lJchCIyAxmlmRblJ8/+J///5/9kbi6dYzc7Dzh3ZeZJOeKImygKWGTGRWucLNkQ180DEbzPRTV2MRjGM6SOHQoADfdn/vX13Zq7bvdmzAaHWaYxtxRuGeiA/JGqh7PMwvZd9KC2NEoEYzKdkrrd/Z21t1u7/+MYxPcYhGY4eAGHLTf0v8++Rq1UzJCdC1k5f3yfRSooW/dmui4H0GqxkF8S+GJJmuU6GQOYJDfCiLo9zim9ElBNAA+/gj5S/+MoxNAYHGY8eAGHKKw6Zmxn++StD2qiVTXJhRFSftxQ4s7mwjZjKC1IcjKvv8xXov/77EeQqjPV3az/vqlNe6XVJFSs7UVlR7oxnY/eeRFcis7KrkJGMgtyc+lMAFWYnvEQQh4ViYhGFC/59/vG+MdJtVsaBhUV3+FHcKDf/EVLf/6KCeBWWK2STEFNRTMu/+MYxPIaLG44eAGHLDEwMKqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq/+MoxMQVRE48eADFKaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq/+MYxPELK54oGABHoaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", |  | ||||||
| d.load(),9==c&&(a.log("Android HTML audio initialized"),a.android_initialized=!0));a.iOS&&(d.src="data:audio/mpeg;base64,/+NIxAAAAAAAAAAAAFhpbmcAAAAPAAAAEwAACZAAIiIiIiIqKioqKjMzMzMzRERERERETExMTExdXV1dXWZmZmZmd3d3d3d3gICAgICRkZGRkZmZmZmZqqqqqqqqs7Ozs7PExMTExMzMzMzM3d3d3d3d5ubm5ub39/f39///////AAAAUExBTUUzLjEwMAQoAAAAAAAAAAAVCCQCQCEAAeAAAAmQ/qJL7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+NIxAAGkAJAGAAAAABn///////////////6w//L/IeGCGc//+U61QAP/4LmWycNjPzmXtEL0VxbXSoQaadV7pSNs2X6hJ3Ok1a9yNRtf7ddPJrLR2nyP/p/30b0OdF6Su29GKp9Ls6LORkWRJ1sOsGr4mUADf9n/P+9v/FR5t08rK1UubPiChtJS2Yoop4MH48ec+PjR01tJJOmX8O3Mvmf//nf6s7pnCzO5wl8y7aVyzX5lLGdCKJYgd6S33q26FtBZVczczydHIbM6oMQuaUADf9n/9v//js/ijDGj7uNKCaLVPLY2TzXwmkzHCZrHdGypjNcBdIf+cssK+/f4397ez1JaRw1aI3FlV5ubTY1LQIWVb2m7K89qpjxLf5g/+MYxPgS5FZAeADFKNGO6mh1fMqEEQGWqWYmg3FqAA2vQlp77/uffWS702wqfv8vFD5PuNitqPG8p77pLmWf/+/HA5ryUlu7/+MYxOcXRFo8eAGHKS//vwnLX//6HPNCIzXla56JRuFPNdKV2pety8ID4VN+uRuoU+VV8zTMMfXYUQ4eh9ZoGKKlPHBCqgAN/+MoxMUX3CY8eAGHKbdmn+OeVJTGIlzpdOsUYwaXtdxnHOiuHjAFIU+ZnMzIo2eVWlxPy//y8rD9GK8OTKZXL6Wply47bXzyeYUcuXSE5qSwGGPcoJv2DchBu8Jw8gGwmW09AA23RXO3nb6WmOopONBSqNIeqnXWiAz7K4XEHwmcIdATmzwV0jJ9s4V/k////+MYxOgYlGo4eAGHLO/5f9nlL8kDpHZv+mbMu4mH7HHuyyqHq6TeK5/8aMjm1eRixEgQJqGo+0p5lQAN/0f477nlU9IqLh3g/+MoxMAV6+48eABHIXO7Otw9wgTCohOLjxNDi9CJZRx1mRayrbDuUE9K1/pzV12nzc/+fe9/4ZerXKtVHrfdcl3Snkp5pGPb7DmYQNJNSh9zwUw9UvZi6fQYM8eKDZqHEZhiAA3/Y/3//e/ncbwBH455AViDJuJXNlQhwMiabt6ZEy6bRZ0EyOvDkSz2KvaZ/+MYxOsWVDY8eAFHJX7d09JbPf7UcpGYFU4MK/TuiMtVI3U+7sa9XVlqveysYtTVmOxmQruJCGeRFdkDcQANv0P3v3+7/3v8/+MoxMwY7F48eAIHLXy7nE/l1671KjRcnSXttqsdJjz2h+kezUHiUdTRuwjpGa8vMy/+f55c7D+2xUlyOfmTv66UvLp0GeRl5WIljlTvLXeKT5Jwvad3F1mByDEbg4DVAA33Y/siOm/FK0CDQEmy6l1gwcQJgyQLX8QIFrg8G8A8hcy4q8OF+ZHkb0p5fP/K/+MYxOsXRCo8eAGFKUPMFnky0+ddOU/S++kPVj1z5qq55m56zXyFmmU0V3mwIsuiUKchEUZjC1y1AA33Y+///fv+5GmZj12N/+MoxMkXhGI8eAGHKcORvd5V0ztA0tUM1d+s21a+e6KTMnBOORPRyKWf/+1Of+f5OxsW9IyZ2uy3M/mef1/vzuZZ1+5S4ttla/eWHjROLbPed0N/NGppAxUqAA33YL08vVo7VkuqIZR2GbZVHBO0MUUIGSGq5ID2e8wpwECpKV8878nSmv//S/Ms5dUdI5Hm/+MYxO4W3F48eABHIQiMTfh86Vs7nfvC9Uz8pZcymIeTPMKyUIcIsjkcyeKlrzc2k0CVAA3/Y+Pr/fn//7zv3OWUiaOhGM2//+MoxM0Wy+48eAGHKRjF4VTgSyzCCRr9P73Jc005wH9MiLp5G/2/Kn+yf/86jUqeNwFTqP5fqU4xMbl/8SdmZ/NtnZjdrWFF6UKjAWGFTDC2EeELBAvBAA2vI/f7nm2z7j8yZbGhowotlks7nfrmUdf4x2L/eGdHO1CiZMbZmtjJ08Rr/e+YzL1v///y7/3O/+MYxPQW3G48eAAGPNpFgkl87qjOVlLOrn9vCSGL5fOHCRe/Unm5gbFu+VQFRSCPW4kxnBUHAA2/R//35++f7/8f5UFOi5dp/+MoxNMXs/48eAGHKeb7ShEhrRrJ7ox2Dwom6lJchCIyAxmlmRblJ8/+J///5/9kbi6dYzc7Dzh3ZeZJOeKImygKWGTGRWucLNkQ180DEbzPRTV2MRjGM6SOHQoADfdn/vX13Zq7bvdmzAaHWaYxtxRuGeiA/JGqh7PMwvZd9KC2NEoEYzKdkrrd/Z21t1u7/+MYxPcYhGY4eAGHLTf0v8++Rq1UzJCdC1k5f3yfRSooW/dmui4H0GqxkF8S+GJJmuU6GQOYJDfCiLo9zim9ElBNAA+/gj5S/+MoxNAYHGY8eAGHKKw6Zmxn++StD2qiVTXJhRFSftxQ4s7mwjZjKC1IcjKvv8xXov/77EeQqjPV3az/vqlNe6XVJFSs7UVlR7oxnY/eeRFcis7KrkJGMgtyc+lMAFWYnvEQQh4ViYhGFC/59/vG+MdJtVsaBhUV3+FHcKDf/EVLf/6KCeBWWK2STEFNRTMu/+MYxPIaLG44eAGHLDEwMKqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq/+MoxMQVRE48eADFKaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq/+MYxPELK54oGABHoaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", |  | ||||||
| d.load(),9==c&&(a.log("iOS HTML audio initialized"),a.iOS_initialized=!0));a.fallback_audiopool.push(d)}a.fallback_audiopool_index=0}};a.allowSpeechClicked=function(b){a.allowSpeechDiv.parentNode.removeChild(a.allowSpeechDiv);a.allowSpeechDiv=null;if(a.speechAllowedByUser=b)a.clickEvent(),a.scheduledSpeak&&(a.speak(a.scheduledSpeak.text,a.scheduledSpeak.voicename,a.scheduledSpeak.parameters),a.scheduledSpeak=null);a.Dispatch("OnAllowSpeechClicked")};a.checkSpeechAllowed=function(b){if(0==a.speechAllowedByUser)return!1; |  | ||||||
| var c=a.is_android||a.iOS,d=a.is_safari&&(a.fallbackMode||a.forcedFallbackMode);if(!0!==a.disablePermissionPopup&&(!0===a.allowPermissionPopupEverywhere||c||d||!0===a.speechSynthesisNotAllowedError)&&!a.click_event_detected){if(a.allowSpeechDiv)return;a.allowSpeechDiv_appearances=null==a.allowSpeechDiv_appearances?1:++a.allowSpeechDiv_appearances;if(2<a.allowSpeechDiv_appearances)return console.log("ResponsiveVoice: Speech not allowed by user"),!1;c=document.createElement("style");c.innerHTML='.rvNotification{position:fixed;background-color:#fff;text-align:center;font-family:-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-weight:400;line-height:1.5;box-shadow:0 4px 8px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.19);z-index:10000;width:100vw;left:0;bottom:0;font-size:1rem;padding-bottom:.5em;padding-right:.5em}.rvButtonRow{padding-right:2em;padding-bottom:1em;text-align:right;font-size:medium}.rvButton{cursor:pointer;display:inline-block;margin-left:1em;padding:.8em 2em;border-radius:3px;font-size:small}.rvButtonAllow{border:none;background-color:#2b8cff;color:#fff}.rvButtonDeny{border:1px solid #2b8cff;color:#2b8cff;background-color:#fff}.rvTextRow{padding-top:1em;padding-bottom:2em}@media (min-width:576px){.rvNotification{width:60vw;left:20vw}}@media (min-width:768px){.rvNotification{width:50vw;left:25vw}}@media (min-width:992px){.rvNotification{width:40vw;left:30vw}}@media (min-width:1200px){.rvNotification{width:30vw;left:35vw}}'; |  | ||||||
| document.body.appendChild(c);a.allowSpeechDiv=document.createElement("div");a.allowSpeechDiv.classList.add("rvNotification");void 0==b&&(b={});a.allowSpeechDiv.innerHTML='<div class="rvTextRow"><strong>'+(void 0!=b.urlOverride?b.urlOverride:window.location.hostname)+"</strong> "+(void 0!=b.textOverride?b.textOverride:"wants to play speech")+'</div><div class="rvButtonRow"><div onclick="responsiveVoice.allowSpeechClicked(false);" class="rvButton rvButtonDeny">DENY</div><div onclick="responsiveVoice.allowSpeechClicked(true);" class="rvButton rvButtonAllow">ALLOW</div></div>'; |  | ||||||
| document.body.appendChild(a.allowSpeechDiv);return!1}return!0};a.fallback_audioPool_getAudio=function(){a.initFallbackPool();a.fallback_audiopool_index>=a.fallback_audiopool.length&&(a.fallback_audiopool_index=0);return a.fallback_audiopool[a.fallback_audiopool_index++]};a.fallback_updateChunksBuffer=function(){for(var b=a.fallbackChunkIndex;b<Math.min(a.fallbackChunks.length,a.fallbackChunkIndex+a.fallbackBufferLength);b++){var c=a.fallbackChunks[b];null==c.audio&&(c.audio=a.fallback_audioPool_getAudio(), |  | ||||||
| function(d){var h=function(){d.audio.src=d.url;d.audio.playbackRate=a.fallback_playbackrate;d.audio.preload="auto";d.audio.load()};0==b?h():setTimeout(h,50*b)}(c))}};a.selectBest=function(b){for(var c=0;c<b.length;c++)if(null!=b[c])return b[c];return null};a.pause=function(){a.fallbackMode?null!=a.fallback_audio&&a.fallback_audio.pause():(speechSynthesis.pause(),a.ttsCancelledByTimeout=!1,a.ttsKeepAliveTimeout=setTimeout(function(){a.ttsKeepAliveTimeout=null;speechSynthesis.cancel();a.ttsCancelledByTimeout= |  | ||||||
| !0},6E4))};a.resume=function(){if(a.fallbackMode)null!=a.fallback_audio&&a.fallback_audio.play();else if(a.ttsCancelledByTimeout)for(var b=a.ttsCancelledByTimeout=!1,c=0;c<a.utterances.length;c++){var d=a.utterances[c];a.currentMsg==d&&(b=!0);b&&a.tts_speak(d)}else a.ttsKeepAliveTimeout&&(clearTimeout(a.ttsKeepAliveTimeout),a.ttsKeepAliveTimeout=null),speechSynthesis.resume()};a.tts_speak=function(b){setTimeout(function(){a.cancelled=!1;a.analytics.characterCount+=b.text.toString().length;speechSynthesis.speak(b)}, |  | ||||||
| .01)};a.setVolume=function(b){if(a.isPlaying())if(a.fallbackMode){for(var c=0;c<a.fallback_audiopool.length;c++)a.fallback_audiopool[c].volume=b;a.fallback_audio.volume=b}else for(c=0;c<a.utterances.length;c++)a.utterances[c].volume=b};a.onPartEnd=function(b){if(null!=a.msgparameters&&null!=a.msgparameters.onchuckend)a.msgparameters.onchuckend();a.Dispatch("OnPartEnd");b=a.utterances.indexOf(b.utterance);a.currentMsg=a.utterances[b+1]};a.onboundary=function(b){a.log("On Boundary");a.iOS&&!a.onstartFired&& |  | ||||||
| a.speech_onstart()};a.numToWords=function(b){var c=function(){return function(r,m){if(Array.isArray(r))return r;if(Symbol.iterator in Object(r)){var v=[],n=!0,A=!1,H=void 0;try{for(var B=r[Symbol.iterator](),E;!(n=(E=B.next()).done)&&(v.push(E.value),!m||v.length!==m);n=!0);}catch(I){A=!0,H=I}finally{try{if(!n&&B["return"])B["return"]()}finally{if(A)throw H;}}return v}throw new TypeError("Invalid attempt to destructure non-iterable instance");}}(),d=function(r){return 0===r.length},h=function(r){return function(m){return m.slice(0, |  | ||||||
| r)}},e=function(r){return function(m){return m.slice(r)}},g=function(r){return r.slice(0).reverse()},k=function(r){return function(m){return function(v){return r(m(v))}}},f=function(r){return!r},l=function v(m){return function(n){if(d(n))var A=[];else{A=[h(m)(n)];var H=A.concat;n=v(m)(e(m)(n));if(Array.isArray(n)){for(var B=0,E=Array(n.length);B<n.length;B++)E[B]=n[B];n=E}else n=Array.from(n);A=H.call(A,n)}return A}},u=" one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen".split(" "), |  | ||||||
| D="  twenty thirty forty fifty sixty seventy eighty ninety".split(" "),G=" thousand million billion trillion quadrillion quintillion sextillion septillion octillion nonillion".split(" "),F=function(m){var v=c(m,3);m=v[0];var n=v[1];v=v[2];return[0===(Number(v)||0)?"":u[v]+" hundred ",0===(Number(m)||0)?D[n]:D[n]&&D[n]+" "||"",u[n+m]||u[m]].join("")},x=function(m,v){return""===m?m:m+" "+G[v]};return"number"===typeof b?a.numToWords(String(b)):"0"===b?"zero":k(l(3))(g)(Array.from(b)).map(F).map(x).filter(k(f)(d)).reverse().join(" ").trim()}; |  | ||||||
| a.getWords=function(b){b=b.replace(/$|\u00a5|\u20a1|\u20ac|\u00a3|\u20aa|\u20b9|\uffe5|\u17db|\u20a9|\u20a6|\u0e3f|\u20b4|\u20ab/gi," dummy currency ");var c=b.split(/(\s*[\s,]\s*|\?|;|:|\.|\(|\)|!)/);c=c.filter(function(h){return/[^\s]/.test(h)});for(var d=0;d<c.length;d++)null!=(b=c[d].toString().match(/\d+/))&&(c.splice(d,1),a.numToWords(+b[0]).split(/\s+/).map(function(h){c.push(h)}));return c};a.getEstimatedTimeLength=function(b,c){b=a.getWords(b);var d=0,h=a.fallbackMode?1300:700;c=c||1;b.map(function(k, |  | ||||||
| f){d+=(k.toString().match(/[^ ]/igm)||k).length});var e=b.length,g=60/a.WORDS_PER_MINUTE*c*1E3*e;5>e&&(g=c*(h+50*d));a.log("Estimated time length: "+g+" ms, words: ["+b+"], charsCount: "+d);return g};a.validateParameters=function(b,c){if("undefined"===typeof b[c])return b[c];switch(c){case "rate":case "pitch":case "volume":var d=Number(b[c]);isNaN(d)&&console.warn("ResponsiveVoice: the parameter "+c+' has a wrong value "'+b[c]+'". Defaults were used.');b[c]=isNaN(d)?"1":b[c]}return b[c]};a.services= |  | ||||||
| {NATIVE_TTS:0,FALLBACK_AUDIO:1};a.servicesPriority=[0,1];a.servicesEnabled=[];a.setServiceEnabled=function(b,c){a.servicesEnabled[b]=c};a.getServiceEnabled=function(b){return a.servicesEnabled[b]||!1};a.setServiceEnabled(a.services.NATIVE_TTS,!0);a.setServiceEnabled(a.services.FALLBACK_AUDIO,!0);a.forceFallbackMode=function(b){a.forcedFallbackMode=b;a.fallbackMode=b;a.mapRVs();a.Dispatch("OnServiceSwitched")};a.enableWindowClickHook=function(){a.userInteractionEvents.forEach(function(b){window.addEventListener(b, |  | ||||||
| a.clickEvent,!1)})};a.setTextReplacements=function(b){if(null==b)q=null;else{q=[];for(var c=0;c<b.length;c++){var d=b[c],h=d.searchvalue;if("string"==typeof h)try{var e=h.match(/^\/(.*?)\/([gimy]*)$/),g=new RegExp(e[1],e[2]);g instanceof RegExp&&(h=g)}catch(k){h=new RegExp(h,"g")}q.push({searchvalue:h,newvalue:d.newvalue,collectionvoices:d.collectionvoices,systemvoices:d.systemvoices})}}};var t=/(code\.responsivevoice\.org|local-lb).*?responsivevoice(\.\w+)?\.js/ig;"interactive"===document.readyState? |  | ||||||
| a.init():document.addEventListener("DOMContentLoaded",function(){a.init()});window.addEventListener("beforeunload",function(){if(rvApiKey&&a.analytics.characterCount){var b=new FormData;b.append("key",rvApiKey);b.append("count",a.analytics.characterCount);navigator.sendBeacon("https://app.responsivevoice.org/analytics/cc/session",b)&&(a.analytics.characterCount=0)}})},responsiveVoice=new ResponsiveVoice; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /// -------- RESPONSIVE VOICE ends |  | ||||||
|     responsiveVoice.debug = true; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| if( document.location.search && /rvWebsiteVerify=8LG4XCOk/gi.test(document.location.search) ){ |  | ||||||
|     function rvNotificationPopup(){ |  | ||||||
|          |  | ||||||
|         var css = '#rv_8LG4XCOk_notification,#rv_8LG4XCOk_notification *{font-family:"Open Sans",Helvetica,Arial,sans-serif,Tahoma!important}#rv_8LG4XCOk_notification{transition-duration:.3s;opacity:1;transform:scale(1);background:#fff;border:1px solid rgba(0,0,0,.125);border-radius:.3rem;position:fixed;z-index:2147483646;top:20px;left:20px;width:400px;padding:25px;-webkit-box-shadow:0 2px 4px 0 rgba(0,0,0,.3);-moz-box-shadow:0 2px 4px 0 rgba(0,0,0,.3);box-shadow:0 2px 4px 0 rgba(0,0,0,.3)}#rv_8LG4XCOk_notification .rv_notification_logo{background:url(https://app.responsivevoice.org/favicon-96x96.png) no-repeat;background-size:50px 50px;float:left;margin:0 20px 0 0;width:50px;height:50px}#rv_8LG4XCOk_notification_play{background:url(https://app.responsivevoice.org/images/play.png) no-repeat;background-size:25px 25px;float:left;margin:0 5px 0 0;width:25px;height:25px;cursor:pointer}#rv_8LG4XCOk_notification .rv_notification_body{float:left;color:#343a40;font-size:13px;width:78%;min-height:50px;vertical-align:middle}#rv_8LG4XCOk_notification .rv_notification_title{color:#1d643b;font-size:16px;font-weight:700;margin:1px 0 4px 0;display:inline-block}#rv_8LG4XCOk_notification_close{position:absolute;top:15px;right:15px;font-size:22px;color:#343a40;cursor:pointer;line-height:11px}.rv_notification_clear{clear:both}', |  | ||||||
|             head = document.head || document.getElementsByTagName('head')[0], |  | ||||||
|             style = document.createElement('style'); |  | ||||||
|         head.appendChild(style); |  | ||||||
|         style.type = 'text/css'; |  | ||||||
|  |  | ||||||
|         if (style.styleSheet){ |  | ||||||
|              |  | ||||||
|             style.styleSheet.cssText = css; |  | ||||||
|         } else { |  | ||||||
|             style.appendChild(document.createTextNode(css) ); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|          |  | ||||||
|         var rvNotification = document.createElement('div'); |  | ||||||
|         rvNotification.innerHTML = '<div id=rv_8LG4XCOk_notification><div id=rv_8LG4XCOk_notification_close>×</div><div class=rv_notification_logo></div><div class=rv_notification_body><div id=rv_8LG4XCOk_notification_play></div><span class=rv_notification_title>ResponsiveVoice URL verified</span><br><span class=rv_notification_text>Your <i style="display: none;">ResponsivVoice</i> code snippet is correctly installed, you may now close this window.</span></div><div class=rv_notification_clear></div></div>'; |  | ||||||
|         document.body.appendChild(rvNotification); |  | ||||||
|  |  | ||||||
|          |  | ||||||
|         function speakVerification(){ |  | ||||||
|             responsiveVoice.speak( document.getElementById('rv_8LG4XCOk_notification').getElementsByClassName('rv_notification_text')[0].textContent ); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         document.getElementById("rv_8LG4XCOk_notification_play").addEventListener( "click" , function(e) { |  | ||||||
|             speakVerification(); |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         document.getElementById("rv_8LG4XCOk_notification_close").addEventListener( "click" , function(e) { |  | ||||||
|             style.remove(); |  | ||||||
|             rvNotification.remove(); |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         speakVerification(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     document.addEventListener('DOMContentLoaded', function(){ |  | ||||||
|         var xhttp = new XMLHttpRequest(); |  | ||||||
|         xhttp.open("POST", "https://code.responsivevoice.org/verify/8LG4XCOk", true); |  | ||||||
|         xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); |  | ||||||
|         xhttp.send("rv=" + (typeof responsiveVoice !== 'undefined') ); |  | ||||||
|         xhttp.onreadystatechange = function() { |  | ||||||
|             if (this.readyState == 4 && this.status == 200) { |  | ||||||
|                 rvNotificationPopup(); |  | ||||||
|             } |  | ||||||
|         }; |  | ||||||
|     }, false); |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  Copyright (c) Tristen Brown |  | ||||||
|  |  | ||||||
|  Permission is hereby granted, free of charge, to any person obtaining |  | ||||||
|  a copy of this software and associated documentation files (the |  | ||||||
|  "Software"), to deal in the Software without restriction, including |  | ||||||
|  without limitation the rights to use, copy, modify, merge, publish, |  | ||||||
|  distribute, sublicense, and/or sell copies of the Software, and to |  | ||||||
|  permit persons to whom the Software is furnished to do so, subject to |  | ||||||
|  the following conditions: |  | ||||||
|  |  | ||||||
|  The above copyright notice and this permission notice shall be |  | ||||||
|  included in all copies or substantial portions of the Software. |  | ||||||
|  |  | ||||||
|  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |  | ||||||
|  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |  | ||||||
|  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |  | ||||||
|  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |  | ||||||
|  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |  | ||||||
|  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |  | ||||||
|  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |  | ||||||
|  */ |  | ||||||
| !function(e,t){if("function"==typeof define&&define.amd)define("hoverintent",["module"],t);else if("undefined"!=typeof exports)t(module);else{var n={exports:{}};t(n),e.hoverintent=n.exports}}(this,function(e){"use strict";var t=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e};e.exports=function(e,n,o){function i(e,t){return y&&(y=clearTimeout(y)),b=0,p?void 0:o.call(e,t)}function r(e){m=e.clientX,d=e.clientY}function u(e,t){if(y&&(y=clearTimeout(y)),Math.abs(h-m)+Math.abs(E-d)<x.sensitivity)return b=1,p?void 0:n.call(e,t);h=m,E=d,y=setTimeout(function(){u(e,t)},x.interval)}function s(t){return L=!0,y&&(y=clearTimeout(y)),e.removeEventListener("mousemove",r,!1),1!==b&&(h=t.clientX,E=t.clientY,e.addEventListener("mousemove",r,!1),y=setTimeout(function(){u(e,t)},x.interval)),this}function c(t){return L=!1,y&&(y=clearTimeout(y)),e.removeEventListener("mousemove",r,!1),1===b&&(y=setTimeout(function(){i(e,t)},x.timeout)),this}function v(t){L||(p=!0,n.call(e,t))}function a(t){!L&&p&&(p=!1,o.call(e,t))}function f(){e.addEventListener("focus",v,!1),e.addEventListener("blur",a,!1)}function l(){e.removeEventListener("focus",v,!1),e.removeEventListener("blur",a,!1)}var m,d,h,E,L=!1,p=!1,T={},b=0,y=0,x={sensitivity:7,interval:100,timeout:0,handleFocus:!1};return T.options=function(e){var n=e.handleFocus!==x.handleFocus;return x=t({},x,e),n&&(x.handleFocus?f():l()),T},T.remove=function(){e&&(e.removeEventListener("mouseover",s,!1),e.removeEventListener("mouseout",c,!1),l())},e&&(e.addEventListener("mouseover",s,!1),e.addEventListener("mouseout",c,!1)),T}}); |  | ||||||
|  |  | ||||||
| var config = {"welcomeMessage":false,"speakSelectedText":true,"speakLinks":true,"speakInactivity":false,"speakEndPage":false,"exitIntent":false,"accesibilityNavigation":false,"accesibilityNavigation2":false,"welcomeMessageTime":false,"text_welcomeMessage":null,"text_speakInactivity":null,"text_speakEndPage":null,"text_exitIntent":null,"trackEvents":false,"abTesting":false,"analytics_id":null,"another_field":null}; |  | ||||||
|  |  | ||||||
|  /*<!-- LearnBriteAnalytics --> |  | ||||||
| var _wla = _wla || []; |  | ||||||
| _wla.push(['trackPageView']); |  | ||||||
| //_wla.setCountPrerender(true); |  | ||||||
| _wla.push(['enableLinkTracking']); |  | ||||||
| (function() { |  | ||||||
|     var u="//ai.learnbrite.com/"; |  | ||||||
|     _wla.push(['setTrackerUrl', u+'analytics.php']); |  | ||||||
|     _wla.push(['setSiteId', 75]); |  | ||||||
|     var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; |  | ||||||
|     g.type='text/javascript'; |  | ||||||
|     g.async=true; g.defer=true; g.src=u+'analytics.js.php'; s.parentNode.insertBefore(g,s); })(); */ |  | ||||||
|  |  | ||||||
| var splitTestEnabled = config.abTesting || false; |  | ||||||
| var splitTest_useGS  = (Math.random() < 0.5); |  | ||||||
|  |  | ||||||
| function GetRandomMsg(text) { |  | ||||||
|     var texts = text.split("|"); |  | ||||||
|     return texts[Math.floor(Math.random() * texts.length)]; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function getHiddenProp(){ |  | ||||||
|     var prefixes = ['webkit', 'moz', 'ms', 'o']; |  | ||||||
|  |  | ||||||
|     // if 'hidden' is natively supported just return it |  | ||||||
|     if ('hidden' in document) return 'hidden'; |  | ||||||
|  |  | ||||||
|     // otherwise loop over all the known prefixes until we find one |  | ||||||
|     for (var i = 0; i < prefixes.length; i++) { |  | ||||||
|         if ((prefixes[i] + 'Hidden') in document) |  | ||||||
|             return prefixes[i] + 'Hidden'; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // otherwise it's not supported |  | ||||||
|     return null; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function getVisibilityState() { |  | ||||||
|     var prefixes = ['webkit', 'moz', 'ms', 'o']; |  | ||||||
|  |  | ||||||
|     // if 'visibilityState' is natively supported just return it |  | ||||||
|     if ('visibilityState' in document) return 'visibilityState'; |  | ||||||
|  |  | ||||||
|     // otherwise loop over all the known prefixes until we find one |  | ||||||
|     for (var i = 0; i < prefixes.length; i++) { |  | ||||||
|         if ((prefixes[i] + 'VisibilityState') in document) |  | ||||||
|             return prefixes[i] + 'VisibilityState'; |  | ||||||
|     } |  | ||||||
|     // otherwise it's not supported |  | ||||||
|     return null; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function isHidden() { |  | ||||||
|     var prop = getHiddenProp(); |  | ||||||
|     if (!prop) return false; |  | ||||||
|  |  | ||||||
|     return document[prop]; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function isPrerendered() { |  | ||||||
|     var prop = getVisibilityState(); |  | ||||||
|     //console.log(prop); |  | ||||||
|     if (!prop) return false; |  | ||||||
|     //console.log(document[prop]); |  | ||||||
|     if (document[prop] != "prerender") return false; |  | ||||||
|     return document[prop]; |  | ||||||
| } |  | ||||||
| console.log("isHidden: " + isHidden()); |  | ||||||
| console.log("Prerender: " + isPrerendered()); |  | ||||||
|  |  | ||||||
| //Analytics |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| //Search Message |  | ||||||
|  |  | ||||||
| var prerenderUsed = false; |  | ||||||
|  |  | ||||||
| if (isPrerendered() && !prerenderUsed) { |  | ||||||
|     prerenderUsed = true; |  | ||||||
|     setTimeout(function () { |  | ||||||
|  |  | ||||||
|         if (!splitTestEnabled || (splitTestEnabled && splitTest_useGS)) { |  | ||||||
|             var txt = GetRandomMsg(''); |  | ||||||
|             if (txt != null && txt != "") { |  | ||||||
|                 console.log("Launching search message"); |  | ||||||
|                 responsiveVoice.speak("According to Voicebrite, " + txt, ''); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         //Search Message Split Test - Impression |  | ||||||
|         if (splitTestEnabled) { |  | ||||||
|             if (splitTest_useGS) { |  | ||||||
|                 trackEvent('searchMessage', 'impressionAB', 'true'); |  | ||||||
|             } else { |  | ||||||
|                 trackEvent('searchMessage', 'impressionAB', 'false'); |  | ||||||
|             } |  | ||||||
|         } else { |  | ||||||
|             trackEvent('searchMessage', 'impression'); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     }, 1500); |  | ||||||
|  |  | ||||||
| } |  | ||||||
|  |  | ||||||
| window.addEventListener('load', function() { |  | ||||||
| //We came from prerender |  | ||||||
|     var smessInterval = null; |  | ||||||
|     if (prerenderUsed) { |  | ||||||
|         smessInterval = setInterval(function () { |  | ||||||
|             if (!isPrerendered()) { |  | ||||||
|  |  | ||||||
|                 clearInterval(smessInterval); |  | ||||||
|  |  | ||||||
|                 //Search Message Split Test - Impression |  | ||||||
|                 if (splitTestEnabled) { |  | ||||||
|                     if (splitTest_useGS) { |  | ||||||
|                         trackEvent('searchMessage', 'visitAB', 'true'); |  | ||||||
|                     } else { |  | ||||||
|                         trackEvent('searchMessage', 'visitAB', 'false'); |  | ||||||
|                     } |  | ||||||
|                 } else { |  | ||||||
|                     trackEvent('searchMessage', 'visit'); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         }, 1000); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     console.log("Configuring"); |  | ||||||
|  |  | ||||||
|     //Speak links |  | ||||||
|     var _allLinks = document.getElementsByTagName('a') |  | ||||||
|     Array.prototype.forEach.call(_allLinks, function(el) { |  | ||||||
|         hoverintent(el, |  | ||||||
|             function () { |  | ||||||
|                 if (config.speakLinks) { |  | ||||||
|                     //responsiveVoice.cancel(); |  | ||||||
|                     responsiveVoice.speak(el.textContent, ''); |  | ||||||
|                     trackEvent('agentFeature', 'spokenLink'); |  | ||||||
|                 } |  | ||||||
|             }, function () { |  | ||||||
|             } |  | ||||||
|         ); |  | ||||||
|     }); |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     //Speak selected text |  | ||||||
|     var selectedText      = ""; |  | ||||||
|     var last_selectedText = ""; |  | ||||||
|  |  | ||||||
|     function getSelectionText() { |  | ||||||
|         var text = ""; |  | ||||||
|         if (window.getSelection) { |  | ||||||
|             text = window.getSelection().toString(); |  | ||||||
|         } else if (document.selection && document.selection.type != "Control") { // for Internet Explorer 8 and below |  | ||||||
|             text = document.selection.createRange().text; |  | ||||||
|         } |  | ||||||
|         return text; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (config.speakSelectedText) { |  | ||||||
|         attachToElements( document.querySelectorAll("PRE,DIV"), ['mouseup', 'touchend'], onMouseUp); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     function attachToElements(elements, events, callback){ |  | ||||||
|         if(elements.length > 0){ |  | ||||||
|             for(var i = 0; i < elements.length; i++){ |  | ||||||
|                 events.forEach(function(event){ |  | ||||||
|                     elements[i].addEventListener(event, function(e){ |  | ||||||
|                         callback(); |  | ||||||
|                     }); |  | ||||||
|                 }); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     function onMouseUp() { |  | ||||||
|         selectedText = getSelectionText(); |  | ||||||
|         console.log("Selected text *" + selectedText + "*"); |  | ||||||
|         if (selectedText != last_selectedText && selectedText != "") { |  | ||||||
|             last_selectedText = selectedText; |  | ||||||
|  |  | ||||||
|             responsiveVoice.cancel(); // stop anything currently being spoken |  | ||||||
|             responsiveVoice.speak(selectedText, ''); //speak the text as returned by getSelectionText |  | ||||||
|             trackEvent('agentFeature', 'highlightText'); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     //Speak welcome message. Will only play if user didn't came from google. |  | ||||||
|     var welcomeMessageLaunched = false; |  | ||||||
|     if (config.welcomeMessage && (!config.welcomeMessageTime || oneTimeTest("welcomeMessage")) && !isPrerendered() && !prerenderUsed) { |  | ||||||
|         welcomeMessageLaunched = true; |  | ||||||
|         setTimeout(function () { |  | ||||||
|             if (config.text_welcomeMessage != null && config.text_welcomeMessage != "") { |  | ||||||
|                 console.log("Launching welcome message"); |  | ||||||
|                 responsiveVoice.speak(GetRandomMsg(config.text_welcomeMessage), ''); |  | ||||||
|                 trackEvent('agentFeature', 'welcomeMessage'); |  | ||||||
|             } |  | ||||||
|         }, 1500); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     //Speak welcome message when user came from Google. Won't play if default message played |  | ||||||
|     var welcomeMessage2Launched = false; |  | ||||||
|     var welcomeMessage2Interval = null; |  | ||||||
|     if (!welcomeMessageLaunched && config.welcomeMessage2 && (!config.welcomeMessageTime || oneTimeTest("welcomeMessage2")) |  | ||||||
|         && config.text_welcomeMessage2 != null && config.text_welcomeMessage2 != "") { |  | ||||||
|         //Wait until we're visible and launch message |  | ||||||
|  |  | ||||||
|         welcomeMessage2Interval = setInterval(function () { |  | ||||||
|             console.log("Welcome Message from Google Waiting"); |  | ||||||
|             if (!isPrerendered() && !welcomeMessage2Launched) { |  | ||||||
|                 console.log("Welcome Message from Google launched"); |  | ||||||
|  |  | ||||||
|                 welcomeMessage2Launched = true; |  | ||||||
|                 responsiveVoice.speak(GetRandomMsg(config.text_welcomeMessage2), ''); |  | ||||||
|                 trackEvent('agentFeature', 'welcomeMessage2'); |  | ||||||
|                 clearInterval(welcomeMessage2Interval); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|         }, 1000); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     //Speak when scroll end |  | ||||||
|     function bindScroll() { |  | ||||||
|         if ((window.innerHeight + window.pageYOffset) >= document.body.offsetHeight - 100 && config.text_speakEndPage != null && config.text_speakEndPage != "") { |  | ||||||
|             console.log("bottom"); |  | ||||||
|             window.removeEventListener('scroll', bindScroll); |  | ||||||
|  |  | ||||||
|             responsiveVoice.speak(GetRandomMsg(config.text_speakEndPage), ''); |  | ||||||
|             trackEvent('agentFeature', 'scrollEnd'); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (config.speakEndPage) { |  | ||||||
|         window.addEventListener('scroll', bindScroll); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     //Inactivity |  | ||||||
|     var idleTime = 0; |  | ||||||
|     if (config.speakInactivity) { |  | ||||||
|         setInterval(timerIncrement, 1000); |  | ||||||
|  |  | ||||||
|         window.addEventListener('mousemove', function() { |  | ||||||
|             idleTime = 0; |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         window.addEventListener('keyup', function() { |  | ||||||
|             idleTime = 0; |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     function timerIncrement() { |  | ||||||
|         idleTime += 1000; |  | ||||||
|  |  | ||||||
|         if (idleTime >= 30000) { |  | ||||||
|             responsiveVoice.speak(GetRandomMsg(config.text_speakInactivity), ''); |  | ||||||
|             trackEvent('agentFeature', 'inactivity'); |  | ||||||
|             idleTime = 0; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     //Exit intent |  | ||||||
|     if (config.speakInactivity) { |  | ||||||
|         console.info("setting up exit intent"); |  | ||||||
|         document.addEventListener('mouseout', exitIntent); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     function exitIntent(e) { |  | ||||||
|         if (e.clientY < 0) { |  | ||||||
|             responsiveVoice.speak(GetRandomMsg(config.text_exitIntent), ''); |  | ||||||
|             trackEvent('agentFeature', 'exitIntent'); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     //Tab and ctrl to speak - Accessibility Navigation |  | ||||||
|     var started = 0; |  | ||||||
|     if (config.accesibilityNavigation) { |  | ||||||
|         console.log("accesibilityNavigation"); |  | ||||||
|  |  | ||||||
|         document.addEventListener('keyup',function(e){ |  | ||||||
|             console.log('keyup called'); |  | ||||||
|  |  | ||||||
|             var code = e.keyCode || e.which; |  | ||||||
|  |  | ||||||
|             if(e.target){ |  | ||||||
|                 switch(e.target.tagName){ |  | ||||||
|                     case 'A': |  | ||||||
|                         if (code == '9') { |  | ||||||
|                             responsiveVoice.speak('Link 2 ' + e.target.text, ''); |  | ||||||
|                             trackEvent('agentFeature', 'accesibilityNavigation', 'tab'); |  | ||||||
|                         } |  | ||||||
|                         break; |  | ||||||
|  |  | ||||||
|                     case 'BUTTON': |  | ||||||
|                         if (code == '9') { |  | ||||||
|                             setTimeout(responsiveVoice.speak( e.target.textContent + ' button', ''), 1000); |  | ||||||
|                             trackEvent('agentFeature', 'accesibilityNavigation', 'tab'); |  | ||||||
|                         } |  | ||||||
|                         break; |  | ||||||
|  |  | ||||||
|                     case 'TEXTAREA': |  | ||||||
|                         if (code == '9') { |  | ||||||
|                             responsiveVoice.speak('Text Input ' + document.querySelectorAll(':focus')[0].getAttribute('placeholder'), ''); |  | ||||||
|                             trackEvent('agentFeature', 'accesibilityNavigation', 'tab'); |  | ||||||
|                         } |  | ||||||
|                         break; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (config.accesibilityNavigation2) { |  | ||||||
|  |  | ||||||
|         document.addEventListener('keyup',function(e){ |  | ||||||
|             console.log('keyup called'); |  | ||||||
|  |  | ||||||
|             var code = e.keyCode || e.which; |  | ||||||
|  |  | ||||||
|             if (code == '40' && e.ctrlKey) { |  | ||||||
|                 console.log('ctrl + down arrow'); |  | ||||||
|  |  | ||||||
|                 responsiveVoice.speak(document.querySelectorAll('p')[started].textContent, ''); |  | ||||||
|                 trackEvent('agentFeature', 'accesibilityNavigation', 'ctrl-arrow'); |  | ||||||
|                 document.querySelectorAll('p')[started].scrollIntoView(false); |  | ||||||
|                 started = started + 1; |  | ||||||
|             } |  | ||||||
|             if (code == '38' && e.ctrlKey) { |  | ||||||
|                 console.log('ctrl + up arrow'); |  | ||||||
|  |  | ||||||
|                 responsiveVoice.speak(document.querySelectorAll('p')[started].textContent, ''); |  | ||||||
|                 trackEvent('agentFeature', 'accesibilityNavigation', 'ctrl-arrow'); |  | ||||||
|                 document.querySelectorAll('p')[started].scrollIntoView(false); |  | ||||||
|                 started = started - 1; |  | ||||||
|                 if(started < 1){ |  | ||||||
|                     started = 0; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
| }); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| function createCookie(name, value, days) { |  | ||||||
|     if (days) { |  | ||||||
|         var date = new Date(); |  | ||||||
|         date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); |  | ||||||
|         var expires = "; expires=" + date.toGMTString(); |  | ||||||
|     } else var expires = ""; |  | ||||||
|     document.cookie = name + "=" + value + expires + "; path=/"; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function readCookie(name) { |  | ||||||
|     var nameEQ = name + "="; |  | ||||||
|     var ca     = document.cookie.split(';'); |  | ||||||
|     for (var i = 0; i < ca.length; i++) { |  | ||||||
|         var c = ca[i]; |  | ||||||
|         while (c.charAt(0) == ' ') c = c.substring(1, c.length); |  | ||||||
|         if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length); |  | ||||||
|     } |  | ||||||
|     return null; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function eraseCookie(name) { |  | ||||||
|     createCookie(name, "", -1); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function getOrCreateTest(name, prob, days) { |  | ||||||
|  |  | ||||||
|     var c = readCookie(name); |  | ||||||
|  |  | ||||||
|     if (c == null) { |  | ||||||
|         console.log("Cookie set"); |  | ||||||
|         var v = (Math.random() < (prob != null ? prob : 0.5)); |  | ||||||
|         //1 hour |  | ||||||
|         createCookie(name, v.toString(), (days != null ? days : (1 / 24))); |  | ||||||
|         return v; |  | ||||||
|     } |  | ||||||
|     console.log("Cookie read"); |  | ||||||
|     return c == (true).toString(); |  | ||||||
|  |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function oneTimeTest(name, days) { |  | ||||||
|  |  | ||||||
|     var c = readCookie(name); |  | ||||||
|  |  | ||||||
|     if (c == null) { |  | ||||||
|         console.log("Cookie set - one time True"); |  | ||||||
|         //1 hour |  | ||||||
|         createCookie(name, (false).toString(), (days != null ? days : (0.5 / 24))); |  | ||||||
|         return true; |  | ||||||
|     } |  | ||||||
|     console.log("Cookie read - one time False"); |  | ||||||
|     return false; |  | ||||||
|  |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function trackEvent(category, action, name, value) { |  | ||||||
|  |  | ||||||
|     if (config.trackEvents != true) return; |  | ||||||
|  |  | ||||||
|     console.log("Track " + category + "," + action + "," + name); |  | ||||||
|  |  | ||||||
|     var url = 'https://ai.learnbrite.com/analytics.php'; |  | ||||||
|     var postArray = []; |  | ||||||
|  |  | ||||||
|     var data = { |  | ||||||
|         idsite: config.analytics_id, |  | ||||||
|         rec: 1, |  | ||||||
|         url: window.location.href, |  | ||||||
|         rand: Math.floor(Math.random() * 1000000000), |  | ||||||
|         e_c: category, |  | ||||||
|         e_a: action, |  | ||||||
|         e_n: name, |  | ||||||
|         e_v: value |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     for (var property in data){ |  | ||||||
|         postArray.push( encodeURI(property + '=' + data[property])); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     var xhttp = new XMLHttpRequest(); |  | ||||||
|  |  | ||||||
|     xhttp.open("POST", url, true); |  | ||||||
|     xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); |  | ||||||
|     xhttp.send( postArray.join('&') ); |  | ||||||
|  |  | ||||||
|     xhttp.onreadystatechange = function() { |  | ||||||
|         if (this.readyState == 4 && this.status == 200) { |  | ||||||
|             console.log("Tracking Success"); |  | ||||||
|             console.log(data); |  | ||||||
|         } |  | ||||||
|     }; |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "9f49e939-dfca-4a26-81e2-e22c98a61c90", |  | ||||||
|   "importer": "javascript", |  | ||||||
|   "isPlugin": true, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.3", |  | ||||||
|   "uuid": "a0181a7b-9c3d-4126-a012-acf5a1e095a2", |  | ||||||
|   "importer": "folder", |  | ||||||
|   "isBundle": false, |  | ||||||
|   "bundleName": "", |  | ||||||
|   "priority": 1, |  | ||||||
|   "compressionType": {}, |  | ||||||
|   "optimizeHotUpdate": {}, |  | ||||||
|   "inlineSpriteFrames": {}, |  | ||||||
|   "isRemoteBundle": {}, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,9 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.3.2", |  | ||||||
|   "uuid": "9d9ca13a-071d-47f4-836c-a69d1045dc14", |  | ||||||
|   "importer": "prefab", |  | ||||||
|   "optimizationPolicy": "AUTO", |  | ||||||
|   "asyncLoadAssets": false, |  | ||||||
|   "readonly": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.3", |  | ||||||
|   "uuid": "29f52784-2fca-467b-92e7-8fd9ef8c57b7", |  | ||||||
|   "importer": "folder", |  | ||||||
|   "isBundle": false, |  | ||||||
|   "bundleName": "", |  | ||||||
|   "priority": 1, |  | ||||||
|   "compressionType": {}, |  | ||||||
|   "optimizeHotUpdate": {}, |  | ||||||
|   "inlineSpriteFrames": {}, |  | ||||||
|   "isRemoteBundle": {}, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,8 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.3.2", |  | ||||||
|   "uuid": "2d2f792f-a40c-49bb-a189-ed176a246e49", |  | ||||||
|   "importer": "scene", |  | ||||||
|   "asyncLoadAssets": false, |  | ||||||
|   "autoReleaseAssets": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.3", |  | ||||||
|   "uuid": "4734c20c-0db8-4eb2-92ea-e692f4d70934", |  | ||||||
|   "importer": "folder", |  | ||||||
|   "isBundle": false, |  | ||||||
|   "bundleName": "", |  | ||||||
|   "priority": 1, |  | ||||||
|   "compressionType": {}, |  | ||||||
|   "optimizeHotUpdate": {}, |  | ||||||
|   "inlineSpriteFrames": {}, |  | ||||||
|   "isRemoteBundle": {}, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.3", |  | ||||||
|   "uuid": "89004b78-f84d-4134-8e8c-f51c5c3800df", |  | ||||||
|   "importer": "folder", |  | ||||||
|   "isBundle": false, |  | ||||||
|   "bundleName": "", |  | ||||||
|   "priority": 1, |  | ||||||
|   "compressionType": {}, |  | ||||||
|   "optimizeHotUpdate": {}, |  | ||||||
|   "inlineSpriteFrames": {}, |  | ||||||
|   "isRemoteBundle": {}, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.3", |  | ||||||
|   "uuid": "a69fe64f-177f-4e4b-83f0-1f418203d85f", |  | ||||||
|   "importer": "folder", |  | ||||||
|   "isBundle": false, |  | ||||||
|   "bundleName": "", |  | ||||||
|   "priority": 1, |  | ||||||
|   "compressionType": {}, |  | ||||||
|   "optimizeHotUpdate": {}, |  | ||||||
|   "inlineSpriteFrames": {}, |  | ||||||
|   "isRemoteBundle": {}, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.3", |  | ||||||
|   "uuid": "f9edb32f-c4ab-4e5d-8270-71fa609e1db7", |  | ||||||
|   "importer": "folder", |  | ||||||
|   "isBundle": false, |  | ||||||
|   "bundleName": "", |  | ||||||
|   "priority": 1, |  | ||||||
|   "compressionType": {}, |  | ||||||
|   "optimizeHotUpdate": {}, |  | ||||||
|   "inlineSpriteFrames": {}, |  | ||||||
|   "isRemoteBundle": {}, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,16 +0,0 @@ | |||||||
| interface StringConstructor {   |  | ||||||
|     IsNullOrEmpty: (value: string) => boolean; |  | ||||||
|     Format: (format: string, ...args: any[]) => string; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| String.IsNullOrEmpty = function (value: string): boolean {   |  | ||||||
|     return value === undefined || value === null || value.trim() === ''; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| String.Format = function (format: string, ...args: any[]): string { |  | ||||||
|     return format.replace(/{(\d+)}/g, (match, index) => { |  | ||||||
|         let value = args[index]; |  | ||||||
|         if (value === null || value === undefined) return ''; |  | ||||||
|         return '' + value; |  | ||||||
|     }); |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "0c3d1ca6-bdaf-4a00-b209-6ef460802cdc", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.3", |  | ||||||
|   "uuid": "01b35dee-e6e0-4a6e-a73c-3b49c37f1c5f", |  | ||||||
|   "importer": "folder", |  | ||||||
|   "isBundle": false, |  | ||||||
|   "bundleName": "", |  | ||||||
|   "priority": 1, |  | ||||||
|   "compressionType": {}, |  | ||||||
|   "optimizeHotUpdate": {}, |  | ||||||
|   "inlineSpriteFrames": {}, |  | ||||||
|   "isRemoteBundle": {}, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,125 +0,0 @@ | |||||||
| /** |  | ||||||
|  * 回呼函數: fnname (arg: TArg): void |  | ||||||
|  */ |  | ||||||
| interface ActionCallback<TArg> { |  | ||||||
|     (arg: TArg): void; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| interface Struct<TArg> { |  | ||||||
|     callback: ActionCallback<TArg>; |  | ||||||
|     target: any; |  | ||||||
|     once?: boolean; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export class Action<TArg> { |  | ||||||
|     private _queue: Struct<TArg>[] = []; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 監聽事件 |  | ||||||
|      * @param callback 回呼函數: fnname (arg: TArg): void |  | ||||||
|      * @param bindTarget 回呼時this綁定的對象 |  | ||||||
|      */ |  | ||||||
|     AddCallback(callback: ActionCallback<TArg>, bindTarget?: any) { |  | ||||||
|         let q = <Struct<TArg>> { |  | ||||||
|             callback: callback, |  | ||||||
|             target: bindTarget |  | ||||||
|         }; |  | ||||||
|         this._queue.push(q); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 監聽事件 (一次性) |  | ||||||
|      * @param callback 回呼函數: fnname (arg: TArg): void |  | ||||||
|      * @param bindTarget 回呼時this綁定的對象 |  | ||||||
|      */ |  | ||||||
|     AddCallbackOnce(callback: ActionCallback<TArg>, bindTarget?: any) { |  | ||||||
|         let q = <Struct<TArg>> { |  | ||||||
|             callback: callback, |  | ||||||
|             target: bindTarget, |  | ||||||
|             once: true |  | ||||||
|         }; |  | ||||||
|         this._queue.push(q); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 移除事件 |  | ||||||
|      * @param callback  |  | ||||||
|      */ |  | ||||||
|     RemoveByCallback(callback: ActionCallback<TArg>) { |  | ||||||
|         let index = this._queue.length; |  | ||||||
|         if (index > 0) { |  | ||||||
|             while (index--) { |  | ||||||
|                 let q = this._queue[index]; |  | ||||||
|                 if (!q.callback || q.callback === callback) { |  | ||||||
|                     q.callback = undefined; |  | ||||||
|                     this._queue.splice(index, 1); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * 移除事件 |  | ||||||
|      * @param bindTarget 回呼時this綁定的對象 |  | ||||||
|      */ |  | ||||||
|     RemoveByBindTarget(bindTarget: any) { |  | ||||||
|         let index = this._queue.length; |  | ||||||
|         if (index > 0) { |  | ||||||
|             while (index--) { |  | ||||||
|                 let q = this._queue[index]; |  | ||||||
|                 if (!q.callback || q.target === bindTarget) { |  | ||||||
|                     q.callback = undefined; |  | ||||||
|                     this._queue.splice(index, 1); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 移除全部事件 |  | ||||||
|      */ |  | ||||||
|     RemoveAllCallbacks() { |  | ||||||
|         this._queue.forEach(q => q.callback = undefined); |  | ||||||
|         this._queue.length = 0; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 發送事件 |  | ||||||
|      * @param arg 參數 |  | ||||||
|      */ |  | ||||||
|     DispatchCallback(arg: TArg) { |  | ||||||
|         let index = this._queue.length; |  | ||||||
|         if (index > 0) { |  | ||||||
|             let cleanRemoved = false; |  | ||||||
|             this._queue.slice().forEach(q => { |  | ||||||
|                 if (!q.callback) { |  | ||||||
|                     cleanRemoved = true; |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 if (q.target) { |  | ||||||
|                     q.callback.call(q.target, arg); |  | ||||||
|                 } else { |  | ||||||
|                     q.callback(arg); |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 if (q.once) { |  | ||||||
|                     q.callback = undefined; |  | ||||||
|                     cleanRemoved = true; |  | ||||||
|                 } |  | ||||||
|             }); |  | ||||||
|  |  | ||||||
|             if (cleanRemoved) { |  | ||||||
|                 index = this._queue.length; |  | ||||||
|                 if (index > 0) { |  | ||||||
|                     while (index--) { |  | ||||||
|                         let q = this._queue[index]; |  | ||||||
|                         if (!q.callback) { |  | ||||||
|                             this._queue.splice(index, 1); |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "ea9bf762-40a7-4bab-b949-8d5b3d4289e2", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,85 +0,0 @@ | |||||||
| import { Action } from "./Action"; |  | ||||||
| import { ActionWithType } from "./ActionWithType"; |  | ||||||
| import { ActionWithType2 } from "./ActionWithType2"; |  | ||||||
|  |  | ||||||
| const {ccclass, property} = cc._decorator; |  | ||||||
|  |  | ||||||
| enum CustomType { |  | ||||||
|     Ex1, Ex2 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| class CustomEvent extends ActionWithType<CustomType, number> {} |  | ||||||
| class CustomEvent2 extends ActionWithType2<CustomType, number> {} |  | ||||||
|  |  | ||||||
| @ccclass |  | ||||||
| export default class NewClass extends cc.Component { |  | ||||||
|     callback: Action<number> = new Action<number>(); |  | ||||||
|     customCallback: CustomEvent = new CustomEvent(); |  | ||||||
|     customCallback2: CustomEvent2 = new CustomEvent2(); |  | ||||||
|  |  | ||||||
|     private num: number = 0; |  | ||||||
|  |  | ||||||
|     start () { |  | ||||||
|         this.callback.AddCallback(this.CB, this); |  | ||||||
|         this.callback.AddCallbackOnce(this.OnceCB, this); |  | ||||||
|  |  | ||||||
|         this.customCallback.AddCallback(CustomType.Ex1, this.CBType, this); |  | ||||||
|         this.customCallback.AddCallbackOnce(CustomType.Ex2, this.OnceCBType, this); |  | ||||||
|  |  | ||||||
|         this.customCallback2.AddCallback(CustomType.Ex2, this.CBTypeAllin1, this); |  | ||||||
|         this.customCallback2.AddCallbackOnce(CustomType.Ex1, this.CBTypeAllin1, this); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     DispatchClick() { |  | ||||||
|         this.num++; |  | ||||||
|  |  | ||||||
|         this.callback.DispatchCallback(this.num); |  | ||||||
|  |  | ||||||
|         this.customCallback.DispatchCallback(CustomType.Ex1, this.num); |  | ||||||
|         this.customCallback.DispatchCallback(CustomType.Ex2, this.num); |  | ||||||
|  |  | ||||||
|         this.customCallback2.DispatchCallback(CustomType.Ex1, this.num); |  | ||||||
|         this.customCallback2.DispatchCallback(CustomType.Ex2, this.num); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     RemoveEventClick() { |  | ||||||
|         this.callback.RemoveByCallback(this.CB); |  | ||||||
|         // this.callback.RemoveByCallback(this.OnceCB); |  | ||||||
|         // this.callback.RemoveByBindTarget(this); |  | ||||||
|         // this.callback.RemoveAll(); |  | ||||||
|  |  | ||||||
|         // this.callbackWithType.RemoveByCallback(this.CBType); |  | ||||||
|         // this.callbackWithType.RemoveByCallback(this.OnceCBType); |  | ||||||
|         this.customCallback.RemoveByType(CustomType.Ex1); |  | ||||||
|         // this.callbackWithType.RemoveByType(CustomType.Ex2); |  | ||||||
|         // this.callbackWithType.RemoveByBindTarget(this); |  | ||||||
|         // this.callbackWithType.RemoveAll(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     OnceCB(x: number) { |  | ||||||
|         cc.log(`OnceCB [${this.num}]`); |  | ||||||
|     } |  | ||||||
|   |  | ||||||
|     CB(x: number) { |  | ||||||
|         cc.log(`CB [${this.num}]`); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     OnceCBType(x: number) { |  | ||||||
|         cc.log(`OnceCBType [${this.num}]`); |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     CBType(x: number) { |  | ||||||
|         cc.log(`CBType [${this.num}]`); |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     CBTypeAllin1(type: CustomType,x: number) { |  | ||||||
|         // switch (type) { |  | ||||||
|         //     case CustomType.Ex1: |  | ||||||
|         //         break; |  | ||||||
|         //     case CustomType.Ex2: |  | ||||||
|         //         break; |  | ||||||
|         // } |  | ||||||
|          |  | ||||||
|         cc.log(`CBTypeAllin1 [${CustomType[type]}][${this.num}]`); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "cc645b73-6192-414d-a5bc-4220c24e322d", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,166 +0,0 @@ | |||||||
| /** |  | ||||||
|  * 回呼函數: fnname (arg: TArg): void |  | ||||||
|  */ |  | ||||||
| interface ActionCallback<TArg> { |  | ||||||
|     (arg: TArg): void; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| interface Struct<TType, TArg> { |  | ||||||
|     callback: ActionCallback<TArg>; |  | ||||||
|     target: any; |  | ||||||
|     type: TType; |  | ||||||
|     once?: boolean; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export class ActionWithType<TType, TArg> { |  | ||||||
|     private _queue: Struct<TType, TArg>[] = []; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 監聽事件 |  | ||||||
|      * @param callback 回呼函數: fnname (arg: TArg): void |  | ||||||
|      * @param bindTarget 回呼時this綁定的對象 |  | ||||||
|      */ |  | ||||||
|     AddCallback(type: TType, callback: ActionCallback<TArg>, bindTarget?: any) { |  | ||||||
|         let q = <Struct<TType, TArg>> { |  | ||||||
|             callback: callback, |  | ||||||
|             target: bindTarget, |  | ||||||
|             type: type |  | ||||||
|         }; |  | ||||||
|         this._queue.push(q); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 監聽事件 (一次性) |  | ||||||
|      * @param callback 回呼函數: fnname (arg: TArg): void |  | ||||||
|      * @param bindTarget 回呼時this綁定的對象 |  | ||||||
|      */ |  | ||||||
|     AddCallbackOnce(type: TType, callback: ActionCallback<TArg>, bindTarget?: any) { |  | ||||||
|         let q = <Struct<TType, TArg>> { |  | ||||||
|             callback: callback, |  | ||||||
|             target: bindTarget, |  | ||||||
|             type: type, |  | ||||||
|             once: true |  | ||||||
|         }; |  | ||||||
|         this._queue.push(q); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 移除事件 |  | ||||||
|      * @param callback  |  | ||||||
|      */ |  | ||||||
|     RemoveByCallback(callback: ActionCallback<TArg>) { |  | ||||||
|         let index = this._queue.length; |  | ||||||
|         if (index > 0) { |  | ||||||
|             while (index--) { |  | ||||||
|                 let q = this._queue[index]; |  | ||||||
|                 if (!q.callback || q.callback === callback) { |  | ||||||
|                     q.callback = undefined; |  | ||||||
|                     this._queue.splice(index, 1); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * 移除事件 |  | ||||||
|      * @param bindTarget 回呼時this綁定的對象 |  | ||||||
|      */ |  | ||||||
|     RemoveByBindTarget(bindTarget: any) { |  | ||||||
|         let index = this._queue.length; |  | ||||||
|         if (index > 0) { |  | ||||||
|             while (index--) { |  | ||||||
|                 let q = this._queue[index]; |  | ||||||
|                 if (!q.callback || q.target === bindTarget) { |  | ||||||
|                     q.callback = undefined; |  | ||||||
|                     this._queue.splice(index, 1); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * 移除事件 |  | ||||||
|      * @param type 事件類型 |  | ||||||
|      */ |  | ||||||
|     RemoveByType(type: TType) { |  | ||||||
|         let index = this._queue.length; |  | ||||||
|         if (index > 0) { |  | ||||||
|             while (index--) { |  | ||||||
|                 let q = this._queue[index]; |  | ||||||
|                 if (!q.callback || q.type === type) { |  | ||||||
|                     q.callback = undefined; |  | ||||||
|                     this._queue.splice(index, 1); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 移除事件 |  | ||||||
|      * @param type 事件類型 |  | ||||||
|      * @param callback  |  | ||||||
|      */ |  | ||||||
|     RemoveCallback(type:TType, callback: ActionCallback<TArg>) { |  | ||||||
|         let index = this._queue.length; |  | ||||||
|         if (index > 0) { |  | ||||||
|             while (index--) { |  | ||||||
|                 let q = this._queue[index]; |  | ||||||
|                 if (!q.callback || (q.type === type && q.callback === callback)) { |  | ||||||
|                     q.callback = undefined; |  | ||||||
|                     this._queue.splice(index, 1); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 移除全部事件 |  | ||||||
|      */ |  | ||||||
|     RemoveAllCallbacks() { |  | ||||||
|         this._queue.forEach(q => q.callback = undefined); |  | ||||||
|         this._queue.length = 0; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 發送事件 |  | ||||||
|      * @param type 事件類型 |  | ||||||
|      * @param arg 參數 |  | ||||||
|      */ |  | ||||||
|     DispatchCallback(type: TType, arg: TArg) { |  | ||||||
|         let index = this._queue.length; |  | ||||||
|         if (index > 0) { |  | ||||||
|             let cleanRemoved = false; |  | ||||||
|             this._queue.slice().forEach(q => { |  | ||||||
|                 if (!q.callback) |  | ||||||
|                 { |  | ||||||
|                     cleanRemoved = true; |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
|                 if (q.type !== type) return; |  | ||||||
|  |  | ||||||
|                 if (q.target) { |  | ||||||
|                     q.callback.call(q.target, arg); |  | ||||||
|                 } else { |  | ||||||
|                     q.callback(arg); |  | ||||||
|                 } |  | ||||||
|                  |  | ||||||
|                 if (q.once) { |  | ||||||
|                     q.callback = undefined; |  | ||||||
|                     cleanRemoved = true; |  | ||||||
|                 } |  | ||||||
|             }); |  | ||||||
|  |  | ||||||
|             if (cleanRemoved) { |  | ||||||
|                 index = this._queue.length; |  | ||||||
|                 if (index > 0) { |  | ||||||
|                     while (index--) { |  | ||||||
|                         let q = this._queue[index]; |  | ||||||
|                         if (!q.callback) { |  | ||||||
|                             this._queue.splice(index, 1); |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "61d770ec-24e2-425b-b66b-2b03e192e45b", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,166 +0,0 @@ | |||||||
| /** |  | ||||||
|  * 回呼函數: fnname (type: TType, arg: TArg): void |  | ||||||
|  */ |  | ||||||
| interface ActionCallback<TType, TArg> { |  | ||||||
|     (type: TType, arg: TArg): void; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| interface Struct<TType, TArg> { |  | ||||||
|     callback: ActionCallback<TType, TArg>; |  | ||||||
|     target: any; |  | ||||||
|     type: TType; |  | ||||||
|     once?: boolean; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export class ActionWithType2<TType, TArg> { |  | ||||||
|     private _queue: Struct<TType, TArg>[] = []; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 監聽事件 |  | ||||||
|      * @param callback 回呼函數: fnname (type: TType, arg: TArg): void |  | ||||||
|      * @param bindTarget 回呼時this綁定的對象 |  | ||||||
|      */ |  | ||||||
|     AddCallback(type: TType, callback: ActionCallback<TType, TArg>, bindTarget?: any) { |  | ||||||
|         let q = <Struct<TType, TArg>> { |  | ||||||
|             callback: callback, |  | ||||||
|             target: bindTarget, |  | ||||||
|             type: type |  | ||||||
|         }; |  | ||||||
|         this._queue.push(q); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 監聽事件 (一次性) |  | ||||||
|      * @param callback 回呼函數: fnname (type: TType, arg: TArg): void |  | ||||||
|      * @param bindTarget 回呼時this綁定的對象 |  | ||||||
|      */ |  | ||||||
|     AddCallbackOnce(type: TType, callback: ActionCallback<TType, TArg>, bindTarget?: any) { |  | ||||||
|         let q = <Struct<TType, TArg>> { |  | ||||||
|             callback: callback, |  | ||||||
|             target: bindTarget, |  | ||||||
|             type: type, |  | ||||||
|             once: true |  | ||||||
|         }; |  | ||||||
|         this._queue.push(q); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 移除事件 |  | ||||||
|      * @param callback  |  | ||||||
|      */ |  | ||||||
|     RemoveByCallback(callback: ActionCallback<TType, TArg>) { |  | ||||||
|         let index = this._queue.length; |  | ||||||
|         if (index > 0) { |  | ||||||
|             while (index--) { |  | ||||||
|                 let q = this._queue[index]; |  | ||||||
|                 if (!q.callback || q.callback === callback) { |  | ||||||
|                     q.callback = undefined; |  | ||||||
|                     this._queue.splice(index, 1); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * 移除事件 |  | ||||||
|      * @param bindTarget 回呼時this綁定的對象 |  | ||||||
|      */ |  | ||||||
|     RemoveByBindTarget(bindTarget: any) { |  | ||||||
|         let index = this._queue.length; |  | ||||||
|         if (index > 0) { |  | ||||||
|             while (index--) { |  | ||||||
|                 let q = this._queue[index]; |  | ||||||
|                 if (!q.callback || q.target === bindTarget) { |  | ||||||
|                     q.callback = undefined; |  | ||||||
|                     this._queue.splice(index, 1); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * 移除事件 |  | ||||||
|      * @param type 事件類型 |  | ||||||
|      */ |  | ||||||
|     RemoveByType(type: TType) { |  | ||||||
|         let index = this._queue.length; |  | ||||||
|         if (index > 0) { |  | ||||||
|             while (index--) { |  | ||||||
|                 let q = this._queue[index]; |  | ||||||
|                 if (!q.callback || q.type === type) { |  | ||||||
|                     q.callback = undefined; |  | ||||||
|                     this._queue.splice(index, 1); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 移除事件 |  | ||||||
|      * @param type 事件類型 |  | ||||||
|      * @param callback  |  | ||||||
|      */ |  | ||||||
|     RemoveCallback(type:TType, callback: ActionCallback<TType, TArg>) { |  | ||||||
|         let index = this._queue.length; |  | ||||||
|         if (index > 0) { |  | ||||||
|             while (index--) { |  | ||||||
|                 let q = this._queue[index]; |  | ||||||
|                 if (!q.callback || (q.type === type && q.callback === callback)) { |  | ||||||
|                     q.callback = undefined; |  | ||||||
|                     this._queue.splice(index, 1); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 移除全部事件 |  | ||||||
|      */ |  | ||||||
|     RemoveAllCallbacks() { |  | ||||||
|         this._queue.forEach(q => q.callback = undefined); |  | ||||||
|         this._queue.length = 0; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 發送事件 |  | ||||||
|      * @param type 事件類型 |  | ||||||
|      * @param arg 參數 |  | ||||||
|      */ |  | ||||||
|     DispatchCallback(type: TType, arg: TArg) { |  | ||||||
|         let index = this._queue.length; |  | ||||||
|         if (index > 0) { |  | ||||||
|             let cleanRemoved = false; |  | ||||||
|             this._queue.slice().forEach(q => { |  | ||||||
|                 if (!q.callback) |  | ||||||
|                 { |  | ||||||
|                     cleanRemoved = true; |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
|                 if (q.type !== type) return; |  | ||||||
|  |  | ||||||
|                 if (q.target) { |  | ||||||
|                     q.callback.call(q.target, type, arg); |  | ||||||
|                 } else { |  | ||||||
|                     q.callback(type, arg); |  | ||||||
|                 } |  | ||||||
|                  |  | ||||||
|                 if (q.once) { |  | ||||||
|                     q.callback = undefined; |  | ||||||
|                     cleanRemoved = true; |  | ||||||
|                 } |  | ||||||
|             }); |  | ||||||
|  |  | ||||||
|             if (cleanRemoved) { |  | ||||||
|                 index = this._queue.length; |  | ||||||
|                 if (index > 0) { |  | ||||||
|                     while (index--) { |  | ||||||
|                         let q = this._queue[index]; |  | ||||||
|                         if (!q.callback) { |  | ||||||
|                             this._queue.splice(index, 1); |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "ed703ebd-efd4-4ec9-9b84-de748ef8f9e8", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,9 +0,0 @@ | |||||||
|  |  | ||||||
| /** System類型 */ |  | ||||||
| export enum System_Eevent { |  | ||||||
| 	/** SetFCMToken */ |  | ||||||
| 	SetFCMToken, |  | ||||||
|  |  | ||||||
| 	/** Test */ |  | ||||||
| 	Test |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "f0d14145-1175-48fa-b591-4b98f59a0e04", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.3", |  | ||||||
|   "uuid": "09d69d12-a6d1-4bb1-bcfe-faa811632467", |  | ||||||
|   "importer": "folder", |  | ||||||
|   "isBundle": false, |  | ||||||
|   "bundleName": "", |  | ||||||
|   "priority": 1, |  | ||||||
|   "compressionType": {}, |  | ||||||
|   "optimizeHotUpdate": {}, |  | ||||||
|   "inlineSpriteFrames": {}, |  | ||||||
|   "isRemoteBundle": {}, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,86 +0,0 @@ | |||||||
| export module Encoding.UTF8 { |  | ||||||
|  |  | ||||||
| 	export function GetBytes(str: string) { |  | ||||||
| 		let len = str.length, resPos = -1; |  | ||||||
| 		let resArr = new Uint8Array(len * 3); |  | ||||||
| 		for (let point = 0, nextcode = 0, i = 0; i !== len;) { |  | ||||||
| 			point = str.charCodeAt(i), i += 1; |  | ||||||
| 			if (point >= 0xD800 && point <= 0xDBFF) { |  | ||||||
| 				if (i === len) { |  | ||||||
| 					resArr[resPos += 1] = 0xef; |  | ||||||
| 					resArr[resPos += 1] = 0xbf; |  | ||||||
| 					resArr[resPos += 1] = 0xbd; |  | ||||||
| 					break; |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				nextcode = str.charCodeAt(i); |  | ||||||
| 				if (nextcode >= 0xDC00 && nextcode <= 0xDFFF) { |  | ||||||
| 					point = (point - 0xD800) * 0x400 + nextcode - 0xDC00 + 0x10000; |  | ||||||
| 					i += 1; |  | ||||||
| 					if (point > 0xffff) { |  | ||||||
| 						resArr[resPos += 1] = (0x1e << 3) | (point >>> 18); |  | ||||||
| 						resArr[resPos += 1] = (0x2 << 6) | ((point >>> 12) & 0x3f); |  | ||||||
| 						resArr[resPos += 1] = (0x2 << 6) | ((point >>> 6) & 0x3f); |  | ||||||
| 						resArr[resPos += 1] = (0x2 << 6) | (point & 0x3f); |  | ||||||
| 						continue; |  | ||||||
| 					} |  | ||||||
| 				} else { |  | ||||||
| 					resArr[resPos += 1] = 0xef; |  | ||||||
| 					resArr[resPos += 1] = 0xbf; |  | ||||||
| 					resArr[resPos += 1] = 0xbd; |  | ||||||
| 					continue; |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 			if (point <= 0x007f) { |  | ||||||
| 				resArr[resPos += 1] = (0x0 << 7) | point; |  | ||||||
| 			} else if (point <= 0x07ff) { |  | ||||||
| 				resArr[resPos += 1] = (0x6 << 5) | (point >>> 6); |  | ||||||
| 				resArr[resPos += 1] = (0x2 << 6) | (point & 0x3f); |  | ||||||
| 			} else { |  | ||||||
| 				resArr[resPos += 1] = (0xe << 4) | (point >>> 12); |  | ||||||
| 				resArr[resPos += 1] = (0x2 << 6) | ((point >>> 6) & 0x3f); |  | ||||||
| 				resArr[resPos += 1] = (0x2 << 6) | (point & 0x3f); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		return resArr.subarray(0, resPos + 1); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	export function GetString(array: Uint8Array) { |  | ||||||
| 		let str = ""; |  | ||||||
| 		let i = 0, len = array.length; |  | ||||||
| 		while (i < len) { |  | ||||||
| 			let c = array[i++]; |  | ||||||
| 			switch (c >> 4) { |  | ||||||
| 				case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: |  | ||||||
| 					str += String.fromCharCode(c); |  | ||||||
| 					break; |  | ||||||
| 				case 12: case 13: |  | ||||||
| 					str += String.fromCharCode(((c & 0x1F) << 6) | (array[i++] & 0x3F)); |  | ||||||
| 					break; |  | ||||||
| 				case 14: |  | ||||||
| 					str += String.fromCharCode(((c & 0x0F) << 12) | ((array[i++] & 0x3F) << 6) | ((array[i++] & 0x3F) << 0)); |  | ||||||
| 					break; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		return str; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	export function b64EncodeUnicode(str) { |  | ||||||
| 		return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) { |  | ||||||
| 			return String.fromCharCode('0x' + p1); |  | ||||||
| 		})); |  | ||||||
| 	} |  | ||||||
| 	export function b64DecodeUnicode(str) { |  | ||||||
| 		return decodeURIComponent(atob(str).split('').map(function (c) { |  | ||||||
| 			return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); |  | ||||||
| 		}).join('')); |  | ||||||
| 	} |  | ||||||
| 	export function isBase64(str) { |  | ||||||
| 		if (str === '' || str.trim() === '') { return false; } |  | ||||||
| 		try { |  | ||||||
| 			return btoa(atob(str)) == str; |  | ||||||
| 		} catch (err) { |  | ||||||
| 			return false; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "43bf5724-e939-4189-b981-c32ef694e5a5", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.3", |  | ||||||
|   "uuid": "9f510f2b-83d8-4097-8683-32d6134323fb", |  | ||||||
|   "importer": "folder", |  | ||||||
|   "isBundle": false, |  | ||||||
|   "bundleName": "", |  | ||||||
|   "priority": 1, |  | ||||||
|   "compressionType": {}, |  | ||||||
|   "optimizeHotUpdate": {}, |  | ||||||
|   "inlineSpriteFrames": {}, |  | ||||||
|   "isRemoteBundle": {}, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,43 +0,0 @@ | |||||||
| const CANCEL = Symbol(); |  | ||||||
|  |  | ||||||
| export interface CancellationToken { |  | ||||||
|     readonly IsCancellationRequested: boolean; |  | ||||||
|     ThrowIfCancellationRequested(): void; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export class CancellationTokenSource { |  | ||||||
|     readonly Token: CancellationToken; |  | ||||||
|  |  | ||||||
|     constructor() { |  | ||||||
|         this.Token = new CancellationTokenImpl(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Cancel() { |  | ||||||
|         this.Token[CANCEL](); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export class TaskCancelledException extends Error { |  | ||||||
|     constructor() { |  | ||||||
|         super("Task Cancelled"); |  | ||||||
|         Reflect.setPrototypeOf(this, TaskCancelledException.prototype); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| class CancellationTokenImpl implements CancellationToken { |  | ||||||
|     IsCancellationRequested: boolean; |  | ||||||
|  |  | ||||||
|     constructor() { |  | ||||||
|         this.IsCancellationRequested = false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     ThrowIfCancellationRequested() { |  | ||||||
|         if (this.IsCancellationRequested) { |  | ||||||
|             throw new TaskCancelledException(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     [CANCEL]() { |  | ||||||
|         this.IsCancellationRequested = true; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "9a414131-91a8-4d02-9921-9d1ee01764c3", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.3", |  | ||||||
|   "uuid": "fbfe97a8-24ca-4f67-b049-323652c7194b", |  | ||||||
|   "importer": "folder", |  | ||||||
|   "isBundle": false, |  | ||||||
|   "bundleName": "", |  | ||||||
|   "priority": 1, |  | ||||||
|   "compressionType": {}, |  | ||||||
|   "optimizeHotUpdate": {}, |  | ||||||
|   "inlineSpriteFrames": {}, |  | ||||||
|   "isRemoteBundle": {}, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,17 +0,0 @@ | |||||||
| import { BaseEnumerator } from "./BaseEnumerator"; |  | ||||||
|  |  | ||||||
| export class ActionEnumerator extends BaseEnumerator { |  | ||||||
|     private _action: Function; |  | ||||||
|  |  | ||||||
|     constructor(action: Function) { |  | ||||||
|         super(); |  | ||||||
|         this._action = action; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     next(value?: any): IteratorResult<any> { |  | ||||||
|         if (this._action) { |  | ||||||
|             this._action(); |  | ||||||
|         } |  | ||||||
|         return { done: true, value: undefined }; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "3cf9e5c3-520f-48a9-8821-9be76d519765", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,87 +0,0 @@ | |||||||
| import { IEnumeratorV2, IEnumeratorV2Started } from "../IEnumeratorV2"; |  | ||||||
| import { CoroutineExecutor } from "./CoroutineExecutor"; |  | ||||||
|  |  | ||||||
| export abstract class BaseEnumerator implements IEnumeratorV2 { |  | ||||||
|     public nextEnumerator: BaseEnumerator; |  | ||||||
|  |  | ||||||
|     abstract next(value?: any): IteratorResult<any>; |  | ||||||
|      |  | ||||||
|     Start(target?: any): IEnumeratorV2Started { |  | ||||||
|         let executor = LazyLoad.EnumeratorExecutor(this, target); |  | ||||||
|         CoroutineExecutor.instance.StartCoroutine(executor); |  | ||||||
|         return executor; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Then(iterator: Iterator<any>): IEnumeratorV2 { |  | ||||||
|         if (!iterator) return this; |  | ||||||
|  |  | ||||||
|         if (iterator instanceof BaseEnumerator) { |  | ||||||
|             BaseEnumerator.getLastEnumerator(this).nextEnumerator = iterator; |  | ||||||
|             return this; |  | ||||||
|         } else { |  | ||||||
|             let enumerator = LazyLoad.SingleEnumerator(iterator); |  | ||||||
|             BaseEnumerator.getLastEnumerator(this).nextEnumerator = enumerator; |  | ||||||
|             return this; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     ThenSerial(...iterators: Iterator<any>[]): IEnumeratorV2 { |  | ||||||
|         let last = BaseEnumerator.getLastEnumerator(this); |  | ||||||
|         for (let iterator of iterators) { |  | ||||||
|             if (iterator instanceof BaseEnumerator) { |  | ||||||
|                 last.nextEnumerator = iterator; |  | ||||||
|             } else { |  | ||||||
|                 let enumerator = LazyLoad.SingleEnumerator(iterator); |  | ||||||
|                 last.nextEnumerator = enumerator; |  | ||||||
|             } |  | ||||||
|             last = last.nextEnumerator; |  | ||||||
|         } |  | ||||||
|         return this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     ThenParallel(...iterators: Iterator<any>[]): IEnumeratorV2 { |  | ||||||
|         return this.Then(LazyLoad.ParallelEnumerator(...iterators)); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     ThenAction(action: Function, delaySeconds?:number): IEnumeratorV2 { |  | ||||||
|         if (delaySeconds > 0) { |  | ||||||
|             return this.ThenSerial(LazyLoad.WaitTimeEnumerator(delaySeconds), LazyLoad.ActionEnumerator(action)); |  | ||||||
|         } else { |  | ||||||
|             return this.Then(LazyLoad.ActionEnumerator(action)); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     ThenWaitTime(seconds: number): IEnumeratorV2 { |  | ||||||
|         return this.Then(LazyLoad.WaitTimeEnumerator(seconds)); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     static getLastEnumerator(enumerator: BaseEnumerator): BaseEnumerator { |  | ||||||
|         let next = enumerator; |  | ||||||
|         while (next.nextEnumerator) { |  | ||||||
|             next = next.nextEnumerator; |  | ||||||
|         } |  | ||||||
|         return next; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| module LazyLoad { |  | ||||||
|     export function EnumeratorExecutor(enumerator: BaseEnumerator, target: any) { |  | ||||||
|         return new (require("./EnumeratorExecutor") as typeof import("./EnumeratorExecutor")).EnumeratorExecutor(enumerator, target); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     export function SingleEnumerator(iterator: Iterator<any>) { |  | ||||||
|         return new (require("./SingleEnumerator") as typeof import("./SingleEnumerator")).SingleEnumerator(iterator); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     export function ParallelEnumerator(...iterators: Iterator<any>[]) { |  | ||||||
|         return new (require("./ParallelEnumerator") as typeof import("./ParallelEnumerator")).ParallelEnumerator(iterators); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     export function WaitTimeEnumerator(seconds: number) { |  | ||||||
|         return new (require("./WaitTimeEnumerator") as typeof import("./WaitTimeEnumerator")).WaitTimeEnumerator(seconds); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     export function ActionEnumerator(action: Function) { |  | ||||||
|         return new (require("./ActionEnumerator") as typeof import("./ActionEnumerator")).ActionEnumerator(action); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "4084537c-c7e8-4d47-b283-39be77ef9685", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,95 +0,0 @@ | |||||||
| import { EnumeratorExecutor } from "./EnumeratorExecutor"; |  | ||||||
|  |  | ||||||
| export class CoroutineExecutor { |  | ||||||
|     private static _instance: CoroutineExecutor;  |  | ||||||
|     static get instance() { |  | ||||||
|         return CoroutineExecutor._instance = CoroutineExecutor._instance || new CoroutineExecutor(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private _executors: EnumeratorExecutor[] = []; |  | ||||||
|     private _nextExecutors: EnumeratorExecutor[] = []; |  | ||||||
|     private _isRunning: boolean = false; |  | ||||||
|     private _cleanRemoved: boolean = false; |  | ||||||
|     private _scheduler: cc.Scheduler; |  | ||||||
|      |  | ||||||
|     constructor() { |  | ||||||
|         this._scheduler = cc.director.getScheduler(); |  | ||||||
|         this._scheduler.enableForTarget(this); |  | ||||||
|         this._scheduler.scheduleUpdate(this, 0, true); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     StartCoroutine(executor: EnumeratorExecutor) { |  | ||||||
|         executor.next(0); |  | ||||||
|         //TODO: 這邊要考量next後馬上接BaseEnumerator/Iterator的情形 |  | ||||||
|          |  | ||||||
|         if (!this._isRunning) { |  | ||||||
|             this._executors.push(executor); |  | ||||||
|  |  | ||||||
|             if (this._scheduler.isTargetPaused(this)) { |  | ||||||
|                 this._scheduler.resumeTarget(this); |  | ||||||
|             } |  | ||||||
|         } else { |  | ||||||
|             this._nextExecutors.push(executor); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     StopCoroutineBy(target: any) { |  | ||||||
|         if (!target) return; |  | ||||||
|  |  | ||||||
|         for (let r of this._executors) { |  | ||||||
|             if (target === r.target) { |  | ||||||
|                 r.Stop(); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|          |  | ||||||
|         for (let r of this._nextExecutors) { |  | ||||||
|             if (target === r.target) { |  | ||||||
|                 r.Stop(); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     update(delta: number) { |  | ||||||
|         if (this._nextExecutors.length) { |  | ||||||
|             this._executors.push(...this._nextExecutors); |  | ||||||
|             this._nextExecutors.length = 0; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (this._cleanRemoved) { |  | ||||||
|             // 移除[doneFlag=true]的協程 |  | ||||||
|             let index = this._executors.length; |  | ||||||
|             while (index--) { |  | ||||||
|                 let r = this._executors[index]; |  | ||||||
|                 if (r.doneFlag) { |  | ||||||
|                     this._executors.splice(index, 1); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             this._cleanRemoved = false; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (this._executors.length == 0) { |  | ||||||
|             if (CC_DEBUG) { |  | ||||||
|                 cc.log("[CoroutineV2] All coroutines done"); |  | ||||||
|             } |  | ||||||
|             this._scheduler.pauseTarget(this); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this._isRunning = true; |  | ||||||
|  |  | ||||||
|         // 執行協程 |  | ||||||
|         for (let r of this._executors) { |  | ||||||
|             if (r.doneFlag || r.pauseFlag || r.childFlag)  |  | ||||||
|             { |  | ||||||
|                 if (r.doneFlag) { |  | ||||||
|                     this._cleanRemoved = true; |  | ||||||
|                 } |  | ||||||
|                 continue; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             r.next(delta); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this._isRunning = false; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "f25b1e42-90d8-4fc0-9925-6e7e92296d57", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,169 +0,0 @@ | |||||||
| import { IEnumeratorV2Started } from "../IEnumeratorV2"; |  | ||||||
| import { BaseEnumerator } from "./BaseEnumerator"; |  | ||||||
| import { SingleEnumerator } from "./SingleEnumerator"; |  | ||||||
|  |  | ||||||
| export class EnumeratorExecutor implements IEnumeratorV2Started { |  | ||||||
|     public Current: any; |  | ||||||
|  |  | ||||||
|     public target: any; |  | ||||||
|     public pauseFlag: boolean; |  | ||||||
|     public doneFlag: boolean; |  | ||||||
|     public childFlag: boolean; |  | ||||||
|     public asyncFlag: boolean; |  | ||||||
|     public error: any; |  | ||||||
|  |  | ||||||
|     private _executor: EnumeratorExecutor; |  | ||||||
|     private _enumerator: BaseEnumerator; |  | ||||||
|  |  | ||||||
|     constructor(enumerator: BaseEnumerator, target: any) { |  | ||||||
|         this.target = target; |  | ||||||
|         this._enumerator = enumerator; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     next(delta?: any): IteratorResult<any> { |  | ||||||
|         if (this._executor && this._executor.doneFlag) { |  | ||||||
|             this._executor = null; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (this.doneFlag || (!this._enumerator && !this._executor)) { |  | ||||||
|             this.doneFlag = true; |  | ||||||
|             return { done: true, value: undefined }; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (this.asyncFlag || this.pauseFlag) return { done: false, value: undefined }; |  | ||||||
|  |  | ||||||
|         let result: IteratorResult<any>; |  | ||||||
|  |  | ||||||
|         if (this._executor) { |  | ||||||
|             result = this._executor.next(delta); |  | ||||||
|             this.Current = this._executor.Current; |  | ||||||
|             if (this._executor.doneFlag) { |  | ||||||
|                 this._executor = null; |  | ||||||
|             } else { |  | ||||||
|                 result.done = false; |  | ||||||
|                 return result; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|          |  | ||||||
|         if (!this._enumerator) { |  | ||||||
|             this.doneFlag = true; |  | ||||||
|             return { done: true, value: undefined }; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         try { |  | ||||||
|             result = this._enumerator.next(delta); |  | ||||||
|             let value = result.value; |  | ||||||
|             let done = result.done; |  | ||||||
|  |  | ||||||
|             if (value) { |  | ||||||
|                 // Iterator |  | ||||||
|                 if (typeof value[Symbol.iterator] === 'function') { |  | ||||||
|                     value = new SingleEnumerator(<Iterator<any>>value); |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 if (value instanceof BaseEnumerator) { |  | ||||||
|                     if (!done) { |  | ||||||
|                         BaseEnumerator.getLastEnumerator(value).nextEnumerator = this._enumerator; |  | ||||||
|                     } |  | ||||||
|                     this._enumerator = value; |  | ||||||
|                     result = this._enumerator.next(delta); |  | ||||||
|                     value = result.value; |  | ||||||
|                     done = result.done; |  | ||||||
|                      |  | ||||||
|                     if (value) { |  | ||||||
|                         // Iterator again |  | ||||||
|                         if (typeof value[Symbol.iterator] === 'function') { |  | ||||||
|                             value = new SingleEnumerator(<Iterator<any>>value); |  | ||||||
|                         }  |  | ||||||
|                          |  | ||||||
|                         if (value instanceof BaseEnumerator) { |  | ||||||
|                             if (!done) { |  | ||||||
|                                 BaseEnumerator.getLastEnumerator(value).nextEnumerator = this._enumerator; |  | ||||||
|                             } |  | ||||||
|                             this._enumerator = value; |  | ||||||
|                             result.done = false; |  | ||||||
|                             done = false; |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                  |  | ||||||
|                 if (value instanceof EnumeratorExecutor) { |  | ||||||
|                     if (done) { |  | ||||||
|                         this._enumerator = this._enumerator.nextEnumerator; |  | ||||||
|                     } |  | ||||||
|                     value.childFlag = true; |  | ||||||
|                     result.done = false; |  | ||||||
|                     done = false; |  | ||||||
|                     this._executor = value; |  | ||||||
|                 } else if (Promise.resolve(value) === value) { |  | ||||||
|                     this.asyncFlag = true; |  | ||||||
|                     result.done = false; |  | ||||||
|                     done = false; |  | ||||||
|                     (<Promise<any>>value) |  | ||||||
|                         .then(v => { |  | ||||||
|                             this.asyncFlag = false; |  | ||||||
|                             this.Current = v; |  | ||||||
|                             if (done) { |  | ||||||
|                                 this._enumerator = this._enumerator.nextEnumerator; |  | ||||||
|                             } |  | ||||||
|                         }) |  | ||||||
|                         .catch(e => { |  | ||||||
|                             this.asyncFlag = false; |  | ||||||
|                             this.doneFlag = true; |  | ||||||
|                             this._enumerator = null; |  | ||||||
|                             this.error = e; |  | ||||||
|                             if (e instanceof Error) { |  | ||||||
|                                 cc.error(e.stack); |  | ||||||
|                             } else { |  | ||||||
|                                 cc.error(`Error: ${JSON.stringify(e)}`); |  | ||||||
|                             } |  | ||||||
|                         }); |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 this.Current = value; |  | ||||||
|             } |  | ||||||
|              |  | ||||||
|             if (done) { |  | ||||||
|                 this._enumerator = this._enumerator.nextEnumerator; |  | ||||||
|                 if (this._enumerator) { |  | ||||||
|                     result.done = false; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         catch (e) |  | ||||||
|         { |  | ||||||
|             this.doneFlag = true; |  | ||||||
|             this.error = e; |  | ||||||
|             if (e instanceof Error) { |  | ||||||
|                 cc.error(e.stack); |  | ||||||
|             } else { |  | ||||||
|                 cc.error(`Error: ${JSON.stringify(e)}`); |  | ||||||
|             } |  | ||||||
|             result = { done: true, value: e }; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return result; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Stop(): void { |  | ||||||
|         this.doneFlag = true; |  | ||||||
|         if (this._executor) { |  | ||||||
|             this._executor.Stop(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Pause(): void { |  | ||||||
|         this.pauseFlag = true; |  | ||||||
|         if (this._executor) { |  | ||||||
|             this._executor.Pause(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Resume(): void { |  | ||||||
|         this.pauseFlag = false; |  | ||||||
|         if (this._executor) { |  | ||||||
|             this._executor.Resume(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "91cb70ed-e6f9-4ce0-b7c5-1720087b3bd7", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,46 +0,0 @@ | |||||||
| import { BaseEnumerator } from "./BaseEnumerator"; |  | ||||||
| import { EnumeratorExecutor } from "./EnumeratorExecutor"; |  | ||||||
| import { SingleEnumerator } from "./SingleEnumerator"; |  | ||||||
|  |  | ||||||
| export class ParallelEnumerator extends BaseEnumerator { |  | ||||||
|     private _executors: EnumeratorExecutor[] = []; |  | ||||||
|  |  | ||||||
|     constructor(iterators: Iterator<any>[]) { |  | ||||||
|         super(); |  | ||||||
|         if (iterators && iterators.length) { |  | ||||||
|             for (let iterator of iterators) { |  | ||||||
|                 if (iterator instanceof BaseEnumerator) { |  | ||||||
|                     this._executors.push(new EnumeratorExecutor(iterator, null)); |  | ||||||
|                 } else { |  | ||||||
|                     this._executors.push(new EnumeratorExecutor(new SingleEnumerator(iterator), null)); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     next(value?: any): IteratorResult<any> { |  | ||||||
|         if (this._executors.length) { |  | ||||||
|             // 先移除[doneFlag=true]協程 |  | ||||||
|             let index = this._executors.length; |  | ||||||
|             while (index--) { |  | ||||||
|                 let r = this._executors[index]; |  | ||||||
|                 if (r.doneFlag) { |  | ||||||
|                     this._executors.splice(index, 1); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (this._executors.length == 0) { |  | ||||||
|                 return { done: true, value: undefined }; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             // 執行協程 |  | ||||||
|             for (let r of this._executors) { |  | ||||||
|                 r.next(value); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             return { done: false, value: undefined }; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return { done: true, value: undefined }; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "017ebc9a-5152-4f94-bbaf-e3b914e87b41", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,18 +0,0 @@ | |||||||
| import { BaseEnumerator } from "./BaseEnumerator"; |  | ||||||
|  |  | ||||||
| export class SingleEnumerator extends BaseEnumerator { |  | ||||||
|     private _iterator: Iterator<any>; |  | ||||||
|  |  | ||||||
|     constructor(iterator: Iterator<any>) { |  | ||||||
|         super(); |  | ||||||
|         this._iterator = iterator; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     next(value?: any): IteratorResult<any> { |  | ||||||
|         if (!this._iterator) { |  | ||||||
|             return { done: true, value: undefined }; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return this._iterator.next(value); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "c439d019-2da8-48b8-a65b-bff928d0fda8", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,21 +0,0 @@ | |||||||
| import { BaseEnumerator } from "./BaseEnumerator"; |  | ||||||
|  |  | ||||||
| export class WaitTimeEnumerator extends BaseEnumerator { |  | ||||||
|     private _seconds: number; |  | ||||||
|  |  | ||||||
|     constructor(seconds: number) { |  | ||||||
|         super(); |  | ||||||
|         this._seconds = seconds; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     next(value?: any): IteratorResult<any> { |  | ||||||
|         let delta = value as number; |  | ||||||
|         this._seconds -= delta; |  | ||||||
|  |  | ||||||
|         if (this._seconds <= 0) { |  | ||||||
|             return { done: true, value: 0 }; |  | ||||||
|         } else { |  | ||||||
|             return { done: false, value: this._seconds }; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "a3038e6f-1bb4-4aff-a686-b69209df3592", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,199 +0,0 @@ | |||||||
| import { CoroutineV2 } from "./CoroutineV2"; |  | ||||||
| import { IEnumeratorV2Started } from "./IEnumeratorV2"; |  | ||||||
|  |  | ||||||
| const {ccclass, property} = cc._decorator; |  | ||||||
|  |  | ||||||
| class A { |  | ||||||
|     private numbers: number[] = [1, 2]; |  | ||||||
|     private index = 0; |  | ||||||
|  |  | ||||||
|     [Symbol.iterator](): IterableIterator<any> { |  | ||||||
|         return this; |  | ||||||
|     }     |  | ||||||
|      |  | ||||||
|     next(value?: any): IteratorResult<any> { |  | ||||||
|         if (this.index < this.numbers.length) { |  | ||||||
|             let value = this.numbers[this.index++]; |  | ||||||
|             cc.log(`A=> ${value}`); |  | ||||||
|             return { |  | ||||||
|                 done: false, |  | ||||||
|                 value: value |  | ||||||
|             }; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return { done: true, value: undefined }; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| @ccclass |  | ||||||
| export default class CoroutineExample extends cc.Component { |  | ||||||
|     private _routine: IEnumeratorV2Started; |  | ||||||
|     private _obj: Object = { "a": true }; |  | ||||||
|     private _obj2: Object = { "b": true }; |  | ||||||
|  |  | ||||||
|     private _num: number = 3; |  | ||||||
|  |  | ||||||
|     button1Clicked() { |  | ||||||
|         // this._routine = CoroutineV2 |  | ||||||
|         //                     .Parallel(this.Coroutine1(1, 3), this.Coroutine1(4, 6)) |  | ||||||
|         //                     .ThenWaitTime(2) |  | ||||||
|         //                     .Then(this.Coroutine1(7, 9)) |  | ||||||
|         //                     .ThenWaitTime(2) |  | ||||||
|         //                     .ThenAction(() => cc.log("action callback 1")) |  | ||||||
|         //                     .ThenWaitTime(2) |  | ||||||
|         //                     .ThenAction(this.actionCallback) |  | ||||||
|         //                     //.Start(this); |  | ||||||
|         //                     .Start(this); |  | ||||||
|         // this._routine = CoroutineV2.Single(this.FunA()).Start(this); |  | ||||||
|  |  | ||||||
|         this._routine = CoroutineV2.Single(this.Test1_1()).Start(this); |  | ||||||
|         // this._routine = CoroutineV2.Single(this.Test2_1()).Start(this); |  | ||||||
|     }  |  | ||||||
|  |  | ||||||
|     *Test1_1() { |  | ||||||
|         yield null; |  | ||||||
|         yield *this.Test1_2(); |  | ||||||
|         // CoroutineV2.Single(this.Test1_3()).Start(this); |  | ||||||
|         yield this.Test1_3(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     *Test1_2() { |  | ||||||
|         yield null; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     *Test1_3() { |  | ||||||
|         yield this.Test1_3_1(); |  | ||||||
|         yield CoroutineV2.Single(this.Test1_4()).Start(this._obj); |  | ||||||
|         // yield CoroutineV2.Single(this.Test1_4()); //.Start(this); |  | ||||||
|         // yield *this.Test1_4(); |  | ||||||
|         cc.log("main wait 3"); |  | ||||||
|         yield CoroutineV2.WaitTime(2); |  | ||||||
|         cc.log("done"); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     *Test1_3_1() { |  | ||||||
|         yield this.Test1_3_2(); |  | ||||||
|         yield CoroutineV2.WaitTime(1); |  | ||||||
|         cc.log("Test1_3_1.1"); |  | ||||||
|         yield CoroutineV2.WaitTime(1); |  | ||||||
|         cc.log("Test1_3_1.2"); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     *Test1_3_2() { |  | ||||||
|         yield this.Test1_3_3(); |  | ||||||
|         yield CoroutineV2.WaitTime(1); |  | ||||||
|         cc.log("Test1_3_2.1"); |  | ||||||
|         yield CoroutineV2.WaitTime(1); |  | ||||||
|         cc.log("Test1_3_2.2"); |  | ||||||
|         yield CoroutineV2.WaitTime(1); |  | ||||||
|         cc.log("Test1_3_2.3"); |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     *Test1_3_3() { |  | ||||||
|         yield CoroutineV2.WaitTime(1); |  | ||||||
|         cc.log("Test1_3_3.1"); |  | ||||||
|         yield CoroutineV2.WaitTime(1); |  | ||||||
|         cc.log("Test1_3_3.2"); |  | ||||||
|         yield CoroutineV2.WaitTime(1); |  | ||||||
|         cc.log("Test1_3_3.3"); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     *Test1_4() { |  | ||||||
|         this._num++; |  | ||||||
|         cc.log(`WaitTime2 ${this._num}`); |  | ||||||
|         yield CoroutineV2.WaitTime(2).Start(this._obj2); |  | ||||||
|         this._num++; |  | ||||||
|         cc.log(`WaitTime2 ${this._num}`); |  | ||||||
|         yield CoroutineV2.WaitTime(2).Start(this._obj2); |  | ||||||
|         this._num++; |  | ||||||
|         cc.log(`WaitTime2 ${this._num}`); |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     *Test2_1() { |  | ||||||
|         cc.log("111"); |  | ||||||
|         CoroutineV2.Single(this.Test2_2()).Start(this); |  | ||||||
|         cc.log("333"); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     *Test2_2() { |  | ||||||
|         cc.log("222"); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     button2Clicked() { |  | ||||||
|         // this._routine && this._routine.Stop(); |  | ||||||
|         if (this._obj2) { |  | ||||||
|             CoroutineV2.StopCoroutinesBy(this._obj2); |  | ||||||
|             this._obj2 = null; |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|         if (this._obj) { |  | ||||||
|             CoroutineV2.StopCoroutinesBy(this._obj); |  | ||||||
|             this._obj = null; |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|          |  | ||||||
|         CoroutineV2.StopCoroutinesBy(this); |  | ||||||
|  |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     button3Clicked() { |  | ||||||
|         // CoroutineV2.StopCoroutinesBy(this); |  | ||||||
|         this._routine && this._routine.Pause(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     button4Clicked() { |  | ||||||
|         // CoroutineV2.StopCoroutinesBy(this); |  | ||||||
|         this._routine && this._routine.Resume(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     *Coroutine1(start:number, end: number) |  | ||||||
|     { |  | ||||||
|         for (let i = start; i <= end; i++) { |  | ||||||
|             // yield CoroutineV2.WaitTime(1).Start(); // Start()可以省略, 會由外層啟動 |  | ||||||
|             // yield CoroutineV2.WaitTime(1).Start(this); // target也可以省略, 由外層的target控制 |  | ||||||
|              |  | ||||||
|             yield CoroutineV2.WaitTime(1).Start(); |  | ||||||
|             cc.log(`C1 => ${i}`); |  | ||||||
|  |  | ||||||
|             // 嵌套 |  | ||||||
|             yield CoroutineV2 |  | ||||||
|                         .WaitTime(1) |  | ||||||
|                         .ThenParallel( |  | ||||||
|                             // 再嵌套 |  | ||||||
|                             CoroutineV2.Action(() => cc.log("start parallel")), |  | ||||||
|                             this.Coroutine2(10, 2),  |  | ||||||
|                             this.Coroutine2(20, 2),  |  | ||||||
|                             new A()) |  | ||||||
|                         .ThenAction(() => cc.log("end parallel")) |  | ||||||
|                         .Start(); |  | ||||||
|  |  | ||||||
|             // Promise |  | ||||||
|             yield this.loadItemAsync("settings.json"); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     *Coroutine2(num: number, repeat: number) |  | ||||||
|     { |  | ||||||
|         for (let i = 0; i < repeat; i++) { |  | ||||||
|             //yield CoroutineV2.WaitTime(2); |  | ||||||
|             yield 0; |  | ||||||
|             cc.log(`C2: ${num}`); |  | ||||||
|             // yield CoroutineV2.WaitTime(1); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     actionCallback() { |  | ||||||
|         cc.log("action callback 2"); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     loadItemAsync(id: string): Promise<{id: string}> { |  | ||||||
|         return new Promise((resolve) => { |  | ||||||
|             cc.log('loading item start:', id); |  | ||||||
|             setTimeout(() => { |  | ||||||
|                 resolve({ id: id }); |  | ||||||
|                 cc.log('loading item done:', id); |  | ||||||
|             }, 3000); |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "dfd32c11-76f6-4e38-9272-1d7966d1ef3c", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,75 +0,0 @@ | |||||||
| import { IEnumeratorV2, IEnumeratorV2Started } from "./IEnumeratorV2"; |  | ||||||
| import { BaseEnumerator } from "./Core/BaseEnumerator"; |  | ||||||
| import { SingleEnumerator } from "./Core/SingleEnumerator"; |  | ||||||
| import { ParallelEnumerator } from "./Core/ParallelEnumerator"; |  | ||||||
| import { WaitTimeEnumerator } from "./Core/WaitTimeEnumerator"; |  | ||||||
| import { ActionEnumerator } from "./Core/ActionEnumerator"; |  | ||||||
| import { CoroutineExecutor } from "./Core/CoroutineExecutor"; |  | ||||||
|  |  | ||||||
| export module CoroutineV2 { |  | ||||||
|     /** |  | ||||||
|      * 啟動一般協程 |  | ||||||
|      */ |  | ||||||
|     export function StartCoroutine(iterator: Iterator<any>, target?: any): IEnumeratorV2Started { |  | ||||||
|         return Single(iterator).Start(target); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 依據IEnumeratorV2.Start(target)綁定的目標, 來停止協程 |  | ||||||
|      * @param target  |  | ||||||
|      */ |  | ||||||
|     export function StopCoroutinesBy(target: any) { |  | ||||||
|         CoroutineExecutor.instance.StopCoroutineBy(target); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 單一協程 |  | ||||||
|      */ |  | ||||||
|     export function Single(iterator: Iterator<any>): IEnumeratorV2 { |  | ||||||
|         if (iterator instanceof BaseEnumerator) { |  | ||||||
|             return iterator; |  | ||||||
|         } else { |  | ||||||
|             return new SingleEnumerator(iterator); |  | ||||||
|         }  |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 平行協程 |  | ||||||
|      */ |  | ||||||
|     export function Parallel(...iterators: Iterator<any>[]): IEnumeratorV2 { |  | ||||||
|         return new ParallelEnumerator(iterators); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 序列協程 |  | ||||||
|      */ |  | ||||||
|     export function Serial(...iterators: Iterator<any>[]): IEnumeratorV2 { |  | ||||||
|         let [iterator, ...others] = iterators; |  | ||||||
|         if (iterator instanceof BaseEnumerator) { |  | ||||||
|             return iterator.ThenSerial(...others); |  | ||||||
|         } else { |  | ||||||
|             return new SingleEnumerator(iterator).ThenSerial(...others); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 執行方法協程 |  | ||||||
|      * @param action 方法 |  | ||||||
|      * @param delaySeconds 延遲秒數 |  | ||||||
|      */ |  | ||||||
|     export function Action(action: Function, delaySeconds?: number): IEnumeratorV2 { |  | ||||||
|         if (delaySeconds > 0) { |  | ||||||
|             return new WaitTimeEnumerator(delaySeconds).Then(new ActionEnumerator(action)); |  | ||||||
|         } else { |  | ||||||
|             return new ActionEnumerator(action); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 等待時間協程 |  | ||||||
|      * @param seconds 秒數 |  | ||||||
|      */ |  | ||||||
|     export function WaitTime(seconds: number): IEnumeratorV2 { |  | ||||||
|         return new WaitTimeEnumerator(seconds); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "fc38e505-bd37-44c3-9e0a-fd463bb88c51", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,16 +0,0 @@ | |||||||
| export interface IEnumeratorV2 extends Iterator<any> { |  | ||||||
|     Start(target?: any): IEnumeratorV2Started; |  | ||||||
|     Then(iterator: Iterator<any>): IEnumeratorV2; |  | ||||||
|     ThenSerial(...iterators: Iterator<any>[]): IEnumeratorV2; |  | ||||||
|     ThenParallel(...iterators: Iterator<any>[]): IEnumeratorV2; |  | ||||||
|     ThenAction(action: Function, delaySeconds?: number): IEnumeratorV2; |  | ||||||
|     ThenWaitTime(seconds: number): IEnumeratorV2; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export interface IEnumeratorV2Started { |  | ||||||
|     readonly Current: any; |  | ||||||
|  |  | ||||||
|     Pause(): void; |  | ||||||
|     Resume(): void; |  | ||||||
|     Stop(): void; |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "df3ab07d-3d2b-4552-b454-29b95223ea85", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.3", |  | ||||||
|   "uuid": "6f870efd-e869-4415-9cf2-138ab667cd5d", |  | ||||||
|   "importer": "folder", |  | ||||||
|   "isBundle": false, |  | ||||||
|   "bundleName": "", |  | ||||||
|   "priority": 1, |  | ||||||
|   "compressionType": {}, |  | ||||||
|   "optimizeHotUpdate": {}, |  | ||||||
|   "inlineSpriteFrames": {}, |  | ||||||
|   "isRemoteBundle": {}, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.3", |  | ||||||
|   "uuid": "5e6c027f-ce4b-47fa-968c-f3bb6059ad81", |  | ||||||
|   "importer": "folder", |  | ||||||
|   "isBundle": false, |  | ||||||
|   "bundleName": "", |  | ||||||
|   "priority": 1, |  | ||||||
|   "compressionType": {}, |  | ||||||
|   "optimizeHotUpdate": {}, |  | ||||||
|   "inlineSpriteFrames": {}, |  | ||||||
|   "isRemoteBundle": {}, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| import { Action } from "../../CSharp/System/Action"; |  | ||||||
| import { INetRequest } from "./INetRequest"; |  | ||||||
| import { INetResponse } from "./INetResponse"; |  | ||||||
|  |  | ||||||
| export interface INetConnector { |  | ||||||
|     readonly OnDataReceived: Action<INetResponse<any>>; |  | ||||||
|     readonly OnDisconnected: Action<void>; |  | ||||||
|     readonly IsConnected: boolean; |  | ||||||
|      |  | ||||||
|     SendAsync<TRequest, TResponse>(req: INetRequest<TRequest, TResponse>): Iterator<any>; |  | ||||||
|     Send<TRequest, TResponse>(req: INetRequest<TRequest, TResponse>); |  | ||||||
|     Logout(); |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "f97991b5-0da6-4220-ab29-13c8f8f7e405", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,12 +0,0 @@ | |||||||
| import { INetResponse } from "./INetResponse"; |  | ||||||
|  |  | ||||||
| export interface INetRequest<TRequest, TResponse> { |  | ||||||
|     readonly Method: string; |  | ||||||
|     readonly MethodBack: string; |  | ||||||
|      |  | ||||||
|     Data: TRequest; |  | ||||||
|     Result: INetResponse<TResponse>; |  | ||||||
|      |  | ||||||
|     SendAsync(): Iterator<any>; |  | ||||||
|     Send(); |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "339fcf27-bdb9-4b8f-ae18-dd54c9500145", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,6 +0,0 @@ | |||||||
| export interface INetResponse<TResponse> { |  | ||||||
|     readonly Method: string; |  | ||||||
|     readonly Status: number; |  | ||||||
|     readonly Data: TResponse; |  | ||||||
|     readonly IsValid: boolean; |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "c4cb0cd4-b98c-4f8e-b1e6-ac3b51281b28", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.3", |  | ||||||
|   "uuid": "94e55972-723c-4dab-9ebc-870bd5043fca", |  | ||||||
|   "importer": "folder", |  | ||||||
|   "isBundle": false, |  | ||||||
|   "bundleName": "", |  | ||||||
|   "priority": 1, |  | ||||||
|   "compressionType": {}, |  | ||||||
|   "optimizeHotUpdate": {}, |  | ||||||
|   "inlineSpriteFrames": {}, |  | ||||||
|   "isRemoteBundle": {}, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,69 +0,0 @@ | |||||||
| import { CoroutineV2 } from "../../CoroutineV2/CoroutineV2"; |  | ||||||
| import { INetResponse } from "../Core/INetResponse"; |  | ||||||
| import { NetConnector } from "../NetConnector"; |  | ||||||
| import { NetManager } from "../NetManager"; |  | ||||||
| import { Slot1_SpinRequestExample } from "./Slot1_SpinRequestExample"; |  | ||||||
|  |  | ||||||
| const {ccclass, property} = cc._decorator; |  | ||||||
|  |  | ||||||
| @ccclass |  | ||||||
| export default class NetTester extends cc.Component { |  | ||||||
|  |  | ||||||
|     onConnectClicked() { |  | ||||||
|         CoroutineV2.StartCoroutine(this.ConnectAsync()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     *ConnectAsync() { |  | ||||||
|         if (!NetManager.HasInit) { |  | ||||||
|             let conn = new NetConnector("192.168.7.165", 9005); |  | ||||||
|             conn.OnDataReceived.AddCallback(this.OnNetDataReceived, this); |  | ||||||
|             conn.OnDisconnected.AddCallback(this.OnNetDisconnected, this); |  | ||||||
|             conn.OnLoadUIMask.AddCallback(this.OnLoadUIMask, this); |  | ||||||
|  |  | ||||||
|             NetManager.Initialize(conn); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         cc.log("連線中..."); |  | ||||||
|         yield NetManager.ConnectAsync(); // 同個connector要再次連線, 可以不用叫CasinoNetManager.Initialize(), 但要先叫CasinoNetManager.Disconnect() |  | ||||||
|         cc.log(`連線狀態: ${NetManager.IsConnected}`); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     onDisconnectClicked() { |  | ||||||
|         cc.log("中斷連線中..."); |  | ||||||
|         NetManager.Disconnect(); // 中斷連線 |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     onSendMessageClicked1() { |  | ||||||
|         cc.log("發送訊息(不使用協程)"); |  | ||||||
|         let req = new Slot1_SpinRequestExample(401); |  | ||||||
|         req.Send(); |  | ||||||
|         // CasinoNetManager.Send(req); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     onSendMessageClicked2() { |  | ||||||
|         CoroutineV2.StartCoroutine(this.SendAsync()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     *SendAsync() { |  | ||||||
|         cc.log("發送訊息中(使用協程)..."); |  | ||||||
|         let req = new Slot1_SpinRequestExample(399); |  | ||||||
|         yield req.SendAsync(); |  | ||||||
|         // yield CasinoNetManager.SendAsync(req); |  | ||||||
|  |  | ||||||
|         let resp = req.Result; |  | ||||||
|         cc.log(`發送協程完畢, Server回應: ${resp.Method}(${JSON.stringify(resp.Data)}), 狀態: ${resp.Status}`); |  | ||||||
|         // cc.log(`使用介面資料: ${resp.Data.slot}`); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private OnNetDisconnected() { |  | ||||||
|         cc.log("[事件] 收到連線中斷事件"); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private OnNetDataReceived(resp: INetResponse<any>) { |  | ||||||
|         cc.log(`[事件] 收到server呼叫: ${resp.Method}(${JSON.stringify(resp.Data)}), 狀態: ${resp.Status}`); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private OnLoadUIMask(value: boolean) { |  | ||||||
|         cc.log(`[事件] LoadUIMask: ${value}`); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "0cb7df7a-d0e7-4ce1-832e-4583cf3385e5", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,37 +0,0 @@ | |||||||
| import { NetRequest } from "../NetRequest"; |  | ||||||
|  |  | ||||||
| // 送給server的結構 |  | ||||||
| interface Request { |  | ||||||
|     pay: number; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // server回應的結構 |  | ||||||
| interface Response { |  | ||||||
|     pay: [[number, number]]; |  | ||||||
|     /**拉霸結果 */ |  | ||||||
|     slot: number[]; |  | ||||||
|     get: any[]; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // class Account_CreateRequest extends CasinoRequest<number, any> { // 也可以是基本類或any, 但不建議用any, 使用介面ts才會有提示 |  | ||||||
| export class Slot1_SpinRequestExample extends NetRequest<Request, Response> { |  | ||||||
|     get Method(): string { |  | ||||||
|         return "slot1.spin"; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // MethodBack預設回傳Method, 不一樣才需要覆寫 |  | ||||||
|     // get MethodBack(): string { |  | ||||||
|     //     return "slot1.freespin"; |  | ||||||
|     // } |  | ||||||
|  |  | ||||||
|     constructor(totalBet: number) { |  | ||||||
|         super(); |  | ||||||
|  |  | ||||||
|         // 原本的SingleValue拿掉, 統一使用Data來存送出結構 |  | ||||||
|  |  | ||||||
|         // this.Data = 2; |  | ||||||
|         this.Data = { |  | ||||||
|             pay: totalBet, |  | ||||||
|         }; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "1af9e6af-3dc3-4d02-8b24-481adc07932a", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,4 +0,0 @@ | |||||||
| export default class NetConfig { |  | ||||||
| 	/**是否顯示RPC接送JSON的LOG */ |  | ||||||
| 	public static ShowServerLog: boolean = true; |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "c7f5f6a9-94fd-4f5f-9f0a-545cd14edca9", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,259 +0,0 @@ | |||||||
| import { BaseEnumerator } from "../CoroutineV2/Core/BaseEnumerator"; |  | ||||||
| import { Action } from "../CSharp/System/Action"; |  | ||||||
| import { Encoding } from "../CSharp/System/Text/Encoding"; |  | ||||||
| import { INetRequest } from "./Core/INetRequest"; |  | ||||||
| import { INetResponse } from "./Core/INetResponse"; |  | ||||||
| import NetConfig from "./NetConfig"; |  | ||||||
|  |  | ||||||
| export class NetConnector { |  | ||||||
| 	readonly OnDataReceived: Action<INetResponse<any>> = new Action<INetResponse<any>>(); |  | ||||||
| 	readonly OnDisconnected: Action<void> = new Action<void>(); |  | ||||||
| 	readonly OnLoadUIMask: Action<boolean> = new Action<boolean>(); |  | ||||||
|  |  | ||||||
| 	get IsConnected() { |  | ||||||
| 		return this._ws && this._ws.readyState === WebSocket.OPEN; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	private _host: string; |  | ||||||
| 	private _ws: WebSocket; |  | ||||||
| 	private _waitings: WsRequestEnumerator[] = []; |  | ||||||
|  |  | ||||||
| 	constructor(host: string, port: number/*, ip: string*/) { |  | ||||||
| 		let checkHttp: string = ""; |  | ||||||
| 		let index: number = host.indexOf("https://"); |  | ||||||
| 		if (index != -1) { |  | ||||||
| 			checkHttp = "https"; |  | ||||||
| 			host = host.replace("https://", ""); |  | ||||||
| 		} else { |  | ||||||
| 			checkHttp = window.location.href.substring(0, 5); |  | ||||||
| 			host = host.replace("http://", ""); |  | ||||||
| 		} |  | ||||||
| 		if (CC_DEBUG) { |  | ||||||
| 			cc.log("[事件]checkHttp=", checkHttp, host, port); |  | ||||||
| 		} |  | ||||||
| 		if (checkHttp != "https") { |  | ||||||
| 			//this._host = `ws://${host}:${port}/?ip=${ip}`; |  | ||||||
| 			this._host = `ws://${host}:${port}` |  | ||||||
| 		} |  | ||||||
| 		else { |  | ||||||
| 			//this._host = `wss://${host}:${port}/?ip=${ip}`; |  | ||||||
| 			this._host = `wss://${host}:${port}`; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	ConnectAsync() { |  | ||||||
| 		if (this._ws) { |  | ||||||
| 			throw new Error("請先執行CasinoNetManager.Disconnect()中斷連線"); |  | ||||||
| 		} |  | ||||||
| 		if (cc.sys.isNative && cc.sys.os == cc.sys.OS_ANDROID && this._host.indexOf("wss") !== -1) { |  | ||||||
| 			let cacert = cc.url.raw('resources/cacert.cer'); |  | ||||||
| 			if (cc.loader.md5Pipe) { |  | ||||||
| 				cacert = cc.loader.md5Pipe.transformURL(cacert) |  | ||||||
| 			} |  | ||||||
| 			//@ts-ignore |  | ||||||
| 			this._ws = new WebSocket(this._host, null, cacert) |  | ||||||
| 		} else { |  | ||||||
| 			//@ts-ignore |  | ||||||
| 			this._ws = new WebSocket(this._host); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		this._ws.binaryType = 'arraybuffer'; |  | ||||||
| 		this._ws.onopen = this.OnWebSocketOpen.bind(this); |  | ||||||
| 		this._ws.onmessage = this.OnWebSocketMessage.bind(this); |  | ||||||
| 		this._ws.onclose = this.OnWebSocketClose.bind(this); |  | ||||||
|  |  | ||||||
| 		return new WsConnectEnumerator(this._ws); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	Send(req: INetRequest<any, any>) { |  | ||||||
| 		if (!this.IsConnected) return; |  | ||||||
|  |  | ||||||
| 		let json = [req.Method]; |  | ||||||
| 		if (req.Data != null && req.Data != undefined && req.Data != NaN) { |  | ||||||
| 			json[1] = req.Data; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if (CC_DEBUG && NetConfig.ShowServerLog) { |  | ||||||
| 			if (req.Data != null && req.Data != undefined && req.Data != NaN) { |  | ||||||
| 				cc.log(`[RPC] 傳送server資料: ${req.Method}(${JSON.stringify(req.Data)})`); |  | ||||||
| 			} else { |  | ||||||
| 				cc.log(`[RPC] 傳送server資料: ${req.Method}()`); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		let str = JSON.stringify(json); |  | ||||||
| 		if (str.length > 65535) { |  | ||||||
| 			throw new Error('要傳的資料太大囉'); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		let strary = Encoding.UTF8.GetBytes(str); |  | ||||||
| 		let buffer = new Uint8Array(4 + strary.byteLength); |  | ||||||
| 		let u16ary = new Uint16Array(buffer.buffer, 0, 3); |  | ||||||
| 		u16ary[0] = strary.byteLength; |  | ||||||
| 		buffer[3] = 0x01; |  | ||||||
| 		buffer.set(strary, 4); |  | ||||||
|  |  | ||||||
| 		this._ws.send(buffer); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	SendAsync(req: INetRequest<any, any>, mask: boolean) { |  | ||||||
| 		let iterator = new WsRequestEnumerator(req); |  | ||||||
| 		if (!this.IsConnected) { |  | ||||||
| 			iterator.SetResponse(ErrorResponse); |  | ||||||
| 		} else { |  | ||||||
| 			this._waitings.push(iterator); |  | ||||||
| 			if (mask) { |  | ||||||
| 				this.OnLoadUIMask.DispatchCallback(true); |  | ||||||
| 			} |  | ||||||
| 			this.Send(req); |  | ||||||
| 		} |  | ||||||
| 		return iterator; |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	Disconnect() { |  | ||||||
| 		this.WebSocketEnded(); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	private WebSocketEnded() { |  | ||||||
| 		if (!this._ws) return; |  | ||||||
|  |  | ||||||
| 		this._ws.close(); |  | ||||||
| 		this._ws.onopen = null; |  | ||||||
| 		this._ws.onmessage = null; |  | ||||||
| 		this._ws.onclose = () => { }; |  | ||||||
| 		this._ws = null; |  | ||||||
|  |  | ||||||
| 		this.CleanWaitings(); |  | ||||||
| 		this.OnDisconnected.DispatchCallback(); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	private CleanWaitings() { |  | ||||||
| 		for (let w of this._waitings) { |  | ||||||
| 			w.SetResponse(ErrorResponse); |  | ||||||
| 			this.OnLoadUIMask.DispatchCallback(false); |  | ||||||
| 		} |  | ||||||
| 		this._waitings.length = 0; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	private OnWebSocketOpen(e: Event) { |  | ||||||
| 		if (CC_DEBUG) { |  | ||||||
| 			cc.log(`[RPC] ${this._host} Connected.`); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	private OnWebSocketMessage(e: MessageEvent) { |  | ||||||
| 		if (e.data instanceof ArrayBuffer) { |  | ||||||
| 			this.ParseRpcMessage(e.data); |  | ||||||
| 		} else if (e.data instanceof Blob) { |  | ||||||
| 			let reader = new FileReader(); |  | ||||||
| 			reader.onload = (e) => { this.ParseRpcMessage(<ArrayBuffer>reader.result); reader.onload = null; } |  | ||||||
| 			reader.readAsArrayBuffer(e.data); |  | ||||||
| 		} else { |  | ||||||
| 			throw new Error(`未知的OnWebSocketMessage(e.data)類型: ${e.data}`); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	private ParseRpcMessage(buffer: ArrayBuffer) { |  | ||||||
| 		let startIndex = 0, byteLength = buffer.byteLength; |  | ||||||
| 		while (startIndex + 4 < byteLength) { |  | ||||||
| 			let strlen = new DataView(buffer, startIndex, 3).getUint16(0, true); |  | ||||||
| 			let str = Encoding.UTF8.GetString(new Uint8Array(buffer, startIndex + 4, strlen)); |  | ||||||
| 			startIndex += strlen + 4; |  | ||||||
|  |  | ||||||
| 			try { |  | ||||||
| 				let json = JSON.parse(str); |  | ||||||
| 				let method = <string>json[0]; |  | ||||||
| 				let status = <number>json[1][0]; |  | ||||||
| 				let data = json[1][1]; |  | ||||||
|  |  | ||||||
| 				let resp = <INetResponse<any>>{ |  | ||||||
| 					Method: method, |  | ||||||
| 					Status: status, |  | ||||||
| 					Data: data, |  | ||||||
| 					IsValid: method && status === 0 |  | ||||||
| 				}; |  | ||||||
|  |  | ||||||
| 				if (CC_DEBUG && NetConfig.ShowServerLog) { |  | ||||||
| 					if (data) { |  | ||||||
| 						cc.log(`[RPC] 收到server呼叫:(${resp.Status}): ${resp.Method}(${JSON.stringify(resp.Data)})`); |  | ||||||
| 					} else { |  | ||||||
| 						cc.log(`[RPC] 收到server呼叫:(${resp.Status}): ${resp.Method}()`); |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				let dispatch = true; |  | ||||||
| 				for (let i = 0, len = this._waitings.length; i < len; i++) { |  | ||||||
| 					let w = this._waitings[i]; |  | ||||||
| 					if (w.MethodBack === resp.Method) { |  | ||||||
| 						dispatch = false; |  | ||||||
| 						this._waitings.splice(i, 1); |  | ||||||
| 						w.SetResponse(resp); |  | ||||||
| 						this.OnLoadUIMask.DispatchCallback(false); |  | ||||||
| 						break; |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				if (dispatch) { |  | ||||||
| 					this.OnDataReceived.DispatchCallback(resp); |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 			catch |  | ||||||
| 			{ |  | ||||||
| 				throw new Error(`[RPC] 無法解析Server回應: ${str}`); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	private OnWebSocketClose(e: CloseEvent) { |  | ||||||
| 		this.WebSocketEnded(); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const ErrorResponse: INetResponse<any> = { |  | ||||||
| 	Status: -1, |  | ||||||
| 	Method: "", |  | ||||||
| 	Data: {}, |  | ||||||
| 	IsValid: false, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| class WsConnectEnumerator extends BaseEnumerator { |  | ||||||
| 	private _ws: WebSocket; |  | ||||||
|  |  | ||||||
| 	constructor(ws: WebSocket) { |  | ||||||
| 		super(); |  | ||||||
| 		this._ws = ws; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	next(value?: any): IteratorResult<any> { |  | ||||||
| 		return { |  | ||||||
| 			done: this._ws.readyState === WebSocket.OPEN || this._ws.readyState === WebSocket.CLOSED, |  | ||||||
| 			value: undefined |  | ||||||
| 		}; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| class WsRequestEnumerator extends BaseEnumerator { |  | ||||||
| 	readonly MethodBack: string; |  | ||||||
|  |  | ||||||
| 	private _req: INetRequest<any, any>; |  | ||||||
| 	private _done: boolean = false; |  | ||||||
|  |  | ||||||
| 	constructor(req: INetRequest<any, any>) { |  | ||||||
| 		super(); |  | ||||||
|  |  | ||||||
| 		this._req = req; |  | ||||||
| 		this.MethodBack = req.MethodBack; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	SetResponse(resp: INetResponse<any>) { |  | ||||||
| 		this._req.Result = resp; |  | ||||||
| 		this._done = true; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	next(value?: any): IteratorResult<any> { |  | ||||||
| 		return { |  | ||||||
| 			done: this._done, |  | ||||||
| 			value: undefined |  | ||||||
| 		}; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "221e1688-cc40-450d-9248-464978540a85", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,50 +0,0 @@ | |||||||
| import { INetRequest } from "./Core/INetRequest"; |  | ||||||
| import { NetConnector } from "./NetConnector"; |  | ||||||
|  |  | ||||||
| export class NetManager { |  | ||||||
|     static get IsConnected() { return this._connector && this._connector.IsConnected; } |  | ||||||
|     static get HasInit() { return this._connector != null; } |  | ||||||
|  |  | ||||||
|     private static _connector: NetConnector; |  | ||||||
|  |  | ||||||
|     static Initialize(connector: NetConnector) { |  | ||||||
|         this._connector = connector; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     static ConnectAsync() { |  | ||||||
|         this.CheckConnector(); |  | ||||||
|         return this._connector.ConnectAsync(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 斷線 |  | ||||||
|      */ |  | ||||||
|     static Disconnect() { |  | ||||||
|         this.CheckConnector(); |  | ||||||
|         this._connector.Disconnect(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 傳送資料給Server, 不等待回應 |  | ||||||
|      * @param req |  | ||||||
|      */ |  | ||||||
|     static Send(req: INetRequest<any, any>) { |  | ||||||
|         this.CheckConnector(); |  | ||||||
|         this._connector.Send(req); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 傳送資料給Server, 並等待回應 |  | ||||||
|      * @param req |  | ||||||
|      */ |  | ||||||
|     static SendAsync(req: INetRequest<any, any>,mask:boolean) { |  | ||||||
|         this.CheckConnector(); |  | ||||||
|         return this._connector.SendAsync(req,mask); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private static CheckConnector() |  | ||||||
|     { |  | ||||||
|         if (!this._connector) throw new Error("請先呼叫CasinoNetManager.Initialize()初始化connector"); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "7c3e375d-3672-42e7-8a45-dd5ecf9d5fe8", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,21 +0,0 @@ | |||||||
| import { INetRequest } from "./Core/INetRequest"; |  | ||||||
| import { NetManager } from "./NetManager"; |  | ||||||
|  |  | ||||||
| export abstract class NetRequest<TResquest, TResponse> implements INetRequest<TResquest, TResponse> { |  | ||||||
|     abstract get Method(): string; |  | ||||||
|  |  | ||||||
|     get MethodBack(): string { |  | ||||||
|         return this.Method; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Data: TResquest; |  | ||||||
|     Result: import("./Core/INetResponse").INetResponse<TResponse>; |  | ||||||
|  |  | ||||||
|     SendAsync(mask: boolean = false): Iterator<any> { |  | ||||||
|         return NetManager.SendAsync(this, mask); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Send() { |  | ||||||
|         NetManager.Send(this); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "36534597-4273-48e8-bbeb-8dde4857d26f", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "90f2152c-2c37-4c7c-b3a3-04c8aee53c34", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.3", |  | ||||||
|   "uuid": "c12c11f7-2e17-4727-a114-d4b19dfbe650", |  | ||||||
|   "importer": "folder", |  | ||||||
|   "isBundle": false, |  | ||||||
|   "bundleName": "", |  | ||||||
|   "priority": 1, |  | ||||||
|   "compressionType": {}, |  | ||||||
|   "optimizeHotUpdate": {}, |  | ||||||
|   "inlineSpriteFrames": {}, |  | ||||||
|   "isRemoteBundle": {}, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.3", |  | ||||||
|   "uuid": "3d4ae989-9f9b-429a-a331-191a8cd8193d", |  | ||||||
|   "importer": "folder", |  | ||||||
|   "isBundle": false, |  | ||||||
|   "bundleName": "", |  | ||||||
|   "priority": 1, |  | ||||||
|   "compressionType": {}, |  | ||||||
|   "optimizeHotUpdate": {}, |  | ||||||
|   "inlineSpriteFrames": {}, |  | ||||||
|   "isRemoteBundle": {}, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,4 +0,0 @@ | |||||||
| export interface ITableJson { |  | ||||||
|     cols: string[], |  | ||||||
|     rows: any[], |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "c5f8c44b-0b24-4f57-b229-4c3ad9301236", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| export interface ITableRow { |  | ||||||
|     Id: number; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * 表沒有欄位 |  | ||||||
|  */ |  | ||||||
| export class WithoutRow implements ITableRow { |  | ||||||
|     Id: number; |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "104d86f0-0cb9-4cd1-a305-44ea90ee3d7f", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,21 +0,0 @@ | |||||||
| import { ITableRow } from "./ITableRow"; |  | ||||||
|  |  | ||||||
| export abstract class TableBase<TRow extends ITableRow> extends Array<TRow> { |  | ||||||
|     constructor() { |  | ||||||
|         super(); |  | ||||||
|         Object.setPrototypeOf(this, new.target.prototype); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /**欄位數量 */ |  | ||||||
|     public get Count(): number { return this.length; } |  | ||||||
|     /**取得全部鍵值 */ |  | ||||||
|     public get Keys(): string[] { return Object.keys(this); } |  | ||||||
|     /**取得全部欄位值 */ |  | ||||||
|     public get Rows(): Array<TRow> { return Object["values"](this); } |  | ||||||
|     // public get Rows(): Array<TRow> { return this; } |  | ||||||
|      |  | ||||||
|     /**是否包含該Id值的欄位 */ |  | ||||||
|     public ContainsRow(id: number): boolean { |  | ||||||
|         return id in this; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "e4f18713-244f-4375-b77a-c26bf197cd3f", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.3", |  | ||||||
|   "uuid": "4a176b88-26e0-42ae-8acc-42ab2e942ace", |  | ||||||
|   "importer": "folder", |  | ||||||
|   "isBundle": false, |  | ||||||
|   "bundleName": "", |  | ||||||
|   "priority": 1, |  | ||||||
|   "compressionType": {}, |  | ||||||
|   "optimizeHotUpdate": {}, |  | ||||||
|   "inlineSpriteFrames": {}, |  | ||||||
|   "isRemoteBundle": {}, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| import { TableManager } from "../TableManager"; |  | ||||||
| import { StringExampleTableRow, StringTableExample } from "./Tables/StringTableExample"; |  | ||||||
|  |  | ||||||
| const { ccclass } = cc._decorator; |  | ||||||
|  |  | ||||||
| @ccclass |  | ||||||
| export default class CSSettingsV3Example { |  | ||||||
|  |  | ||||||
| 	private static _stringExample: StringTableExample; |  | ||||||
| 	/** 共用_字串表#string.xlsx */ |  | ||||||
| 	public static get StringExample(): StringTableExample { return this._stringExample = this._stringExample || TableManager.InitTable("#string", StringTableExample, StringExampleTableRow); } |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "04f57003-d6a1-4fee-adf8-69994db08f05", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,82 +0,0 @@ | |||||||
| import CSSettingsV3Example from "./CSSettingsV3Example"; |  | ||||||
| import { StringExampleTable } from "./Tables/StringTableExample"; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| const { ccclass, property } = cc._decorator; |  | ||||||
|  |  | ||||||
| @ccclass |  | ||||||
| export default class TableUseExample extends cc.Component { |  | ||||||
|  |  | ||||||
|     start() { |  | ||||||
|  |  | ||||||
|         //#region StringExample表 |  | ||||||
|         cc.log("----------------#stringExample"); |  | ||||||
|         cc.log(CSSettingsV3Example.StringExample instanceof StringExampleTable); // true |  | ||||||
|         cc.log(Array.isArray(CSSettingsV3Example.StringExample)); // true, 所以Array相關的方法都可以拿來操作 |  | ||||||
|  |  | ||||||
|         cc.log(CSSettingsV3Example.StringExample.length); |  | ||||||
|         cc.log(CSSettingsV3Example.StringExample.Count); // 跟length一樣 |  | ||||||
|  |  | ||||||
|         cc.log(CSSettingsV3Example.StringExample.ContainsRow(11)); // 是否包含id=11的Row |  | ||||||
|         cc.log(11 in CSSettingsV3Example.StringExample); // 同上 |  | ||||||
|  |  | ||||||
|         cc.log(CSSettingsV3Example.StringExample[1].MsgZnCh); |  | ||||||
|         cc.log(CSSettingsV3Example.StringExample[1]["MsgZnCh"]); // 同上 |  | ||||||
|         cc.log(CSSettingsV3Example["StringExample"][1]["MsgZnCh"]); // 同上 |  | ||||||
|  |  | ||||||
|         cc.log("----------------"); |  | ||||||
|         for (let row of CSSettingsV3Example.StringExample) { |  | ||||||
|             if (row) { // 如果Row沒有連號, 那有可能取到undefined值, 要先判斷, 不想判斷就用 CSSettings.StringExample.Rows |  | ||||||
|                 cc.log(row.Id, row.MsgZnCh); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         cc.log("----------------"); |  | ||||||
|         for (let id of CSSettingsV3Example.StringExample.Keys) { |  | ||||||
|             cc.log(id); // 只會列出有值的id, undefined會跳過 |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         cc.log("----------------"); |  | ||||||
|         for (let row of CSSettingsV3Example.StringExample.Rows) { |  | ||||||
|             cc.log(row.Id, row.MsgZnCh); // 只會列出有值的Row, undefined會跳過 |  | ||||||
|         } |  | ||||||
|         //#endregion |  | ||||||
|  |  | ||||||
|         //#region StringExample表 #StringFilter表 |  | ||||||
|         cc.log("----------------#stringExample#string_filter"); |  | ||||||
|         //cc.log(CSSettings.StringExample.StringFilter instanceof StringFilterTable); // true |  | ||||||
|         cc.log(Array.isArray(CSSettingsV3Example.StringExample.StringFilter)); // true, 所以Array相關的方法都可以拿來操作 |  | ||||||
|  |  | ||||||
|         cc.log(CSSettingsV3Example.StringExample.StringFilter.length); |  | ||||||
|         cc.log(CSSettingsV3Example.StringExample.StringFilter.Count); // 跟length一樣 |  | ||||||
|  |  | ||||||
|         cc.log(CSSettingsV3Example.StringExample.StringFilter.ContainsRow(11)); // 是否包含id=11的Row |  | ||||||
|         cc.log(11 in CSSettingsV3Example.StringExample.StringFilter); // 同上 |  | ||||||
|  |  | ||||||
|         cc.log(CSSettingsV3Example.StringExample.StringFilter[1].FilterWord); |  | ||||||
|         cc.log(CSSettingsV3Example.StringExample.StringFilter[1]["FilterWord"]); // 同上 |  | ||||||
|         cc.log(CSSettingsV3Example["StringExample"]["StringFilter"][1]["FilterWord"]); // 同上 |  | ||||||
|  |  | ||||||
|         cc.log("----------------"); |  | ||||||
|         for (let row of CSSettingsV3Example.StringExample.StringFilter) { |  | ||||||
|             if (row) { // 如果Row沒有連號, 那有可能取到undefined值, 要先判斷, 不想判斷就用 CSSettings.StringExample.StringFilter.Rows |  | ||||||
|                 cc.log(row.Id, row.FilterWord); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         cc.log("----------------"); |  | ||||||
|         for (let id of CSSettingsV3Example.StringExample.StringFilter.Keys) { |  | ||||||
|             cc.log(id); // 只會列出有值的id, undefined會跳過 |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         cc.log("----------------"); |  | ||||||
|         for (let row of CSSettingsV3Example.StringExample.StringFilter.Rows) { |  | ||||||
|             cc.log(row.Id, row.FilterWord); // 只會列出有值的Row, undefined會跳過 |  | ||||||
|         } |  | ||||||
|         //#endregion |  | ||||||
|  |  | ||||||
|         cc.log("----------------"); |  | ||||||
|         //CSSettingsV3.ResetTables(); // 重置表 |  | ||||||
|  |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "27d36ad6-da65-4673-abdb-4635a1a3d3a8", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.3", |  | ||||||
|   "uuid": "e65b6243-578c-4cea-ac46-1dfd4d455017", |  | ||||||
|   "importer": "folder", |  | ||||||
|   "isBundle": false, |  | ||||||
|   "bundleName": "", |  | ||||||
|   "priority": 1, |  | ||||||
|   "compressionType": {}, |  | ||||||
|   "optimizeHotUpdate": {}, |  | ||||||
|   "inlineSpriteFrames": {}, |  | ||||||
|   "isRemoteBundle": {}, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,45 +0,0 @@ | |||||||
| import { ITableRow } from "../../Core/ITableRow"; |  | ||||||
| import { TableBase } from "../../Core/TableBase"; |  | ||||||
| import { TableManager } from "../../TableManager"; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * 共用_字串表#string.xlsx |  | ||||||
|  * ##程式碼由工具產生, 在此做的修改都將被覆蓋## |  | ||||||
|  */ |  | ||||||
| export class StringTableExample extends TableBase<StringExampleTableRow> { |  | ||||||
| 	private _stringFilter: StringFilterTable; |  | ||||||
| 	/**  共用_字串表#string.xlsx > #string_filter */ |  | ||||||
| 	public get StringFilter(): StringFilterTable { return this._stringFilter = this._stringFilter || TableManager.InitTable("#string#string_filter", StringFilterTable, StringFilterTableRow); } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * #string |  | ||||||
|  */ |  | ||||||
| export class StringExampleTable extends TableBase<StringExampleTableRow> {} |  | ||||||
|  |  | ||||||
| export class StringExampleTableRow implements ITableRow { |  | ||||||
| 	/** 編號 */ |  | ||||||
| 	Id: number; |  | ||||||
| 	/** 英文訊息 */ |  | ||||||
| 	MsgEn: string; |  | ||||||
| 	/** 繁體中文訊息 */ |  | ||||||
| 	MsgZnTw: string; |  | ||||||
| 	/** 簡體中文讯息 */ |  | ||||||
| 	MsgZnCh: string; |  | ||||||
| 	/** 越南文讯息 */ |  | ||||||
| 	MsgVi: string; |  | ||||||
| 	/** 泰文讯息 */ |  | ||||||
| 	MsgTh: string; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * #string_filter |  | ||||||
|  */ |  | ||||||
| export class StringFilterTable extends TableBase<StringFilterTableRow> {} |  | ||||||
|  |  | ||||||
| export class StringFilterTableRow implements ITableRow { |  | ||||||
| 	/** 編號 */ |  | ||||||
| 	Id: number; |  | ||||||
| 	/** 過濾字串 */ |  | ||||||
| 	FilterWord: string; |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|   "ver": "1.1.0", |  | ||||||
|   "uuid": "c4bea919-96cd-40ee-a5f7-d9327414b1b2", |  | ||||||
|   "importer": "typescript", |  | ||||||
|   "isPlugin": false, |  | ||||||
|   "loadPluginInWeb": true, |  | ||||||
|   "loadPluginInNative": true, |  | ||||||
|   "loadPluginInEditor": false, |  | ||||||
|   "subMetas": {} |  | ||||||
| } |  | ||||||
| @@ -1,48 +0,0 @@ | |||||||
| import { ITableJson } from "./Core/ITableJson"; |  | ||||||
| import { ITableRow } from "./Core/ITableRow"; |  | ||||||
|  |  | ||||||
| export class TableManager { |  | ||||||
|     private static _tableJsons: { [key: string]: ITableJson } = {}; |  | ||||||
|  |  | ||||||
|     public static AddJsonAssets(jsonAssets: cc.JsonAsset[]) { |  | ||||||
|         if (!jsonAssets) return; |  | ||||||
|         let newAssets: cc.JsonAsset[] = jsonAssets.concat(); |  | ||||||
|         for (let jsonAsset of newAssets) { |  | ||||||
|             this.AddJsonAsset(jsonAsset); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public static AddJsonAsset(jsonAsset: cc.JsonAsset) { |  | ||||||
|         if (!jsonAsset) { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|         for (let tableName in jsonAsset.json) { |  | ||||||
|             console.log(`TableV3 [${tableName}] json loaded`); |  | ||||||
|             this._tableJsons[tableName] = jsonAsset.json[tableName]; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public static GetTable(name: string): ITableJson { |  | ||||||
|         return this._tableJsons[name]; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public static InitTable<T extends Array<ITableRow>>(name: string, tableType: { new(): T }, rowType: { new(): ITableRow }): T { |  | ||||||
|         let json = this._tableJsons[name]; |  | ||||||
|         if (!json) { |  | ||||||
|             throw new Error(`TableV3 [${name}] 尚未載入json檔`); |  | ||||||
|         } |  | ||||||
|         let table = new tableType(); |  | ||||||
|         let cols = json.cols; |  | ||||||
|         let colLength = cols.length; |  | ||||||
|         let rows = json.rows; |  | ||||||
|         for (let r of rows) { |  | ||||||
|             let trow = new rowType(); |  | ||||||
|             for (let i = 0; i < colLength; i++) { |  | ||||||
|                 trow[cols[i]] = r[i]; |  | ||||||
|             } |  | ||||||
|             table[trow.Id] = trow; |  | ||||||
|         } |  | ||||||
|         //cc.log(`TableV3 [${name}] init done`); |  | ||||||
|         return table; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user