@mlikiowa/nanaeo 1.0.1702966759079 → 1.0.1702967656417

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/2022/08/04/NewBlog/index.html +3473 -0
  2. package/2022/08/13/GaussWave/index.html +3407 -0
  3. package/about/index.html +3236 -0
  4. package/archives/2022/08/index.html +3411 -0
  5. package/archives/2022/index.html +3411 -0
  6. package/archives/index.html +3308 -0
  7. package/asset/Sotheby.ttf +0 -0
  8. package/asset/backimg.png +0 -0
  9. package/atom.xml +171 -0
  10. package/categories/DevLog/index.html +3351 -0
  11. package/categories/SiteLog/index.html +3351 -0
  12. package/categories/index.html +3174 -0
  13. package/category/devlog/atom.xml +58 -0
  14. package/category/devlog/feed.json +19 -0
  15. package/category/devlog/rss.xml +62 -0
  16. package/category/sitelog/atom.xml +125 -0
  17. package/category/sitelog/feed.json +20 -0
  18. package/category/sitelog/rss.xml +129 -0
  19. package/content.json +1 -0
  20. package/css/Readme.html +9 -0
  21. package/css/first.css +1504 -0
  22. package/css/style.css +7106 -0
  23. package/favicon.ico +0 -0
  24. package/feed.json +31 -0
  25. package/friends/index.html +3661 -0
  26. package/index.html +3421 -0
  27. package/js/app.js +1223 -0
  28. package/js/plugins/aplayer.js +186 -0
  29. package/js/plugins/parallax.js +191 -0
  30. package/js/plugins/rightMenu.js +577 -0
  31. package/js/plugins/rightMenus.js +618 -0
  32. package/js/plugins/tags/contributors.js +92 -0
  33. package/js/plugins/tags/friends.js +93 -0
  34. package/js/plugins/tags/sites.js +96 -0
  35. package/js/search/hexo.js +192 -0
  36. package/package.json +1 -1
  37. package/rss.xml +175 -0
  38. package/tag/devlog/atom.xml +58 -0
  39. package/tag/devlog/feed.json +19 -0
  40. package/tag/devlog/rss.xml +62 -0
  41. package/tag/gauss/atom.xml +58 -0
  42. package/tag/gauss/feed.json +19 -0
  43. package/tag/gauss/rss.xml +62 -0
  44. package/tag/hexo/atom.xml +125 -0
  45. package/tag/hexo/feed.json +20 -0
  46. package/tag/hexo/rss.xml +129 -0
  47. package/tag/hexothemes/atom.xml +125 -0
  48. package/tag/hexothemes/feed.json +20 -0
  49. package/tag/hexothemes/rss.xml +129 -0
  50. package/tag/sitelog/atom.xml +125 -0
  51. package/tag/sitelog/feed.json +20 -0
  52. package/tag/sitelog/rss.xml +129 -0
  53. package/tags/DevLog/index.html +3351 -0
  54. package/tags/Gauss/index.html +3351 -0
  55. package/tags/Hexo/index.html +3351 -0
  56. package/tags/HexoThemes/index.html +3351 -0
  57. package/tags/SiteLog/index.html +3351 -0
  58. package/tags/index.html +3159 -0
  59. package/volantis-sw.js +797 -0
package/volantis-sw.js ADDED
@@ -0,0 +1,797 @@
1
+ // 全站打包上传 npm,sw 并发请求 cdn
2
+ const prefix = 'volantis-community';
3
+ const cacheSuffixVersion = '00000018-0.5253040751038547';
4
+ const CACHE_NAME = prefix + '-v' + cacheSuffixVersion;
5
+ const PreCachlist = [
6
+ "/css/style.css",
7
+ "/js/app.js",
8
+ "/js/search/hexo.js",
9
+ ];
10
+ let NPMMirror = true;
11
+ const NPMPackage = "@mlikiowa/nanaeo";
12
+ let NPMPackageVersion = "1.0.1674055760561";
13
+ let debug = true;
14
+ // location.hostname == 'localhost' && (debug = true) && (NPMMirror = false);
15
+ const handleFetch = async (event) => {
16
+ const url = event.request.url;
17
+ if (/nocache/.test(url)) {
18
+ return NetworkOnly(event)
19
+ } else if (/@latest/.test(url)) {
20
+ return CacheFirst(event)
21
+ } else if (/cdnjs\.cloudflare\.com/.test(url)) {
22
+ return CacheAlways(event)
23
+ } else if (/music\.126\.net/.test(url)) {
24
+ return CacheAlways(event)
25
+ } else if (/qqmusic\.qq\.com/.test(url)) {
26
+ return CacheAlways(event)
27
+ } else if (/jsdelivr\.net/.test(url)) {
28
+ return CacheAlways(event)
29
+ } else if (/npm\.elemecdn\.com/.test(url)) {
30
+ return CacheAlways(event)
31
+ } else if (/unpkg\.com/.test(url)) {
32
+ return CacheAlways(event)
33
+ } else if (/.*\.(?:png|jpg|jpeg|svg|gif|webp|ico|eot|ttf|woff|woff2|mp3)$/.test(url)) {
34
+ return CacheAlways(event)
35
+ } else if (/.*\.(css|js)$/.test(url)) {
36
+ return CacheAlways(event)
37
+ } else {
38
+ return CacheFirst(event)
39
+ }
40
+ }
41
+ const cdn = {
42
+ gh: {
43
+ jsdelivr: 'https://cdn.jsdelivr.net/gh',
44
+ fastly: 'https://fastly.jsdelivr.net/gh',
45
+ gcore: 'https://gcore.jsdelivr.net/gh',
46
+ testingcf: 'https://testingcf.jsdelivr.net/gh',
47
+ test1: 'https://test1.jsdelivr.net/gh',
48
+ },
49
+ combine: {
50
+ jsdelivr: 'https://cdn.jsdelivr.net/combine',
51
+ fastly: 'https://fastly.jsdelivr.net/combine',
52
+ gcore: 'https://gcore.jsdelivr.net/combine',
53
+ testingcf: 'https://testingcf.jsdelivr.net/combine',
54
+ test1: 'https://test1.jsdelivr.net/combine',
55
+ },
56
+ npm: {
57
+ jsdelivr: 'https://cdn.jsdelivr.net/npm',
58
+ fastly: 'https://fastly.jsdelivr.net/npm',
59
+ gcore: 'https://gcore.jsdelivr.net/npm',
60
+ testingcf: 'https://testingcf.jsdelivr.net/npm',
61
+ test1: 'https://test1.jsdelivr.net/npm',
62
+ unpkg: 'https://unpkg.com',
63
+ eleme: 'https://npm.elemecdn.com',
64
+ },
65
+ cdnjs: {
66
+ cdnjs: 'https://cdnjs.cloudflare.com/ajax/libs',
67
+ baomitu: 'https://lib.baomitu.com',
68
+ bootcdn: 'https://cdn.bootcdn.net/ajax/libs',
69
+ bytedance: 'https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M',
70
+ sustech: 'https://mirrors.sustech.edu.cn/cdnjs/ajax/libs',
71
+ }
72
+ }
73
+ const cdn_match_list = []
74
+ for (const type in cdn) {
75
+ for (const key in cdn[type]) {
76
+ cdn_match_list.push({ type: type, key: cdn[type][key] })
77
+ }
78
+ }
79
+ const _console = console;
80
+ const color = {
81
+ black: '#000000',
82
+ red: '#FF0000',
83
+ green: '#008000',
84
+ yellow: '#FFFF00',
85
+ blue: '#0000FF',
86
+ magenta: '#FF00FF',
87
+ cyan: '#00FFFF',
88
+ white: '#FFFFFF',
89
+ };
90
+ const add = (...arr) => {
91
+ let fi = [
92
+ []
93
+ ];
94
+ for (let key = 0; key < arr.length; key++) {
95
+ const [first, ...other] = arr[key];
96
+ fi[0] += first;
97
+ fi = fi.concat(other);
98
+ }
99
+ return fi;
100
+ };
101
+ const createlog = (util) => (...args) => {
102
+ // const fun = _console[util] ? _console[util] : _console.log;
103
+ const fun = util == "error" ? _console[util] : _console.log;
104
+ fun.apply(void 0, args);
105
+ };
106
+ const creategroup = (util) => (...args) => {
107
+ const fun = _console.groupCollapsed;
108
+ fun.apply(void 0, args);
109
+ };
110
+ const colorUtils = {
111
+ bold: (str) => {
112
+ if (typeof str === 'string' || typeof str === 'number') {
113
+ return `${str};font-weight: bold;`;
114
+ }
115
+ for (let key = 1; key < str.length; key++) {
116
+ str[key] += `;font-weight: bold;`;
117
+ }
118
+ return str;
119
+ }
120
+ };
121
+ const colorHash = {
122
+ log: 'black',
123
+ wait: 'cyan',
124
+ error: 'red',
125
+ warn: 'yellow',
126
+ ready: 'green',
127
+ info: 'blue',
128
+ event: 'magenta',
129
+ };
130
+ const createChalk = (name) => (...str) => {
131
+ if (typeof str[0] === 'object') {
132
+ createlog(name)(...add(colorUtils.bold(colorUtils[colorHash[name]](`[${firstToUpperCase(name)}] `)), ...str));
133
+ return;
134
+ }
135
+ let strArr = str;
136
+ if (typeof str === 'string' || typeof str === 'number') {
137
+ strArr = colorUtils[colorHash[name]](str);
138
+ }
139
+ createlog(name)(...add(colorUtils.bold(colorUtils[colorHash[name]](`[${firstToUpperCase(name)}] `)), strArr));
140
+ };
141
+ const createChalkBg = (name) => (...str) => {
142
+ if (typeof str[0] === 'object') {
143
+ createlog(name)(...add(colorUtils.bold(colorUtils[`bg${firstToUpperCase(colorHash[name])}`](`[${firstToUpperCase(name)}] `)), ...str));
144
+ return;
145
+ }
146
+ let strArr = str;
147
+ if (typeof str === 'string' || typeof str === 'number') {
148
+ strArr = colorUtils[colorHash[name]](str);
149
+ }
150
+ createlog(name)(...add(colorUtils.bold(colorUtils[`bg${firstToUpperCase(colorHash[name])}`](`[${firstToUpperCase(name)}] `)), strArr));
151
+ };
152
+ const createChalkGroup = (name) => (...str) => {
153
+ if (typeof str[0] === 'object') {
154
+ creategroup(name)(...add(colorUtils.bold(colorUtils[colorHash[name]](`[${firstToUpperCase(name)}] `)), ...str));
155
+ return;
156
+ }
157
+ let strArr = str;
158
+ if (typeof str === 'string' || typeof str === 'number') {
159
+ strArr = colorUtils[colorHash[name]](str);
160
+ }
161
+ creategroup(name)(...add(colorUtils.bold(colorUtils[colorHash[name]](`[${firstToUpperCase(name)}] `)), strArr));
162
+ };
163
+ const chalk = {
164
+ group: {
165
+ end: _console.groupEnd
166
+ },
167
+ bg: {}
168
+ };
169
+ Object.keys(colorHash).forEach(key => {
170
+ chalk[key] = createChalk(key);
171
+ chalk.group[key] = createChalkGroup(key);
172
+ chalk.bg[key] = createChalkBg(key);
173
+ });
174
+ const firstToUpperCase = (str) => str.toLowerCase().replace(/( |^)[a-z]/g, (L) => L.toUpperCase());
175
+ Object.keys(color).forEach(key => {
176
+ colorUtils[key] = (str) => {
177
+ if (typeof str === 'string' || typeof str === 'number') {
178
+ return [`%c${str}`, `color:${color[key]}`];
179
+ }
180
+ for (let i = 1; i < str.length; i++) {
181
+ str[i] += `;color:${color[key]}`;
182
+ }
183
+ return str;
184
+ };
185
+ colorUtils[`bg${firstToUpperCase(key)}`] = (str) => {
186
+ if (typeof str === 'string' || typeof str === 'number') {
187
+ return [`%c${str}`, `padding: 2px 4px; border-radius: 3px; color: ${key === 'white' ? '#000' : '#fff'}; font-weight: bold; background:${color[key]};`];
188
+ }
189
+ for (let i = 1; i < str.length; i++) {
190
+ str[i] += `;padding: 2px 4px; border-radius: 3px; font-weight: bold; background:${color[key]};`;
191
+ }
192
+ return str;
193
+ };
194
+ });
195
+ self.logger = {
196
+ add,
197
+ ...chalk,
198
+ ...colorUtils,
199
+ };
200
+
201
+ if (!debug) {
202
+ logger = {
203
+ log: () => { },
204
+ wait: () => { },
205
+ error: () => { },
206
+ warn: () => { },
207
+ ready: () => { },
208
+ info: () => { },
209
+ event: () => { },
210
+ group: {
211
+ log: () => { },
212
+ wait: () => { },
213
+ error: () => { },
214
+ warn: () => { },
215
+ ready: () => { },
216
+ info: () => { },
217
+ event: () => { },
218
+ end: () => { },
219
+ },
220
+ bg: {
221
+ log: () => { },
222
+ wait: () => { },
223
+ error: () => { },
224
+ warn: () => { },
225
+ ready: () => { },
226
+ info: () => { },
227
+ event: () => { },
228
+ }
229
+ };
230
+ console.log = () => { };
231
+ }
232
+
233
+ const generate_uuid = () => {
234
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
235
+ var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
236
+ return v.toString(16);
237
+ });
238
+ }
239
+ self.db = {
240
+ read: (key, config) => {
241
+ if (!config) { config = { type: "text" } }
242
+ return new Promise((resolve, reject) => {
243
+ caches.open(CACHE_NAME).then(cache => {
244
+ cache.match(new Request(`https://LOCALCACHE/${encodeURIComponent(key)}`)).then(function (res) {
245
+ if (!res) resolve(null)
246
+ res.text().then(text => resolve(text))
247
+ }).catch(() => {
248
+ resolve(null)
249
+ })
250
+ })
251
+ })
252
+ },
253
+ write: (key, value) => {
254
+ return new Promise((resolve, reject) => {
255
+ caches.open(CACHE_NAME).then(function (cache) {
256
+ cache.put(new Request(`https://LOCALCACHE/${encodeURIComponent(key)}`), new Response(value));
257
+ resolve()
258
+ }).catch(() => {
259
+ reject()
260
+ })
261
+ })
262
+ }
263
+ }
264
+ const compareVersion = (a, b) => {
265
+ let v1 = a.split('.');
266
+ let v2 = b.split('.');
267
+ const len = Math.max(v1.length, v2.length);
268
+ while (v1.length < len) {
269
+ v1.push('0');
270
+ }
271
+ while (v2.length < len) {
272
+ v2.push('0');
273
+ }
274
+ for (let i = 0; i < len; i++) {
275
+ const num1 = parseInt(v1[i]);
276
+ const num2 = parseInt(v2[i]);
277
+ if (num1 > num2) {
278
+ return a;
279
+ } else if (num1 < num2) {
280
+ return b;
281
+ }
282
+ }
283
+ return a;
284
+ }
285
+
286
+ const mirrors = [
287
+ `https://registry.npmjs.org/${NPMPackage}/latest`,
288
+ `https://registry.npmmirror.com/${NPMPackage}/latest`,
289
+ `https://mirrors.cloud.tencent.com/npm/${NPMPackage}/latest`
290
+ ]
291
+ const getLocalVersion = async () => {
292
+ NPMPackageVersion = await db.read('blog_version') || NPMPackageVersion
293
+ logger.bg.info(`Local Version: ${NPMPackage}@${NPMPackageVersion}`)
294
+ }
295
+ let mirror_time = 0;
296
+ const setNewestVersion = async () => {
297
+ if (!NPMMirror) {
298
+ return
299
+ }
300
+ let f = null;
301
+ if (!(mirror_time % (mirrors.length + 1))) {
302
+ f = FetchEngine(mirrors);
303
+ } else {
304
+ f = fetch(mirrors[(mirror_time % (mirrors.length + 1)) - 1]);
305
+ }
306
+ mirror_time++;
307
+ return f
308
+ .then(res => res.json())
309
+ .then(async res => {
310
+ if (!res.version) throw ('No Version Found!')
311
+ NPMPackageVersion = compareVersion(res.version, await db.read('blog_version') || NPMPackageVersion)
312
+ logger.bg.ready(`${NPMPackage}@${NPMPackageVersion}`)
313
+ await db.write('blog_version', NPMPackageVersion)
314
+ })
315
+ .catch(error => {
316
+ logger.error('[Set Newest Version] ' + (error.stack || error))
317
+ })
318
+ }
319
+ setInterval(async () => {
320
+ await setNewestVersion()
321
+ }, 60 * 1000);
322
+ setTimeout(async () => {
323
+ await setNewestVersion()
324
+ }, 5000)
325
+ const installFunction = async () => {
326
+ await getLocalVersion();
327
+ return caches.open(CACHE_NAME + "-precache")
328
+ .then(async function (cache) {
329
+ if (!await db.read('uuid')) {
330
+ await db.write('uuid', generate_uuid())
331
+ }
332
+ if (PreCachlist.length) {
333
+ logger.group.event(`Precaching ${PreCachlist.length} files.`);
334
+ let index = 0;
335
+ PreCachlist.forEach(function (url) {
336
+ cache.match(new Request(url)).then(function (response) {
337
+ if (response) {
338
+ logger.ready(`Precaching ${url}`);
339
+ } else {
340
+ logger.wait(`Precaching ${url}`);
341
+ cache.add(new Request(url));
342
+ }
343
+ index++;
344
+ if (index === PreCachlist.length) {
345
+ logger.ready(`Precached ${PreCachlist.length} files.`);
346
+ logger.group.end();
347
+ }
348
+ })
349
+ })
350
+ }
351
+ }).catch((error) => {
352
+ logger.error('[install] ' + (error.stack || error));
353
+ })
354
+ }
355
+ self.addEventListener('install', async function (event) {
356
+ logger.bg.event("service worker install event listening");
357
+ try {
358
+ self.skipWaiting();
359
+ event.waitUntil(installFunction());
360
+ logger.bg.ready('service worker install sucess!');
361
+ } catch (error) {
362
+ logger.error('[install] ' + (error.stack || error));
363
+ }
364
+ });
365
+ self.addEventListener('activate', async event => {
366
+ logger.bg.event("service worker activate event listening");
367
+ try {
368
+ event.waitUntil(
369
+ caches.keys().then((keys) => {
370
+ return Promise.all(keys.map((key) => {
371
+ if (!key.includes(cacheSuffixVersion)) {
372
+ caches.delete(key);
373
+ logger.bg.ready('Deleted Outdated Cache: ' + key);
374
+ }
375
+ }));
376
+ }).catch((error) => {
377
+ logger.error('[activate] ' + (error.stack || error));
378
+ })
379
+ );
380
+ await self.clients.claim()
381
+ logger.bg.ready('service worker activate sucess!');
382
+ } catch (error) {
383
+ logger.error('[activate] ' + (error.stack || error));
384
+ }
385
+ })
386
+ self.addEventListener('fetch', async event => {
387
+ event.respondWith(
388
+ handleFetch(event).catch((error) => {
389
+ logger.error('[fetch] ' + event.request.url + '\n[error] ' + (error.stack || error));
390
+ })
391
+ )
392
+ });
393
+
394
+
395
+ const NetworkOnly = async (event) => {
396
+ logger.group.info('NetworkOnly: ' + new URL(event.request.url).pathname);
397
+ logger.wait('service worker fetch: ' + event.request.url)
398
+ logger.group.end();
399
+ return fetch(event.request)
400
+ }
401
+ const CacheFirst = async (event) => {
402
+ return caches.match(event.request).then(function (resp) {
403
+ logger.group.info('CacheFirst: ' + new URL(event.request.url).pathname);
404
+ logger.wait('service worker fetch: ' + event.request.url)
405
+ if (resp) {
406
+ logger.group.ready(`Cache Hit`);
407
+ console.log(resp)
408
+ logger.group.end();
409
+ logger.group.end();
410
+ event.waitUntil(CacheRuntime(event.request))
411
+ return resp;
412
+ } else {
413
+ logger.warn(`Cache Miss`);
414
+ logger.group.end();
415
+ return CacheRuntime(event.request)
416
+ }
417
+ })
418
+ }
419
+ const CacheAlways = async (event) => {
420
+ return caches.match(event.request).then(function (resp) {
421
+ logger.group.info('CacheAlways: ' + new URL(event.request.url).pathname);
422
+ logger.wait('service worker fetch: ' + event.request.url)
423
+ if (resp) {
424
+ logger.group.ready(`Cache Hit`);
425
+ console.log(resp)
426
+ logger.group.end();
427
+ logger.group.end();
428
+ return resp;
429
+ } else {
430
+ logger.warn(`Cache Miss`);
431
+ logger.group.end();
432
+ return CacheRuntime(event.request)
433
+ }
434
+ })
435
+ }
436
+
437
+ const matchCache = async (event) => {
438
+ return caches.match(event.request).then(function (resp) {
439
+ logger.group.info('service worker fetch: ' + event.request.url)
440
+ if (resp) {
441
+ logger.group.ready(`Cache Hit`);
442
+ console.log(resp)
443
+ logger.group.end();
444
+ logger.group.end();
445
+ return resp;
446
+ } else {
447
+ logger.warn(`Cache Miss`);
448
+ logger.group.end();
449
+ return CacheRuntime(event.request)
450
+ }
451
+ })
452
+ }
453
+ async function CacheRuntime(request) {
454
+ const url = new URL(request.url);
455
+ let response = await matchCDN(request);
456
+ if (!response) {
457
+ response = await fetch(request).catch(() => null)
458
+ }
459
+ logger.group.event(`Cache Runtime ${url.pathname}`);
460
+ logger.wait(`Caching url: ${request.url}`);
461
+ console.log(response);
462
+
463
+ if (request.method === "GET" && (url.protocol == "https:")) {
464
+ const cache = await caches.open(CACHE_NAME + "-runtime");
465
+ cache.put(request, response.clone()).catch(error => {
466
+ logger.error('[Cache Runtime] ' + (error.stack || error));
467
+ if (error.name === 'QuotaExceededError') {
468
+ caches.delete(CACHE_NAME + "-runtime");
469
+ logger.ready("deleted cache")
470
+ }
471
+ })
472
+ logger.ready(`Cached url: ${request.url}`);
473
+ } else {
474
+ logger.warn(`Not Cached url: ${request.url}`);
475
+ }
476
+ logger.group.end();
477
+ return response;
478
+ }
479
+
480
+ const matchCDN = async (req) => {
481
+ const nav = navigator
482
+ const { saveData, effectiveType } = nav.connection || nav.mozConnection || nav.webkitConnection || {}
483
+ if (saveData || /2g/.test(effectiveType)) {
484
+ logger.warn("Slow Network: Transparent Proxy");
485
+ return fetch(req);
486
+ }
487
+ const urls = []
488
+ let urlObj = new URL(req.url)
489
+ let pathType = urlObj.pathname.split('/')[1]
490
+ let pathTestRes = "";
491
+
492
+ if (NPMMirror && new RegExp(location.origin).test(req.url)) {
493
+ logger.group.ready(`Match NPM Mirror: ` + req.url);
494
+ for (const key in cdn.npm) {
495
+ let url = cdn.npm[key] + "/" + NPMPackage + "@" + NPMPackageVersion + req.url.replace(location.origin, '')
496
+ url = fullPath(fullPath(url))
497
+ console.log(url);
498
+ urls.push(url)
499
+ }
500
+ logger.group.end()
501
+ }
502
+ if (!urls.length) {
503
+ for (const item of cdn_match_list) {
504
+ if (new RegExp(item.key).test(req.url)) {
505
+ pathType = item.type
506
+ pathTestRes = new RegExp(item.key).exec(req.url)[0]
507
+ break;
508
+ }
509
+ }
510
+ for (const type in cdn) {
511
+ if (type === pathType) {
512
+ logger.group.ready(`Match CDN ${pathType}: ` + req.url);
513
+ for (const key in cdn[type]) {
514
+ const url = cdn[type][key] + req.url.replace(pathTestRes, '')
515
+ console.log(url);
516
+ urls.push(url)
517
+ }
518
+ logger.group.end()
519
+ }
520
+ }
521
+ }
522
+
523
+ let res;
524
+ if (urls.length)
525
+ res = FetchEngine(urls)
526
+ else
527
+ res = fetch(req)
528
+ if (res && NPMMirror && new RegExp(location.origin).test(req.url)) {
529
+ const ext = fullPath(fullPath(req.url)).split('.').pop()
530
+ const contentType = getContentType(ext)
531
+ res = res
532
+ .then(res => res.arrayBuffer())
533
+ .then(buffer => new Response(buffer, {
534
+ headers: {
535
+ "Content-Type": contentType
536
+ }
537
+ }))
538
+ .catch(() => null)
539
+ }
540
+ return res
541
+ }
542
+
543
+ const fullPath = (url) => {
544
+ url = url.split('?')[0].split('#')[0]
545
+ if (url.endsWith('/')) {
546
+ url += 'index.html'
547
+ } else {
548
+ const list = url.split('/')
549
+ const last = list[list.length - 1]
550
+ if (last.indexOf('.') === -1) {
551
+ url += '.html'
552
+ }
553
+ }
554
+ return url
555
+ }
556
+ async function progress(res) {
557
+ return new Response(await res.arrayBuffer(), {
558
+ status: res.status,
559
+ headers: res.headers
560
+ })
561
+ }
562
+
563
+ function createPromiseAny() {
564
+ Promise.any = function (promises) {
565
+ return new Promise((resolve, reject) => {
566
+ promises = Array.isArray(promises) ? promises : []
567
+ let len = promises.length
568
+ let errs = []
569
+ if (len === 0) return reject(new AggregateError('All promises were rejected'))
570
+ promises.forEach((p) => {
571
+ if (p instanceof Promise) {
572
+ p.then(
573
+ (res) => resolve(res),
574
+ (err) => {
575
+ len--
576
+ errs.push(err)
577
+ if (len === 0) reject(new AggregateError(errs))
578
+ }
579
+ )
580
+ } else {
581
+ reject(p)
582
+ }
583
+ })
584
+ })
585
+ }
586
+ }
587
+
588
+ function fetchAny(reqs) {
589
+ const controller = new AbortController()
590
+
591
+ return reqs.map(req => {
592
+ return new Promise((resolve, reject) => {
593
+ fetch(req, {
594
+ signal: controller.signal
595
+ })
596
+ .then(progress)
597
+ .then(res => {
598
+ controller.abort()
599
+ if (res.status !== 200)
600
+ reject(null)
601
+ else
602
+ resolve(res)
603
+ })
604
+ .catch(() => reject(null))
605
+ })
606
+ })
607
+ }
608
+
609
+ function fetchParallel(reqs) {
610
+ const abortEvent = new Event("abortOtherInstance")
611
+ const eventTarget = new EventTarget();
612
+
613
+ return reqs.map(async req => {
614
+ const controller = new AbortController();
615
+ let tagged = false;
616
+ eventTarget.addEventListener(abortEvent.type, () => {
617
+ if (!tagged) controller.abort();
618
+ })
619
+ return new Promise((resolve, reject) => {
620
+ fetch(req, {
621
+ signal: controller.signal,
622
+ }).then(res => {
623
+ tagged = true;
624
+ eventTarget.dispatchEvent(abortEvent)
625
+ if (res.status !== 200)
626
+ reject(null)
627
+ else
628
+ resolve(res)
629
+ }).catch(() => reject(null))
630
+ })
631
+ });
632
+ }
633
+
634
+ const FetchEngine = (reqs) => {
635
+ if (!Promise.any) createPromiseAny();
636
+ return Promise.any(fetchParallel(reqs)).then(res => res)
637
+ .catch((e) => {
638
+ if (e == "AggregateError: All promises were rejected") {
639
+ return Promise.any(fetchAny(reqs))
640
+ .then((res) => res)
641
+ .catch(() => null);
642
+ }
643
+ return null;
644
+ });
645
+ };
646
+
647
+ const getContentType = (ext) => {
648
+ switch (ext) {
649
+ case 'js':
650
+ return 'text/javascript'
651
+ case 'html':
652
+ return 'text/html'
653
+ case 'css':
654
+ return 'text/css'
655
+ case 'json':
656
+ return 'application/json'
657
+ case 'webp':
658
+ return 'image/webp'
659
+ case 'jpg':
660
+ return 'image/jpg'
661
+ case 'jpeg':
662
+ return 'image/jpeg'
663
+ case 'png':
664
+ return 'image/png'
665
+ case 'gif':
666
+ return 'image/gif'
667
+ case 'xml':
668
+ return 'text/xml'
669
+ case 'xsl':
670
+ return 'text/xml'
671
+ case 'webmanifest':
672
+ return 'text/webmanifest'
673
+ case 'map':
674
+ return 'application/json'
675
+ case 'bcmap':
676
+ return 'image/vnd.wap.wbmp'
677
+ case 'wbmp':
678
+ return 'image/vnd.wap.wbmp'
679
+ case 'bmp':
680
+ return 'image/bmp'
681
+ case 'ico':
682
+ return 'image/vnd.microsoft.icon'
683
+ case 'tiff':
684
+ return 'image/tiff'
685
+ case 'tif':
686
+ return 'image/tiff'
687
+ case 'svg':
688
+ return 'image/svg+xml'
689
+ case 'svgz':
690
+ return 'image/svg+xml'
691
+ case 'woff':
692
+ return 'application/font-woff'
693
+ case 'woff2':
694
+ return 'application/font-woff2'
695
+ case 'ttf':
696
+ return 'application/font-ttf'
697
+ case 'otf':
698
+ return 'application/font-otf'
699
+ case 'eot':
700
+ return 'application/vnd.ms-fontobject'
701
+ case 'zip':
702
+ return 'application/zip'
703
+ case 'tar':
704
+ return 'application/x-tar'
705
+ case 'gz':
706
+ return 'application/gzip'
707
+ case 'bz2':
708
+ return 'application/x-bzip2'
709
+ case 'rar':
710
+ return 'application/x-rar-compressed'
711
+ case '7z':
712
+ return 'application/x-7z-compressed'
713
+ case 'doc':
714
+ return 'application/msword'
715
+ case 'docx':
716
+ return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
717
+ case 'xls':
718
+ return 'application/vnd.ms-excel'
719
+ case 'xlsx':
720
+ return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
721
+ case 'ppt':
722
+ return 'application/vnd.ms-powerpoint'
723
+ case 'pptx':
724
+ return 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
725
+ case 'pdf':
726
+ return 'application/pdf'
727
+ case 'txt':
728
+ return 'text/plain'
729
+ case 'rtf':
730
+ return 'application/rtf'
731
+ case 'mp3':
732
+ return 'audio/mpeg'
733
+ case 'wav':
734
+ return 'audio/x-wav'
735
+ case 'ogg':
736
+ return 'audio/ogg'
737
+ case 'mp4':
738
+ return 'video/mp4'
739
+ case 'm4v':
740
+ return 'video/x-m4v'
741
+ case 'mov':
742
+ return 'video/quicktime'
743
+ case 'avi':
744
+ return 'video/x-msvideo'
745
+ case 'wmv':
746
+ return 'video/x-ms-wmv'
747
+ case 'flv':
748
+ return 'video/x-flv'
749
+ case 'swf':
750
+ return 'application/x-shockwave-flash'
751
+ case 'mpg':
752
+ return 'video/mpeg'
753
+ case 'mpeg':
754
+ return 'video/mpeg'
755
+ case 'mpe':
756
+ return 'video/mpeg'
757
+ case 'mpv':
758
+ return 'video/mpeg'
759
+ case 'm2v':
760
+ return 'video/mpeg'
761
+ case 'm4a':
762
+ return 'audio/mp4'
763
+ case 'aac':
764
+ return 'audio/aac'
765
+ case 'm3u':
766
+ return 'audio/x-mpegurl'
767
+ case 'm3u8':
768
+ return 'application/vnd.apple.mpegurl'
769
+ case 'pls':
770
+ return 'audio/x-scpls'
771
+ case 'cue':
772
+ return 'application/x-cue'
773
+ case 'wma':
774
+ return 'audio/x-ms-wma'
775
+ case 'flac':
776
+ return 'audio/flac'
777
+ case 'aif':
778
+ return 'audio/x-aiff'
779
+ case 'aiff':
780
+ return 'audio/x-aiff'
781
+ case 'aifc':
782
+ return 'audio/x-aiff'
783
+ case 'au':
784
+ return 'audio/basic'
785
+ case 'snd':
786
+ return 'audio/basic'
787
+ case 'mid':
788
+ return 'audio/midi'
789
+ case 'midi':
790
+ return 'audio/midi'
791
+ case 'kar':
792
+ return 'audio/midi'
793
+ default:
794
+ return 'text/plain'
795
+ }
796
+ }
797
+