sliftutils 1.7.63 → 1.7.65
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +23 -5
- package/misc/dist/environment.ts.cache +2 -2
- package/misc/dist/getSecret.ts.cache +2 -2
- package/misc/dist/strings.ts.cache +2 -2
- package/misc/dist/zip.ts.cache +2 -2
- package/misc/https/dist/certs.ts.cache +2 -2
- package/misc/https/dist/persistentLocalStorage.ts.cache +2 -2
- package/package.json +1 -1
- package/render-utils/dist/observer.tsx.cache +2 -2
- package/storage/BulkDatabase2/dist/BulkDatabaseBase.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/BulkDatabaseFormat.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/BulkDatabaseMerge.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/BulkDatabaseReader.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/LoadedIndex.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/WriteOverlay.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/blockCache.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/mergeLock.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/mergeMarkers.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/streamLog.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/syncClient.ts.cache +2 -2
- package/storage/IArchives.d.ts +6 -1
- package/storage/IArchives.ts +3 -3
- package/storage/dist/ArchivesDisk.ts.cache +2 -2
- package/storage/dist/FileFolderAPI.tsx.cache +2 -2
- package/storage/dist/IArchives.ts.cache +4 -4
- package/storage/dist/IndexedDBFileFolderAPI.ts.cache +2 -2
- package/storage/dist/JSONStorage.ts.cache +2 -2
- package/storage/dist/PendingManager.tsx.cache +2 -2
- package/storage/dist/TransactionStorage.ts.cache +2 -2
- package/storage/dist/backblaze.ts.cache +2 -2
- package/storage/dist/fileSystemPointer.ts.cache +2 -2
- package/storage/dist/remoteFileStorage.ts.cache +2 -2
- package/storage/remoteStorage/blobStore.ts +8 -2
- package/storage/remoteStorage/createArchives.d.ts +17 -4
- package/storage/remoteStorage/createArchives.ts +119 -77
- package/storage/remoteStorage/dist/ArchivesRemote.ts.cache +2 -2
- package/storage/remoteStorage/dist/ArchivesUrl.ts.cache +2 -2
- package/storage/remoteStorage/dist/blobStore.ts.cache +11 -5
- package/storage/remoteStorage/dist/cliArgs.ts.cache +2 -2
- package/storage/remoteStorage/dist/createArchives.ts.cache +119 -77
- package/storage/remoteStorage/dist/deployTakeover.ts.cache +2 -2
- package/storage/remoteStorage/dist/intermediateSources.ts.cache +2 -2
- package/storage/remoteStorage/dist/remoteConfig.ts.cache +2 -2
- package/storage/remoteStorage/dist/sourceWrapper.ts.cache +2 -2
- package/storage/remoteStorage/dist/sourcesList.ts.cache +2 -2
- package/storage/remoteStorage/dist/storageClientController.ts.cache +2 -2
- package/storage/remoteStorage/dist/storageController.ts.cache +2 -2
- package/storage/remoteStorage/dist/storageServerState.ts.cache +2 -2
- package/test.ts +48 -38
- package/treeSummary.ts +127 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isNode, sort } from "socket-function/src/misc";
|
|
1
|
+
import { isNode, sort, watchSlowPromise } from "socket-function/src/misc";
|
|
2
2
|
import { delay } from "socket-function/src/batching";
|
|
3
3
|
import {
|
|
4
4
|
IArchives, RemoteConfig, RemoteConfigBase, HostedConfig, BackblazeConfig,
|
|
@@ -25,8 +25,21 @@ const WRONG_TARGET_BOUNDARY_WINDOW = 30 * 1000;
|
|
|
25
25
|
const WRONG_TARGET_BOUNDARY_RETRY_DELAY = 15 * 1000;
|
|
26
26
|
const CONFIG_REFRESH_THROTTLE = 30 * 1000;
|
|
27
27
|
const AVAILABILITY_RECHECK_THROTTLE = 5 * 1000;
|
|
28
|
-
const
|
|
29
|
-
const
|
|
28
|
+
const PRIMARY_RETRY_TIMEOUT = 30 * 1000;
|
|
29
|
+
const PRIMARY_RETRY_DELAY = 2 * 1000;
|
|
30
|
+
// Smart timeouts: an attempt gets this long to produce anything before we probe getInfo for the file's size (and the probe itself gets the same window)
|
|
31
|
+
const SMART_TIMEOUT_PROBE = 10 * 1000;
|
|
32
|
+
// Very generous assumed transfer rates - the resulting deadline exists to catch stuck sources, not slow ones
|
|
33
|
+
const SMART_TIMEOUT_DOWNLOAD_BYTES_PER_SECOND = 1024 * 1024;
|
|
34
|
+
const SMART_TIMEOUT_UPLOAD_BYTES_PER_SECOND = 512 * 1024;
|
|
35
|
+
// Marker in smart-timeout errors, so the read loop can log them and continue with the other sources (a connected source's other errors still throw)
|
|
36
|
+
const SMART_TIMEOUT_MARKER = "ARCHIVES_SMART_TIMEOUT_c41a9d";
|
|
37
|
+
|
|
38
|
+
// Sizes a generous per-attempt deadline. Get-style calls pass path: the size is only fetched (via getInfo) when the call turns out to be slow. Set-style calls pass uploadBytes, which they already know.
|
|
39
|
+
type SmartTimeout = {
|
|
40
|
+
path?: string;
|
|
41
|
+
uploadBytes?: number;
|
|
42
|
+
};
|
|
30
43
|
|
|
31
44
|
/** The address, port, account, and bucket name a bucket routing URL addresses. Throws when the URL isn't a hosted bucket routing URL (https://host:port/file/<account>/<bucketName>/storage/storagerouting.json). */
|
|
32
45
|
export { parseHostedUrl, parseBackblazeUrl, getBucketBaseUrl } from "./remoteConfig";
|
|
@@ -407,45 +420,12 @@ export class ArchivesChain implements IArchives {
|
|
|
407
420
|
await this.adoptNewConfig(state, latest);
|
|
408
421
|
}
|
|
409
422
|
|
|
410
|
-
private async run<T>(state: ChainState, config: { apiOnly?: boolean; write?: boolean; route?: number; noFallbacks?: boolean; fast?: boolean }, run: (archives: IArchives, sourceUrl: string) => Promise<T>): Promise<T> {
|
|
423
|
+
private async run<T>(state: ChainState, config: { apiOnly?: boolean; write?: boolean; route?: number; noFallbacks?: boolean; fast?: boolean; timeout?: SmartTimeout }, run: (archives: IArchives, sourceUrl: string) => Promise<T>): Promise<T> {
|
|
411
424
|
if (config.fast && config.noFallbacks) {
|
|
412
425
|
throw new Error(`fast and noFallbacks are mutually exclusive for ${this.getDebugName()}: noFallbacks only considers one source (the write node), so there is no order to speed up`);
|
|
413
426
|
}
|
|
414
|
-
if (config.write) {
|
|
415
|
-
return await this.
|
|
416
|
-
}
|
|
417
|
-
if (config.noFallbacks) {
|
|
418
|
-
// Only the primary (the source writes would target) is guaranteed current, so the caller asked to never degrade to a possibly-lagging copy. A slow call is almost always better than throwing, so a failing primary is retried until the timeout - re-resolved each attempt, as a config refresh can change which source is primary
|
|
419
|
-
let deadline = Date.now() + NO_FALLBACKS_RETRY_TIMEOUT;
|
|
420
|
-
let attempt = 0;
|
|
421
|
-
while (true) {
|
|
422
|
-
attempt++;
|
|
423
|
-
let attemptStart = Date.now();
|
|
424
|
-
// The primary is strictly the first source matching the route and valid window - identical to the write target's selection, connectivity ignored
|
|
425
|
-
let target = state.sources.find(x => configAcceptsWrites(x.config) && (config.route === undefined || routeContains(x.config.route, config.route)));
|
|
426
|
-
try {
|
|
427
|
-
if (!target) {
|
|
428
|
-
throw new Error(`No primary source to read from for ${this.getDebugName()}${config.route !== undefined && ` (route ${config.route})` || ""} (noFallbacks: every source is outside its valid window or outside the key's route)`);
|
|
429
|
-
}
|
|
430
|
-
const primary = target;
|
|
431
|
-
return await primary.read(archives => run(archives, primary.config.url));
|
|
432
|
-
} catch (e) {
|
|
433
|
-
if (target && !target.isConnected()) target.noteFailure();
|
|
434
|
-
if (target && (attempt === 1 || attempt % 3 === 0)) {
|
|
435
|
-
// The reason we try the HTTP request: httpsRequest has better DNS retrying capabilities than our WebSocket server (we have more control over it), so just using it can fix some DNS issues, which can propagate to fix the WebSocket connection. It is still the primary source's own data, so noFallbacks semantics hold - and ArchivesUrl has no setup cost, so making one on the spot is fine.
|
|
436
|
-
try {
|
|
437
|
-
return await run(target.url || new ArchivesUrl(getBucketBaseUrl(target.config.url)), target.config.url);
|
|
438
|
-
} catch {
|
|
439
|
-
// Best-effort: the primary's error (thrown at the deadline) is the real one
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
if (Date.now() >= deadline) throw e;
|
|
443
|
-
}
|
|
444
|
-
// At most one attempt per interval, in case the failure is fast
|
|
445
|
-
await delay(Math.max(0, attemptStart + NO_FALLBACKS_RETRY_DELAY - Date.now()));
|
|
446
|
-
await this.recheckAvailability();
|
|
447
|
-
state = await this.getState();
|
|
448
|
-
}
|
|
427
|
+
if (config.write || config.noFallbacks) {
|
|
428
|
+
return await this.runPrimary(config, run);
|
|
449
429
|
}
|
|
450
430
|
let recheckedAvailability = false;
|
|
451
431
|
while (true) {
|
|
@@ -469,11 +449,17 @@ export class ArchivesChain implements IArchives {
|
|
|
469
449
|
}
|
|
470
450
|
return await run(api, source.config.url);
|
|
471
451
|
}
|
|
472
|
-
return await source.read(archives => run(archives, source.config.url));
|
|
452
|
+
return await this.applySmartTimeout(config.timeout, source, () => source.read(archives => run(archives, source.config.url)));
|
|
473
453
|
} catch (e) {
|
|
454
|
+
let message = String((e as Error).stack ?? e);
|
|
455
|
+
if (message.includes(SMART_TIMEOUT_MARKER)) {
|
|
456
|
+
console.error(`Source timed out for ${this.getDebugName()}, continuing with the next source: ${message}`);
|
|
457
|
+
errors.push(message);
|
|
458
|
+
continue;
|
|
459
|
+
}
|
|
474
460
|
if (source.isConnected()) throw e;
|
|
475
461
|
source.noteFailure();
|
|
476
|
-
errors.push(
|
|
462
|
+
errors.push(message);
|
|
477
463
|
}
|
|
478
464
|
}
|
|
479
465
|
if (!recheckedAvailability) {
|
|
@@ -486,25 +472,26 @@ export class ArchivesChain implements IArchives {
|
|
|
486
472
|
}
|
|
487
473
|
}
|
|
488
474
|
|
|
489
|
-
// It's important that writing always accesses the same node everywhere, even if that node is down - otherwise we're just writing into the void, and who knows if the writes will even be accepted, or clobbered, or what.
|
|
490
|
-
private async
|
|
475
|
+
// Writes and noFallbacks reads are the same case: take the authoritative node - strictly the first source matching the route and valid window, whether it is up or down - and use it, never falling back to another node. It's important that writing always accesses the same node everywhere, even if that node is down - otherwise we're just writing into the void, and who knows if the writes will even be accepted, or clobbered, or what; and noFallbacks reads want the same node precisely because it is the one writes target. A slow call is almost always better than throwing, so a failing primary is retried (the SAME node, re-resolved each attempt since a config refresh can change which source is primary) until the deadline, then throws.
|
|
476
|
+
private async runPrimary<T>(config: { write?: boolean; route?: number; timeout?: SmartTimeout }, run: (archives: IArchives, sourceUrl: string) => Promise<T>): Promise<T> {
|
|
491
477
|
let retriedWrongWindow = false;
|
|
492
478
|
let retriedWrongRoute = false;
|
|
493
|
-
let
|
|
479
|
+
let deadline = Date.now() + PRIMARY_RETRY_TIMEOUT;
|
|
480
|
+
let attempt = 0;
|
|
494
481
|
while (true) {
|
|
482
|
+
attempt++;
|
|
483
|
+
let attemptStart = Date.now();
|
|
495
484
|
let state = await this.getState();
|
|
496
|
-
let target = state.sources.find(x => configAcceptsWrites(x.config) && (route === undefined || routeContains(x.config.route, route)));
|
|
497
|
-
if (!target) {
|
|
498
|
-
if (!recheckedAvailability) {
|
|
499
|
-
recheckedAvailability = true;
|
|
500
|
-
await this.recheckAvailability();
|
|
501
|
-
continue;
|
|
502
|
-
}
|
|
503
|
-
throw new Error(`No source accepts writes for ${this.getDebugName()}${route !== undefined && ` (route ${route})` || ""} (every source is outside its valid window or outside the key's route)`);
|
|
504
|
-
}
|
|
485
|
+
let target = state.sources.find(x => configAcceptsWrites(x.config) && (config.route === undefined || routeContains(x.config.route, config.route)));
|
|
505
486
|
try {
|
|
506
|
-
|
|
507
|
-
|
|
487
|
+
if (!target) {
|
|
488
|
+
throw new Error(`No source is the ${config.write && "write target" || "primary read source"} for ${this.getDebugName()}${config.route !== undefined && ` (route ${config.route})` || ""} (every source is outside its valid window or outside the key's route)`);
|
|
489
|
+
}
|
|
490
|
+
const primary = target;
|
|
491
|
+
return await this.applySmartTimeout(config.timeout, primary, () => {
|
|
492
|
+
if (config.write) return primary.write(archives => run(archives, primary.config.url));
|
|
493
|
+
return primary.read(archives => run(archives, primary.config.url));
|
|
494
|
+
});
|
|
508
495
|
} catch (e) {
|
|
509
496
|
let message = String((e as Error).stack ?? e);
|
|
510
497
|
if (message.includes(STORAGE_WRONG_VALID_WINDOW) && !retriedWrongWindow) {
|
|
@@ -517,17 +504,64 @@ export class ArchivesChain implements IArchives {
|
|
|
517
504
|
await this.prepareWrongTargetRetry(state, "route");
|
|
518
505
|
continue;
|
|
519
506
|
}
|
|
520
|
-
if (!target.isConnected())
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
await
|
|
525
|
-
|
|
507
|
+
if (target && !target.isConnected()) target.noteFailure();
|
|
508
|
+
if (!config.write && target && (attempt === 1 || attempt % 3 === 0)) {
|
|
509
|
+
// The reason we try the HTTP request: httpsRequest has better DNS retrying capabilities than our WebSocket server (we have more control over it), so just using it can fix some DNS issues, which can propagate to fix the WebSocket connection. It is still the primary source's own data, so the no-fallback semantics hold - and ArchivesUrl has no setup cost, so making one on the spot is fine.
|
|
510
|
+
try {
|
|
511
|
+
return await run(target.url || new ArchivesUrl(getBucketBaseUrl(target.config.url)), target.config.url);
|
|
512
|
+
} catch {
|
|
513
|
+
// Best-effort: the primary's error (thrown at the deadline) is the real one
|
|
526
514
|
}
|
|
527
515
|
}
|
|
528
|
-
throw e;
|
|
529
|
-
}
|
|
516
|
+
if (Date.now() >= deadline) throw e;
|
|
517
|
+
}
|
|
518
|
+
// At most one attempt per interval, in case the failure is fast
|
|
519
|
+
await delay(Math.max(0, attemptStart + PRIMARY_RETRY_DELAY - Date.now()));
|
|
520
|
+
await this.recheckAvailability();
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/** Races call against a size-based deadline. Uploads know their size upfront; gets are given SMART_TIMEOUT_PROBE to produce anything, and only then is the file's info fetched (from the same source, itself time-limited) to size the deadline - measured from the call's start, so a source that was slow before the probe doesn't get the full allowance again. Timed-out calls keep running in the background (they cannot be cancelled) but their eventual result is ignored. */
|
|
525
|
+
private async applySmartTimeout<T>(timeout: SmartTimeout | undefined, source: SourceWrapper, call: () => Promise<T>): Promise<T> {
|
|
526
|
+
if (!timeout) return await call();
|
|
527
|
+
let start = Date.now();
|
|
528
|
+
let callPromise = call();
|
|
529
|
+
// An abandoned call must not surface an unhandled rejection when it eventually fails
|
|
530
|
+
let abandon = () => void callPromise.then(() => { }, () => { });
|
|
531
|
+
if (timeout.uploadBytes !== undefined) {
|
|
532
|
+
// A flat base plus the predicted transfer time, so tiny uploads still get the full base window
|
|
533
|
+
let allowed = SMART_TIMEOUT_PROBE + timeout.uploadBytes / SMART_TIMEOUT_UPLOAD_BYTES_PER_SECOND * 1000;
|
|
534
|
+
let result = await Promise.race([callPromise.then(value => ({ value })), delay(allowed).then(() => undefined)]);
|
|
535
|
+
if (result) return result.value;
|
|
536
|
+
abandon();
|
|
537
|
+
throw new Error(`${SMART_TIMEOUT_MARKER} Upload of ${timeout.uploadBytes} bytes to ${source.getDebugName()} timed out after ${Date.now() - start}ms (allowed ${Math.round(allowed)}ms: ${SMART_TIMEOUT_PROBE}ms base plus transfer at an assumed ${SMART_TIMEOUT_UPLOAD_BYTES_PER_SECOND} bytes/s)`);
|
|
538
|
+
}
|
|
539
|
+
const path = timeout.path;
|
|
540
|
+
if (path === undefined) return await callPromise;
|
|
541
|
+
let first = await Promise.race([callPromise.then(value => ({ value })), delay(SMART_TIMEOUT_PROBE).then(() => undefined)]);
|
|
542
|
+
if (first) return first.value;
|
|
543
|
+
let probeError: string | undefined;
|
|
544
|
+
let info: { size: number } | undefined;
|
|
545
|
+
try {
|
|
546
|
+
info = await Promise.race([
|
|
547
|
+
source.read(archives => archives.getInfo(path)).then(x => ({ size: x && x.size || 0 })),
|
|
548
|
+
delay(SMART_TIMEOUT_PROBE).then(() => undefined),
|
|
549
|
+
]);
|
|
550
|
+
} catch (e) {
|
|
551
|
+
probeError = String((e as Error).stack ?? e);
|
|
552
|
+
}
|
|
553
|
+
if (!info) {
|
|
554
|
+
abandon();
|
|
555
|
+
throw new Error(`${SMART_TIMEOUT_MARKER} Read of ${JSON.stringify(path)} from ${source.getDebugName()} timed out: no result after ${Date.now() - start}ms, and getInfo ${probeError && `failed (${probeError})` || `could not answer within ${SMART_TIMEOUT_PROBE}ms either`}`);
|
|
556
|
+
}
|
|
557
|
+
let allowed = Math.max(SMART_TIMEOUT_PROBE, info.size / SMART_TIMEOUT_DOWNLOAD_BYTES_PER_SECOND * 1000);
|
|
558
|
+
let remaining = start + allowed - Date.now();
|
|
559
|
+
if (remaining > 0) {
|
|
560
|
+
let second = await Promise.race([callPromise.then(value => ({ value })), delay(remaining).then(() => undefined)]);
|
|
561
|
+
if (second) return second.value;
|
|
530
562
|
}
|
|
563
|
+
abandon();
|
|
564
|
+
throw new Error(`${SMART_TIMEOUT_MARKER} Read of ${JSON.stringify(path)} (${info.size} bytes) from ${source.getDebugName()} timed out after ${Date.now() - start}ms (allowed ${Math.round(allowed)}ms from the call's start, at an assumed ${SMART_TIMEOUT_DOWNLOAD_BYTES_PER_SECOND} bytes/s)`);
|
|
531
565
|
}
|
|
532
566
|
|
|
533
567
|
private lastConfigRefresh = 0;
|
|
@@ -547,7 +581,7 @@ export class ArchivesChain implements IArchives {
|
|
|
547
581
|
await this.refreshActiveConfig();
|
|
548
582
|
}
|
|
549
583
|
|
|
550
|
-
private async request<T>(config: { apiOnly?: boolean; write?: boolean; route?: number; noFallbacks?: boolean; fast?: boolean }, run: (archives: IArchives, sourceUrl: string) => Promise<T>): Promise<T> {
|
|
584
|
+
private async request<T>(config: { apiOnly?: boolean; write?: boolean; route?: number; noFallbacks?: boolean; fast?: boolean; timeout?: SmartTimeout }, run: (archives: IArchives, sourceUrl: string) => Promise<T>): Promise<T> {
|
|
551
585
|
let state = await this.getState();
|
|
552
586
|
return await this.run(state, config, run);
|
|
553
587
|
}
|
|
@@ -570,16 +604,17 @@ export class ArchivesChain implements IArchives {
|
|
|
570
604
|
return result && result.data || undefined;
|
|
571
605
|
}
|
|
572
606
|
/** get2, but trying sources in latency order (fastest first) instead of config order. While this is much faster, it might miss immediate writes: the write node is no longer tried first, so a lagging replica may answer with a slightly older value. Exclusive with noFallbacks (which only considers one source - the write node - so there is no order to speed up); passing both throws. */
|
|
573
|
-
public async getFast(fileName: string, config?: GetConfig): Promise<{ data: Buffer; writeTime: number; size: number; url: string } | undefined> {
|
|
574
|
-
return await this.request({ route: getRoute(fileName), noFallbacks: config?.noFallbacks, fast: true }, async (archives, url) => {
|
|
607
|
+
public async getFast(fileName: string, config?: GetConfig): Promise<{ data: Buffer; writeTime: number; size: number; url: string } | { data?: undefined; writeTime?: undefined; size?: undefined; url: string }> {
|
|
608
|
+
return await this.request({ route: getRoute(fileName), noFallbacks: config?.noFallbacks, fast: true, timeout: { path: fileName } }, async (archives, url) => {
|
|
575
609
|
let result = await archives.get2(fileName, config);
|
|
576
|
-
return result && {
|
|
610
|
+
return result && result.data && { data: result.data, writeTime: result.writeTime, size: result.size, url } || { url };
|
|
577
611
|
});
|
|
578
612
|
}
|
|
579
|
-
|
|
580
|
-
|
|
613
|
+
/** Always resolves with a url - the authority that answered. A value that doesn't exist is still an answer FROM a server, so it comes back as { url } with no data (never plain undefined); errors from every source throw instead. */
|
|
614
|
+
public async get2(fileName: string, config?: GetConfig): Promise<{ data: Buffer; writeTime: number; size: number; url: string } | { data?: undefined; writeTime?: undefined; size?: undefined; url: string }> {
|
|
615
|
+
return await this.request({ route: getRoute(fileName), noFallbacks: config?.noFallbacks, timeout: { path: fileName } }, async (archives, url) => {
|
|
581
616
|
let result = await archives.get2(fileName, config);
|
|
582
|
-
return result && {
|
|
617
|
+
return result && result.data && { data: result.data, writeTime: result.writeTime, size: result.size, url } || { url };
|
|
583
618
|
});
|
|
584
619
|
}
|
|
585
620
|
public async getInfo(fileName: string): Promise<{ writeTime: number; size: number; url: string } | undefined> {
|
|
@@ -692,7 +727,7 @@ export class ArchivesChain implements IArchives {
|
|
|
692
727
|
if (fileName.includes(VARIABLE_SHARD) && parseVariableRoute(fileName) === undefined) {
|
|
693
728
|
return await this.setVariableShard(fileName, data, config);
|
|
694
729
|
}
|
|
695
|
-
await this.request({ write: true, route: getRoute(fileName) }, archives => archives.set(fileName, data, config));
|
|
730
|
+
await this.request({ write: true, route: getRoute(fileName), timeout: { uploadBytes: data.length } }, archives => archives.set(fileName, data, config));
|
|
696
731
|
return fileName;
|
|
697
732
|
}
|
|
698
733
|
|
|
@@ -721,10 +756,10 @@ export class ArchivesChain implements IArchives {
|
|
|
721
756
|
return ROUTING_FILE;
|
|
722
757
|
}
|
|
723
758
|
public async del(fileName: string): Promise<void> {
|
|
724
|
-
await this.request({ write: true, route: getRoute(fileName) }, archives => archives.del(fileName));
|
|
759
|
+
await this.request({ write: true, route: getRoute(fileName), timeout: { uploadBytes: 0 } }, archives => archives.del(fileName));
|
|
725
760
|
}
|
|
726
761
|
|
|
727
|
-
// One write target per route range, lowest latency first. Within a shard the target is ALWAYS the first source in config order (see
|
|
762
|
+
// One write target per route range, lowest latency first. Within a shard the target is ALWAYS the first source in config order (see runPrimary - writes must stay on the same node): connectivity only decides which SHARD we pick, never which node within it, so a shard whose node is disconnected is dropped entirely when connectedOnly is set.
|
|
728
763
|
private getVariableShardTargets(state: ChainState, config: { connectedOnly: boolean }): SourceWrapper[] {
|
|
729
764
|
let targetsByRoute = new Map<string, SourceWrapper>();
|
|
730
765
|
for (let source of state.sources) {
|
|
@@ -767,13 +802,20 @@ export class ArchivesChain implements IArchives {
|
|
|
767
802
|
for (let target of targets) {
|
|
768
803
|
let fullKey = materializeShardKey(key, target);
|
|
769
804
|
try {
|
|
770
|
-
|
|
805
|
+
// The shard picking already retries across shards, so a stuck shard just costs its timeout and we move on
|
|
806
|
+
await this.applySmartTimeout({ uploadBytes: data.length }, target, () => target.write(archives => archives.set(fullKey, data, config)));
|
|
771
807
|
return fullKey;
|
|
772
808
|
} catch (e) {
|
|
809
|
+
let message = String((e as Error).stack ?? e);
|
|
810
|
+
if (message.includes(SMART_TIMEOUT_MARKER)) {
|
|
811
|
+
console.error(`Variable-shard write target ${target.getDebugName()} timed out; moving to the next-lowest-latency shard: ${message}`);
|
|
812
|
+
errors.push(message);
|
|
813
|
+
continue;
|
|
814
|
+
}
|
|
773
815
|
if (target.isConnected()) throw e;
|
|
774
816
|
target.noteFailure();
|
|
775
817
|
console.log(`Variable-shard write target ${target.getDebugName()} is down; moving to the next-lowest-latency shard`);
|
|
776
|
-
errors.push(
|
|
818
|
+
errors.push(message);
|
|
777
819
|
}
|
|
778
820
|
}
|
|
779
821
|
if (!recheckedAvailability) {
|
|
@@ -804,7 +846,7 @@ export class ArchivesChain implements IArchives {
|
|
|
804
846
|
throw new Error(`No source accepts writes for setLargeFile on ${this.getDebugName()} (route ${route})`);
|
|
805
847
|
}
|
|
806
848
|
try {
|
|
807
|
-
await target.write(archives => archives.setLargeFile(config));
|
|
849
|
+
await watchSlowPromise(`setLargeFile|${config.path}`, target.write(archives => archives.setLargeFile(config)));
|
|
808
850
|
return;
|
|
809
851
|
} catch (e) {
|
|
810
852
|
if (!target.isConnected()) {
|
|
@@ -823,7 +865,7 @@ export class ArchivesChain implements IArchives {
|
|
|
823
865
|
return urls[0];
|
|
824
866
|
}
|
|
825
867
|
|
|
826
|
-
/** Every URL that could serve this path: public sources matching both the path's route and the current valid window. The first is the write node's (first matching source in config order, see
|
|
868
|
+
/** Every URL that could serve this path: public sources matching both the path's route and the current valid window. The first is the write node's (first matching source in config order, see runPrimary - the one guaranteed current); the rest are ranked fastest-first by measured latency. Empty when none qualify. */
|
|
827
869
|
public async getURLs(path: string): Promise<string[]> {
|
|
828
870
|
return (await this.getGetURLs())(path);
|
|
829
871
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
|
|
3
3
|
//exports.ArchivesRemote = exports.authenticateStorage = exports.parseStorageUrl = void 0;
|
|
4
4
|
const SocketFunction_1 = require("socket-function/SocketFunction");
|
|
@@ -182,4 +182,4 @@ class ArchivesRemote {
|
|
|
182
182
|
}
|
|
183
183
|
exports.ArchivesRemote = ArchivesRemote;
|
|
184
184
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXJjaGl2ZXNSZW1vdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJBcmNoaXZlc1JlbW90ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtRUFBZ0U7QUFDaEUsbURBQXdEO0FBQ3hELDJEQUFxRDtBQUNyRCxrREFBNkU7QUFFN0UsaURBQWdGO0FBQ2hGLDJEQUc2QjtBQUU3QixrVkFBa1Y7QUFFbFYsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO0FBQ3JDLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFVN0MsU0FBZ0IsZUFBZSxDQUFDLEdBQVc7SUFDdkMsSUFBSSxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDckIsSUFBSSxDQUFDLENBQUMsUUFBUSxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQzFCLE1BQU0sSUFBSSxLQUFLLENBQUMsbUNBQW1DLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQy9HLENBQUM7SUFDRCxPQUFPLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxHQUFHLEVBQUUsQ0FBQztBQUN6RCxDQUFDO0FBTkQsMENBTUM7QUFFRCx1RkFBdUY7QUFDaEYsS0FBSyxVQUFVLG1CQUFtQixDQUFDLE1BQXlEO0lBQy9GLG9KQUFvSjtJQUNwSiwrQkFBYyxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQztJQUN6QyxJQUFJLFVBQVUsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDL0Qs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Q3JILElBQUksQ0FBQztZQUNELE9BQU8sSUFBSSxFQUFFLENBQUM7Z0JBQ1YsSUFBSSxJQUFJLEdBQUcsTUFBTSxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQ3RDLElBQUksQ0FBQyxJQUFJO29CQUFFLE1BQU07Z0JBQ2pCLEtBQUssSUFBSSxNQUFNLEdBQUcsQ0FBQyxFQUFFLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLE1BQU0sSUFBSSxvQkFBb0IsRUFBRSxDQUFDO29CQUN4RSxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxNQUFNLEdBQUcsb0JBQW9CLENBQUMsQ0FBQyxDQUFDO2dCQUNyRyxDQUFDO1lBQ0wsQ0FBQztZQUNELE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDcEQsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDVCxJQUFJLENBQUM7Z0JBQ0QsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNwRCxDQUFDO1lBQUMsV0FBTSxDQUFDLENBQUMsQ0FBQztZQUNYLE1BQU0sQ0FBQyxDQUFDO1FBQ1osQ0FBQztJQUNMLENBQUM7SUFFTSxLQUFLLENBQUMsTUFBTSxDQUFDLElBQVk7UUFDNUIsd0ZBQXdGO1FBQ3hGLE9BQU8sSUFBQSwyQkFBWSxFQUFDLElBQUEsK0JBQWdCLEVBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNqRSxDQUFDO0NBQ0o7QUF0SkQsd0NBc0pDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU29ja2V0RnVuY3Rpb24gfSBmcm9tIFwic29ja2V0LWZ1bmN0aW9uL1NvY2tldEZ1bmN0aW9uXCI7XG5pbXBvcnQgeyB0aW1lSW5NaW51dGUgfSBmcm9tIFwic29ja2V0LWZ1bmN0aW9uL3NyYy9taXNjXCI7XG5pbXBvcnQgeyBkZWxheSB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2JhdGNoaW5nXCI7XG5pbXBvcnQgeyBnZXRJZGVudGl0eUNBLCBsb2FkSWRlbnRpdHlDQSwgc2lnbiB9IGZyb20gXCIuLi8uLi9taXNjL2h0dHBzL2NlcnRzXCI7XG5pbXBvcnQgeyBJQXJjaGl2ZXMsIEFyY2hpdmVGaWxlSW5mbywgQXJjaGl2ZXNDb25maWcsIEFyY2hpdmVzU3luY1N0YXR1cywgQ2hhbmdlc0FmdGVyQ29uZmlnLCBHZXRDb25maWcsIFNldENvbmZpZyB9IGZyb20gXCIuLi9JQXJjaGl2ZXNcIjtcbmltcG9ydCB7IHBhcnNlSG9zdGVkVXJsLCBnZXRCdWNrZXRCYXNlVXJsLCBidWlsZEZpbGVVcmwgfSBmcm9tIFwiLi9yZW1vdGVDb25maWdcIjtcbmltcG9ydCB7XG4gICAgUmVtb3RlU3RvcmFnZUNvbnRyb2xsZXIsIFNUT1JBR0VfQVVUSF9QVVJQT1NFLFxuICAgIFNUT1JBR0VfTk9UX0FVVEhFTlRJQ0FURUQsIFNUT1JBR0VfQUNDRVNTX0RFTklFRCxcbn0gZnJvbSBcIi4vc3RvcmFnZUNvbnRyb2xsZXJcIjtcblxuLy8gQSBidWNrZXQgb24gb3VyIHJlbW90ZSBzdG9yYWdlIHNlcnZlciAoc3RvcmFnZVNlcnZlci50cyksIHVzZWQgbGlrZSBBcmNoaXZlc0JhY2tibGF6ZS4gV29ya3MgaW4gTm9kZS5qcyBhbmQgdGhlIGJyb3dzZXIuIEF1dGhlbnRpY2F0ZXMgd2l0aCB0aGlzIG1hY2hpbmUncyBjZXJ0cy50cyBpZGVudGl0eTsgaWYgdGhlIGFjY291bnQgaGFzbid0IHRydXN0ZWQgdGhpcyBtYWNoaW5lIHlldCBpdCByZXF1ZXN0cyBhY2Nlc3MsIGFuZCBieSBkZWZhdWx0IHdhaXRzLCBsb2dnaW5nIGluc3RydWN0aW9ucyBldmVyeSBtaW51dGUgKGNhbGxzIGJsb2NrIHVudGlsIGFjY2VzcyBpcyBncmFudGVkKS5cblxuY29uc3QgQUNDRVNTX1JFVFJZX0RFTEFZID0gMTAwMCAqIDMwO1xuY29uc3QgTEFSR0VfRklMRV9QQVJUX1NJWkUgPSA4ICogMTAyNCAqIDEwMjQ7XG5cbmV4cG9ydCB0eXBlIEFyY2hpdmVzUmVtb3RlQ29uZmlnID0ge1xuICAgIC8vIFRoZSBidWNrZXQncyByb3V0aW5nIFVSTCwgd2hpY2ggYWRkcmVzc2VzIHRoZSBzZXJ2ZXIsIGFjY291bnQsIGFuZCBidWNrZXQgaW4gb25lOlxuICAgIC8vICBodHRwczovL3N0b3JhZ2UuZXhhbXBsZS5jb206NDQ0NC9maWxlLzxhY2NvdW50Pi88YnVja2V0TmFtZT4vc3RvcmFnZS9zdG9yYWdlcm91dGluZy5qc29uXG4gICAgdXJsOiBzdHJpbmc7XG4gICAgLy8gZmFsc2U6IGFjY2Vzcy1kZW5pZWQgY2FsbHMgdGhyb3cgaW1tZWRpYXRlbHkgKHRoZSBlcnJvciBpbmNsdWRlcyB0aGUgYWNjZXNzIHBhZ2UgbGluaykgaW5zdGVhZCBvZiByZXF1ZXN0aW5nIGFjY2VzcyBhbmQgYmxvY2tpbmcgdW50aWwgaXQgaXMgZ3JhbnRlZCAodGhlIGRlZmF1bHQpLlxuICAgIHdhaXRGb3JBY2Nlc3M/OiBib29sZWFuO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlU3RvcmFnZVVybCh1cmw6IHN0cmluZyk6IHsgYWRkcmVzczogc3RyaW5nOyBwb3J0OiBudW1iZXIgfSB7XG4gICAgbGV0IHUgPSBuZXcgVVJMKHVybCk7XG4gICAgaWYgKHUucHJvdG9jb2wgIT09IFwiaHR0cHM6XCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTdG9yYWdlIFVSTCBtdXN0IHVzZSBodHRwcywgZ290ICR7SlNPTi5zdHJpbmdpZnkodS5wcm90b2NvbCl9IGluICR7SlNPTi5zdHJpbmdpZnkodXJsKX1gKTtcbiAgICB9XG4gICAgcmV0dXJuIHsgYWRkcmVzczogdS5ob3N0bmFtZSwgcG9ydDogK3UucG9ydCB8fCA0NDMgfTtcbn1cblxuLy8gQXV0aGVudGljYXRlcyBhIGNvbm5lY3Rpb24gdG8gYSBzdG9yYWdlIHNlcnZlciB3aXRoIHRoaXMgbWFjaGluZSdzIGNlcnRzLnRzIGlkZW50aXR5XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXV0aGVudGljYXRlU3RvcmFnZShjb25maWc6IHsgYWRkcmVzczogc3RyaW5nOyBwb3J0OiBudW1iZXI7IG5vZGVJZDogc3RyaW5nIH0pOiBQcm9taXNlPHsgbWFjaGluZUlkOiBzdHJpbmc7IGlwOiBzdHJpbmcgfT4ge1xuICAgIC8vIGhvc3RTZXJ2ZXIgbm9kZUlkcyBhcmUgbWFjaGluZS1zcGVjaWZpYywgc28gY29ubmVjdGlvbnMgYnkgZG9tYWluIG11c3QgdGFyZ2V0IFwiYW55IHNlcnZlciBhdCB0aGlzIGFkZHJlc3NcIiAod2hpY2ggaXMgaG93IGJyb3dzZXJzIGFsd2F5cyBjb25uZWN0KVxuICAgIFNvY2tldEZ1bmN0aW9uLkVOQUJMRV9DTElFTlRfTU9ERSA9IHRydWU7XG4gICAgbGV0IHJvb3REb21haW4gPSBjb25maWcuYWRkcmVzcy5zcGxpdChcIi5cIikuc2xpY2UoLTIpLmpvaW4oXCIuXCIpO1xuICAgIGF3YWl0IGxvYWRJZGVudGl0eUNBKHJvb3REb21haW4pO1xuICAgIGxldCBjYSA9IGdldElkZW50aXR5Q0Eocm9vdERvbWFpbik7XG4gICAgbGV0IGRhdGEgPSB7XG4gICAgICAgIHB1cnBvc2U6IFNUT1JBR0VfQVVUSF9QVVJQT1NFLFxuICAgICAgICB0aW1lOiBEYXRlLm5vdygpLFxuICAgICAgICBzZXJ2ZXI6IGAke2NvbmZpZy5hZGRyZXNzfToke2NvbmZpZy5wb3J0fWAsXG4gICAgfTtcbiAgICBsZXQgc2lnbmF0dXJlID0gc2lnbih7IGtleTogY2Eua2V5IH0sIGRhdGEpO1xuICAgIHJldHVybiBhd2FpdCBSZW1vdGVTdG9yYWdlQ29udHJvbGxlci5ub2Rlc1tjb25maWcubm9kZUlkXS5hdXRoZW50aWNhdGUoeyBjZXJ0UGVtOiBjYS5jZXJ0LnRvU3RyaW5nKCksIHNpZ25hdHVyZSwgZGF0YSB9KTtcbn1cblxuZXhwb3J0IGNsYXNzIEFyY2hpdmVzUmVtb3RlIGltcGxlbWVudHMgSUFyY2hpdmVzIHtcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNvbmZpZzogQXJjaGl2ZXNSZW1vdGVDb25maWcpIHtcbiAgICAgICAgLy8gaG9zdFNlcnZlciBub2RlSWRzIGFyZSBtYWNoaW5lLXNwZWNpZmljLCBzbyBjb25uZWN0aW9ucyBieSBkb21haW4gbXVzdCB0YXJnZXQgXCJhbnkgc2VydmVyIGF0IHRoaXMgYWRkcmVzc1wiICh3aGljaCBpcyBob3cgYnJvd3NlcnMgYWx3YXlzIGNvbm5lY3QpXG4gICAgICAgIFNvY2tldEZ1bmN0aW9uLkVOQUJMRV9DTElFTlRfTU9ERSA9IHRydWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBwYXJzZWQgPSBwYXJzZUhvc3RlZFVybCh0aGlzLmNvbmZpZy51cmwpO1xuICAgIHByaXZhdGUgYWNjb3VudCA9IHRoaXMucGFyc2VkLmFjY291bnQ7XG4gICAgcHJpdmF0ZSBidWNrZXROYW1lID0gdGhpcy5wYXJzZWQuYnVja2V0TmFtZTtcbiAgICBwcml2YXRlIG5vZGVJZCA9IFNvY2tldEZ1bmN0aW9uLmNvbm5lY3QoeyBhZGRyZXNzOiB0aGlzLnBhcnNlZC5hZGRyZXNzLCBwb3J0OiB0aGlzLnBhcnNlZC5wb3J0IH0pO1xuICAgIHByaXZhdGUgY29udHJvbGxlciA9IFJlbW90ZVN0b3JhZ2VDb250cm9sbGVyLm5vZGVzW3RoaXMubm9kZUlkXTtcbiAgICBwcml2YXRlIGxhc3REZW5pZWRMb2cgPSAwO1xuXG4gICAgcHVibGljIGdldERlYnVnTmFtZSgpIHtcbiAgICAgICAgcmV0dXJuIGByZW1vdGVTdG9yYWdlICR7dGhpcy5wYXJzZWQuYWRkcmVzc306JHt0aGlzLnBhcnNlZC5wb3J0fSBhY2NvdW50ICR7dGhpcy5hY2NvdW50fSBidWNrZXQgJHt0aGlzLmJ1Y2tldE5hbWV9YDtcbiAgICB9XG5cbiAgICBwdWJsaWMgaXNDb25uZWN0ZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBTb2NrZXRGdW5jdGlvbi5pc05vZGVDb25uZWN0ZWQodGhpcy5ub2RlSWQpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBwaW5nKCk6IFByb21pc2U8e30+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY29udHJvbGxlci5waW5nKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBhdXRoZW50aWNhdGUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IGF1dGhlbnRpY2F0ZVN0b3JhZ2UoeyBhZGRyZXNzOiB0aGlzLnBhcnNlZC5hZGRyZXNzLCBwb3J0OiB0aGlzLnBhcnNlZC5wb3J0LCBub2RlSWQ6IHRoaXMubm9kZUlkIH0pO1xuICAgIH1cblxuICAgIC8vIFJ1bnMgYSBjYWxsLCBhdXRoZW50aWNhdGluZyAoYW5kIHJlLWF1dGhlbnRpY2F0aW5nIGFmdGVyIHJlY29ubmVjdHMpIGFzIG5lZWRlZC4gVW5saWtlIGNhbGwoKSwgZG9lcyBOT1Qgd2FpdCBmb3IgYWNjb3VudCBhY2Nlc3MuXG4gICAgcHJpdmF0ZSBhc3luYyBjYWxsQXV0aGVkPFQ+KGZuYzogKCkgPT4gUHJvbWlzZTxUPik6IFByb21pc2U8VD4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IGZuYygpO1xuICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgICAgIGlmICghU3RyaW5nKGUuc3RhY2sgfHwgZSkuaW5jbHVkZXMoU1RPUkFHRV9OT1RfQVVUSEVOVElDQVRFRCkpIHRocm93IGU7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmF1dGhlbnRpY2F0ZSgpO1xuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IGZuYygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gUmV0dXJucyB1bmRlZmluZWQgaWYgdGhpcyBtYWNoaW5lIGhhcyBhY2Nlc3MgdG8gdGhlIGFjY291bnQuIE90aGVyd2lzZSBwdXRzIGluIGFuIGFjY2VzcyByZXF1ZXN0IGFuZCByZXR1cm5zIG91ciBtYWNoaW5lSWQgKyBpcCAoc28gdGhlIGNhbGxlciBjYW4gZGlzcGxheSB0aGVtIGFsb25nc2lkZSB0aGUgbGluaywgZm9yIHRoZSBhcHByb3ZlciB0byBtYXRjaCB0aGUgaW5jb21pbmcgcmVxdWVzdCkgYW5kIHRoZSBsaW5rIHRvIHRoZSBncmFudCBwYWdlLlxuICAgIHB1YmxpYyBhc3luYyB3YWl0aW5nRm9yQWNjZXNzKCk6IFByb21pc2U8eyBsaW5rOiBzdHJpbmc7IG1hY2hpbmVJZDogc3RyaW5nOyBpcDogc3RyaW5nIH0gfCB1bmRlZmluZWQ+IHtcbiAgICAgICAgbGV0IHN0YXRlID0gYXdhaXQgdGhpcy5jYWxsQXV0aGVkKCgpID0+IHRoaXMuY29udHJvbGxlci5nZXRBY2Nlc3NTdGF0ZSh0aGlzLmFjY291bnQpKTtcbiAgICAgICAgaWYgKHN0YXRlLmhhc0FjY2VzcykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IHJlcXVlc3RlZCA9IGF3YWl0IHRoaXMuY2FsbEF1dGhlZCgoKSA9PiB0aGlzLmNvbnRyb2xsZXIucmVxdWVzdEFjY2Vzcyh0aGlzLmFjY291bnQpKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGxpbms6IGBodHRwczovLyR7dGhpcy5wYXJzZWQuYWRkcmVzc306JHt0aGlzLnBhcnNlZC5wb3J0fS8ke3RoaXMuYWNjb3VudH1gLFxuICAgICAgICAgICAgbWFjaGluZUlkOiByZXF1ZXN0ZWQubWFjaGluZUlkLFxuICAgICAgICAgICAgaXA6IHJlcXVlc3RlZC5pcCxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgaGFzV3JpdGVBY2Nlc3MoKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgIGxldCBzdGF0ZSA9IGF3YWl0IHRoaXMuY2FsbEF1dGhlZCgoKSA9PiB0aGlzLmNvbnRyb2xsZXIuZ2V0QWNjZXNzU3RhdGUodGhpcy5hY2NvdW50KSk7XG4gICAgICAgIHJldHVybiAhIXN0YXRlLmhhc0FjY2VzcztcbiAgICB9XG5cbiAgICAvLyBSZWdpc3RlcnMgb3VyIGFjY2VzcyByZXF1ZXN0IHNlcnZlci1zaWRlIChzbyBhbiBhZG1pbiBoYXMgYSByZXF1ZXN0SWQgdG8gZ3JhbnQpIGFuZCBsb2dzIHRoZSBncmFudCBpbnN0cnVjdGlvbnMsIGF0IG1vc3Qgb25jZSBhIG1pbnV0ZVxuICAgIHByaXZhdGUgYXN5bmMgcmVnaXN0ZXJBY2Nlc3NSZXF1ZXN0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBsZXQgcmVxdWVzdGVkID0gYXdhaXQgdGhpcy5jYWxsQXV0aGVkKCgpID0+IHRoaXMuY29udHJvbGxlci5yZXF1ZXN0QWNjZXNzKHRoaXMuYWNjb3VudCkpO1xuICAgICAgICBpZiAoRGF0ZS5ub3coKSAtIHRoaXMubGFzdERlbmllZExvZyA+IHRpbWVJbk1pbnV0ZSkge1xuICAgICAgICAgICAgdGhpcy5sYXN0RGVuaWVkTG9nID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBObyBhY2Nlc3MgdG8gc3RvcmFnZSBhY2NvdW50ICR7SlNPTi5zdHJpbmdpZnkodGhpcy5hY2NvdW50KX0gb24gJHt0aGlzLnBhcnNlZC5hZGRyZXNzfToke3RoaXMucGFyc2VkLnBvcnR9IChvdXIgbWFjaGluZSAke3JlcXVlc3RlZC5tYWNoaW5lSWR9LCBpcCAke3JlcXVlc3RlZC5pcH0pLiBTZWUgaHR0cHM6Ly8ke3RoaXMucGFyc2VkLmFkZHJlc3N9OiR7dGhpcy5wYXJzZWQucG9ydH0vJHt0aGlzLmFjY291bnR9IC0gb3IgZ3JhbnQgaXQgd2l0aDogJHtyZXF1ZXN0ZWQuZ3JhbnRBY2Nlc3NDb21tYW5kfWApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gUnVucyBhIGNhbGwsIGF1dGhlbnRpY2F0aW5nIChhbmQgcmUtYXV0aGVudGljYXRpbmcgYWZ0ZXIgcmVjb25uZWN0cykgYW5kIHdhaXRpbmcgZm9yIGFjY291bnQgYWNjZXNzIGFzIG5lZWRlZC4gV2l0aCB3YWl0Rm9yQWNjZXNzIGZhbHNlLCBkZW5pZWQgY2FsbHMgdGhyb3cgaW1tZWRpYXRlbHkgaW5zdGVhZCAtIGJ1dCB0aGUgYWNjZXNzIHJlcXVlc3QgaXMgc3RpbGwgcmVnaXN0ZXJlZCAoaW4gdGhlIGJhY2tncm91bmQpLCBzbyB0aGUgZGVuaWFsIGlzIGdyYW50YWJsZS5cbiAgICBwcml2YXRlIGFzeW5jIGNhbGw8VD4oZm5jOiAoKSA9PiBQcm9taXNlPFQ+KTogUHJvbWlzZTxUPiB7XG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJldHVybiBhd2FpdCBmbmMoKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICAgICAgICAgIGxldCBtZXNzYWdlID0gU3RyaW5nKGUuc3RhY2sgfHwgZSk7XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5jbHVkZXMoU1RPUkFHRV9OT1RfQVVUSEVOVElDQVRFRCkpIHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5hdXRoZW50aWNhdGUoKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLmluY2x1ZGVzKFNUT1JBR0VfQUNDRVNTX0RFTklFRCkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY29uZmlnLndhaXRGb3JBY2Nlc3MgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2b2lkIHRoaXMucmVnaXN0ZXJBY2Nlc3NSZXF1ZXN0KCkuY2F0Y2goKCkgPT4geyB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5yZWdpc3RlckFjY2Vzc1JlcXVlc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgZGVsYXkoQUNDRVNTX1JFVFJZX0RFTEFZKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ2V0KGZpbGVOYW1lOiBzdHJpbmcsIGNvbmZpZz86IEdldENvbmZpZyk6IFByb21pc2U8QnVmZmVyIHwgdW5kZWZpbmVkPiB7XG4gICAgICAgIGxldCByZXN1bHQgPSBhd2FpdCB0aGlzLmdldDIoZmlsZU5hbWUsIGNvbmZpZyk7XG4gICAgICAgIHJldHVybiByZXN1bHQgJiYgcmVzdWx0LmRhdGEgfHwgdW5kZWZpbmVkO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZ2V0MihmaWxlTmFtZTogc3RyaW5nLCBjb25maWc/OiBHZXRDb25maWcpOiBQcm9taXNlPHsgZGF0YTogQnVmZmVyOyB3cml0ZVRpbWU6IG51bWJlcjsgc2l6ZTogbnVtYmVyIH0gfCB1bmRlZmluZWQ+IHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IHRoaXMuY2FsbCgoKSA9PiB0aGlzLmNvbnRyb2xsZXIuZ2V0Mih0aGlzLmFjY291bnQsIHRoaXMuYnVja2V0TmFtZSwgZmlsZU5hbWUsIGNvbmZpZz8ucmFuZ2UpKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdCAmJiB7IGRhdGE6IEJ1ZmZlci5mcm9tKHJlc3VsdC5kYXRhKSwgd3JpdGVUaW1lOiByZXN1bHQud3JpdGVUaW1lLCBzaXplOiByZXN1bHQuc2l6ZSB9IHx8IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcHVibGljIGFzeW5jIHNldChmaWxlTmFtZTogc3RyaW5nLCBkYXRhOiBCdWZmZXIsIGNvbmZpZz86IFNldENvbmZpZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuY2FsbCgoKSA9PiB0aGlzLmNvbnRyb2xsZXIuc2V0KHRoaXMuYWNjb3VudCwgdGhpcy5idWNrZXROYW1lLCBmaWxlTmFtZSwgZGF0YSwgY29uZmlnPy5sYXN0TW9kaWZpZWQsIGNvbmZpZz8uZm9yY2VTZXRJbW11dGFibGUpKTtcbiAgICAgICAgcmV0dXJuIGZpbGVOYW1lO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZGVsKGZpbGVOYW1lOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5jYWxsKCgpID0+IHRoaXMuY29udHJvbGxlci5kZWwodGhpcy5hY2NvdW50LCB0aGlzLmJ1Y2tldE5hbWUsIGZpbGVOYW1lKSk7XG4gICAgfVxuICAgIHB1YmxpYyBhc3luYyBnZXRJbmZvKGZpbGVOYW1lOiBzdHJpbmcpOiBQcm9taXNlPHsgd3JpdGVUaW1lOiBudW1iZXI7IHNpemU6IG51bWJlciB9IHwgdW5kZWZpbmVkPiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNhbGwoKCkgPT4gdGhpcy5jb250cm9sbGVyLmdldEluZm8odGhpcy5hY2NvdW50LCB0aGlzLmJ1Y2tldE5hbWUsIGZpbGVOYW1lKSk7XG4gICAgfVxuICAgIHB1YmxpYyBhc3luYyBmaW5kSW5mbyhwcmVmaXg6IHN0cmluZywgY29uZmlnPzogeyBzaGFsbG93PzogYm9vbGVhbjsgdHlwZTogXCJmaWxlc1wiIHwgXCJmb2xkZXJzXCIgfSk6IFByb21pc2U8QXJjaGl2ZUZpbGVJbmZvW10+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2FsbCgoKSA9PiB0aGlzLmNvbnRyb2xsZXIuZmluZEluZm8odGhpcy5hY2NvdW50LCB0aGlzLmJ1Y2tldE5hbWUsIHByZWZpeCwgY29uZmlnKSk7XG4gICAgfVxuICAgIHB1YmxpYyBhc3luYyBmaW5kKHByZWZpeDogc3RyaW5nLCBjb25maWc/OiB7IHNoYWxsb3c/OiBib29sZWFuOyB0eXBlOiBcImZpbGVzXCIgfCBcImZvbGRlcnNcIiB9KTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgICAgICByZXR1cm4gKGF3YWl0IHRoaXMuZmluZEluZm8ocHJlZml4LCBjb25maWcpKS5tYXAoeCA9PiB4LnBhdGgpO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZ2V0Q2hhbmdlc0FmdGVyMihjb25maWc6IENoYW5nZXNBZnRlckNvbmZpZyk6IFByb21pc2U8QXJjaGl2ZUZpbGVJbmZvW10+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2FsbCgoKSA9PiB0aGlzLmNvbnRyb2xsZXIuZ2V0Q2hhbmdlc0FmdGVyMih0aGlzLmFjY291bnQsIHRoaXMuYnVja2V0TmFtZSwgY29uZmlnKSk7XG4gICAgfVxuICAgIHB1YmxpYyBhc3luYyBnZXRDb25maWcoKTogUHJvbWlzZTxBcmNoaXZlc0NvbmZpZz4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jYWxsKCgpID0+IHRoaXMuY29udHJvbGxlci5nZXRBcmNoaXZlc0NvbmZpZyh0aGlzLmFjY291bnQsIHRoaXMuYnVja2V0TmFtZSkpO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZ2V0U3luY1N0YXR1cygpOiBQcm9taXNlPEFyY2hpdmVzU3luY1N0YXR1cz4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jYWxsKCgpID0+IHRoaXMuY29udHJvbGxlci5nZXRTeW5jU3RhdHVzKHRoaXMuYWNjb3VudCwgdGhpcy5idWNrZXROYW1lKSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHNldExhcmdlRmlsZShjb25maWc6IHsgcGF0aDogc3RyaW5nOyBsYXN0TW9kaWZpZWQ/OiBudW1iZXI7IGdldE5leHREYXRhKCk6IFByb21pc2U8QnVmZmVyIHwgdW5kZWZpbmVkPiB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIC8vIEVuc3VyZSB3ZSdyZSBhdXRoZW50aWNhdGVkIHdpdGggYWNjZXNzIEJFRk9SRSBjb25zdW1pbmcgYW55IGRhdGEgKHRoZSBzdHJlYW0gY2Fubm90IGJlIHJld291bmQsIHNvIHdlIGNhbid0IHVzZSB0aGUgcmV0cnkgbG9vcCBhcm91bmQgdGhlIGFjdHVhbCB1cGxvYWQpXG4gICAgICAgIGF3YWl0IHRoaXMuY2FsbCgoKSA9PiB0aGlzLmNvbnRyb2xsZXIuZ2V0SW5mbyh0aGlzLmFjY291bnQsIHRoaXMuYnVja2V0TmFtZSwgY29uZmlnLnBhdGgpKTtcbiAgICAgICAgbGV0IHVwbG9hZElkID0gYXdhaXQgdGhpcy5jb250cm9sbGVyLnN0YXJ0TGFyZ2VGaWxlKHRoaXMuYWNjb3VudCwgdGhpcy5idWNrZXROYW1lLCBjb25maWcucGF0aCwgY29uZmlnLmxhc3RNb2RpZmllZCk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgICAgIGxldCBkYXRhID0gYXdhaXQgY29uZmlnLmdldE5leHREYXRhKCk7XG4gICAgICAgICAgICAgICAgaWYgKCFkYXRhKSBicmVhaztcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBvZmZzZXQgPSAwOyBvZmZzZXQgPCBkYXRhLmxlbmd0aDsgb2Zmc2V0ICs9IExBUkdFX0ZJTEVfUEFSVF9TSVpFKSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuY29udHJvbGxlci51cGxvYWRQYXJ0KHVwbG9hZElkLCBkYXRhLnN1YmFycmF5KG9mZnNldCwgb2Zmc2V0ICsgTEFSR0VfRklMRV9QQVJUX1NJWkUpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNvbnRyb2xsZXIuZmluaXNoTGFyZ2VGaWxlKHVwbG9hZElkKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmNvbnRyb2xsZXIuY2FuY2VsTGFyZ2VGaWxlKHVwbG9hZElkKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggeyB9XG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGdldFVSTChwYXRoOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICAvLyBPbmx5IGFjdHVhbGx5IGxvYWRzIGZvciBwdWJsaWMgYnVja2V0cyAodGhlIHNlcnZlciByZWplY3RzIHBsYWluIFVSTCByZWFkcyBvdGhlcndpc2UpXG4gICAgICAgIHJldHVybiBidWlsZEZpbGVVcmwoZ2V0QnVja2V0QmFzZVVybCh0aGlzLmNvbmZpZy51cmwpLCBwYXRoKTtcbiAgICB9XG59XG4iXX0=
|
|
185
|
-
/* _JS_SOURCE_HASH = "
|
|
185
|
+
/* _JS_SOURCE_HASH = "00e2c308d302e35ed33070a9d233edaac1d309f5fa338a4784de6ccc079a0b45"; */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
|
|
3
3
|
//exports.ArchivesUrl = void 0;
|
|
4
4
|
const https_1 = require("socket-function/src/https");
|
|
@@ -95,4 +95,4 @@ class ArchivesUrl {
|
|
|
95
95
|
}
|
|
96
96
|
exports.ArchivesUrl = ArchivesUrl;
|
|
97
97
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXJjaGl2ZXNVcmwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJBcmNoaXZlc1VybC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxxREFBNEU7QUFFNUUsaURBQThDO0FBRTlDLGtGQUFrRjtBQUNsRixnTUFBZ007QUFFaE0sTUFBYSxXQUFXO0lBQ3BCLDJGQUEyRjtJQUMzRixZQUFvQixJQUFZO1FBQVosU0FBSSxHQUFKLElBQUksQ0FBUTtJQUFJLENBQUM7SUFFOUIsWUFBWTtRQUNmLE9BQU8sT0FBTyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDOUIsQ0FBQztJQUVPLGFBQWEsQ0FBQyxTQUFpQjtRQUNuQyxPQUFPLElBQUksS0FBSyxDQUFDLEdBQUcsU0FBUyx5R0FBeUcsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFDdkosQ0FBQztJQUVNLEtBQUssQ0FBQyxHQUFHLENBQUMsUUFBZ0IsRUFBRSxNQUFrQjtRQUNqRCxJQUFJLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQy9DLE9BQU8sTUFBTSxJQUFJLE1BQU0sQ0FBQyxJQUFJLElBQUksU0FBUyxDQUFDO0lBQzlDLENBQUM7SUFDTSxLQUFLLENBQUMsSUFBSSxDQUFDLFFBQWdCLEVBQUUsTUFBa0I7UUFDbEQsSUFBSSxHQUFHLEdBQUcsSUFBQSwyQkFBWSxFQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDNUMsSUFBSSxPQUFPLEdBQTJCLEVBQUUsQ0FBQztRQUN6QyxJQUFJLEtBQUssR0FBRyxNQUFNLGFBQU4sTUFBTSx1QkFBTixNQUFNLENBQUUsS0FBSyxDQUFDO1FBQzFCLElBQUksS0FBSyxFQUFFLENBQUM7WUFDUixPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsU0FBUyxLQUFLLENBQUMsS0FBSyxJQUFJLEtBQUssQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFF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LEtBQUssQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFDTSxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQW9FO1FBQzFGLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBQ00sS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFjLEVBQUUsTUFBeUQ7UUFDdkYsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDL0MsQ0FBQztJQUNNLEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBYyxFQUFFLE1BQXlEO1FBQzNGLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFDTSxLQUFLLENBQUMsZ0JBQWdCLENBQUMsTUFBMEI7UUFDcEQsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLDRCQUE0QixDQUFDLENBQUM7SUFDM0QsQ0FBQztJQUVNLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBWTtRQUM1QixPQUFPLElBQUEsMkJBQVksRUFBQyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFDTSxLQUFLLENBQUMsU0FBUztRQUNsQixPQUFPLEVBQUUsQ0FBQztJQUNkLENBQUM7SUFFTSxLQUFLLENBQUMsY0FBYztRQUN2QixPQUFPLEtBQUssQ0FBQztJQUNqQixDQUFDO0NBQ0o7QUF4RkQsa0NBd0ZDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaHR0cHNSZXF1ZXN0LCBIdHRwc1Jlc3BvbnNlSW5mbyB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2h0dHBzXCI7XG5pbXBvcnQgeyBJQXJjaGl2ZXMsIEFyY2hpdmVGaWxlSW5mbywgQXJjaGl2ZXNDb25maWcsIENoYW5nZXNBZnRlckNvbmZpZywgR2V0Q29uZmlnIH0gZnJvbSBcIi4uL0lBcmNoaXZlc1wiO1xuaW1wb3J0IHsgYnVpbGRGaWxlVXJsIH0gZnJvbSBcIi4vcmVtb3RlQ29uZmlnXCI7XG5cbi8vIFJlYWQtb25seSBJQXJjaGl2ZXMgb3ZlciBhIHB1YmxpYyBidWNrZXQncyBwbGFpbi1VUkwgZm9ybSAob3VyIHN0b3JhZ2Ugc2VydmVyJ3Ncbi8vIC9maWxlLzxhY2NvdW50Pi88YnVja2V0TmFtZT4vLi4uIHJvdXRlLCBvciBhIGJhY2tibGF6ZSBmcmllbmRseSBVUkwpLiBVc2VkIHdoZW4gd2UgaGF2ZSBubyBBUEkgYWNjZXNzIHRvIGEgc291cmNlLiBPbmx5IHNpbmdsZS1maWxlIHJlYWRzIHdvcms6IHRoZXJlIGlzIG5vIGxpc3RpbmcsIGFuZCB3cml0ZXMgYWx3YXlzIHRocm93LlxuXG5leHBvcnQgY2xhc3MgQXJjaGl2ZXNVcmwgaW1wbGVtZW50cyBJQXJjaGl2ZXMge1xuICAgIC8vIGJhc2UgaXMgdGhlIGJ1Y2tldCdzIHB1YmxpYyBiYXNlIFVSTCwgZS5nLiBodHRwczovL2hvc3Q6cG9ydC9maWxlLzxhY2NvdW50Pi88YnVja2V0TmFtZT5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGJhc2U6IHN0cmluZykgeyB9XG5cbiAgICBwdWJsaWMgZ2V0RGVidWdOYW1lKCkge1xuICAgICAgICByZXR1cm4gYHVybCAke3RoaXMuYmFzZX1gO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVhZE9ubHlFcnJvcihvcGVyYXRpb246IHN0cmluZyk6IEVycm9yIHtcbiAgICAgICAgcmV0dXJuIG5ldyBFcnJvcihgJHtvcGVyYXRpb259IGlzIG5vdCBzdXBwb3J0ZWQgb3ZlciBVUkwtZm9ybSBhY2Nlc3MgKG5vIEFQSSBhY2Nlc3MgdG8gdGhpcyBzb3VyY2UsIG9ubHkgcHVibGljIFVSTCByZWFkcykuIFNvdXJjZTogJHt0aGlzLmJhc2V9YCk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGdldChmaWxlTmFtZTogc3RyaW5nLCBjb25maWc/OiBHZXRDb25maWcpOiBQcm9taXNlPEJ1ZmZlciB8IHVuZGVmaW5lZD4ge1xuICAgICAgICBsZXQgcmVzdWx0ID0gYXdhaXQgdGhpcy5nZXQyKGZpbGVOYW1lLCBjb25maWcpO1xuICAgICAgICByZXR1cm4gcmVzdWx0ICYmIHJlc3VsdC5kYXRhIHx8IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcHVibGljIGFzeW5jIGdldDIoZmlsZU5hbWU6IHN0cmluZywgY29uZmlnPzogR2V0Q29uZmlnKTogUHJvbWlzZTx7IGRhdGE6IEJ1ZmZlcjsgd3JpdGVUaW1lOiBudW1iZXI7IHNpemU6IG51bWJlciB9IHwgdW5kZWZpbmVkPiB7XG4gICAgICAgIGxldCB1cmwgPSBidWlsZEZpbGVVcmwodGhpcy5iYXNlLCBmaWxlTmFtZSk7XG4gICAgICAgIGxldCBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG4gICAgICAgIGxldCByYW5nZSA9IGNvbmZpZz8ucmFuZ2U7XG4gICAgICAgIGlmIChyYW5nZSkge1xuICAgICAgICAgICAgaGVhZGVyc1tcIlJhbmdlXCJdID0gYGJ5dGVzPSR7cmFuZ2Uuc3RhcnR9LSR7cmFuZ2UuZW5kIC0gMX1gO1xuICAgICAgICB9XG4gICAgICAgIGxldCByZXNwb25zZTogSHR0cHNSZXNwb25zZUluZm8gPSB7IGhlYWRlcnM6IHt9IH07XG4gICAgICAgIGxldCBkYXRhOiBCdWZmZXI7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBkYXRhID0gYXdhaXQgaHR0cHNSZXF1ZXN0KHVybCwgdW5kZWZpbmVkLCBcIkdFVFwiLCBmYWxzZSwgeyBoZWFkZXJzLCBvdXRSZXNwb25zZTogcmVzcG9uc2UgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIC8vIGh0dHBzUmVxdWVzdCB0aHJvd3Mgb24gYW55IG5vbi0yeHg7IGEgbWlzc2luZyBmaWxlIGlzIGEgbm9ybWFsIGFic2VudCByZXN1bHQsIG5vdCBhbiBlcnJvci5cbiAgICAgICAgICAgIGlmIChyZXNwb25zZS5zdGF0dXNDb2RlID09PSA0MDQpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICAgIC8vIEEgcmVhbCAyMDYgb25seSByZXR1cm5zIHRoZSByZXF1ZXN0ZWQgc2xpY2UsIHNvIHRoZSBmdWxsIHNpemUgbGl2ZXMgaW4gQ29udGVudC1SYW5nZSdzIHRvdGFsLlxuICAgICAgICBsZXQgc2l6ZSA9IGRhdGEubGVuZ3RoO1xuICAgICAgICBsZXQgY29udGVudFJhbmdlID0gcmVzcG9uc2UuaGVhZGVyc1tcImNvbnRlbnQtcmFuZ2VcIl07XG4gICAgICAgIGxldCB0b3RhbCA9IGNvbnRlbnRSYW5nZSAmJiBOdW1iZXIoY29udGVudFJhbmdlLnNwbGl0KFwiL1wiKVsxXSk7XG4gICAgICAgIGlmICh0b3RhbCAmJiBOdW1iZXIuaXNGaW5pdGUodG90YWwpKSB7XG4gICAgICAgICAgICBzaXplID0gdG90YWw7XG4gICAgICAgIH1cbiAgICAgICAgLy8gU2VydmVycyB0aGF0IGRvbid0IHN1cHBvcnQgcmFuZ2VzIHJldHVybiB0aGUgZnVsbCBmaWxlIHdpdGggYSAyMDAgKG91cnMgc2VydmVzIHJlYWwgMjA2cywgYnV0IGJhY2tibGF6ZSBmcmllbmRseSBVUkxzIGFuZCBwcm94aWVzIG1heSBub3QpXG4gICAgICAgIGlmIChyYW5nZSAmJiByZXNwb25zZS5zdGF0dXNDb2RlID09PSAyMDApIHtcbiAgICAgICAgICAgIGRhdGEgPSBkYXRhLnN1YmFycmF5KE1hdGgubWluKHJhbmdlLnN0YXJ0LCBkYXRhLmxlbmd0aCksIE1hdGgubWluKHJhbmdlLmVuZCwgZGF0YS5sZW5ndGgpKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgbGFzdE1vZGlmaWVkID0gcmVzcG9uc2UuaGVhZGVyc1tcImxhc3QtbW9kaWZpZWRcIl07XG4gICAgICAgIGxldCB3cml0ZVRpbWUgPSBsYXN0TW9kaWZpZWQgJiYgbmV3IERhdGUobGFzdE1vZGlmaWVkKS5nZXRUaW1lKCkgfHwgMDtcbiAgICAgICAgcmV0dXJuIHsgZGF0YSwgd3JpdGVUaW1lLCBzaXplIH07XG4gICAgfVxuICAgIHB1YmxpYyBhc3luYyBnZXRJbmZvKGZpbGVOYW1lOiBzdHJpbmcpOiBQcm9taXNlPHsgd3JpdGVUaW1lOiBudW1iZXI7IHNpemU6IG51bWJlciB9IHwgdW5kZWZpbmVkPiB7XG4gICAgICAgIC8vIEEgMS1ieXRlIHJhbmdlZCByZWFkOiBDb250ZW50LVJhbmdlIGNhcnJpZXMgdGhlIGZ1bGwgc2l6ZSBhbmQgTGFzdC1Nb2RpZmllZCB0aGUgd3JpdGUgdGltZSwgc28gbWV0YWRhdGEgbmV2ZXIgZG93bmxvYWRzIHRoZSBmaWxlXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgcmVzdWx0ID0gYXdhaXQgdGhpcy5nZXQyKGZpbGVOYW1lLCB7IHJhbmdlOiB7IHN0YXJ0OiAwLCBlbmQ6IDEgfSB9KTtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQgJiYgeyB3cml0ZVRpbWU6IHJlc3VsdC53cml0ZVRpbWUsIHNpemU6IHJlc3VsdC5zaXplIH0gfHwgdW5kZWZpbmVkO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIC8vIFNvbWUgc2VydmVycyByZWplY3QgcmFuZ2VkIHJlYWRzIG9mIGVtcHR5IGZpbGVzICg0MTYgaW5zdGVhZCBvZiBhbiBlbXB0eSAyMDYpOyBhIGZ1bGwgcmVhZCBpcyB0aGUgZmFsbGJhY2ssIGFuZCBmb3IgYW4gZW1wdHkgZmlsZSBpdCBpcyBmcmVlIGFueXdheVxuICAgICAgICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZ2V0MihmaWxlTmFtZSk7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0ICYmIHsgd3JpdGVUaW1lOiByZXN1bHQud3JpdGVUaW1lLCBzaXplOiByZXN1bHQuc2l6ZSB9IHx8IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBzZXQoZmlsZU5hbWU6IHN0cmluZywgZGF0YTogQnVmZmVyLCBjb25maWc/OiB7IGxhc3RNb2RpZmllZD86IG51bWJlciB9KTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgdGhyb3cgdGhpcy5yZWFkT25seUVycm9yKFwic2V0XCIpO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZGVsKGZpbGVOYW1lOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhyb3cgdGhpcy5yZWFkT25seUVycm9yKFwiZGVsXCIpO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgc2V0TGFyZ2VGaWxlKGNvbmZpZzogeyBwYXRoOiBzdHJpbmc7IGdldE5leHREYXRhKCk6IFByb21pc2U8QnVmZmVyIHwgdW5kZWZpbmVkPiB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRocm93IHRoaXMucmVhZE9ubHlFcnJvcihcInNldExhcmdlRmlsZVwiKTtcbiAgICB9XG4gICAgcHVibGljIGFzeW5jIGZpbmQocHJlZml4OiBzdHJpbmcsIGNvbmZpZz86IHsgc2hhbGxvdz86IGJvb2xlYW47IHR5cGU6IFwiZmlsZXNcIiB8IFwiZm9sZGVyc1wiIH0pOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgICAgIHRocm93IHRoaXMucmVhZE9ubHlFcnJvcihcImZpbmQgKGxpc3RpbmcpXCIpO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZmluZEluZm8ocHJlZml4OiBzdHJpbmcsIGNvbmZpZz86IHsgc2hhbGxvdz86IGJvb2xlYW47IHR5cGU6IFwiZmlsZXNcIiB8IFwiZm9sZGVyc1wiIH0pOiBQcm9taXNlPEFyY2hpdmVGaWxlSW5mb1tdPiB7XG4gICAgICAgIHRocm93IHRoaXMucmVhZE9ubHlFcnJvcihcImZpbmRJbmZvIChsaXN0aW5nKVwiKTtcbiAgICB9XG4gICAgcHVibGljIGFzeW5jIGdldENoYW5nZXNBZnRlcjIoY29uZmlnOiBDaGFuZ2VzQWZ0ZXJDb25maWcpOiBQcm9taXNlPEFyY2hpdmVGaWxlSW5mb1tdPiB7XG4gICAgICAgIHRocm93IHRoaXMucmVhZE9ubHlFcnJvcihcImdldENoYW5nZXNBZnRlcjIgKGxpc3RpbmcpXCIpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBnZXRVUkwocGF0aDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIGJ1aWxkRmlsZVVybCh0aGlzLmJhc2UsIHBhdGgpO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZ2V0Q29uZmlnKCk6IFByb21pc2U8QXJjaGl2ZXNDb25maWc+IHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBoYXNXcml0ZUFjY2VzcygpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cbiJdfQ==
|
|
98
|
-
/* _JS_SOURCE_HASH = "
|
|
98
|
+
/* _JS_SOURCE_HASH = "6b92fba9af77651d209fb3de6b45b4ae8e0267086b338eb2c43d80d24e167de7"; */
|