@lynx-js/react 0.117.0 → 0.118.0
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/CHANGELOG.md +24 -0
- package/package.json +14 -14
- package/refresh/.turbo/turbo-build.log +1 -1
- package/runtime/lazy/internal.js +8 -0
- package/runtime/lepus/jsx-runtime/index.js +17 -17
- package/runtime/lib/debug/printSnapshot.d.ts +3 -3
- package/runtime/lib/debug/printSnapshot.js +2 -2
- package/runtime/lib/debug/printSnapshot.js.map +1 -1
- package/runtime/lib/debug/profile.js +1 -2
- package/runtime/lib/debug/profile.js.map +1 -1
- package/runtime/lib/document.d.ts +2 -2
- package/runtime/lib/document.js +2 -2
- package/runtime/lib/document.js.map +1 -1
- package/runtime/lib/gesture/types.d.ts +13 -12
- package/runtime/lib/gesture/types.js +11 -12
- package/runtime/lib/gesture/types.js.map +1 -1
- package/runtime/lib/hooks/react.d.ts +2 -1
- package/runtime/lib/hooks/react.js +13 -7
- package/runtime/lib/hooks/react.js.map +1 -1
- package/runtime/lib/internal.d.ts +5 -3
- package/runtime/lib/internal.js +5 -3
- package/runtime/lib/internal.js.map +1 -1
- package/runtime/lib/lifecycle/constant.d.ts +19 -0
- package/runtime/lib/lifecycle/constant.js +17 -0
- package/runtime/lib/lifecycle/constant.js.map +1 -0
- package/runtime/lib/lifecycle/event/delayLifecycleEvents.d.ts +1 -1
- package/runtime/lib/lifecycle/event/jsReady.js +1 -1
- package/runtime/lib/lifecycle/event/jsReady.js.map +1 -1
- package/runtime/lib/lifecycle/isRendering.js +6 -8
- package/runtime/lib/lifecycle/isRendering.js.map +1 -1
- package/runtime/lib/lifecycle/patch/commit.d.ts +1 -1
- package/runtime/lib/lifecycle/patch/commit.js +10 -10
- package/runtime/lib/lifecycle/patch/commit.js.map +1 -1
- package/runtime/lib/lifecycle/patch/error.js +2 -1
- package/runtime/lib/lifecycle/patch/error.js.map +1 -1
- package/runtime/lib/lifecycle/patch/globalState.d.ts +8 -0
- package/runtime/lib/lifecycle/patch/globalState.js +14 -0
- package/runtime/lib/lifecycle/patch/globalState.js.map +1 -0
- package/runtime/lib/lifecycle/patch/snapshotPatchApply.js +1 -1
- package/runtime/lib/lifecycle/patch/snapshotPatchApply.js.map +1 -1
- package/runtime/lib/lifecycle/patch/updateMainThread.js +3 -3
- package/runtime/lib/lifecycle/patch/updateMainThread.js.map +1 -1
- package/runtime/lib/lifecycle/ref/delay.js +1 -1
- package/runtime/lib/lifecycle/ref/delay.js.map +1 -1
- package/runtime/lib/lifecycle/reload.js +9 -8
- package/runtime/lib/lifecycle/reload.js.map +1 -1
- package/runtime/lib/lifecycle/render.js +3 -15
- package/runtime/lib/lifecycle/render.js.map +1 -1
- package/runtime/lib/{list.d.ts → list/list.d.ts} +1 -1
- package/runtime/lib/{list.js → list/list.js} +3 -3
- package/runtime/lib/list/list.js.map +1 -0
- package/runtime/lib/{listUpdateInfo.d.ts → list/listUpdateInfo.d.ts} +1 -1
- package/runtime/lib/{listUpdateInfo.js → list/listUpdateInfo.js} +2 -2
- package/runtime/lib/list/listUpdateInfo.js.map +1 -0
- package/runtime/lib/list/pendingListUpdates.js.map +1 -0
- package/runtime/lib/lynx/calledByNative.js +7 -6
- package/runtime/lib/lynx/calledByNative.js.map +1 -1
- package/runtime/lib/lynx/injectLepusMethods.js +1 -1
- package/runtime/lib/lynx/injectLepusMethods.js.map +1 -1
- package/runtime/lib/lynx/performance.js +6 -13
- package/runtime/lib/lynx/performance.js.map +1 -1
- package/runtime/lib/lynx/suspense.js +2 -2
- package/runtime/lib/lynx/suspense.js.map +1 -1
- package/runtime/lib/lynx/tt.js +2 -3
- package/runtime/lib/lynx/tt.js.map +1 -1
- package/runtime/lib/lynx-api.js +1 -1
- package/runtime/lib/lynx-api.js.map +1 -1
- package/runtime/lib/renderToOpcodes/constants.d.ts +2 -0
- package/runtime/lib/renderToOpcodes/constants.js +2 -0
- package/runtime/lib/renderToOpcodes/constants.js.map +1 -1
- package/runtime/lib/{hydrate.d.ts → renderToOpcodes/hydrate.d.ts} +2 -2
- package/runtime/lib/{hydrate.js → renderToOpcodes/hydrate.js} +6 -6
- package/runtime/lib/renderToOpcodes/hydrate.js.map +1 -0
- package/runtime/lib/renderToOpcodes/index.d.ts +2 -1
- package/runtime/lib/renderToOpcodes/index.js +79 -24
- package/runtime/lib/renderToOpcodes/index.js.map +1 -1
- package/runtime/lib/{opcodes.d.ts → renderToOpcodes/opcodes.d.ts} +1 -2
- package/runtime/lib/{opcodes.js → renderToOpcodes/opcodes.js} +62 -65
- package/runtime/lib/renderToOpcodes/opcodes.js.map +1 -0
- package/runtime/lib/root.d.ts +2 -2
- package/runtime/lib/root.js +2 -2
- package/runtime/lib/root.js.map +1 -1
- package/runtime/lib/{backgroundSnapshot.d.ts → snapshot/backgroundSnapshot.d.ts} +13 -2
- package/runtime/lib/{backgroundSnapshot.js → snapshot/backgroundSnapshot.js} +77 -16
- package/runtime/lib/snapshot/backgroundSnapshot.js.map +1 -0
- package/runtime/lib/snapshot/constants.d.ts +11 -0
- package/runtime/lib/snapshot/constants.js +15 -0
- package/runtime/lib/snapshot/constants.js.map +1 -0
- package/runtime/lib/snapshot/definition.d.ts +29 -0
- package/runtime/lib/snapshot/definition.js +109 -0
- package/runtime/lib/snapshot/definition.js.map +1 -0
- package/runtime/lib/snapshot/dynamicPartType.d.ts +13 -8
- package/runtime/lib/snapshot/dynamicPartType.js +12 -9
- package/runtime/lib/snapshot/dynamicPartType.js.map +1 -1
- package/runtime/lib/snapshot/event.d.ts +1 -1
- package/runtime/lib/snapshot/event.js +1 -1
- package/runtime/lib/snapshot/event.js.map +1 -1
- package/runtime/lib/snapshot/gesture.d.ts +1 -1
- package/runtime/lib/snapshot/gesture.js +0 -1
- package/runtime/lib/snapshot/gesture.js.map +1 -1
- package/runtime/lib/snapshot/index.d.ts +4 -0
- package/runtime/lib/snapshot/index.js +8 -0
- package/runtime/lib/snapshot/index.js.map +1 -0
- package/runtime/lib/snapshot/list.d.ts +1 -1
- package/runtime/lib/snapshot/list.js +2 -2
- package/runtime/lib/snapshot/list.js.map +1 -1
- package/runtime/lib/snapshot/platformInfo.d.ts +1 -1
- package/runtime/lib/snapshot/platformInfo.js +2 -3
- package/runtime/lib/snapshot/platformInfo.js.map +1 -1
- package/runtime/lib/snapshot/ref.d.ts +1 -1
- package/runtime/lib/snapshot/ref.js.map +1 -1
- package/runtime/lib/snapshot/snapshot.d.ts +58 -0
- package/runtime/lib/{snapshot.js → snapshot/snapshot.js} +24 -172
- package/runtime/lib/snapshot/snapshot.js.map +1 -0
- package/runtime/lib/snapshot/snapshotInstanceHydrationMap.js.map +1 -0
- package/runtime/lib/snapshot/spread.d.ts +2 -2
- package/runtime/lib/snapshot/spread.js +3 -3
- package/runtime/lib/snapshot/spread.js.map +1 -1
- package/runtime/lib/snapshot/types.d.ts +19 -0
- package/runtime/lib/snapshot/types.js +5 -0
- package/runtime/lib/snapshot/types.js.map +1 -0
- package/runtime/lib/snapshot/utils.d.ts +12 -0
- package/runtime/lib/snapshot/utils.js +20 -0
- package/runtime/lib/snapshot/utils.js.map +1 -0
- package/runtime/lib/snapshot/workletEvent.d.ts +1 -1
- package/runtime/lib/snapshot/workletEvent.js +1 -1
- package/runtime/lib/snapshot/workletEvent.js.map +1 -1
- package/runtime/lib/snapshot/workletRef.d.ts +1 -1
- package/runtime/lib/tsconfig.tsbuildinfo +1 -0
- package/runtime/lib/utils.d.ts +1 -0
- package/runtime/lib/utils.js +4 -1
- package/runtime/lib/utils.js.map +1 -1
- package/runtime/lib/worklet/ref/updateInitValue.js +1 -1
- package/runtime/lib/worklet/ref/updateInitValue.js.map +1 -1
- package/runtime/lib/worklet-runtime/api/animation/animation.js.map +1 -0
- package/runtime/lib/worklet-runtime/api/animation/effect.js.map +1 -0
- package/runtime/lib/worklet-runtime/api/element.js.map +1 -0
- package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/api/lepusQuerySelector.js +10 -2
- package/runtime/lib/worklet-runtime/api/lepusQuerySelector.js.map +1 -0
- package/runtime/lib/worklet-runtime/api/lynxApi.js.map +1 -0
- package/runtime/lib/worklet-runtime/bindings/bindings.js.map +1 -0
- package/runtime/lib/worklet-runtime/bindings/events.js.map +1 -0
- package/runtime/lib/worklet-runtime/bindings/index.js.map +1 -0
- package/runtime/lib/worklet-runtime/bindings/loadRuntime.js.map +1 -0
- package/runtime/lib/worklet-runtime/bindings/observers.js.map +1 -0
- package/runtime/lib/worklet-runtime/bindings/types.js.map +1 -0
- package/runtime/lib/worklet-runtime/delayRunOnBackground.js.map +1 -0
- package/runtime/lib/worklet-runtime/delayWorkletEvent.js.map +1 -0
- package/runtime/lib/worklet-runtime/eomImpl.js.map +1 -0
- package/runtime/lib/worklet-runtime/eventPropagation.js.map +1 -0
- package/runtime/lib/worklet-runtime/global.js.map +1 -0
- package/runtime/lib/worklet-runtime/hydrate.js.map +1 -0
- package/runtime/lib/worklet-runtime/index.js.map +1 -0
- package/runtime/lib/worklet-runtime/jsFunctionLifecycle.js.map +1 -0
- package/runtime/lib/worklet-runtime/listeners.js.map +1 -0
- package/runtime/lib/worklet-runtime/runOnMainThread.js.map +1 -0
- package/runtime/lib/worklet-runtime/utils/mainThreadFlushLoopGuard.js.map +1 -0
- package/runtime/lib/worklet-runtime/utils/profile.js.map +1 -0
- package/runtime/lib/worklet-runtime/utils/version.js.map +1 -0
- package/runtime/lib/worklet-runtime/workletRef.js.map +1 -0
- package/runtime/lib/worklet-runtime/workletRuntime.js.map +1 -0
- package/runtime/worklet-runtime/dev.js +629 -0
- package/{worklet-runtime/dist → runtime/worklet-runtime}/main.js +1 -1
- package/testing-library/dist/pure.js +1 -1
- package/testing-library/dist/vitest-global-setup.js +4 -5
- package/transform/dist/wasm.cjs +1 -1
- package/transform/index.d.ts +27 -1
- package/runtime/lib/backgroundSnapshot.js.map +0 -1
- package/runtime/lib/hydrate.js.map +0 -1
- package/runtime/lib/lifecycleConstant.d.ts +0 -17
- package/runtime/lib/lifecycleConstant.js +0 -19
- package/runtime/lib/lifecycleConstant.js.map +0 -1
- package/runtime/lib/list.js.map +0 -1
- package/runtime/lib/listUpdateInfo.js.map +0 -1
- package/runtime/lib/opcodes.js.map +0 -1
- package/runtime/lib/pendingListUpdates.js.map +0 -1
- package/runtime/lib/snapshot.d.ts +0 -104
- package/runtime/lib/snapshot.js.map +0 -1
- package/runtime/lib/snapshotInstanceHydrationMap.js.map +0 -1
- package/worklet-runtime/dist/dev.js +0 -625
- package/worklet-runtime/lib/api/animation/animation.js.map +0 -1
- package/worklet-runtime/lib/api/animation/effect.js.map +0 -1
- package/worklet-runtime/lib/api/element.js.map +0 -1
- package/worklet-runtime/lib/api/lepusQuerySelector.js.map +0 -1
- package/worklet-runtime/lib/api/lynxApi.js.map +0 -1
- package/worklet-runtime/lib/bindings/bindings.js.map +0 -1
- package/worklet-runtime/lib/bindings/events.js.map +0 -1
- package/worklet-runtime/lib/bindings/index.js.map +0 -1
- package/worklet-runtime/lib/bindings/loadRuntime.js.map +0 -1
- package/worklet-runtime/lib/bindings/observers.js.map +0 -1
- package/worklet-runtime/lib/bindings/types.js.map +0 -1
- package/worklet-runtime/lib/delayRunOnBackground.js.map +0 -1
- package/worklet-runtime/lib/delayWorkletEvent.js.map +0 -1
- package/worklet-runtime/lib/eomImpl.js.map +0 -1
- package/worklet-runtime/lib/eventPropagation.js.map +0 -1
- package/worklet-runtime/lib/global.js.map +0 -1
- package/worklet-runtime/lib/hydrate.js.map +0 -1
- package/worklet-runtime/lib/index.js.map +0 -1
- package/worklet-runtime/lib/jsFunctionLifecycle.js.map +0 -1
- package/worklet-runtime/lib/listeners.js.map +0 -1
- package/worklet-runtime/lib/runOnMainThread.js.map +0 -1
- package/worklet-runtime/lib/utils/mainThreadFlushLoopGuard.js.map +0 -1
- package/worklet-runtime/lib/utils/profile.js.map +0 -1
- package/worklet-runtime/lib/utils/version.js.map +0 -1
- package/worklet-runtime/lib/workletRef.js.map +0 -1
- package/worklet-runtime/lib/workletRuntime.js.map +0 -1
- /package/runtime/lib/{pendingListUpdates.d.ts → list/pendingListUpdates.d.ts} +0 -0
- /package/runtime/lib/{pendingListUpdates.js → list/pendingListUpdates.js} +0 -0
- /package/runtime/lib/{snapshotInstanceHydrationMap.d.ts → snapshot/snapshotInstanceHydrationMap.d.ts} +0 -0
- /package/runtime/lib/{snapshotInstanceHydrationMap.js → snapshot/snapshotInstanceHydrationMap.js} +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/api/animation/animation.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/api/animation/animation.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/api/animation/effect.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/api/animation/effect.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/api/element.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/api/element.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/api/lepusQuerySelector.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/api/lynxApi.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/api/lynxApi.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/bindings/bindings.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/bindings/bindings.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/bindings/events.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/bindings/events.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/bindings/index.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/bindings/index.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/bindings/loadRuntime.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/bindings/loadRuntime.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/bindings/observers.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/bindings/observers.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/bindings/types.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/bindings/types.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/delayRunOnBackground.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/delayRunOnBackground.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/delayWorkletEvent.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/delayWorkletEvent.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/eomImpl.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/eomImpl.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/eventPropagation.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/eventPropagation.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/global.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/global.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/hydrate.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/hydrate.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/index.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/index.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/jsFunctionLifecycle.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/jsFunctionLifecycle.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/listeners.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/listeners.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/runOnMainThread.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/runOnMainThread.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/utils/mainThreadFlushLoopGuard.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/utils/mainThreadFlushLoopGuard.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/utils/profile.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/utils/profile.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/utils/version.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/utils/version.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/workletRef.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/workletRef.js +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/workletRuntime.d.ts +0 -0
- /package/{worklet-runtime/lib → runtime/lib/worklet-runtime}/workletRuntime.js +0 -0
|
@@ -0,0 +1,629 @@
|
|
|
1
|
+
(()=>{
|
|
2
|
+
"use strict";
|
|
3
|
+
function _define_property(obj, key, value) {
|
|
4
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
5
|
+
value: value,
|
|
6
|
+
enumerable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
writable: true
|
|
9
|
+
});
|
|
10
|
+
else obj[key] = value;
|
|
11
|
+
return obj;
|
|
12
|
+
}
|
|
13
|
+
class Animation {
|
|
14
|
+
cancel() {
|
|
15
|
+
return __ElementAnimate(this.effect.target.element, [
|
|
16
|
+
3,
|
|
17
|
+
this.id
|
|
18
|
+
]);
|
|
19
|
+
}
|
|
20
|
+
pause() {
|
|
21
|
+
return __ElementAnimate(this.effect.target.element, [
|
|
22
|
+
2,
|
|
23
|
+
this.id
|
|
24
|
+
]);
|
|
25
|
+
}
|
|
26
|
+
play() {
|
|
27
|
+
return __ElementAnimate(this.effect.target.element, [
|
|
28
|
+
1,
|
|
29
|
+
this.id
|
|
30
|
+
]);
|
|
31
|
+
}
|
|
32
|
+
start() {
|
|
33
|
+
return __ElementAnimate(this.effect.target.element, [
|
|
34
|
+
0,
|
|
35
|
+
this.id,
|
|
36
|
+
this.effect.keyframes,
|
|
37
|
+
this.effect.options
|
|
38
|
+
]);
|
|
39
|
+
}
|
|
40
|
+
constructor(effect){
|
|
41
|
+
_define_property(this, "effect", void 0);
|
|
42
|
+
_define_property(this, "id", void 0);
|
|
43
|
+
this.effect = effect;
|
|
44
|
+
this.id = '__lynx-inner-js-animation-' + Animation.count++;
|
|
45
|
+
this.start();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
_define_property(Animation, "count", 0);
|
|
49
|
+
function effect_define_property(obj, key, value) {
|
|
50
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
51
|
+
value: value,
|
|
52
|
+
enumerable: true,
|
|
53
|
+
configurable: true,
|
|
54
|
+
writable: true
|
|
55
|
+
});
|
|
56
|
+
else obj[key] = value;
|
|
57
|
+
return obj;
|
|
58
|
+
}
|
|
59
|
+
class KeyframeEffect {
|
|
60
|
+
constructor(target, keyframes, options){
|
|
61
|
+
effect_define_property(this, "target", void 0);
|
|
62
|
+
effect_define_property(this, "keyframes", void 0);
|
|
63
|
+
effect_define_property(this, "options", void 0);
|
|
64
|
+
this.target = target;
|
|
65
|
+
this.keyframes = keyframes;
|
|
66
|
+
this.options = options;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const TRACE_LIMIT = 256;
|
|
70
|
+
const DEFAULT_FLUSH_LIMIT = 256;
|
|
71
|
+
let trace = [];
|
|
72
|
+
let flushCountInWindow = 0;
|
|
73
|
+
let resetScheduled = false;
|
|
74
|
+
let trippedError = null;
|
|
75
|
+
function pushTrace(marker) {
|
|
76
|
+
trace.push(marker);
|
|
77
|
+
if (trace.length > TRACE_LIMIT) trace = trace.slice(trace.length - TRACE_LIMIT);
|
|
78
|
+
}
|
|
79
|
+
function compressTrace(markers) {
|
|
80
|
+
if (0 === markers.length) return '';
|
|
81
|
+
const out = [];
|
|
82
|
+
let prev = markers[markers.length - 1];
|
|
83
|
+
let count = 1;
|
|
84
|
+
for(let i = markers.length - 2; i >= 0; i--){
|
|
85
|
+
const cur = markers[i];
|
|
86
|
+
if (cur === prev) {
|
|
87
|
+
count++;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
out.push(1 === count ? prev : `${prev} x${count}`);
|
|
91
|
+
prev = cur;
|
|
92
|
+
count = 1;
|
|
93
|
+
}
|
|
94
|
+
out.push(1 === count ? prev : `${prev} x${count}`);
|
|
95
|
+
return out.join(' <- ');
|
|
96
|
+
}
|
|
97
|
+
function mainThreadFlushLoopMark(marker) {
|
|
98
|
+
pushTrace(marker);
|
|
99
|
+
}
|
|
100
|
+
function mainThreadFlushLoopOnFlushMicrotask() {
|
|
101
|
+
if (trippedError) return trippedError;
|
|
102
|
+
if (!resetScheduled) {
|
|
103
|
+
resetScheduled = true;
|
|
104
|
+
setTimeout(()=>{
|
|
105
|
+
mainThreadFlushLoopReset();
|
|
106
|
+
}, 0);
|
|
107
|
+
}
|
|
108
|
+
flushCountInWindow++;
|
|
109
|
+
const limit = DEFAULT_FLUSH_LIMIT;
|
|
110
|
+
if (flushCountInWindow > limit) {
|
|
111
|
+
const traceText = compressTrace(trace);
|
|
112
|
+
trippedError = new Error(`[ReactLynx][DEV] MainThread flush loop detected: render executed ${flushCountInWindow} times without yielding (limit=${limit}). Trace: ${traceText}`);
|
|
113
|
+
return trippedError;
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
function mainThreadFlushLoopReport(error) {
|
|
118
|
+
setTimeout(()=>{
|
|
119
|
+
throw error;
|
|
120
|
+
}, 0);
|
|
121
|
+
}
|
|
122
|
+
function mainThreadFlushLoopReset() {
|
|
123
|
+
trace = [];
|
|
124
|
+
flushCountInWindow = 0;
|
|
125
|
+
resetScheduled = false;
|
|
126
|
+
trippedError = null;
|
|
127
|
+
}
|
|
128
|
+
function isSdkVersionGt(major, minor) {
|
|
129
|
+
var _SystemInfo_lynxSdkVersion;
|
|
130
|
+
const lynxSdkVersion = null != (_SystemInfo_lynxSdkVersion = SystemInfo.lynxSdkVersion) ? _SystemInfo_lynxSdkVersion : '1.0';
|
|
131
|
+
const version = lynxSdkVersion.split('.');
|
|
132
|
+
return Number(version[0]) > major || Number(version[0]) == major && Number(version[1]) > minor;
|
|
133
|
+
}
|
|
134
|
+
function element_define_property(obj, key, value) {
|
|
135
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
136
|
+
value: value,
|
|
137
|
+
enumerable: true,
|
|
138
|
+
configurable: true,
|
|
139
|
+
writable: true
|
|
140
|
+
});
|
|
141
|
+
else obj[key] = value;
|
|
142
|
+
return obj;
|
|
143
|
+
}
|
|
144
|
+
let willFlush = false;
|
|
145
|
+
let shouldFlush = true;
|
|
146
|
+
function setShouldFlush(value) {
|
|
147
|
+
shouldFlush = value;
|
|
148
|
+
}
|
|
149
|
+
class Element {
|
|
150
|
+
setAttribute(name, value) {
|
|
151
|
+
mainThreadFlushLoopMark(`element:setAttribute ${name}`);
|
|
152
|
+
__SetAttribute(this.element, name, value);
|
|
153
|
+
this.flushElementTree();
|
|
154
|
+
}
|
|
155
|
+
setStyleProperty(name, value) {
|
|
156
|
+
mainThreadFlushLoopMark(`element:setStyleProperty ${name}`);
|
|
157
|
+
__AddInlineStyle(this.element, name, value);
|
|
158
|
+
this.flushElementTree();
|
|
159
|
+
}
|
|
160
|
+
setStyleProperties(styles) {
|
|
161
|
+
mainThreadFlushLoopMark(`element:setStyleProperties keys=${Object.keys(styles).length}`);
|
|
162
|
+
for(const key in styles)__AddInlineStyle(this.element, key, styles[key]);
|
|
163
|
+
this.flushElementTree();
|
|
164
|
+
}
|
|
165
|
+
getAttribute(attributeName) {
|
|
166
|
+
return __GetAttributeByName(this.element, attributeName);
|
|
167
|
+
}
|
|
168
|
+
getAttributeNames() {
|
|
169
|
+
return __GetAttributeNames(this.element);
|
|
170
|
+
}
|
|
171
|
+
querySelector(selector) {
|
|
172
|
+
const ref = __QuerySelector(this.element, selector, {});
|
|
173
|
+
return ref ? new Element(ref) : null;
|
|
174
|
+
}
|
|
175
|
+
querySelectorAll(selector) {
|
|
176
|
+
return __QuerySelectorAll(this.element, selector, {}).map((element)=>new Element(element));
|
|
177
|
+
}
|
|
178
|
+
getComputedStyleProperty(key) {
|
|
179
|
+
if (!isSdkVersionGt(3, 4)) throw new Error('getComputedStyleProperty requires Lynx sdk version 3.5');
|
|
180
|
+
if (!key) throw new Error('getComputedStyleProperty: key is required');
|
|
181
|
+
return __GetComputedStyleByKey(this.element, key);
|
|
182
|
+
}
|
|
183
|
+
animate(keyframes, options) {
|
|
184
|
+
const normalizedOptions = 'number' == typeof options ? {
|
|
185
|
+
duration: options
|
|
186
|
+
} : null != options ? options : {};
|
|
187
|
+
return new Animation(new KeyframeEffect(this, keyframes, normalizedOptions));
|
|
188
|
+
}
|
|
189
|
+
invoke(methodName, params) {
|
|
190
|
+
mainThreadFlushLoopMark(`element:invoke ${methodName}`);
|
|
191
|
+
return new Promise((resolve, reject)=>{
|
|
192
|
+
__InvokeUIMethod(this.element, methodName, null != params ? params : {}, (res)=>{
|
|
193
|
+
if (0 === res.code) resolve(res.data);
|
|
194
|
+
else reject(new Error('UI method invoke: ' + JSON.stringify(res)));
|
|
195
|
+
});
|
|
196
|
+
this.flushElementTree();
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
flushElementTree() {
|
|
200
|
+
if (willFlush || !shouldFlush) return;
|
|
201
|
+
willFlush = true;
|
|
202
|
+
Promise.resolve().then(()=>{
|
|
203
|
+
willFlush = false;
|
|
204
|
+
{
|
|
205
|
+
mainThreadFlushLoopMark('render');
|
|
206
|
+
const error = mainThreadFlushLoopOnFlushMicrotask();
|
|
207
|
+
if (error) {
|
|
208
|
+
shouldFlush = false;
|
|
209
|
+
mainThreadFlushLoopReport(error);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
__FlushElementTree();
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
constructor(element){
|
|
217
|
+
element_define_property(this, "element", void 0);
|
|
218
|
+
Object.defineProperty(this, 'element', {
|
|
219
|
+
get () {
|
|
220
|
+
return element;
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
function lepusQuerySelector_define_property(obj, key, value) {
|
|
226
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
227
|
+
value: value,
|
|
228
|
+
enumerable: true,
|
|
229
|
+
configurable: true,
|
|
230
|
+
writable: true
|
|
231
|
+
});
|
|
232
|
+
else obj[key] = value;
|
|
233
|
+
return obj;
|
|
234
|
+
}
|
|
235
|
+
class PageElement {
|
|
236
|
+
static get() {
|
|
237
|
+
var _PageElement;
|
|
238
|
+
null != (_PageElement = PageElement).pageElement || (_PageElement.pageElement = __GetPageElement());
|
|
239
|
+
return PageElement.pageElement;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
lepusQuerySelector_define_property(PageElement, "pageElement", void 0);
|
|
243
|
+
function querySelector(cssSelector) {
|
|
244
|
+
const pageElement = PageElement.get();
|
|
245
|
+
if (!pageElement) return null;
|
|
246
|
+
const element = __QuerySelector(pageElement, cssSelector, {});
|
|
247
|
+
return element ? new Element(element) : null;
|
|
248
|
+
}
|
|
249
|
+
function querySelectorAll(cssSelector) {
|
|
250
|
+
const pageElement = PageElement.get();
|
|
251
|
+
if (!pageElement) return [];
|
|
252
|
+
return __QuerySelectorAll(pageElement, cssSelector, {}).map((element)=>new Element(element));
|
|
253
|
+
}
|
|
254
|
+
function initApiEnv() {
|
|
255
|
+
var _lynx_clearInterval;
|
|
256
|
+
lynx.querySelector = querySelector;
|
|
257
|
+
lynx.querySelectorAll = querySelectorAll;
|
|
258
|
+
globalThis.setTimeout = lynx.setTimeout;
|
|
259
|
+
globalThis.setInterval = lynx.setInterval;
|
|
260
|
+
globalThis.clearTimeout = lynx.clearTimeout;
|
|
261
|
+
globalThis.clearInterval = null != (_lynx_clearInterval = lynx.clearInterval) ? _lynx_clearInterval : lynx.clearTimeInterval;
|
|
262
|
+
{
|
|
263
|
+
const requestAnimationFrame = lynx.requestAnimationFrame;
|
|
264
|
+
lynx.requestAnimationFrame = globalThis.requestAnimationFrame = (callback)=>{
|
|
265
|
+
if (!isSdkVersionGt(2, 15)) throw new Error("requestAnimationFrame in main thread script requires Lynx sdk version 2.16");
|
|
266
|
+
return requestAnimationFrame(callback);
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
globalThis.cancelAnimationFrame = lynx.cancelAnimationFrame;
|
|
270
|
+
}
|
|
271
|
+
function runRunOnMainThreadTask(task, params, resolveId) {
|
|
272
|
+
let returnValue;
|
|
273
|
+
try {
|
|
274
|
+
returnValue = runWorklet(task, params);
|
|
275
|
+
} finally{
|
|
276
|
+
lynx.getJSContext().dispatchEvent({
|
|
277
|
+
type: "Lynx.Worklet.FunctionCallRet",
|
|
278
|
+
data: JSON.stringify({
|
|
279
|
+
resolveId,
|
|
280
|
+
returnValue
|
|
281
|
+
})
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
function profile(sliceName, f) {
|
|
286
|
+
var _console_profile, _console;
|
|
287
|
+
null == (_console_profile = (_console = console).profile) || _console_profile.call(_console, sliceName);
|
|
288
|
+
try {
|
|
289
|
+
return f();
|
|
290
|
+
} finally{
|
|
291
|
+
var _console_profileEnd, _console1;
|
|
292
|
+
null == (_console_profileEnd = (_console1 = console).profileEnd) || _console_profileEnd.call(_console1);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
let impl;
|
|
296
|
+
function initWorkletRef() {
|
|
297
|
+
return impl = {
|
|
298
|
+
_workletRefMap: {},
|
|
299
|
+
_firstScreenWorkletRefMap: {},
|
|
300
|
+
updateWorkletRef,
|
|
301
|
+
updateWorkletRefInitValueChanges,
|
|
302
|
+
clearFirstScreenWorkletRefMap
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
const createWorkletRef = (id, value)=>({
|
|
306
|
+
current: value,
|
|
307
|
+
_wvid: id
|
|
308
|
+
});
|
|
309
|
+
const getFromWorkletRefMap = (refImpl)=>{
|
|
310
|
+
const id = refImpl._wvid;
|
|
311
|
+
mainThreadFlushLoopMark(`MainThreadRef:get id=${id}`);
|
|
312
|
+
let value;
|
|
313
|
+
if (id < 0) {
|
|
314
|
+
value = impl._firstScreenWorkletRefMap[id];
|
|
315
|
+
if (!value) value = impl._firstScreenWorkletRefMap[id] = createWorkletRef(id, refImpl._initValue);
|
|
316
|
+
} else value = impl._workletRefMap[id];
|
|
317
|
+
if (void 0 === value) throw new Error('MainThreadRef is not initialized: ' + id);
|
|
318
|
+
return value;
|
|
319
|
+
};
|
|
320
|
+
function removeValueFromWorkletRefMap(id) {
|
|
321
|
+
delete impl._workletRefMap[id];
|
|
322
|
+
}
|
|
323
|
+
function updateWorkletRef(handle, element) {
|
|
324
|
+
getFromWorkletRefMap(handle).current = element ? new Element(element) : null;
|
|
325
|
+
}
|
|
326
|
+
function updateWorkletRefInitValueChanges(patch) {
|
|
327
|
+
profile('updateWorkletRefInitValueChanges', ()=>{
|
|
328
|
+
patch.forEach(([id, value])=>{
|
|
329
|
+
if (!impl._workletRefMap[id]) impl._workletRefMap[id] = createWorkletRef(id, value);
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
function clearFirstScreenWorkletRefMap() {
|
|
334
|
+
impl._firstScreenWorkletRefMap = {};
|
|
335
|
+
}
|
|
336
|
+
function initEventListeners() {
|
|
337
|
+
const jsContext = lynx.getJSContext();
|
|
338
|
+
jsContext.addEventListener("Lynx.Worklet.runWorkletCtx", (event)=>{
|
|
339
|
+
const data = JSON.parse(event.data);
|
|
340
|
+
runRunOnMainThreadTask(data.worklet, data.params, data.resolveId);
|
|
341
|
+
});
|
|
342
|
+
jsContext.addEventListener("Lynx.Worklet.releaseWorkletRef", (event)=>{
|
|
343
|
+
removeValueFromWorkletRefMap(event.data.id);
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
let delayRunOnBackground_impl;
|
|
347
|
+
function initRunOnBackgroundDelay() {
|
|
348
|
+
return delayRunOnBackground_impl = {
|
|
349
|
+
delayedBackgroundFunctionArray: [],
|
|
350
|
+
delayRunOnBackground,
|
|
351
|
+
runDelayedBackgroundFunctions
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
function delayRunOnBackground(fnObj, task) {
|
|
355
|
+
var _fnObj, __delayIndices;
|
|
356
|
+
delayRunOnBackground_impl.delayedBackgroundFunctionArray.push({
|
|
357
|
+
task
|
|
358
|
+
});
|
|
359
|
+
const delayIndices = null != (__delayIndices = (_fnObj = fnObj)._delayIndices) ? __delayIndices : _fnObj._delayIndices = [];
|
|
360
|
+
delayIndices.push(delayRunOnBackground_impl.delayedBackgroundFunctionArray.length - 1);
|
|
361
|
+
}
|
|
362
|
+
function runDelayedBackgroundFunctions() {
|
|
363
|
+
for (const details of delayRunOnBackground_impl.delayedBackgroundFunctionArray)if (details.jsFnHandle) details.task(details.jsFnHandle._jsFnId, details.jsFnHandle._execId);
|
|
364
|
+
delayRunOnBackground_impl.delayedBackgroundFunctionArray.length = 0;
|
|
365
|
+
}
|
|
366
|
+
let delayWorkletEvent_impl;
|
|
367
|
+
function initEventDelay() {
|
|
368
|
+
return delayWorkletEvent_impl = {
|
|
369
|
+
_delayedWorkletParamsMap: new Map(),
|
|
370
|
+
runDelayedWorklet,
|
|
371
|
+
clearDelayedWorklets
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
function delayExecUntilJsReady(hash, params) {
|
|
375
|
+
profile('delayExecUntilJsReady: ' + hash, ()=>{
|
|
376
|
+
const map = delayWorkletEvent_impl._delayedWorkletParamsMap;
|
|
377
|
+
const paramVec = map.get(hash);
|
|
378
|
+
if (paramVec) paramVec.push(params);
|
|
379
|
+
else map.set(hash, [
|
|
380
|
+
params
|
|
381
|
+
]);
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
function runDelayedWorklet(worklet, element) {
|
|
385
|
+
profile('commitDelayedWorklet', ()=>{
|
|
386
|
+
const paramsVec = delayWorkletEvent_impl._delayedWorkletParamsMap.get(worklet._wkltId);
|
|
387
|
+
if (void 0 === paramsVec) return;
|
|
388
|
+
const leftParamsVec = [];
|
|
389
|
+
paramsVec.forEach((params)=>{
|
|
390
|
+
var _firstParam_currentTarget;
|
|
391
|
+
const firstParam = params[0];
|
|
392
|
+
if ((null == firstParam ? void 0 : null == (_firstParam_currentTarget = firstParam.currentTarget) ? void 0 : _firstParam_currentTarget.elementRefptr) === element) setTimeout(()=>{
|
|
393
|
+
profile('runDelayedWorklet', ()=>{
|
|
394
|
+
runWorklet(worklet, params);
|
|
395
|
+
});
|
|
396
|
+
}, 0);
|
|
397
|
+
else leftParamsVec.push(params);
|
|
398
|
+
});
|
|
399
|
+
delayWorkletEvent_impl._delayedWorkletParamsMap.set(worklet._wkltId, leftParamsVec);
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
function clearDelayedWorklets() {
|
|
403
|
+
delayWorkletEvent_impl._delayedWorkletParamsMap.clear();
|
|
404
|
+
}
|
|
405
|
+
function initEomImpl() {
|
|
406
|
+
return {
|
|
407
|
+
setShouldFlush: setShouldFlush
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
const EventResult = {
|
|
411
|
+
kDefault: 0x0,
|
|
412
|
+
kStopPropagationMask: 0x1,
|
|
413
|
+
kStopImmediatePropagationMask: 0x2
|
|
414
|
+
};
|
|
415
|
+
function isEventObject(ctx, options) {
|
|
416
|
+
if (!Array.isArray(ctx) || 'object' != typeof ctx[0] || null === ctx[0]) return false;
|
|
417
|
+
if (options && 1 === options.source) return true;
|
|
418
|
+
return false;
|
|
419
|
+
}
|
|
420
|
+
function addEventMethodsIfNeeded(ctx, options) {
|
|
421
|
+
if (!isEventObject(ctx, options)) return [
|
|
422
|
+
false,
|
|
423
|
+
{}
|
|
424
|
+
];
|
|
425
|
+
const eventCtx = {};
|
|
426
|
+
const eventObj = ctx[0];
|
|
427
|
+
eventObj['stopPropagation'] = function() {
|
|
428
|
+
var _eventCtx__eventReturnResult;
|
|
429
|
+
eventCtx._eventReturnResult = (null != (_eventCtx__eventReturnResult = eventCtx._eventReturnResult) ? _eventCtx__eventReturnResult : EventResult.kDefault) | EventResult.kStopPropagationMask;
|
|
430
|
+
};
|
|
431
|
+
eventObj['stopImmediatePropagation'] = function() {
|
|
432
|
+
var _eventCtx__eventReturnResult;
|
|
433
|
+
eventCtx._eventReturnResult = (null != (_eventCtx__eventReturnResult = eventCtx._eventReturnResult) ? _eventCtx__eventReturnResult : EventResult.kDefault) | EventResult.kStopImmediatePropagationMask;
|
|
434
|
+
};
|
|
435
|
+
return [
|
|
436
|
+
true,
|
|
437
|
+
eventCtx
|
|
438
|
+
];
|
|
439
|
+
}
|
|
440
|
+
function hydrateCtx(ctx, firstScreenCtx) {
|
|
441
|
+
profile('hydrateCtx', ()=>{
|
|
442
|
+
hydrateCtxImpl(ctx, firstScreenCtx, ctx._execId);
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
function hydrateCtxImpl(ctx, firstScreenCtx, execId) {
|
|
446
|
+
if (!ctx || 'object' != typeof ctx || !firstScreenCtx || 'object' != typeof firstScreenCtx) return;
|
|
447
|
+
const ctxObj = ctx;
|
|
448
|
+
const firstScreenCtxObj = firstScreenCtx;
|
|
449
|
+
if (ctxObj['_wkltId'] && ctxObj['_wkltId'] !== firstScreenCtxObj['_wkltId']) return;
|
|
450
|
+
for(const key in ctx)if ('_wvid' === key) hydrateMainThreadRef(ctxObj[key], firstScreenCtxObj);
|
|
451
|
+
else if ('_jsFn' === key) hydrateDelayRunOnBackgroundTasks(ctxObj[key], firstScreenCtxObj[key], execId);
|
|
452
|
+
else {
|
|
453
|
+
const firstScreenValue = 'function' == typeof firstScreenCtxObj[key] ? firstScreenCtxObj[key].ctx : firstScreenCtxObj[key];
|
|
454
|
+
hydrateCtxImpl(ctxObj[key], firstScreenValue, execId);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
function hydrateMainThreadRef(refId, value) {
|
|
458
|
+
if ('_initValue' in value) return;
|
|
459
|
+
lynxWorkletImpl._refImpl._workletRefMap[refId] = value;
|
|
460
|
+
}
|
|
461
|
+
function hydrateDelayRunOnBackgroundTasks(fnObjs, firstScreenFnObjs, execId) {
|
|
462
|
+
for(const fnName in fnObjs){
|
|
463
|
+
const fnObj = fnObjs[fnName];
|
|
464
|
+
const firstScreenFnObj = firstScreenFnObjs[fnName];
|
|
465
|
+
if (!(null == firstScreenFnObj ? void 0 : firstScreenFnObj._delayIndices)) {
|
|
466
|
+
if (firstScreenFnObj) {
|
|
467
|
+
firstScreenFnObj._isFirstScreen = false;
|
|
468
|
+
firstScreenFnObj._execId = execId;
|
|
469
|
+
Object.assign(firstScreenFnObj, fnObj);
|
|
470
|
+
}
|
|
471
|
+
continue;
|
|
472
|
+
}
|
|
473
|
+
for (const index of firstScreenFnObj._delayIndices){
|
|
474
|
+
const details = lynxWorkletImpl._runOnBackgroundDelayImpl.delayedBackgroundFunctionArray[index];
|
|
475
|
+
fnObj._execId = execId;
|
|
476
|
+
details.jsFnHandle = fnObj;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
function jsFunctionLifecycle_define_property(obj, key, value) {
|
|
481
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
482
|
+
value: value,
|
|
483
|
+
enumerable: true,
|
|
484
|
+
configurable: true,
|
|
485
|
+
writable: true
|
|
486
|
+
});
|
|
487
|
+
else obj[key] = value;
|
|
488
|
+
return obj;
|
|
489
|
+
}
|
|
490
|
+
class JsFunctionLifecycleManager {
|
|
491
|
+
addRef(execId, objToRef) {
|
|
492
|
+
var _this_execIdRefCount_get;
|
|
493
|
+
this.execIdRefCount.set(execId, (null != (_this_execIdRefCount_get = this.execIdRefCount.get(execId)) ? _this_execIdRefCount_get : 0) + 1);
|
|
494
|
+
this.registry.register(objToRef, execId);
|
|
495
|
+
}
|
|
496
|
+
removeRef(execId) {
|
|
497
|
+
const rc = this.execIdRefCount.get(execId);
|
|
498
|
+
if (rc > 1) return void this.execIdRefCount.set(execId, rc - 1);
|
|
499
|
+
this.execIdRefCount.delete(execId);
|
|
500
|
+
this.execIdSetToFire.add(execId);
|
|
501
|
+
if (!this.willFire) {
|
|
502
|
+
this.willFire = true;
|
|
503
|
+
Promise.resolve().then(()=>{
|
|
504
|
+
this.fire();
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
fire() {
|
|
509
|
+
profile('JsFunctionLifecycleManager.fire', ()=>{
|
|
510
|
+
lynx.getJSContext().dispatchEvent({
|
|
511
|
+
type: "Lynx.Worklet.releaseBackgroundWorkletCtx",
|
|
512
|
+
data: Array.from(this.execIdSetToFire)
|
|
513
|
+
});
|
|
514
|
+
this.execIdSetToFire.clear();
|
|
515
|
+
this.willFire = false;
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
constructor(){
|
|
519
|
+
jsFunctionLifecycle_define_property(this, "execIdRefCount", new Map());
|
|
520
|
+
jsFunctionLifecycle_define_property(this, "execIdSetToFire", new Set());
|
|
521
|
+
jsFunctionLifecycle_define_property(this, "willFire", false);
|
|
522
|
+
jsFunctionLifecycle_define_property(this, "registry", void 0);
|
|
523
|
+
this.registry = new FinalizationRegistry(this.removeRef.bind(this));
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
function isRunOnBackgroundEnabled() {
|
|
527
|
+
return isSdkVersionGt(2, 15);
|
|
528
|
+
}
|
|
529
|
+
function initWorklet() {
|
|
530
|
+
globalThis.lynxWorkletImpl = {
|
|
531
|
+
_workletMap: {},
|
|
532
|
+
_refImpl: initWorkletRef(),
|
|
533
|
+
_runOnBackgroundDelayImpl: initRunOnBackgroundDelay(),
|
|
534
|
+
_hydrateCtx: hydrateCtx,
|
|
535
|
+
_eventDelayImpl: initEventDelay(),
|
|
536
|
+
_eomImpl: initEomImpl(),
|
|
537
|
+
_runRunOnMainThreadTask: runRunOnMainThreadTask
|
|
538
|
+
};
|
|
539
|
+
if (isRunOnBackgroundEnabled()) globalThis.lynxWorkletImpl._jsFunctionLifecycleManager = new JsFunctionLifecycleManager();
|
|
540
|
+
globalThis.registerWorklet = registerWorklet;
|
|
541
|
+
globalThis.registerWorkletInternal = registerWorklet;
|
|
542
|
+
globalThis.runWorklet = workletRuntime_runWorklet;
|
|
543
|
+
}
|
|
544
|
+
function registerWorklet(_type, id, worklet) {
|
|
545
|
+
lynxWorkletImpl._workletMap[id] = worklet;
|
|
546
|
+
}
|
|
547
|
+
function workletRuntime_runWorklet(ctx, params, options) {
|
|
548
|
+
if (!validateWorklet(ctx)) return void console.warn('MainThreadFunction: Invalid function object: ' + JSON.stringify(ctx));
|
|
549
|
+
if ((null == options ? void 0 : options.source) === 1 && Array.isArray(params)) {
|
|
550
|
+
const first = params[0];
|
|
551
|
+
const t = first.type;
|
|
552
|
+
if ('string' == typeof t) mainThreadFlushLoopMark(`event:${t}`);
|
|
553
|
+
}
|
|
554
|
+
mainThreadFlushLoopMark(`MainThreadFunction id=${String(ctx._wkltId)}`);
|
|
555
|
+
if ('_lepusWorkletHash' in ctx) return void delayExecUntilJsReady(ctx._lepusWorkletHash, params);
|
|
556
|
+
return runWorkletImpl(ctx, params, options);
|
|
557
|
+
}
|
|
558
|
+
function runWorkletImpl(ctx, params, options) {
|
|
559
|
+
const worklet = profile('transformWorkletCtx ' + ctx._wkltId, ()=>transformWorklet(ctx, true));
|
|
560
|
+
const params_ = profile('transformWorkletParams', ()=>transformWorklet(params || [], false));
|
|
561
|
+
const [hasEventMethods, eventCtx] = addEventMethodsIfNeeded(params_, options);
|
|
562
|
+
const result = profile('runWorklet', ()=>worklet(...params_));
|
|
563
|
+
if (hasEventMethods) return {
|
|
564
|
+
returnValue: result,
|
|
565
|
+
eventReturnResult: eventCtx._eventReturnResult
|
|
566
|
+
};
|
|
567
|
+
return result;
|
|
568
|
+
}
|
|
569
|
+
function validateWorklet(ctx) {
|
|
570
|
+
return 'object' == typeof ctx && null !== ctx && ('_wkltId' in ctx || '_lepusWorkletHash' in ctx);
|
|
571
|
+
}
|
|
572
|
+
const workletCache = new WeakMap();
|
|
573
|
+
function transformWorklet(ctx, isWorklet) {
|
|
574
|
+
if ('object' != typeof ctx || null === ctx) return ctx;
|
|
575
|
+
if (isWorklet) {
|
|
576
|
+
const res = workletCache.get(ctx);
|
|
577
|
+
if (res) return res;
|
|
578
|
+
}
|
|
579
|
+
const worklet = {
|
|
580
|
+
main: ctx
|
|
581
|
+
};
|
|
582
|
+
transformWorkletInner(worklet, 0, ctx);
|
|
583
|
+
if (isWorklet) workletCache.set(ctx, worklet.main);
|
|
584
|
+
return worklet.main;
|
|
585
|
+
}
|
|
586
|
+
const transformWorkletInner = (value, depth, ctx)=>{
|
|
587
|
+
const limit = 1000;
|
|
588
|
+
if (++depth >= limit) throw new Error('Depth of value exceeds limit of ' + limit + '.');
|
|
589
|
+
if ('object' != typeof value || null === value) return;
|
|
590
|
+
const obj = value;
|
|
591
|
+
for(const key in obj){
|
|
592
|
+
const subObj = obj[key];
|
|
593
|
+
if ('object' != typeof subObj || null === subObj) continue;
|
|
594
|
+
if ('elementRefptr' in subObj) {
|
|
595
|
+
obj[key] = new Element(subObj['elementRefptr']);
|
|
596
|
+
continue;
|
|
597
|
+
}
|
|
598
|
+
if (subObj instanceof Element) continue;
|
|
599
|
+
transformWorkletInner(subObj, depth, ctx);
|
|
600
|
+
const isWorkletRef = '_wvid' in subObj;
|
|
601
|
+
if (isWorkletRef) {
|
|
602
|
+
obj[key] = getFromWorkletRefMap(subObj);
|
|
603
|
+
continue;
|
|
604
|
+
}
|
|
605
|
+
const isWorklet = '_wkltId' in subObj;
|
|
606
|
+
if (isWorklet) {
|
|
607
|
+
obj[key] = lynxWorkletImpl._workletMap[subObj._wkltId].bind({
|
|
608
|
+
...subObj
|
|
609
|
+
});
|
|
610
|
+
obj[key].ctx = subObj;
|
|
611
|
+
continue;
|
|
612
|
+
}
|
|
613
|
+
const isJsFn = '_jsFnId' in subObj;
|
|
614
|
+
if (isJsFn) {
|
|
615
|
+
var _lynxWorkletImpl__jsFunctionLifecycleManager;
|
|
616
|
+
subObj['_execId'] = ctx._execId;
|
|
617
|
+
null == (_lynxWorkletImpl__jsFunctionLifecycleManager = lynxWorkletImpl._jsFunctionLifecycleManager) || _lynxWorkletImpl__jsFunctionLifecycleManager.addRef(ctx._execId, subObj);
|
|
618
|
+
continue;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
};
|
|
622
|
+
if (void 0 === globalThis.lynxWorkletImpl) {
|
|
623
|
+
initWorklet();
|
|
624
|
+
initApiEnv();
|
|
625
|
+
initEventListeners();
|
|
626
|
+
}
|
|
627
|
+
})();
|
|
628
|
+
|
|
629
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGV2LmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vQGx5bngtanMvcmVhY3QvLi9ydW50aW1lL3NyYy93b3JrbGV0LXJ1bnRpbWUvYXBpL2FuaW1hdGlvbi9hbmltYXRpb24udHM/YzY0NCIsIndlYnBhY2s6Ly9AbHlueC1qcy9yZWFjdC8uL3J1bnRpbWUvc3JjL3dvcmtsZXQtcnVudGltZS9hcGkvYW5pbWF0aW9uL2VmZmVjdC50cz9jZDQ4Iiwid2VicGFjazovL0BseW54LWpzL3JlYWN0Ly4vcnVudGltZS9zcmMvd29ya2xldC1ydW50aW1lL3V0aWxzL21haW5UaHJlYWRGbHVzaExvb3BHdWFyZC50cz8zODdmIiwid2VicGFjazovL0BseW54LWpzL3JlYWN0Ly4vcnVudGltZS9zcmMvd29ya2xldC1ydW50aW1lL3V0aWxzL3ZlcnNpb24udHM/NjExMSIsIndlYnBhY2s6Ly9AbHlueC1qcy9yZWFjdC8uL3J1bnRpbWUvc3JjL3dvcmtsZXQtcnVudGltZS9hcGkvZWxlbWVudC50cz84YjMyIiwid2VicGFjazovL0BseW54LWpzL3JlYWN0Ly4vcnVudGltZS9zcmMvd29ya2xldC1ydW50aW1lL2FwaS9sZXB1c1F1ZXJ5U2VsZWN0b3IudHM/YzlhNCIsIndlYnBhY2s6Ly9AbHlueC1qcy9yZWFjdC8uL3J1bnRpbWUvc3JjL3dvcmtsZXQtcnVudGltZS9hcGkvbHlueEFwaS50cz9lMDU5Iiwid2VicGFjazovL0BseW54LWpzL3JlYWN0Ly4vcnVudGltZS9zcmMvd29ya2xldC1ydW50aW1lL3J1bk9uTWFpblRocmVhZC50cz83Mzc0Iiwid2VicGFjazovL0BseW54LWpzL3JlYWN0Ly4vcnVudGltZS9zcmMvd29ya2xldC1ydW50aW1lL3V0aWxzL3Byb2ZpbGUudHM/OWVjYiIsIndlYnBhY2s6Ly9AbHlueC1qcy9yZWFjdC8uL3J1bnRpbWUvc3JjL3dvcmtsZXQtcnVudGltZS93b3JrbGV0UmVmLnRzPzdiOWIiLCJ3ZWJwYWNrOi8vQGx5bngtanMvcmVhY3QvLi9ydW50aW1lL3NyYy93b3JrbGV0LXJ1bnRpbWUvbGlzdGVuZXJzLnRzPzc3ZDQiLCJ3ZWJwYWNrOi8vQGx5bngtanMvcmVhY3QvLi9ydW50aW1lL3NyYy93b3JrbGV0LXJ1bnRpbWUvZGVsYXlSdW5PbkJhY2tncm91bmQudHM/N2JmYiIsIndlYnBhY2s6Ly9AbHlueC1qcy9yZWFjdC8uL3J1bnRpbWUvc3JjL3dvcmtsZXQtcnVudGltZS9kZWxheVdvcmtsZXRFdmVudC50cz9kYzA4Iiwid2VicGFjazovL0BseW54LWpzL3JlYWN0Ly4vcnVudGltZS9zcmMvd29ya2xldC1ydW50aW1lL2VvbUltcGwudHM/YTAzOSIsIndlYnBhY2s6Ly9AbHlueC1qcy9yZWFjdC8uL3J1bnRpbWUvc3JjL3dvcmtsZXQtcnVudGltZS9ldmVudFByb3BhZ2F0aW9uLnRzP2Y1NWYiLCJ3ZWJwYWNrOi8vQGx5bngtanMvcmVhY3QvLi9ydW50aW1lL3NyYy93b3JrbGV0LXJ1bnRpbWUvaHlkcmF0ZS50cz84NTViIiwid2VicGFjazovL0BseW54LWpzL3JlYWN0Ly4vcnVudGltZS9zcmMvd29ya2xldC1ydW50aW1lL2pzRnVuY3Rpb25MaWZlY3ljbGUudHM/MWRjOCIsIndlYnBhY2s6Ly9AbHlueC1qcy9yZWFjdC8uL3J1bnRpbWUvc3JjL3dvcmtsZXQtcnVudGltZS93b3JrbGV0UnVudGltZS50cz9jYjAxIiwiW3JlbGF0aXZlLXJlc291cmNlLXBhdGhdIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI1IFRoZSBMeW54IEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UgVmVyc2lvbiAyLjAgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlXG4vLyBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuXG5pbXBvcnQgdHlwZSB7IEtleWZyYW1lRWZmZWN0IH0gZnJvbSAnLi9lZmZlY3QuanMnO1xuXG5leHBvcnQgZW51bSBBbmltYXRpb25PcGVyYXRpb24ge1xuICBTVEFSVCA9IDAsIC8vIFN0YXJ0IGEgbmV3IGFuaW1hdGlvblxuICBQTEFZID0gMSwgLy8gUGxheS9yZXN1bWUgYSBwYXVzZWQgYW5pbWF0aW9uXG4gIFBBVVNFID0gMiwgLy8gUGF1c2UgYW4gZXhpc3RpbmcgYW5pbWF0aW9uXG4gIENBTkNFTCA9IDMsIC8vIENhbmNlbCBhbiBhbmltYXRpb25cbn1cblxuZXhwb3J0IGNsYXNzIEFuaW1hdGlvbiB7XG4gIHN0YXRpYyBjb3VudCA9IDA7XG4gIHB1YmxpYyByZWFkb25seSBlZmZlY3Q6IEtleWZyYW1lRWZmZWN0O1xuICBwdWJsaWMgcmVhZG9ubHkgaWQ6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihlZmZlY3Q6IEtleWZyYW1lRWZmZWN0KSB7XG4gICAgdGhpcy5lZmZlY3QgPSBlZmZlY3Q7XG4gICAgdGhpcy5pZCA9ICdfX2x5bngtaW5uZXItanMtYW5pbWF0aW9uLScgKyBBbmltYXRpb24uY291bnQrKztcbiAgICB0aGlzLnN0YXJ0KCk7XG4gIH1cblxuICBwdWJsaWMgY2FuY2VsKCk6IHZvaWQge1xuICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgYWNjZXNzaW5nIHByaXZhdGUgbWVtYmVyICdlbGVtZW50J1xuICAgIHJldHVybiBfX0VsZW1lbnRBbmltYXRlKHRoaXMuZWZmZWN0LnRhcmdldC5lbGVtZW50LCBbQW5pbWF0aW9uT3BlcmF0aW9uLkNBTkNFTCwgdGhpcy5pZF0pO1xuICB9XG5cbiAgcHVibGljIHBhdXNlKCk6IHZvaWQge1xuICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgYWNjZXNzaW5nIHByaXZhdGUgbWVtYmVyICdlbGVtZW50J1xuICAgIHJldHVybiBfX0VsZW1lbnRBbmltYXRlKHRoaXMuZWZmZWN0LnRhcmdldC5lbGVtZW50LCBbQW5pbWF0aW9uT3BlcmF0aW9uLlBBVVNFLCB0aGlzLmlkXSk7XG4gIH1cblxuICBwdWJsaWMgcGxheSgpOiB2b2lkIHtcbiAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGFjY2Vzc2luZyBwcml2YXRlIG1lbWJlciAnZWxlbWVudCdcbiAgICByZXR1cm4gX19FbGVtZW50QW5pbWF0ZSh0aGlzLmVmZmVjdC50YXJnZXQuZWxlbWVudCwgW0FuaW1hdGlvbk9wZXJhdGlvbi5QTEFZLCB0aGlzLmlkXSk7XG4gIH1cblxuICBwcml2YXRlIHN0YXJ0KCk6IHZvaWQge1xuICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgYWNjZXNzaW5nIHByaXZhdGUgbWVtYmVyICdlbGVtZW50J1xuICAgIHJldHVybiBfX0VsZW1lbnRBbmltYXRlKHRoaXMuZWZmZWN0LnRhcmdldC5lbGVtZW50LCBbXG4gICAgICBBbmltYXRpb25PcGVyYXRpb24uU1RBUlQsXG4gICAgICB0aGlzLmlkLFxuICAgICAgdGhpcy5lZmZlY3Qua2V5ZnJhbWVzLFxuICAgICAgdGhpcy5lZmZlY3Qub3B0aW9ucyxcbiAgICBdKTtcbiAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IDIwMjUgVGhlIEx5bnggQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSBWZXJzaW9uIDIuMCB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGVcbi8vIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbmltcG9ydCB0eXBlIHsgRWxlbWVudCB9IGZyb20gJy4uL2VsZW1lbnQuanMnO1xuXG5leHBvcnQgY2xhc3MgS2V5ZnJhbWVFZmZlY3Qge1xuICBwdWJsaWMgcmVhZG9ubHkgdGFyZ2V0OiBFbGVtZW50O1xuICBwdWJsaWMgcmVhZG9ubHkga2V5ZnJhbWVzOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXIgfCBzdHJpbmc+W107XG4gIHB1YmxpYyByZWFkb25seSBvcHRpb25zOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXIgfCBzdHJpbmc+O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHRhcmdldDogRWxlbWVudCxcbiAgICBrZXlmcmFtZXM6IFJlY29yZDxzdHJpbmcsIG51bWJlciB8IHN0cmluZz5bXSxcbiAgICBvcHRpb25zOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXIgfCBzdHJpbmc+LFxuICApIHtcbiAgICB0aGlzLnRhcmdldCA9IHRhcmdldDtcbiAgICB0aGlzLmtleWZyYW1lcyA9IGtleWZyYW1lcztcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgMjAyNiBUaGUgTHlueCBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlIFZlcnNpb24gMi4wIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZVxuLy8gTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuXG5jb25zdCBUUkFDRV9MSU1JVCA9IDI1NjtcbmNvbnN0IERFRkFVTFRfRkxVU0hfTElNSVQgPSAyNTY7XG5cbmxldCB0cmFjZTogc3RyaW5nW10gPSBbXTtcblxubGV0IGZsdXNoQ291bnRJbldpbmRvdyA9IDA7XG5sZXQgcmVzZXRTY2hlZHVsZWQgPSBmYWxzZTtcbmxldCB0cmlwcGVkRXJyb3I6IEVycm9yIHwgbnVsbCA9IG51bGw7XG5cbmZ1bmN0aW9uIHB1c2hUcmFjZShtYXJrZXI6IHN0cmluZyk6IHZvaWQge1xuICB0cmFjZS5wdXNoKG1hcmtlcik7XG4gIGlmICh0cmFjZS5sZW5ndGggPiBUUkFDRV9MSU1JVCkge1xuICAgIHRyYWNlID0gdHJhY2Uuc2xpY2UodHJhY2UubGVuZ3RoIC0gVFJBQ0VfTElNSVQpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbXByZXNzVHJhY2UobWFya2Vyczogc3RyaW5nW10pOiBzdHJpbmcge1xuICBpZiAobWFya2Vycy5sZW5ndGggPT09IDApIHJldHVybiAnJztcbiAgY29uc3Qgb3V0OiBzdHJpbmdbXSA9IFtdO1xuICAvLyBEaXNwbGF5IG1vc3QtcmVjZW50LWZpcnN0IHRvIG1ha2UgbG9vcHMgZWFzaWVyIHRvIHJlYWQuXG4gIGxldCBwcmV2ID0gbWFya2Vyc1ttYXJrZXJzLmxlbmd0aCAtIDFdITtcbiAgbGV0IGNvdW50ID0gMTtcblxuICBmb3IgKGxldCBpID0gbWFya2Vycy5sZW5ndGggLSAyOyBpID49IDA7IGktLSkge1xuICAgIGNvbnN0IGN1ciA9IG1hcmtlcnNbaV0hO1xuICAgIGlmIChjdXIgPT09IHByZXYpIHtcbiAgICAgIGNvdW50Kys7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgb3V0LnB1c2goY291bnQgPT09IDEgPyBwcmV2IDogYCR7cHJldn0geCR7Y291bnR9YCk7XG4gICAgcHJldiA9IGN1cjtcbiAgICBjb3VudCA9IDE7XG4gIH1cbiAgb3V0LnB1c2goY291bnQgPT09IDEgPyBwcmV2IDogYCR7cHJldn0geCR7Y291bnR9YCk7XG4gIHJldHVybiBvdXQuam9pbignIDwtICcpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWFpblRocmVhZEZsdXNoTG9vcE1hcmsobWFya2VyOiBzdHJpbmcpOiB2b2lkIHtcbiAgaWYgKF9fREVWX18pIHtcbiAgICBwdXNoVHJhY2UobWFya2VyKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gbWFpblRocmVhZEZsdXNoTG9vcE9uRmx1c2hNaWNyb3Rhc2soKTogRXJyb3IgfCBudWxsIHtcbiAgLyogdjggaWdub3JlIG5leHQgMSAqL1xuICBpZiAoIV9fREVWX18pIHJldHVybiBudWxsO1xuICBpZiAodHJpcHBlZEVycm9yKSByZXR1cm4gdHJpcHBlZEVycm9yO1xuXG4gIGlmICghcmVzZXRTY2hlZHVsZWQpIHtcbiAgICByZXNldFNjaGVkdWxlZCA9IHRydWU7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBtYWluVGhyZWFkRmx1c2hMb29wUmVzZXQoKTtcbiAgICB9LCAwKTtcbiAgfVxuXG4gIGZsdXNoQ291bnRJbldpbmRvdysrO1xuICBjb25zdCBsaW1pdCA9IERFRkFVTFRfRkxVU0hfTElNSVQ7XG4gIGlmIChmbHVzaENvdW50SW5XaW5kb3cgPiBsaW1pdCkge1xuICAgIGNvbnN0IHRyYWNlVGV4dCA9IGNvbXByZXNzVHJhY2UodHJhY2UpO1xuICAgIHRyaXBwZWRFcnJvciA9IG5ldyBFcnJvcihcbiAgICAgIGBbUmVhY3RMeW54XVtERVZdIE1haW5UaHJlYWQgZmx1c2ggbG9vcCBkZXRlY3RlZDogcmVuZGVyIGV4ZWN1dGVkICR7Zmx1c2hDb3VudEluV2luZG93fSB0aW1lcyB3aXRob3V0IHlpZWxkaW5nIChsaW1pdD0ke2xpbWl0fSkuIFRyYWNlOiAke3RyYWNlVGV4dH1gLFxuICAgICk7XG4gICAgcmV0dXJuIHRyaXBwZWRFcnJvcjtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWFpblRocmVhZEZsdXNoTG9vcFJlcG9ydChlcnJvcjogRXJyb3IpOiB2b2lkIHtcbiAgaWYgKF9fREVWX18pIHtcbiAgICAvLyBUaHJvdyBvbiBtYWNyb3Rhc2sgdG8gYXZvaWQgUHJvbWlzZS11bmhhbmRsZWQtcmVqZWN0aW9uIG5vaXNlLlxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfSwgMCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1haW5UaHJlYWRGbHVzaExvb3BSZXNldCgpOiB2b2lkIHtcbiAgdHJhY2UgPSBbXTtcbiAgZmx1c2hDb3VudEluV2luZG93ID0gMDtcbiAgcmVzZXRTY2hlZHVsZWQgPSBmYWxzZTtcbiAgdHJpcHBlZEVycm9yID0gbnVsbDtcbn1cbiIsIi8vIENvcHlyaWdodCAyMDI0IFRoZSBMeW54IEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UgVmVyc2lvbiAyLjAgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlXG4vLyBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuXG5leHBvcnQgZnVuY3Rpb24gaXNTZGtWZXJzaW9uR3QobWFqb3I6IG51bWJlciwgbWlub3I6IG51bWJlcik6IGJvb2xlYW4ge1xuICBjb25zdCBseW54U2RrVmVyc2lvbjogc3RyaW5nID0gU3lzdGVtSW5mby5seW54U2RrVmVyc2lvbiA/PyAnMS4wJztcbiAgY29uc3QgdmVyc2lvbiA9IGx5bnhTZGtWZXJzaW9uLnNwbGl0KCcuJyk7XG4gIHJldHVybiAoXG4gICAgTnVtYmVyKHZlcnNpb25bMF0pID4gbWFqb3JcbiAgICB8fCAoTnVtYmVyKHZlcnNpb25bMF0pID09IG1ham9yICYmIE51bWJlcih2ZXJzaW9uWzFdKSA+IG1pbm9yKVxuICApO1xufVxuIiwiLy8gQ29weXJpZ2h0IDIwMjQgVGhlIEx5bnggQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSBWZXJzaW9uIDIuMCB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGVcbi8vIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbmltcG9ydCB7IEFuaW1hdGlvbiB9IGZyb20gJy4vYW5pbWF0aW9uL2FuaW1hdGlvbi5qcyc7XG5pbXBvcnQgeyBLZXlmcmFtZUVmZmVjdCB9IGZyb20gJy4vYW5pbWF0aW9uL2VmZmVjdC5qcyc7XG5pbXBvcnQge1xuICBtYWluVGhyZWFkRmx1c2hMb29wTWFyayxcbiAgbWFpblRocmVhZEZsdXNoTG9vcE9uRmx1c2hNaWNyb3Rhc2ssXG4gIG1haW5UaHJlYWRGbHVzaExvb3BSZXBvcnQsXG59IGZyb20gJy4uL3V0aWxzL21haW5UaHJlYWRGbHVzaExvb3BHdWFyZC5qcyc7XG5pbXBvcnQgeyBpc1Nka1ZlcnNpb25HdCB9IGZyb20gJy4uL3V0aWxzL3ZlcnNpb24uanMnO1xuXG5sZXQgd2lsbEZsdXNoID0gZmFsc2U7XG5sZXQgc2hvdWxkRmx1c2ggPSB0cnVlO1xuXG5leHBvcnQgZnVuY3Rpb24gc2V0U2hvdWxkRmx1c2godmFsdWU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgc2hvdWxkRmx1c2ggPSB2YWx1ZTtcbn1cblxuZXhwb3J0IGNsYXNzIEVsZW1lbnQge1xuICAvLyBAdHMtZXhwZWN0LWVycm9yIHNldCBpbiBjb25zdHJ1Y3RvclxuICBwcml2YXRlIHJlYWRvbmx5IGVsZW1lbnQ6IEVsZW1lbnROb2RlO1xuXG4gIGNvbnN0cnVjdG9yKGVsZW1lbnQ6IEVsZW1lbnROb2RlKSB7XG4gICAgLy8gSW4gTHlueCB2ZXJzaW9ucyBwcmlvciB0byBhbmQgaW5jbHVkaW5nIDIuMTUsXG4gICAgLy8gYSBjcmFzaCBvY2N1cnMgd2hlbiBwcmludGluZyBvciB0cmFuc2ZlcnJpbmcgcmVmQ291bnRlZCBhY3Jvc3MgdGhyZWFkcy5cbiAgICAvLyBCeXBhc3MgdGhpcyBwcm9ibGVtIGJ5IGhpZGluZyB0aGUgZWxlbWVudCBvYmplY3QuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdlbGVtZW50Jywge1xuICAgICAgZ2V0KCkge1xuICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgc2V0QXR0cmlidXRlKG5hbWU6IHN0cmluZywgdmFsdWU6IHVua25vd24pOiB2b2lkIHtcbiAgICAvKiB2OCBpZ25vcmUgbmV4dCAzICovXG4gICAgaWYgKF9fREVWX18pIHtcbiAgICAgIG1haW5UaHJlYWRGbHVzaExvb3BNYXJrKGBlbGVtZW50OnNldEF0dHJpYnV0ZSAke25hbWV9YCk7XG4gICAgfVxuICAgIF9fU2V0QXR0cmlidXRlKHRoaXMuZWxlbWVudCwgbmFtZSwgdmFsdWUpO1xuICAgIHRoaXMuZmx1c2hFbGVtZW50VHJlZSgpO1xuICB9XG5cbiAgcHVibGljIHNldFN0eWxlUHJvcGVydHkobmFtZTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgLyogdjggaWdub3JlIG5leHQgMyAqL1xuICAgIGlmIChfX0RFVl9fKSB7XG4gICAgICBtYWluVGhyZWFkRmx1c2hMb29wTWFyayhgZWxlbWVudDpzZXRTdHlsZVByb3BlcnR5ICR7bmFtZX1gKTtcbiAgICB9XG4gICAgX19BZGRJbmxpbmVTdHlsZSh0aGlzLmVsZW1lbnQsIG5hbWUsIHZhbHVlKTtcbiAgICB0aGlzLmZsdXNoRWxlbWVudFRyZWUoKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRTdHlsZVByb3BlcnRpZXMoc3R5bGVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KTogdm9pZCB7XG4gICAgLyogdjggaWdub3JlIG5leHQgNSAqL1xuICAgIGlmIChfX0RFVl9fKSB7XG4gICAgICBtYWluVGhyZWFkRmx1c2hMb29wTWFyayhcbiAgICAgICAgYGVsZW1lbnQ6c2V0U3R5bGVQcm9wZXJ0aWVzIGtleXM9JHtPYmplY3Qua2V5cyhzdHlsZXMpLmxlbmd0aH1gLFxuICAgICAgKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBrZXkgaW4gc3R5bGVzKSB7XG4gICAgICBfX0FkZElubGluZVN0eWxlKHRoaXMuZWxlbWVudCwga2V5LCBzdHlsZXNba2V5XSEpO1xuICAgIH1cbiAgICB0aGlzLmZsdXNoRWxlbWVudFRyZWUoKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRBdHRyaWJ1dGUoYXR0cmlidXRlTmFtZTogc3RyaW5nKTogdW5rbm93biB7XG4gICAgcmV0dXJuIF9fR2V0QXR0cmlidXRlQnlOYW1lKHRoaXMuZWxlbWVudCwgYXR0cmlidXRlTmFtZSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0QXR0cmlidXRlTmFtZXMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBfX0dldEF0dHJpYnV0ZU5hbWVzKHRoaXMuZWxlbWVudCk7XG4gIH1cblxuICBwdWJsaWMgcXVlcnlTZWxlY3RvcihzZWxlY3Rvcjogc3RyaW5nKTogRWxlbWVudCB8IG51bGwge1xuICAgIGNvbnN0IHJlZiA9IF9fUXVlcnlTZWxlY3Rvcih0aGlzLmVsZW1lbnQsIHNlbGVjdG9yLCB7fSk7XG4gICAgcmV0dXJuIHJlZiA/IG5ldyBFbGVtZW50KHJlZikgOiBudWxsO1xuICB9XG5cbiAgcHVibGljIHF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3I6IHN0cmluZyk6IEVsZW1lbnRbXSB7XG4gICAgcmV0dXJuIF9fUXVlcnlTZWxlY3RvckFsbCh0aGlzLmVsZW1lbnQsIHNlbGVjdG9yLCB7fSkubWFwKChlbGVtZW50KSA9PiB7XG4gICAgICByZXR1cm4gbmV3IEVsZW1lbnQoZWxlbWVudCk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0Q29tcHV0ZWRTdHlsZVByb3BlcnR5KGtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoIWlzU2RrVmVyc2lvbkd0KDMsIDQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdnZXRDb21wdXRlZFN0eWxlUHJvcGVydHkgcmVxdWlyZXMgTHlueCBzZGsgdmVyc2lvbiAzLjUnLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoIWtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdnZXRDb21wdXRlZFN0eWxlUHJvcGVydHk6IGtleSBpcyByZXF1aXJlZCcpO1xuICAgIH1cbiAgICByZXR1cm4gX19HZXRDb21wdXRlZFN0eWxlQnlLZXkodGhpcy5lbGVtZW50LCBrZXkpO1xuICB9XG5cbiAgcHVibGljIGFuaW1hdGUoXG4gICAga2V5ZnJhbWVzOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXIgfCBzdHJpbmc+W10sXG4gICAgb3B0aW9ucz86IG51bWJlciB8IFJlY29yZDxzdHJpbmcsIG51bWJlciB8IHN0cmluZz4sXG4gICk6IEFuaW1hdGlvbiB7XG4gICAgY29uc3Qgbm9ybWFsaXplZE9wdGlvbnMgPSB0eXBlb2Ygb3B0aW9ucyA9PT0gJ251bWJlcicgPyB7IGR1cmF0aW9uOiBvcHRpb25zIH0gOiBvcHRpb25zID8/IHt9O1xuICAgIHJldHVybiBuZXcgQW5pbWF0aW9uKG5ldyBLZXlmcmFtZUVmZmVjdCh0aGlzLCBrZXlmcmFtZXMsIG5vcm1hbGl6ZWRPcHRpb25zKSk7XG4gIH1cblxuICBwdWJsaWMgaW52b2tlKFxuICAgIG1ldGhvZE5hbWU6IHN0cmluZyxcbiAgICBwYXJhbXM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAgKTogUHJvbWlzZTx1bmtub3duPiB7XG4gICAgLyogdjggaWdub3JlIG5leHQgMyAqL1xuICAgIGlmIChfX0RFVl9fKSB7XG4gICAgICBtYWluVGhyZWFkRmx1c2hMb29wTWFyayhgZWxlbWVudDppbnZva2UgJHttZXRob2ROYW1lfWApO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgX19JbnZva2VVSU1ldGhvZChcbiAgICAgICAgdGhpcy5lbGVtZW50LFxuICAgICAgICBtZXRob2ROYW1lLFxuICAgICAgICBwYXJhbXMgPz8ge30sXG4gICAgICAgIChyZXM6IHsgY29kZTogbnVtYmVyOyBkYXRhOiB1bmtub3duIH0pID0+IHtcbiAgICAgICAgICBpZiAocmVzLmNvZGUgPT09IDApIHtcbiAgICAgICAgICAgIHJlc29sdmUocmVzLmRhdGEpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZWplY3QobmV3IEVycm9yKCdVSSBtZXRob2QgaW52b2tlOiAnICsgSlNPTi5zdHJpbmdpZnkocmVzKSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgICB0aGlzLmZsdXNoRWxlbWVudFRyZWUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZmx1c2hFbGVtZW50VHJlZSgpIHtcbiAgICBpZiAod2lsbEZsdXNoIHx8ICFzaG91bGRGbHVzaCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB3aWxsRmx1c2ggPSB0cnVlO1xuICAgIHZvaWQgUHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKSA9PiB7XG4gICAgICB3aWxsRmx1c2ggPSBmYWxzZTtcbiAgICAgIGlmIChfX0RFVl9fKSB7XG4gICAgICAgIG1haW5UaHJlYWRGbHVzaExvb3BNYXJrKCdyZW5kZXInKTtcbiAgICAgICAgY29uc3QgZXJyb3IgPSBtYWluVGhyZWFkRmx1c2hMb29wT25GbHVzaE1pY3JvdGFzaygpO1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAvLyBTdG9wIHNjaGVkdWxpbmcgZnVydGhlciBmbHVzaGVzIHNvIHdlIGNhbiBzdXJmYWNlIHRoZSBlcnJvci5cbiAgICAgICAgICAvLyBUaGlzIGlzIERFVi1vbmx5IGJlaGF2aW9yIGd1YXJkZWQgaW50ZXJuYWxseSBieSB0aGUgZGV2IGd1YXJkLlxuICAgICAgICAgIHNob3VsZEZsdXNoID0gZmFsc2U7XG4gICAgICAgICAgbWFpblRocmVhZEZsdXNoTG9vcFJlcG9ydChlcnJvcik7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBfX0ZsdXNoRWxlbWVudFRyZWUoKTtcbiAgICB9KTtcbiAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IDIwMjQgVGhlIEx5bnggQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSBWZXJzaW9uIDIuMCB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGVcbi8vIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbmltcG9ydCB7IEVsZW1lbnQgfSBmcm9tICcuL2VsZW1lbnQuanMnO1xuXG5jbGFzcyBQYWdlRWxlbWVudCB7XG4gIHByaXZhdGUgc3RhdGljIHBhZ2VFbGVtZW50OiBFbGVtZW50Tm9kZSB8IHVuZGVmaW5lZDtcblxuICBzdGF0aWMgZ2V0KCkge1xuICAgIFBhZ2VFbGVtZW50LnBhZ2VFbGVtZW50ID8/PSBfX0dldFBhZ2VFbGVtZW50KCk7XG4gICAgcmV0dXJuIFBhZ2VFbGVtZW50LnBhZ2VFbGVtZW50O1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBxdWVyeVNlbGVjdG9yKGNzc1NlbGVjdG9yOiBzdHJpbmcpOiBFbGVtZW50IHwgbnVsbCB7XG4gIGNvbnN0IHBhZ2VFbGVtZW50ID0gUGFnZUVsZW1lbnQuZ2V0KCk7XG4gIGlmICghcGFnZUVsZW1lbnQpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBjb25zdCBlbGVtZW50ID0gX19RdWVyeVNlbGVjdG9yKHBhZ2VFbGVtZW50LCBjc3NTZWxlY3Rvciwge30pO1xuICByZXR1cm4gZWxlbWVudCA/IG5ldyBFbGVtZW50KGVsZW1lbnQpIDogbnVsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHF1ZXJ5U2VsZWN0b3JBbGwoY3NzU2VsZWN0b3I6IHN0cmluZyk6IEVsZW1lbnRbXSB7XG4gIGNvbnN0IHBhZ2VFbGVtZW50ID0gUGFnZUVsZW1lbnQuZ2V0KCk7XG4gIGlmICghcGFnZUVsZW1lbnQpIHtcbiAgICByZXR1cm4gW107XG4gIH1cbiAgcmV0dXJuIF9fUXVlcnlTZWxlY3RvckFsbChwYWdlRWxlbWVudCwgY3NzU2VsZWN0b3IsIHt9KS5tYXAoXG4gICAgKGVsZW1lbnQpID0+IHtcbiAgICAgIHJldHVybiBuZXcgRWxlbWVudChlbGVtZW50KTtcbiAgICB9LFxuICApO1xufVxuIiwiLy8gQ29weXJpZ2h0IDIwMjQgVGhlIEx5bnggQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSBWZXJzaW9uIDIuMCB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGVcbi8vIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbmltcG9ydCB7IHF1ZXJ5U2VsZWN0b3IsIHF1ZXJ5U2VsZWN0b3JBbGwgfSBmcm9tICcuL2xlcHVzUXVlcnlTZWxlY3Rvci5qcyc7XG5pbXBvcnQgeyBpc1Nka1ZlcnNpb25HdCB9IGZyb20gJy4uL3V0aWxzL3ZlcnNpb24uanMnO1xuXG5mdW5jdGlvbiBpbml0QXBpRW52KCk6IHZvaWQge1xuICAvLyBAdHMtZXhwZWN0LWVycm9yIHR5cGVcbiAgbHlueC5xdWVyeVNlbGVjdG9yID0gcXVlcnlTZWxlY3RvcjtcbiAgLy8gQHRzLWV4cGVjdC1lcnJvciB0eXBlXG4gIGx5bngucXVlcnlTZWxlY3RvckFsbCA9IHF1ZXJ5U2VsZWN0b3JBbGw7XG4gIC8vIEB0cy1leHBlY3QtZXJyb3IgdHlwZVxuICBnbG9iYWxUaGlzLnNldFRpbWVvdXQgPSBseW54LnNldFRpbWVvdXQgYXMgKGNiOiAoKSA9PiB2b2lkLCB0aW1lb3V0OiBudW1iZXIpID0+IG51bWJlcjtcbiAgLy8gQHRzLWV4cGVjdC1lcnJvciB0eXBlXG4gIGdsb2JhbFRoaXMuc2V0SW50ZXJ2YWwgPSBseW54LnNldEludGVydmFsIGFzIChjYjogKCkgPT4gdm9pZCwgdGltZW91dDogbnVtYmVyKSA9PiBudW1iZXI7XG4gIC8vIEB0cy1leHBlY3QtZXJyb3IgdHlwZVxuICBnbG9iYWxUaGlzLmNsZWFyVGltZW91dCA9IGx5bnguY2xlYXJUaW1lb3V0IGFzICh0aW1lb3V0OiBudW1iZXIpID0+IHZvaWQ7XG4gIC8vIEluIGx5bnggMi4xNCBgY2xlYXJJbnRlcnZhbGAgaXMgbWlzdGFrZW5seSBzcGVsbGVkIGFzIGBjbGVhclRpbWVJbnRlcnZhbGAuIFRoaXMgaXMgZml4ZWQgaW4gbHlueCAyLjE1LlxuICAvLyBAdHMtZXhwZWN0LWVycm9yIHR5cGVcbiAgZ2xvYmFsVGhpcy5jbGVhckludGVydmFsID0gKGx5bnguY2xlYXJJbnRlcnZhbCA/PyBseW54LmNsZWFyVGltZUludGVydmFsKSBhcyAodGltZW91dDogbnVtYmVyKSA9PiB2b2lkO1xuXG4gIHtcbiAgICAvLyBAdHMtZXhwZWN0LWVycm9yIHR5cGVcbiAgICBjb25zdCByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPSBseW54LnJlcXVlc3RBbmltYXRpb25GcmFtZSBhcyAoY2FsbGJhY2s6ICgpID0+IHZvaWQpID0+IG51bWJlcjtcbiAgICAvLyBAdHMtZXhwZWN0LWVycm9yIHR5cGVcbiAgICBseW54LnJlcXVlc3RBbmltYXRpb25GcmFtZSA9IGdsb2JhbFRoaXMucmVxdWVzdEFuaW1hdGlvbkZyYW1lID0gKFxuICAgICAgY2FsbGJhY2s6ICgpID0+IHZvaWQsXG4gICAgKSA9PiB7XG4gICAgICBpZiAoIWlzU2RrVmVyc2lvbkd0KDIsIDE1KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgJ3JlcXVlc3RBbmltYXRpb25GcmFtZSBpbiBtYWluIHRocmVhZCBzY3JpcHQgcmVxdWlyZXMgTHlueCBzZGsgdmVyc2lvbiAyLjE2JyxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoY2FsbGJhY2spO1xuICAgIH07XG4gIH1cblxuICAvLyBAdHMtZXhwZWN0LWVycm9yIHR5cGVcbiAgZ2xvYmFsVGhpcy5jYW5jZWxBbmltYXRpb25GcmFtZSA9IGx5bnguY2FuY2VsQW5pbWF0aW9uRnJhbWUgYXMgKHJlcXVlc3RJZDogbnVtYmVyKSA9PiB2b2lkO1xufVxuXG5leHBvcnQgeyBpbml0QXBpRW52IH07XG4iLCIvLyBDb3B5cmlnaHQgMjAyNSBUaGUgTHlueCBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlIFZlcnNpb24gMi4wIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZVxuLy8gTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuaW1wb3J0IHsgV29ya2xldEV2ZW50cyB9IGZyb20gJy4vYmluZGluZ3MvaW5kZXguanMnO1xuaW1wb3J0IHR5cGUgeyBDbG9zdXJlVmFsdWVUeXBlLCBSdW5Xb3JrbGV0Q3R4UmV0RGF0YSwgV29ya2xldCB9IGZyb20gJy4vYmluZGluZ3MvaW5kZXguanMnO1xuXG5leHBvcnQgZnVuY3Rpb24gcnVuUnVuT25NYWluVGhyZWFkVGFzayh0YXNrOiBXb3JrbGV0LCBwYXJhbXM6IENsb3N1cmVWYWx1ZVR5cGVbXSwgcmVzb2x2ZUlkOiBudW1iZXIpOiB2b2lkIHtcbiAgbGV0IHJldHVyblZhbHVlO1xuICB0cnkge1xuICAgIHJldHVyblZhbHVlID0gcnVuV29ya2xldCh0YXNrLCBwYXJhbXMpO1xuICB9IGZpbmFsbHkge1xuICAgIC8vIFRPRE86IFNob3VsZCBiZSBtb3JlIHByb3BlciB0byByZWplY3QgdGhlIHByb21pc2UgaWYgdGhlcmUgaXMgYW4gZXJyb3IuXG4gICAgbHlueC5nZXRKU0NvbnRleHQoKS5kaXNwYXRjaEV2ZW50KHtcbiAgICAgIHR5cGU6IFdvcmtsZXRFdmVudHMuRnVuY3Rpb25DYWxsUmV0LFxuICAgICAgZGF0YTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICByZXNvbHZlSWQsXG4gICAgICAgIHJldHVyblZhbHVlLFxuICAgICAgfSBhcyBSdW5Xb3JrbGV0Q3R4UmV0RGF0YSksXG4gICAgfSk7XG4gIH1cbn1cbiIsIi8vIENvcHlyaWdodCAyMDI0IFRoZSBMeW54IEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UgVmVyc2lvbiAyLjAgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlXG4vLyBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuXG5leHBvcnQgZnVuY3Rpb24gcHJvZmlsZTxSZXQsIEZuIGV4dGVuZHMgKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gUmV0PihcbiAgc2xpY2VOYW1lOiBzdHJpbmcsXG4gIGY6IEZuLFxuKTogUmV0IHtcbiAgLyogdjggaWdub3JlIG5leHQgOSAqL1xuICAvLyBUT0RPOiBjaGFuZ2UgaXQgdG8gX19QUk9GSUxFX19cbiAgaWYgKF9fREVWX18pIHtcbiAgICBjb25zb2xlLnByb2ZpbGU/LihzbGljZU5hbWUpO1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gZigpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBjb25zb2xlLnByb2ZpbGVFbmQ/LigpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZigpO1xuICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgMjAyNCBUaGUgTHlueCBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlIFZlcnNpb24gMi4wIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZVxuLy8gTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuaW1wb3J0IHsgRWxlbWVudCB9IGZyb20gJy4vYXBpL2VsZW1lbnQuanMnO1xuaW1wb3J0IHR5cGUgeyBXb3JrbGV0UmVmLCBXb3JrbGV0UmVmSWQsIFdvcmtsZXRSZWZJbXBsIH0gZnJvbSAnLi9iaW5kaW5ncy90eXBlcy5qcyc7XG5pbXBvcnQgeyBtYWluVGhyZWFkRmx1c2hMb29wTWFyayB9IGZyb20gJy4vdXRpbHMvbWFpblRocmVhZEZsdXNoTG9vcEd1YXJkLmpzJztcbmltcG9ydCB7IHByb2ZpbGUgfSBmcm9tICcuL3V0aWxzL3Byb2ZpbGUuanMnO1xuXG5pbnRlcmZhY2UgUmVmSW1wbCB7XG4gIF93b3JrbGV0UmVmTWFwOiBSZWNvcmQ8V29ya2xldFJlZklkLCBXb3JrbGV0UmVmPHVua25vd24+PjtcbiAgX2ZpcnN0U2NyZWVuV29ya2xldFJlZk1hcDogUmVjb3JkPFdvcmtsZXRSZWZJZCwgV29ya2xldFJlZjx1bmtub3duPj47XG4gIHVwZGF0ZVdvcmtsZXRSZWYoXG4gICAgcmVmSW1wbDogV29ya2xldFJlZkltcGw8RWxlbWVudCB8IG51bGw+LFxuICAgIGVsZW1lbnQ6IEVsZW1lbnROb2RlIHwgbnVsbCxcbiAgKTogdm9pZDtcbiAgdXBkYXRlV29ya2xldFJlZkluaXRWYWx1ZUNoYW5nZXMocGF0Y2g6IFtudW1iZXIsIHVua25vd25dW10pOiB2b2lkO1xuICBjbGVhckZpcnN0U2NyZWVuV29ya2xldFJlZk1hcCgpOiB2b2lkO1xufVxuXG5sZXQgaW1wbDogUmVmSW1wbCB8IHVuZGVmaW5lZDtcblxuZnVuY3Rpb24gaW5pdFdvcmtsZXRSZWYoKTogUmVmSW1wbCB7XG4gIHJldHVybiAoaW1wbCA9IHtcbiAgICBfd29ya2xldFJlZk1hcDoge30sXG4gICAgLyoqXG4gICAgICogTWFwIG9mIHdvcmtsZXQgcmVmcyB0aGF0IGFyZSBjcmVhdGVkIGR1cmluZyBmaXJzdCBzY3JlZW4gcmVuZGVyaW5nLlxuICAgICAqIFRoZXNlIHJlZnMgYXJlIGNyZWF0ZWQgd2l0aCBuZWdhdGl2ZSBJRHMgYW5kIG5lZWQgdG8gYmUgaHlkcmF0ZWRcbiAgICAgKiB3aGVuIHRoZSBhcHAgc3RhcnRzLiBUaGUgbWFwIGlzIGNsZWFyZWQgYWZ0ZXIgaHlkcmF0aW9uIGlzIGNvbXBsZXRlXG4gICAgICogdG8gZnJlZSB1cCBtZW1vcnkuXG4gICAgICovXG4gICAgX2ZpcnN0U2NyZWVuV29ya2xldFJlZk1hcDoge30sXG4gICAgdXBkYXRlV29ya2xldFJlZixcbiAgICB1cGRhdGVXb3JrbGV0UmVmSW5pdFZhbHVlQ2hhbmdlcyxcbiAgICBjbGVhckZpcnN0U2NyZWVuV29ya2xldFJlZk1hcCxcbiAgfSk7XG59XG5cbmNvbnN0IGNyZWF0ZVdvcmtsZXRSZWYgPSA8VD4oXG4gIGlkOiBXb3JrbGV0UmVmSWQsXG4gIHZhbHVlOiBULFxuKTogV29ya2xldFJlZjxUPiA9PiB7XG4gIHJldHVybiB7XG4gICAgY3VycmVudDogdmFsdWUsXG4gICAgX3d2aWQ6IGlkLFxuICB9O1xufTtcblxuY29uc3QgZ2V0RnJvbVdvcmtsZXRSZWZNYXAgPSA8VD4oXG4gIHJlZkltcGw6IFdvcmtsZXRSZWZJbXBsPFQ+LFxuKTogV29ya2xldFJlZjxUPiA9PiB7XG4gIGNvbnN0IGlkID0gcmVmSW1wbC5fd3ZpZDtcbiAgLyogdjggaWdub3JlIG5leHQgMyAqL1xuICBpZiAoX19ERVZfXykge1xuICAgIG1haW5UaHJlYWRGbHVzaExvb3BNYXJrKGBNYWluVGhyZWFkUmVmOmdldCBpZD0ke2lkfWApO1xuICB9XG4gIGxldCB2YWx1ZTtcbiAgaWYgKGlkIDwgMCkge1xuICAgIC8vIEF0IHRoZSBmaXJzdCBzY3JlZW4gcmVuZGVyaW5nLCB0aGUgd29ya2xldCByZWYgaXMgY3JlYXRlZCB3aXRoIGEgbmVnYXRpdmUgSUQuXG4gICAgLy8gTWlnaHQgYmUgY2FsbGVkIGluIHR3byBzY2VuYXJpb3M6XG4gICAgLy8gMS4gSW4gTVRTIGV2ZW50c1xuICAgIC8vIDIuIEluIGBtYWluLXRocmVhZDpyZWZgXG4gICAgdmFsdWUgPSBpbXBsIS5fZmlyc3RTY3JlZW5Xb3JrbGV0UmVmTWFwW2lkXSBhcyBXb3JrbGV0UmVmPFQ+O1xuICAgIGlmICghdmFsdWUpIHtcbiAgICAgIHZhbHVlID0gaW1wbCEuX2ZpcnN0U2NyZWVuV29ya2xldFJlZk1hcFtpZF0gPSBjcmVhdGVXb3JrbGV0UmVmKGlkLCByZWZJbXBsLl9pbml0VmFsdWUpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YWx1ZSA9IGltcGwhLl93b3JrbGV0UmVmTWFwW2lkXSBhcyBXb3JrbGV0UmVmPFQ+O1xuICB9XG5cbiAgLyogdjggaWdub3JlIG5leHQgMyAqL1xuICBpZiAoX19ERVZfXyAmJiB2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNYWluVGhyZWFkUmVmIGlzIG5vdCBpbml0aWFsaXplZDogJyArIGlkKTtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59O1xuXG5mdW5jdGlvbiByZW1vdmVWYWx1ZUZyb21Xb3JrbGV0UmVmTWFwKGlkOiBXb3JrbGV0UmVmSWQpOiB2b2lkIHtcbiAgZGVsZXRlIGltcGwhLl93b3JrbGV0UmVmTWFwW2lkXTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgYW4gZWxlbWVudCBpbnN0YW5jZSBvZiB0aGUgZ2l2ZW4gZWxlbWVudCBub2RlLCB0aGVuIHNldCB0aGUgd29ya2xldCB2YWx1ZSB0byBpdC5cbiAqIFRoaXMgaXMgY2FsbGVkIGluIGBzbmFwc2hvdENvbnRleHRVcGRhdGVXb3JrbGV0UmVmYC5cbiAqIEBwYXJhbSBoYW5kbGUgaGFuZGxlIG9mIHRoZSB3b3JrbGV0IHZhbHVlLlxuICogQHBhcmFtIGVsZW1lbnQgdGhlIGVsZW1lbnQgbm9kZS5cbiAqL1xuZnVuY3Rpb24gdXBkYXRlV29ya2xldFJlZihcbiAgaGFuZGxlOiBXb3JrbGV0UmVmSW1wbDxFbGVtZW50IHwgbnVsbD4sXG4gIGVsZW1lbnQ6IEVsZW1lbnROb2RlIHwgbnVsbCxcbik6IHZvaWQge1xuICBnZXRGcm9tV29ya2xldFJlZk1hcChoYW5kbGUpLmN1cnJlbnQgPSBlbGVtZW50XG4gICAgPyBuZXcgRWxlbWVudChlbGVtZW50KVxuICAgIDogbnVsbDtcbn1cblxuZnVuY3Rpb24gdXBkYXRlV29ya2xldFJlZkluaXRWYWx1ZUNoYW5nZXMoXG4gIHBhdGNoOiBbV29ya2xldFJlZklkLCB1bmtub3duXVtdLFxuKTogdm9pZCB7XG4gIHByb2ZpbGUoJ3VwZGF0ZVdvcmtsZXRSZWZJbml0VmFsdWVDaGFuZ2VzJywgKCkgPT4ge1xuICAgIHBhdGNoLmZvckVhY2goKFtpZCwgdmFsdWVdKSA9PiB7XG4gICAgICBpZiAoIWltcGwhLl93b3JrbGV0UmVmTWFwW2lkXSkge1xuICAgICAgICBpbXBsIS5fd29ya2xldFJlZk1hcFtpZF0gPSBjcmVhdGVXb3JrbGV0UmVmKGlkLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBjbGVhckZpcnN0U2NyZWVuV29ya2xldFJlZk1hcCgpOiB2b2lkIHtcbiAgaW1wbCEuX2ZpcnN0U2NyZWVuV29ya2xldFJlZk1hcCA9IHt9O1xufVxuXG5leHBvcnQge1xuICB0eXBlIFJlZkltcGwsXG4gIGNyZWF0ZVdvcmtsZXRSZWYsXG4gIGluaXRXb3JrbGV0UmVmLFxuICBnZXRGcm9tV29ya2xldFJlZk1hcCxcbiAgcmVtb3ZlVmFsdWVGcm9tV29ya2xldFJlZk1hcCxcbiAgdXBkYXRlV29ya2xldFJlZkluaXRWYWx1ZUNoYW5nZXMsXG59O1xuIiwiLy8gQ29weXJpZ2h0IDIwMjQgVGhlIEx5bnggQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSBWZXJzaW9uIDIuMCB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGVcbi8vIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbmltcG9ydCB7IFdvcmtsZXRFdmVudHMgfSBmcm9tICcuL2JpbmRpbmdzL2V2ZW50cy5qcyc7XG5pbXBvcnQgdHlwZSB7IFJlbGVhc2VXb3JrbGV0UmVmRGF0YSwgUnVuV29ya2xldEN0eERhdGEgfSBmcm9tICcuL2JpbmRpbmdzL2V2ZW50cy5qcyc7XG5pbXBvcnQgdHlwZSB7IENsb3N1cmVWYWx1ZVR5cGUgfSBmcm9tICcuL2JpbmRpbmdzL3R5cGVzLmpzJztcbmltcG9ydCB7IHJ1blJ1bk9uTWFpblRocmVhZFRhc2sgfSBmcm9tICcuL3J1bk9uTWFpblRocmVhZC5qcyc7XG5pbXBvcnQgdHlwZSB7IEV2ZW50IH0gZnJvbSAnLi90eXBlcy9ydW50aW1lUHJveHkuanMnO1xuaW1wb3J0IHsgcmVtb3ZlVmFsdWVGcm9tV29ya2xldFJlZk1hcCB9IGZyb20gJy4vd29ya2xldFJlZi5qcyc7XG5cbmZ1bmN0aW9uIGluaXRFdmVudExpc3RlbmVycygpOiB2b2lkIHtcbiAgY29uc3QganNDb250ZXh0ID0gbHlueC5nZXRKU0NvbnRleHQoKTtcbiAganNDb250ZXh0LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgV29ya2xldEV2ZW50cy5ydW5Xb3JrbGV0Q3R4LFxuICAgIChldmVudDogRXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IGRhdGEgPSBKU09OLnBhcnNlKGV2ZW50LmRhdGEgYXMgc3RyaW5nKSBhcyBSdW5Xb3JrbGV0Q3R4RGF0YTtcbiAgICAgIHJ1blJ1bk9uTWFpblRocmVhZFRhc2soZGF0YS53b3JrbGV0LCBkYXRhLnBhcmFtcyBhcyBDbG9zdXJlVmFsdWVUeXBlW10sIGRhdGEucmVzb2x2ZUlkKTtcbiAgICB9LFxuICApO1xuICBqc0NvbnRleHQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICBXb3JrbGV0RXZlbnRzLnJlbGVhc2VXb3JrbGV0UmVmLFxuICAgIChldmVudDogRXZlbnQpID0+IHtcbiAgICAgIHJlbW92ZVZhbHVlRnJvbVdvcmtsZXRSZWZNYXAoKGV2ZW50LmRhdGEgYXMgUmVsZWFzZVdvcmtsZXRSZWZEYXRhKS5pZCk7XG4gICAgfSxcbiAgKTtcbn1cblxuZXhwb3J0IHsgaW5pdEV2ZW50TGlzdGVuZXJzIH07XG4iLCIvLyBDb3B5cmlnaHQgMjAyNCBUaGUgTHlueCBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlIFZlcnNpb24gMi4wIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZVxuLy8gTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuaW1wb3J0IHR5cGUgeyBKc0ZuSGFuZGxlIH0gZnJvbSAnLi9iaW5kaW5ncy90eXBlcy5qcyc7XG5cbmludGVyZmFjZSBEZXRhaWxzIHtcbiAgdGFzazogKGZuSWQ6IG51bWJlciwgZXhlY0lkOiBudW1iZXIpID0+IHZvaWQ7XG5cbiAgLy8gVGhpcyBjb21lcyBmcm9tIHRoZSBiYWNrZ3JvdW5kIHRocmVhZCwgaW5zZXJ0ZWQgaGVyZSBkdXJpbmcgY3R4IGh5ZHJhdGlvbi5cbiAganNGbkhhbmRsZT86IEpzRm5IYW5kbGU7XG59XG5cbmludGVyZmFjZSBSdW5PbkJhY2tncm91bmREZWxheUltcGwge1xuICAvLyBFbGVtZW50cyBzaG91bGQga2VlcCB0aGUgb3JkZXIgYmVpbmcgY2FsbGVkIGJ5IHRoZSB1c2VyLlxuICBkZWxheWVkQmFja2dyb3VuZEZ1bmN0aW9uQXJyYXk6IERldGFpbHNbXTtcbiAgZGVsYXlSdW5PbkJhY2tncm91bmQoZm5PYmo6IEpzRm5IYW5kbGUsIGZuOiAoZm5JZDogbnVtYmVyLCBleGVjSWQ6IG51bWJlcikgPT4gdm9pZCk6IHZvaWQ7XG4gIHJ1bkRlbGF5ZWRCYWNrZ3JvdW5kRnVuY3Rpb25zKCk6IHZvaWQ7XG59XG5cbmxldCBpbXBsOiBSdW5PbkJhY2tncm91bmREZWxheUltcGwgfCB1bmRlZmluZWQ7XG5cbmZ1bmN0aW9uIGluaXRSdW5PbkJhY2tncm91bmREZWxheSgpOiBSdW5PbkJhY2tncm91bmREZWxheUltcGwge1xuICByZXR1cm4gKGltcGwgPSB7XG4gICAgZGVsYXllZEJhY2tncm91bmRGdW5jdGlvbkFycmF5OiBbXSxcbiAgICBkZWxheVJ1bk9uQmFja2dyb3VuZCxcbiAgICBydW5EZWxheWVkQmFja2dyb3VuZEZ1bmN0aW9ucyxcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGRlbGF5UnVuT25CYWNrZ3JvdW5kKGZuT2JqOiBKc0ZuSGFuZGxlLCB0YXNrOiAoZm5JZDogbnVtYmVyLCBleGVjSWQ6IG51bWJlcikgPT4gdm9pZCkge1xuICBpbXBsIS5kZWxheWVkQmFja2dyb3VuZEZ1bmN0aW9uQXJyYXkucHVzaCh7IHRhc2sgfSk7XG4gIGNvbnN0IGRlbGF5SW5kaWNlcyA9IGZuT2JqLl9kZWxheUluZGljZXMgPz89IFtdO1xuICBkZWxheUluZGljZXMucHVzaChpbXBsIS5kZWxheWVkQmFja2dyb3VuZEZ1bmN0aW9uQXJyYXkubGVuZ3RoIC0gMSk7XG59XG5cbmZ1bmN0aW9uIHJ1bkRlbGF5ZWRCYWNrZ3JvdW5kRnVuY3Rpb25zKCk6IHZvaWQge1xuICBmb3IgKGNvbnN0IGRldGFpbHMgb2YgaW1wbCEuZGVsYXllZEJhY2tncm91bmRGdW5jdGlvbkFycmF5KSB7XG4gICAgaWYgKGRldGFpbHMuanNGbkhhbmRsZSkge1xuICAgICAgZGV0YWlscy50YXNrKGRldGFpbHMuanNGbkhhbmRsZS5fanNGbklkISwgZGV0YWlscy5qc0ZuSGFuZGxlLl9leGVjSWQhKTtcbiAgICB9XG4gIH1cbiAgaW1wbCEuZGVsYXllZEJhY2tncm91bmRGdW5jdGlvbkFycmF5Lmxlbmd0aCA9IDA7XG59XG5cbmV4cG9ydCB7IHR5cGUgUnVuT25CYWNrZ3JvdW5kRGVsYXlJbXBsLCBpbml0UnVuT25CYWNrZ3JvdW5kRGVsYXkgfTtcbiIsIi8vIENvcHlyaWdodCAyMDI0IFRoZSBMeW54IEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UgVmVyc2lvbiAyLjAgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlXG4vLyBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuXG5pbXBvcnQgdHlwZSB7IENsb3N1cmVWYWx1ZVR5cGUsIFdvcmtsZXQgfSBmcm9tICcuL2JpbmRpbmdzL3R5cGVzLmpzJztcbmltcG9ydCB7IHByb2ZpbGUgfSBmcm9tICcuL3V0aWxzL3Byb2ZpbGUuanMnO1xuXG5pbnRlcmZhY2UgRXZlbnREZWxheUltcGwge1xuICBfZGVsYXllZFdvcmtsZXRQYXJhbXNNYXA6IE1hcDxzdHJpbmcsIENsb3N1cmVWYWx1ZVR5cGVbXVtdPjtcbiAgcnVuRGVsYXllZFdvcmtsZXQod29ya2xldDogV29ya2xldCwgZWxlbWVudDogRWxlbWVudE5vZGUpOiB2b2lkO1xuICBjbGVhckRlbGF5ZWRXb3JrbGV0cygpOiB2b2lkO1xufVxuXG5sZXQgaW1wbDogRXZlbnREZWxheUltcGwgfCB1bmRlZmluZWQ7XG5cbmZ1bmN0aW9uIGluaXRFdmVudERlbGF5KCk6IEV2ZW50RGVsYXlJbXBsIHtcbiAgcmV0dXJuIChpbXBsID0ge1xuICAgIF9kZWxheWVkV29ya2xldFBhcmFtc01hcDogbmV3IE1hcCgpLFxuICAgIHJ1bkRlbGF5ZWRXb3JrbGV0LFxuICAgIGNsZWFyRGVsYXllZFdvcmtsZXRzLFxuICB9KTtcbn1cblxuZnVuY3Rpb24gZGVsYXlFeGVjVW50aWxKc1JlYWR5KFxuICBoYXNoOiBzdHJpbmcsXG4gIHBhcmFtczogQ2xvc3VyZVZhbHVlVHlwZVtdLFxuKTogdm9pZCB7XG4gIHByb2ZpbGUoJ2RlbGF5RXhlY1VudGlsSnNSZWFkeTogJyArIGhhc2gsICgpID0+IHtcbiAgICBjb25zdCBtYXAgPSBpbXBsIS5fZGVsYXllZFdvcmtsZXRQYXJhbXNNYXA7XG4gICAgY29uc3QgcGFyYW1WZWMgPSBtYXAuZ2V0KGhhc2gpO1xuICAgIGlmIChwYXJhbVZlYykge1xuICAgICAgcGFyYW1WZWMucHVzaChwYXJhbXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBtYXAuc2V0KGhhc2gsIFtwYXJhbXNdKTtcbiAgICB9XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBydW5EZWxheWVkV29ya2xldCh3b3JrbGV0OiBXb3JrbGV0LCBlbGVtZW50OiBFbGVtZW50Tm9kZSk6IHZvaWQge1xuICBwcm9maWxlKCdjb21taXREZWxheWVkV29ya2xldCcsICgpID0+IHtcbiAgICBjb25zdCBwYXJhbXNWZWMgPSBpbXBsIS5fZGVsYXllZFdvcmtsZXRQYXJhbXNNYXAuZ2V0KFxuICAgICAgd29ya2xldC5fd2tsdElkLFxuICAgICk7XG4gICAgaWYgKHBhcmFtc1ZlYyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGxlZnRQYXJhbXNWZWM6IENsb3N1cmVWYWx1ZVR5cGVbXVtdID0gW107XG4gICAgcGFyYW1zVmVjLmZvckVhY2goKHBhcmFtcykgPT4ge1xuICAgICAgY29uc3QgZmlyc3RQYXJhbSA9IHBhcmFtc1swXSBhcyB7IGN1cnJlbnRUYXJnZXQ/OiB7IGVsZW1lbnRSZWZwdHI/OiBFbGVtZW50Tm9kZSB9IH0gfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoZmlyc3RQYXJhbT8uY3VycmVudFRhcmdldD8uZWxlbWVudFJlZnB0ciA9PT0gZWxlbWVudCkge1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICBwcm9maWxlKCdydW5EZWxheWVkV29ya2xldCcsICgpID0+IHtcbiAgICAgICAgICAgIHJ1bldvcmtsZXQod29ya2xldCwgcGFyYW1zKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSwgMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZWZ0UGFyYW1zVmVjLnB1c2gocGFyYW1zKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpbXBsIS5fZGVsYXllZFdvcmtsZXRQYXJhbXNNYXAuc2V0KFxuICAgICAgd29ya2xldC5fd2tsdElkLFxuICAgICAgbGVmdFBhcmFtc1ZlYyxcbiAgICApO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gY2xlYXJEZWxheWVkV29ya2xldHMoKTogdm9pZCB7XG4gIGltcGwhLl9kZWxheWVkV29ya2xldFBhcmFtc01hcC5jbGVhcigpO1xufVxuXG5leHBvcnQgeyB0eXBlIEV2ZW50RGVsYXlJbXBsLCBpbml0RXZlbnREZWxheSwgZGVsYXlFeGVjVW50aWxKc1JlYWR5LCBydW5EZWxheWVkV29ya2xldCwgY2xlYXJEZWxheWVkV29ya2xldHMgfTtcbiIsIi8vIENvcHlyaWdodCAyMDI1IFRoZSBMeW54IEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UgVmVyc2lvbiAyLjAgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlXG4vLyBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuXG5pbXBvcnQgeyBzZXRTaG91bGRGbHVzaCB9IGZyb20gJy4vYXBpL2VsZW1lbnQuanMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEVvbUltcGwge1xuICBzZXRTaG91bGRGbHVzaCh2YWx1ZTogYm9vbGVhbik6IHZvaWQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpbml0RW9tSW1wbCgpOiBFb21JbXBsIHtcbiAgcmV0dXJuIHtcbiAgICBzZXRTaG91bGRGbHVzaCxcbiAgfTtcbn1cbiIsIi8vIENvcHlyaWdodCAyMDI0IFRoZSBMeW54IEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UgVmVyc2lvbiAyLjAgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlXG4vLyBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuXG5cbmltcG9ydCB0eXBlIHsgQ2xvc3VyZVZhbHVlVHlwZSwgRXZlbnRDdHgsIFJ1bldvcmtsZXRPcHRpb25zIH0gZnJvbSAnLi9iaW5kaW5ncy90eXBlcy5qcyc7XG5pbXBvcnQgeyBSdW5Xb3JrbGV0U291cmNlIH0gZnJvbSAnLi9iaW5kaW5ncy90eXBlcy5qcyc7XG5cbi8vIEV2ZW50UmVzdWx0IGVudW0gdmFsdWVzXG5leHBvcnQgY29uc3QgRXZlbnRSZXN1bHQgPSB7XG4gIGtEZWZhdWx0OiAweDAsXG4gIGtTdG9wUHJvcGFnYXRpb25NYXNrOiAweDEsXG4gIGtTdG9wSW1tZWRpYXRlUHJvcGFnYXRpb25NYXNrOiAweDIsXG59IGFzIGNvbnN0O1xuXG50eXBlIEV2ZW50TGlrZSA9IFJlY29yZDxzdHJpbmcsIENsb3N1cmVWYWx1ZVR5cGU+O1xuXG5leHBvcnQgZnVuY3Rpb24gaXNFdmVudE9iamVjdChcbiAgY3R4OiBDbG9zdXJlVmFsdWVUeXBlW10sXG4gIG9wdGlvbnM/OiBSdW5Xb3JrbGV0T3B0aW9ucyxcbik6IGN0eCBpcyBbRXZlbnRMaWtlLCAuLi5DbG9zdXJlVmFsdWVUeXBlW11dIHtcbiAgaWYgKCFBcnJheS5pc0FycmF5KGN0eCkgfHwgdHlwZW9mIGN0eFswXSAhPT0gJ29iamVjdCcgfHwgY3R4WzBdID09PSBudWxsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMuc291cmNlID09PSBSdW5Xb3JrbGV0U291cmNlLkVWRU5UKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIEFkZCBldmVudCBtZXRob2RzIHRvIGFuIGV2ZW50IG9iamVjdCBpZiBuZWVkZWRcbiAqIEBwYXJhbSBjdHggVGhlIGV2ZW50IG9iamVjdCB0byBlbmhhbmNlXG4gKiBAcGFyYW0gb3B0aW9ucyBUaGUgcnVuIHdvcmtsZXQgb3B0aW9uc1xuICogQHJldHVybnMgQSB0dXBsZSBvZiBib29sZWFuIGFuZCB0aGUgZXZlbnQgcmV0dXJuIHJlc3VsdFxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkRXZlbnRNZXRob2RzSWZOZWVkZWQoY3R4OiBDbG9zdXJlVmFsdWVUeXBlW10sIG9wdGlvbnM/OiBSdW5Xb3JrbGV0T3B0aW9ucyk6IFtib29sZWFuLCBFdmVudEN0eF0ge1xuICBpZiAoIWlzRXZlbnRPYmplY3QoY3R4LCBvcHRpb25zKSkge1xuICAgIHJldHVybiBbZmFsc2UsIHt9XTtcbiAgfVxuICBjb25zdCBldmVudEN0eDogRXZlbnRDdHggPSB7fTtcbiAgY29uc3QgZXZlbnRPYmogPSBjdHhbMF07XG5cbiAgLy8gQWRkIHN0b3BQcm9wYWdhdGlvbiBtZXRob2RcbiAgZXZlbnRPYmpbJ3N0b3BQcm9wYWdhdGlvbiddID0gZnVuY3Rpb24oKSB7XG4gICAgZXZlbnRDdHguX2V2ZW50UmV0dXJuUmVzdWx0ID0gKGV2ZW50Q3R4Ll9ldmVudFJldHVyblJlc3VsdCA/PyBFdmVudFJlc3VsdC5rRGVmYXVsdClcbiAgICAgIHwgRXZlbnRSZXN1bHQua1N0b3BQcm9wYWdhdGlvbk1hc2s7XG4gIH07XG5cbiAgLy8gQWRkIHN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiBtZXRob2RcbiAgZXZlbnRPYmpbJ3N0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiddID0gZnVuY3Rpb24oKSB7XG4gICAgZXZlbnRDdHguX2V2ZW50UmV0dXJuUmVzdWx0ID0gKGV2ZW50Q3R4Ll9ldmVudFJldHVyblJlc3VsdCA/PyBFdmVudFJlc3VsdC5rRGVmYXVsdClcbiAgICAgIHwgRXZlbnRSZXN1bHQua1N0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbk1hc2s7XG4gIH07XG5cbiAgcmV0dXJuIFt0cnVlLCBldmVudEN0eF07XG59XG4iLCIvLyBDb3B5cmlnaHQgMjAyNCBUaGUgTHlueCBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlIFZlcnNpb24gMi4wIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZVxuLy8gTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuXG5pbXBvcnQgdHlwZSB7IENsb3N1cmVWYWx1ZVR5cGUsIEpzRm5IYW5kbGUsIFdvcmtsZXQsIFdvcmtsZXRSZWZJZCwgV29ya2xldFJlZkltcGwgfSBmcm9tICcuL2JpbmRpbmdzL2luZGV4LmpzJztcbmltcG9ydCB7IHByb2ZpbGUgfSBmcm9tICcuL3V0aWxzL3Byb2ZpbGUuanMnO1xuXG4vKipcbiAqIEh5ZHJhdGVzIGEgV29ya2xldCBjb250ZXh0IHdpdGggZGF0YSBmcm9tIGEgZmlyc3Qtc2NyZWVuIFdvcmtsZXQgY29udGV4dC5cbiAqIFRoaXMgcHJvY2VzcyBpcyB0eXBpY2FsbHkgdXNlZCB0byBydW4gYWxsIGRlbGF5ZWQgYHJ1bk9uQmFja2dyb3VuZGAgZnVuY3Rpb25zXG4gKiBhbmQgaW5pdGlhbGl6ZSBgV29ya2xldFJlZmAgdmFsdWVzIG1vZGlmaWVkIGJlZm9yZSBoeWRyYXRpb24uXG4gKlxuICogQHBhcmFtIGN0eCBUaGUgdGFyZ2V0IFdvcmtsZXQgY29udGV4dCB0byBiZSBoeWRyYXRlZC5cbiAqIEBwYXJhbSBmaXJzdFNjcmVlbkN0eCBUaGUgV29ya2xldCBjb250ZXh0IGZyb20gdGhlIGZpcnN0IHNjcmVlbiByZW5kZXJpbmcsXG4gKiAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmluZyB0aGUgZGF0YSB0byBoeWRyYXRlIHdpdGguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoeWRyYXRlQ3R4KGN0eDogV29ya2xldCwgZmlyc3RTY3JlZW5DdHg6IFdvcmtsZXQpOiB2b2lkIHtcbiAgcHJvZmlsZSgnaHlkcmF0ZUN0eCcsICgpID0+IHtcbiAgICBoeWRyYXRlQ3R4SW1wbChjdHgsIGZpcnN0U2NyZWVuQ3R4LCBjdHguX2V4ZWNJZCEpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gaHlkcmF0ZUN0eEltcGwoXG4gIGN0eDogQ2xvc3VyZVZhbHVlVHlwZSxcbiAgZmlyc3RTY3JlZW5DdHg6IENsb3N1cmVWYWx1ZVR5cGUsXG4gIGV4ZWNJZDogbnVtYmVyLFxuKTogdm9pZCB7XG4gIGlmIChcbiAgICAhY3R4IHx8IHR5cGVvZiBjdHggIT09ICdvYmplY3QnIHx8ICFmaXJzdFNjcmVlbkN0eFxuICAgIHx8IHR5cGVvZiBmaXJzdFNjcmVlbkN0eCAhPT0gJ29iamVjdCdcbiAgKSByZXR1cm47XG5cbiAgY29uc3QgY3R4T2JqID0gY3R4IGFzIFJlY29yZDxzdHJpbmcsIENsb3N1cmVWYWx1ZVR5cGU+O1xuICBjb25zdCBmaXJzdFNjcmVlbkN0eE9iaiA9IGZpcnN0U2NyZWVuQ3R4IGFzIFJlY29yZDxzdHJpbmcsIENsb3N1cmVWYWx1ZVR5cGU+O1xuXG4gIGlmIChjdHhPYmpbJ193a2x0SWQnXSAmJiBjdHhPYmpbJ193a2x0SWQnXSAhPT0gZmlyc3RTY3JlZW5DdHhPYmpbJ193a2x0SWQnXSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZm9yLWluLWFycmF5XG4gIGZvciAoY29uc3Qga2V5IGluIGN0eCkge1xuICAgIGlmIChrZXkgPT09ICdfd3ZpZCcpIHtcbiAgICAgIGh5ZHJhdGVNYWluVGhyZWFkUmVmKFxuICAgICAgICBjdHhPYmpba2V5XSBhcyBXb3JrbGV0UmVmSWQsXG4gICAgICAgIGZpcnN0U2NyZWVuQ3R4T2JqIGFzIHVua25vd24gYXMgV29ya2xldFJlZkltcGw8dW5rbm93bj4sXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAoa2V5ID09PSAnX2pzRm4nKSB7XG4gICAgICBoeWRyYXRlRGVsYXlSdW5PbkJhY2tncm91bmRUYXNrcyhcbiAgICAgICAgY3R4T2JqW2tleV0gYXMgUmVjb3JkPHN0cmluZywgSnNGbkhhbmRsZT4sXG4gICAgICAgIGZpcnN0U2NyZWVuQ3R4T2JqW2tleV0gYXMgUmVjb3JkPHN0cmluZywgSnNGbkhhbmRsZT4sXG4gICAgICAgIGV4ZWNJZCxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGZpcnN0U2NyZWVuVmFsdWUgPSB0eXBlb2YgZmlyc3RTY3JlZW5DdHhPYmpba2V5XSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgICA/IChmaXJzdFNjcmVlbkN0eE9ialtrZXldIGFzIHsgY3R4OiBDbG9zdXJlVmFsdWVUeXBlIH0pLmN0eFxuICAgICAgICA6IGZpcnN0U2NyZWVuQ3R4T2JqW2tleV07XG4gICAgICBoeWRyYXRlQ3R4SW1wbChjdHhPYmpba2V5XSwgZmlyc3RTY3JlZW5WYWx1ZSwgZXhlY0lkKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBIeWRyYXRlcyBhIFdvcmtsZXRSZWYgb24gdGhlIG1haW4gdGhyZWFkLlxuICogVGhpcyBpcyB1c2VkIHRvIHVwZGF0ZSB0aGUgV29ya2xldFJlZidzIGJhY2tncm91bmQgaW5pdGlhbCB2YWx1ZSBiYXNlZCBvbiBjaGFuZ2VzXG4gKiB0aGF0IG9jY3VycmVkIGluIHRoZSBmaXJzdC1zY3JlZW4gV29ya2xldCBjb250ZXh0IGJlZm9yZSBoeWRyYXRpb24uXG4gKlxuICogQHBhcmFtIHJlZklkIFRoZSBJRCBvZiB0aGUgV29ya2xldFJlZiB0byBoeWRyYXRlLlxuICogQHBhcmFtIHZhbHVlIFRoZSBuZXcgdmFsdWUgZm9yIHRoZSBXb3JrbGV0UmVmLlxuICovXG5mdW5jdGlvbiBoeWRyYXRlTWFpblRocmVhZFJlZihcbiAgcmVmSWQ6IFdvcmtsZXRSZWZJZCxcbiAgdmFsdWU6IFdvcmtsZXRSZWZJbXBsPHVua25vd24+LFxuKSB7XG4gIGlmICgnX2luaXRWYWx1ZScgaW4gdmFsdWUpIHtcbiAgICAvLyBUaGUgcmVmIGhhcyBub3QgYmVlbiBhY2Nlc3NlZCB5ZXQuXG4gICAgcmV0dXJuO1xuICB9XG4gIGx5bnhXb3JrbGV0SW1wbCEuX3JlZkltcGwuX3dvcmtsZXRSZWZNYXBbcmVmSWRdID0gdmFsdWU7XG59XG5cbi8qKlxuICogSHlkcmF0ZXMgZGVsYXllZCBgcnVuT25CYWNrZ3JvdW5kYCB0YXNrcy5cbiAqIFRoaXMgZnVuY3Rpb24gZW5zdXJlcyB0aGF0IGFueSBgcnVuT25CYWNrZ3JvdW5kYCBjYWxscyB0aGF0IHdlcmUgZGVsYXllZFxuICogZHVyaW5nIHRoZSBmaXJzdC1zY3JlZW4gcmVuZGVyaW5nIGFyZSBjb3JyZWN0bHkgYXNzb2NpYXRlZCB3aXRoIHRoZWlyXG4gKiByZXNwZWN0aXZlIEphdmFTY3JpcHQgZnVuY3Rpb24gaGFuZGxlcyBpbiB0aGUgaHlkcmF0ZWQgV29ya2xldCBjb250ZXh0LlxuICovXG5mdW5jdGlvbiBoeWRyYXRlRGVsYXlSdW5PbkJhY2tncm91bmRUYXNrcyhcbiAgZm5PYmpzOiBSZWNvcmQ8c3RyaW5nLCBKc0ZuSGFuZGxlPiwgLy8gZXhhbXBsZToge1wiX2pzRm4xXCI6e1wiX2pzRm5JZFwiOjF9fVxuICBmaXJzdFNjcmVlbkZuT2JqczogUmVjb3JkPHN0cmluZywgSnNGbkhhbmRsZT4sIC8vIGV4YW1wbGU6IHtcIl9qc0ZuMVwiOntcIl9pc0ZpcnN0U2NyZWVuXCI6dHJ1ZSxcIl9kZWxheUluZGljZXNcIjpbMF19fVxuICBleGVjSWQ6IG51bWJlcixcbikge1xuICBmb3IgKGNvbnN0IGZuTmFtZSBpbiBmbk9ianMpIHtcbiAgICBjb25zdCBmbk9iaiA9IGZuT2Jqc1tmbk5hbWVdITtcbiAgICBjb25zdCBmaXJzdFNjcmVlbkZuT2JqOiBKc0ZuSGFuZGxlIHwgdW5kZWZpbmVkID0gZmlyc3RTY3JlZW5Gbk9ianNbZm5OYW1lXTtcbiAgICBpZiAoIWZpcnN0U2NyZWVuRm5PYmo/Ll9kZWxheUluZGljZXMpIHtcbiAgICAgIGlmIChmaXJzdFNjcmVlbkZuT2JqKSB7XG4gICAgICAgIGZpcnN0U2NyZWVuRm5PYmouX2lzRmlyc3RTY3JlZW4gPSBmYWxzZTtcbiAgICAgICAgZmlyc3RTY3JlZW5Gbk9iai5fZXhlY0lkID0gZXhlY0lkO1xuICAgICAgICBPYmplY3QuYXNzaWduKGZpcnN0U2NyZWVuRm5PYmosIGZuT2JqKTtcbiAgICAgIH1cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGluZGV4IG9mIGZpcnN0U2NyZWVuRm5PYmouX2RlbGF5SW5kaWNlcykge1xuICAgICAgY29uc3QgZGV0YWlscyA9IGx5bnhXb3JrbGV0SW1wbCEuX3J1bk9uQmFja2dyb3VuZERlbGF5SW1wbFxuICAgICAgICAuZGVsYXllZEJhY2tncm91bmRGdW5jdGlvbkFycmF5W2luZGV4XSE7XG4gICAgICBmbk9iai5fZXhlY0lkID0gZXhlY0lkO1xuICAgICAgZGV0YWlscy5qc0ZuSGFuZGxlID0gZm5PYmo7XG4gICAgfVxuICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgMjAyNCBUaGUgTHlueCBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlIFZlcnNpb24gMi4wIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZVxuLy8gTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuaW1wb3J0IHsgV29ya2xldEV2ZW50cyB9IGZyb20gJy4vYmluZGluZ3MvZXZlbnRzLmpzJztcbmltcG9ydCB7IHByb2ZpbGUgfSBmcm9tICcuL3V0aWxzL3Byb2ZpbGUuanMnO1xuaW1wb3J0IHsgaXNTZGtWZXJzaW9uR3QgfSBmcm9tICcuL3V0aWxzL3ZlcnNpb24uanMnO1xuXG4vKipcbiAqIGBKc0Z1bmN0aW9uTGlmZWN5Y2xlTWFuYWdlcmAgbW9uaXRvcnMgcmVmZXJlbmNlcyB0byBKUyBmdW5jdGlvbiBoYW5kbGVzIHRvIGJlIGNhbGxlZCBieSBgcnVuT25CYWNrZ3JvdW5kKClgLlxuICogSW4gSlMgY29udGV4dCwgZnVuY3Rpb25zIHRvIGJlIGNhbGxlZCBieSBgcnVuT25CYWNrZ3JvdW5kKClgIGlzIHJlZmVyZW5jZWQgYnkgYEpzRm5IYW5kbGVgcyBhbmQgZmluYWxseSBieSBgZXhlY0lkYC5cbiAqIFdoZW4gYWxsIGBKc0ZuSGFuZGxlYHMgaW4gbGVwdXMgYXJlIHJlbGVhc2VkLCBhbiBldmVudCB3aWxsIGJlIHNlbnQgdG8gSlMgY29udGV4dCB0byBkZS1yZWYgdGhlIGBleGVjSWRgLFxuICogcmVzdWx0aW5nIGEgZGUtcmVmIHRvIHRoZSBqcyBmdW5jdGlvbiBpbiBKUyBjb250ZXh0LlxuICovXG5jbGFzcyBKc0Z1bmN0aW9uTGlmZWN5Y2xlTWFuYWdlciB7XG4gIHByaXZhdGUgZXhlY0lkUmVmQ291bnQgPSBuZXcgTWFwPG51bWJlciwgbnVtYmVyPigpO1xuICBwcml2YXRlIGV4ZWNJZFNldFRvRmlyZSA9IG5ldyBTZXQ8bnVtYmVyPigpO1xuICBwcml2YXRlIHdpbGxGaXJlID0gZmFsc2U7XG4gIHByaXZhdGUgcmVnaXN0cnk/OiBGaW5hbGl6YXRpb25SZWdpc3RyeTxudW1iZXI+ID0gdW5kZWZpbmVkO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMucmVnaXN0cnkgPSBuZXcgRmluYWxpemF0aW9uUmVnaXN0cnk8bnVtYmVyPih0aGlzLnJlbW92ZVJlZi5iaW5kKHRoaXMpKTtcbiAgfVxuXG4gIGFkZFJlZihleGVjSWQ6IG51bWJlciwgb2JqVG9SZWY6IG9iamVjdCk6IHZvaWQge1xuICAgIHRoaXMuZXhlY0lkUmVmQ291bnQuc2V0KFxuICAgICAgZXhlY0lkLFxuICAgICAgKHRoaXMuZXhlY0lkUmVmQ291bnQuZ2V0KGV4ZWNJZCkgPz8gMCkgKyAxLFxuICAgICk7XG4gICAgdGhpcy5yZWdpc3RyeSEucmVnaXN0ZXIob2JqVG9SZWYsIGV4ZWNJZCk7XG4gIH1cblxuICByZW1vdmVSZWYoZXhlY0lkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCByYyA9IHRoaXMuZXhlY0lkUmVmQ291bnQuZ2V0KGV4ZWNJZCkhO1xuICAgIGlmIChyYyA+IDEpIHtcbiAgICAgIHRoaXMuZXhlY0lkUmVmQ291bnQuc2V0KGV4ZWNJZCwgcmMgLSAxKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5leGVjSWRSZWZDb3VudC5kZWxldGUoZXhlY0lkKTtcbiAgICB0aGlzLmV4ZWNJZFNldFRvRmlyZS5hZGQoZXhlY0lkKTtcbiAgICBpZiAoIXRoaXMud2lsbEZpcmUpIHtcbiAgICAgIHRoaXMud2lsbEZpcmUgPSB0cnVlO1xuICAgICAgdm9pZCBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5maXJlKCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBmaXJlKCk6IHZvaWQge1xuICAgIHByb2ZpbGUoJ0pzRnVuY3Rpb25MaWZlY3ljbGVNYW5hZ2VyLmZpcmUnLCAoKSA9PiB7XG4gICAgICBseW54LmdldEpTQ29udGV4dCgpLmRpc3BhdGNoRXZlbnQoe1xuICAgICAgICB0eXBlOiBXb3JrbGV0RXZlbnRzLnJlbGVhc2VCYWNrZ3JvdW5kV29ya2xldEN0eCxcbiAgICAgICAgZGF0YTogQXJyYXkuZnJvbSh0aGlzLmV4ZWNJZFNldFRvRmlyZSksXG4gICAgICB9KTtcbiAgICAgIHRoaXMuZXhlY0lkU2V0VG9GaXJlLmNsZWFyKCk7XG4gICAgICB0aGlzLndpbGxGaXJlID0gZmFsc2U7XG4gICAgfSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNSdW5PbkJhY2tncm91bmRFbmFibGVkKCk6IGJvb2xlYW4ge1xuICByZXR1cm4gaXNTZGtWZXJzaW9uR3QoMiwgMTUpO1xufVxuXG5leHBvcnQgeyBKc0Z1bmN0aW9uTGlmZWN5Y2xlTWFuYWdlciwgaXNSdW5PbkJhY2tncm91bmRFbmFibGVkIH07XG4iLCIvLyBDb3B5cmlnaHQgMjAyNCBUaGUgTHlueCBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlIFZlcnNpb24gMi4wIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZVxuLy8gTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuaW1wb3J0IHsgRWxlbWVudCB9IGZyb20gJy4vYXBpL2VsZW1lbnQuanMnO1xuaW1wb3J0IHR5cGUgeyBDbG9zdXJlVmFsdWVUeXBlLCBSdW5Xb3JrbGV0T3B0aW9ucywgV29ya2xldCwgV29ya2xldFJlZkltcGwgfSBmcm9tICcuL2JpbmRpbmdzL3R5cGVzLmpzJztcbmltcG9ydCB7IFJ1bldvcmtsZXRTb3VyY2UgfSBmcm9tICcuL2JpbmRpbmdzL3R5cGVzLmpzJztcbmltcG9ydCB7IGluaXRSdW5PbkJhY2tncm91bmREZWxheSB9IGZyb20gJy4vZGVsYXlSdW5PbkJhY2tncm91bmQuanMnO1xuaW1wb3J0IHsgZGVsYXlFeGVjVW50aWxKc1JlYWR5LCBpbml0RXZlbnREZWxheSB9IGZyb20gJy4vZGVsYXlXb3JrbGV0RXZlbnQuanMnO1xuaW1wb3J0IHsgaW5pdEVvbUltcGwgfSBmcm9tICcuL2VvbUltcGwuanMnO1xuaW1wb3J0IHsgYWRkRXZlbnRNZXRob2RzSWZOZWVkZWQgfSBmcm9tICcuL2V2ZW50UHJvcGFnYXRpb24uanMnO1xuaW1wb3J0IHsgaHlkcmF0ZUN0eCB9IGZyb20gJy4vaHlkcmF0ZS5qcyc7XG5pbXBvcnQgeyBKc0Z1bmN0aW9uTGlmZWN5Y2xlTWFuYWdlciwgaXNSdW5PbkJhY2tncm91bmRFbmFibGVkIH0gZnJvbSAnLi9qc0Z1bmN0aW9uTGlmZWN5Y2xlLmpzJztcbmltcG9ydCB7IHJ1blJ1bk9uTWFpblRocmVhZFRhc2sgfSBmcm9tICcuL3J1bk9uTWFpblRocmVhZC5qcyc7XG5pbXBvcnQgeyBtYWluVGhyZWFkRmx1c2hMb29wTWFyayB9IGZyb20gJy4vdXRpbHMvbWFpblRocmVhZEZsdXNoTG9vcEd1YXJkLmpzJztcbmltcG9ydCB7IHByb2ZpbGUgfSBmcm9tICcuL3V0aWxzL3Byb2ZpbGUuanMnO1xuaW1wb3J0IHsgZ2V0RnJvbVdvcmtsZXRSZWZNYXAsIGluaXRXb3JrbGV0UmVmIH0gZnJvbSAnLi93b3JrbGV0UmVmLmpzJztcblxuZnVuY3Rpb24gaW5pdFdvcmtsZXQoKTogdm9pZCB7XG4gIGdsb2JhbFRoaXMubHlueFdvcmtsZXRJbXBsID0ge1xuICAgIF93b3JrbGV0TWFwOiB7fSxcbiAgICBfcmVmSW1wbDogaW5pdFdvcmtsZXRSZWYoKSxcbiAgICBfcnVuT25CYWNrZ3JvdW5kRGVsYXlJbXBsOiBpbml0UnVuT25CYWNrZ3JvdW5kRGVsYXkoKSxcbiAgICBfaHlkcmF0ZUN0eDogaHlkcmF0ZUN0eCxcbiAgICBfZXZlbnREZWxheUltcGw6IGluaXRFdmVudERlbGF5KCksXG4gICAgX2VvbUltcGw6IGluaXRFb21JbXBsKCksXG4gICAgX3J1blJ1bk9uTWFpblRocmVhZFRhc2s6IHJ1blJ1bk9uTWFpblRocmVhZFRhc2ssXG4gIH07XG5cbiAgaWYgKGlzUnVuT25CYWNrZ3JvdW5kRW5hYmxlZCgpKSB7XG4gICAgZ2xvYmFsVGhpcy5seW54V29ya2xldEltcGwuX2pzRnVuY3Rpb25MaWZlY3ljbGVNYW5hZ2VyID0gbmV3IEpzRnVuY3Rpb25MaWZlY3ljbGVNYW5hZ2VyKCk7XG4gIH1cblxuICBnbG9iYWxUaGlzLnJlZ2lzdGVyV29ya2xldCA9IHJlZ2lzdGVyV29ya2xldDtcbiAgZ2xvYmFsVGhpcy5yZWdpc3RlcldvcmtsZXRJbnRlcm5hbCA9IHJlZ2lzdGVyV29ya2xldDtcbiAgZ2xvYmFsVGhpcy5ydW5Xb3JrbGV0ID0gcnVuV29ya2xldDtcbn1cblxuLyoqXG4gKiBSZWdpc3RlciBhIHdvcmtsZXQgZnVuY3Rpb24sIGFsbG93aW5nIGl0IHRvIGJlIGV4ZWN1dGVkIGJ5IGBydW5Xb3JrbGV0KClgLlxuICogVGhpcyBpcyBjYWxsZWQgaW4gbGVwdXMuanMuXG4gKiBAcGFyYW0gX3R5cGUgd29ya2xldCB0eXBlLCAnbWFpbi10aHJlYWQnIG9yICd1aSdcbiAqIEBwYXJhbSBpZCB3b3JrbGV0IGhhc2hcbiAqIEBwYXJhbSB3b3JrbGV0IHdvcmtsZXQgZnVuY3Rpb25cbiAqL1xuZnVuY3Rpb24gcmVnaXN0ZXJXb3JrbGV0KF90eXBlOiBzdHJpbmcsIGlkOiBzdHJpbmcsIHdvcmtsZXQ6ICguLi5hcmdzOiB1bmtub3duW10pID0+IHVua25vd24pOiB2b2lkIHtcbiAgbHlueFdvcmtsZXRJbXBsLl93b3JrbGV0TWFwW2lkXSA9IHdvcmtsZXQ7XG59XG5cbi8qKlxuICogRW50cmFuY2Ugb2YgYWxsIHdvcmtsZXQgY2FsbHMuXG4gKiBOYXRpdmUgZXZlbnQgdG91Y2ggaGFuZGxlciB3aWxsIGNhbGwgdGhpcyBmdW5jdGlvbi5cbiAqIEBwYXJhbSBjdHggd29ya2xldCBvYmplY3QuXG4gKiBAcGFyYW0gcGFyYW1zIHdvcmtsZXQgcGFyYW1zLlxuICogQHBhcmFtIG9wdGlvbnMgcnVuIHdvcmtsZXQgb3B0aW9ucy5cbiAqL1xuZnVuY3Rpb24gcnVuV29ya2xldChjdHg6IFdvcmtsZXQsIHBhcmFtczogQ2xvc3VyZVZhbHVlVHlwZVtdLCBvcHRpb25zPzogUnVuV29ya2xldE9wdGlvbnMpOiB1bmtub3duIHtcbiAgaWYgKCF2YWxpZGF0ZVdvcmtsZXQoY3R4KSkge1xuICAgIGNvbnNvbGUud2FybignTWFpblRocmVhZEZ1bmN0aW9uOiBJbnZhbGlkIGZ1bmN0aW9uIG9iamVjdDogJyArIEpTT04uc3RyaW5naWZ5KGN0eCkpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChfX0RFVl9fKSB7XG4gICAgaWYgKG9wdGlvbnM/LnNvdXJjZSA9PT0gUnVuV29ya2xldFNvdXJjZS5FVkVOVCAmJiBBcnJheS5pc0FycmF5KHBhcmFtcykpIHtcbiAgICAgIGNvbnN0IGZpcnN0ID0gcGFyYW1zWzBdO1xuICAgICAgY29uc3QgdCA9IChmaXJzdCBhcyB7IHR5cGU/OiB1bmtub3duIH0pLnR5cGU7XG4gICAgICBpZiAodHlwZW9mIHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIG1haW5UaHJlYWRGbHVzaExvb3BNYXJrKGBldmVudDoke3R9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbWFpblRocmVhZEZsdXNoTG9vcE1hcmsoYE1haW5UaHJlYWRGdW5jdGlvbiBpZD0ke1N0cmluZyhjdHguX3drbHRJZCl9YCk7XG4gIH1cblxuICBpZiAoJ19sZXB1c1dvcmtsZXRIYXNoJyBpbiBjdHgpIHtcbiAgICBkZWxheUV4ZWNVbnRpbEpzUmVhZHkoY3R4Ll9sZXB1c1dvcmtsZXRIYXNoLCBwYXJhbXMpO1xuICAgIHJldHVybjtcbiAgfVxuICByZXR1cm4gcnVuV29ya2xldEltcGwoY3R4LCBwYXJhbXMsIG9wdGlvbnMpO1xufVxuXG5mdW5jdGlvbiBydW5Xb3JrbGV0SW1wbChjdHg6IFdvcmtsZXQsIHBhcmFtczogQ2xvc3VyZVZhbHVlVHlwZVtdLCBvcHRpb25zPzogUnVuV29ya2xldE9wdGlvbnMpOiB1bmtub3duIHtcbiAgY29uc3Qgd29ya2xldDogKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gdW5rbm93biA9IHByb2ZpbGUoXG4gICAgJ3RyYW5zZm9ybVdvcmtsZXRDdHggJyArIGN0eC5fd2tsdElkLFxuICAgICgpID0+IHRyYW5zZm9ybVdvcmtsZXQoY3R4LCB0cnVlKSxcbiAgKTtcbiAgY29uc3QgcGFyYW1zXzogQ2xvc3VyZVZhbHVlVHlwZVtdID0gcHJvZmlsZShcbiAgICAndHJhbnNmb3JtV29ya2xldFBhcmFtcycsXG4gICAgKCkgPT4gdHJhbnNmb3JtV29ya2xldChwYXJhbXMgfHwgW10sIGZhbHNlKSxcbiAgKTtcblxuICBjb25zdCBbaGFzRXZlbnRNZXRob2RzLCBldmVudEN0eF0gPSBhZGRFdmVudE1ldGhvZHNJZk5lZWRlZChwYXJhbXNfLCBvcHRpb25zKTtcblxuICBjb25zdCByZXN1bHQgPSBwcm9maWxlKCdydW5Xb3JrbGV0JywgKCkgPT4gd29ya2xldCguLi5wYXJhbXNfKSk7XG5cbiAgaWYgKGhhc0V2ZW50TWV0aG9kcykge1xuICAgIHJldHVybiB7XG4gICAgICByZXR1cm5WYWx1ZTogcmVzdWx0LFxuICAgICAgZXZlbnRSZXR1cm5SZXN1bHQ6IGV2ZW50Q3R4Ll9ldmVudFJldHVyblJlc3VsdCxcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVXb3JrbGV0KGN0eDogdW5rbm93bik6IGN0eCBpcyBXb3JrbGV0IHtcbiAgcmV0dXJuIHR5cGVvZiBjdHggPT09ICdvYmplY3QnICYmIGN0eCAhPT0gbnVsbCAmJiAoJ193a2x0SWQnIGluIGN0eCB8fCAnX2xlcHVzV29ya2xldEhhc2gnIGluIGN0eCk7XG59XG5cbmNvbnN0IHdvcmtsZXRDYWNoZSA9IG5ldyBXZWFrTWFwPG9iamVjdCwgQ2xvc3VyZVZhbHVlVHlwZSB8ICgoLi4uYXJnczogdW5rbm93bltdKSA9PiB1bmtub3duKT4oKTtcblxuZnVuY3Rpb24gdHJhbnNmb3JtV29ya2xldChjdHg6IFdvcmtsZXQsIGlzV29ya2xldDogdHJ1ZSk6ICguLi5hcmdzOiB1bmtub3duW10pID0+IHVua25vd247XG5mdW5jdGlvbiB0cmFuc2Zvcm1Xb3JrbGV0KFxuICBjdHg6IENsb3N1cmVWYWx1ZVR5cGVbXSxcbiAgaXNXb3JrbGV0OiBmYWxzZSxcbik6IENsb3N1cmVWYWx1ZVR5cGVbXTtcblxuZnVuY3Rpb24gdHJhbnNmb3JtV29ya2xldChcbiAgY3R4OiBDbG9zdXJlVmFsdWVUeXBlLFxuICBpc1dvcmtsZXQ6IGJvb2xlYW4sXG4pOiBDbG9zdXJlVmFsdWVUeXBlIHwgKCguLi5hcmdzOiB1bmtub3duW10pID0+IHVua25vd24pIHtcbiAgLyogdjggaWdub3JlIG5leHQgMyAqL1xuICBpZiAodHlwZW9mIGN0eCAhPT0gJ29iamVjdCcgfHwgY3R4ID09PSBudWxsKSB7XG4gICAgcmV0dXJuIGN0eDtcbiAgfVxuXG4gIGlmIChpc1dvcmtsZXQpIHtcbiAgICBjb25zdCByZXMgPSB3b3JrbGV0Q2FjaGUuZ2V0KGN0eCk7XG4gICAgaWYgKHJlcykge1xuICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG4gIH1cblxuICBjb25zdCB3b3JrbGV0ID0geyBtYWluOiBjdHggfTtcbiAgdHJhbnNmb3JtV29ya2xldElubmVyKHdvcmtsZXQsIDAsIGN0eCk7XG5cbiAgaWYgKGlzV29ya2xldCkge1xuICAgIHdvcmtsZXRDYWNoZS5zZXQoY3R4LCB3b3JrbGV0Lm1haW4pO1xuICB9XG5cbiAgcmV0dXJuIHdvcmtsZXQubWFpbjtcbn1cblxuY29uc3QgdHJhbnNmb3JtV29ya2xldElubmVyID0gKFxuICB2YWx1ZTogQ2xvc3VyZVZhbHVlVHlwZSxcbiAgZGVwdGg6IG51bWJlcixcbiAgY3R4OiB1bmtub3duLFxuKSA9PiB7XG4gIGNvbnN0IGxpbWl0ID0gMTAwMDtcbiAgaWYgKCsrZGVwdGggPj0gbGltaXQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0RlcHRoIG9mIHZhbHVlIGV4Y2VlZHMgbGltaXQgb2YgJyArIGxpbWl0ICsgJy4nKTtcbiAgfVxuICAvKiB2OCBpZ25vcmUgbmV4dCAzICovXG4gIGlmICh0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnIHx8IHZhbHVlID09PSBudWxsKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGNvbnN0IG9iaiA9IHZhbHVlIGFzIFJlY29yZDxzdHJpbmcsIENsb3N1cmVWYWx1ZVR5cGU+O1xuXG4gIGZvciAoY29uc3Qga2V5IGluIG9iaikge1xuICAgIGNvbnN0IHN1Yk9iajogQ2xvc3VyZVZhbHVlVHlwZSA9IG9ialtrZXldO1xuICAgIGlmICh0eXBlb2Ygc3ViT2JqICE9PSAnb2JqZWN0JyB8fCBzdWJPYmogPT09IG51bGwpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmICgvKiogaXNFdmVudFRhcmdldCAqLyAnZWxlbWVudFJlZnB0cicgaW4gc3ViT2JqKSB7XG4gICAgICBvYmpba2V5XSA9IG5ldyBFbGVtZW50KHN1Yk9ialsnZWxlbWVudFJlZnB0ciddIGFzIEVsZW1lbnROb2RlKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH0gZWxzZSBpZiAoc3ViT2JqIGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdHJhbnNmb3JtV29ya2xldElubmVyKHN1Yk9iaiwgZGVwdGgsIGN0eCk7XG5cbiAgICBjb25zdCBpc1dvcmtsZXRSZWYgPSAnX3d2aWQnIGluIChzdWJPYmogYXMgb2JqZWN0KTtcbiAgICBpZiAoaXNXb3JrbGV0UmVmKSB7XG4gICAgICBvYmpba2V5XSA9IGdldEZyb21Xb3JrbGV0UmVmTWFwKFxuICAgICAgICBzdWJPYmogYXMgdW5rbm93biBhcyBXb3JrbGV0UmVmSW1wbDx1bmtub3duPixcbiAgICAgICk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgY29uc3QgaXNXb3JrbGV0ID0gJ193a2x0SWQnIGluIHN1Yk9iajtcbiAgICBpZiAoaXNXb3JrbGV0KSB7XG4gICAgICAvLyBgc3ViT2JqYCBpcyB3b3JrbGV0IGN0eC4gU2hhbGxvdyBjb3B5IGl0IHRvIHByZXZlbnQgdGhlIHRyYW5zZm9ybWVkIHdvcmtsZXQgZnJvbSByZWZlcmVuY2luZyBjdHguXG4gICAgICAvLyBUaGlzIHdvdWxkIHJlc3VsdCBpbiB0aGUgdmFsdWUgb2YgYHdvcmtsZXRDYWNoZWAgcmVmZXJlbmNpbmcgaXRzIGtleS5cbiAgICAgIG9ialtrZXldID0gbHlueFdvcmtsZXRJbXBsLl93b3JrbGV0TWFwWyhzdWJPYmogYXMgV29ya2xldCkuX3drbHRJZF0hXG4gICAgICAgIC5iaW5kKHsgLi4uc3ViT2JqIH0pO1xuICAgICAgb2JqW2tleV0uY3R4ID0gc3ViT2JqO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnN0IGlzSnNGbiA9ICdfanNGbklkJyBpbiBzdWJPYmo7XG4gICAgaWYgKGlzSnNGbikge1xuICAgICAgc3ViT2JqWydfZXhlY0lkJ10gPSAoY3R4IGFzIFdvcmtsZXQpLl9leGVjSWQ7XG4gICAgICBseW54V29ya2xldEltcGwuX2pzRnVuY3Rpb25MaWZlY3ljbGVNYW5hZ2VyPy5hZGRSZWYoXG4gICAgICAgIChjdHggYXMgV29ya2xldCkuX2V4ZWNJZCEsXG4gICAgICAgIHN1Yk9iaixcbiAgICAgICk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gIH1cbn07XG5cbmV4cG9ydCB7IGluaXRXb3JrbGV0IH07XG4iLCIvLyBDb3B5cmlnaHQgMjAyNCBUaGUgTHlueCBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlIFZlcnNpb24gMi4wIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZVxuLy8gTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuaW1wb3J0IHsgaW5pdEFwaUVudiB9IGZyb20gJy4vYXBpL2x5bnhBcGkuanMnO1xuaW1wb3J0IHsgaW5pdEV2ZW50TGlzdGVuZXJzIH0gZnJvbSAnLi9saXN0ZW5lcnMuanMnO1xuaW1wb3J0IHsgaW5pdFdvcmtsZXQgfSBmcm9tICcuL3dvcmtsZXRSdW50aW1lLmpzJztcblxuaWYgKGdsb2JhbFRoaXMubHlueFdvcmtsZXRJbXBsID09PSB1bmRlZmluZWQpIHtcbiAgaW5pdFdvcmtsZXQoKTtcbiAgaW5pdEFwaUVudigpO1xuICBpbml0RXZlbnRMaXN0ZW5lcnMoKTtcbn1cbiJdLCJuYW1lcyI6WyJBbmltYXRpb24iLCJfX0VsZW1lbnRBbmltYXRlIiwiZWZmZWN0IiwiS2V5ZnJhbWVFZmZlY3QiLCJ0YXJnZXQiLCJrZXlmcmFtZXMiLCJvcHRpb25zIiwiVFJBQ0VfTElNSVQiLCJERUZBVUxUX0ZMVVNIX0xJTUlUIiwidHJhY2UiLCJmbHVzaENvdW50SW5XaW5kb3ciLCJyZXNldFNjaGVkdWxlZCIsInRyaXBwZWRFcnJvciIsInB1c2hUcmFjZSIsIm1hcmtlciIsImNvbXByZXNzVHJhY2UiLCJtYXJrZXJzIiwib3V0IiwicHJldiIsImNvdW50IiwiaSIsImN1ciIsIm1haW5UaHJlYWRGbHVzaExvb3BNYXJrIiwibWFpblRocmVhZEZsdXNoTG9vcE9uRmx1c2hNaWNyb3Rhc2siLCJzZXRUaW1lb3V0IiwibWFpblRocmVhZEZsdXNoTG9vcFJlc2V0IiwibGltaXQiLCJ0cmFjZVRleHQiLCJFcnJvciIsIm1haW5UaHJlYWRGbHVzaExvb3BSZXBvcnQiLCJlcnJvciIsImlzU2RrVmVyc2lvbkd0IiwibWFqb3IiLCJtaW5vciIsIl9TeXN0ZW1JbmZvX2x5bnhTZGtWZXJzaW9uIiwibHlueFNka1ZlcnNpb24iLCJ2ZXJzaW9uIiwiTnVtYmVyIiwid2lsbEZsdXNoIiwic2hvdWxkRmx1c2giLCJzZXRTaG91bGRGbHVzaCIsInZhbHVlIiwiRWxlbWVudCIsIm5hbWUiLCJfX1NldEF0dHJpYnV0ZSIsIl9fQWRkSW5saW5lU3R5bGUiLCJzdHlsZXMiLCJPYmplY3QiLCJrZXkiLCJhdHRyaWJ1dGVOYW1lIiwiX19HZXRBdHRyaWJ1dGVCeU5hbWUiLCJfX0dldEF0dHJpYnV0ZU5hbWVzIiwic2VsZWN0b3IiLCJyZWYiLCJfX1F1ZXJ5U2VsZWN0b3IiLCJfX1F1ZXJ5U2VsZWN0b3JBbGwiLCJlbGVtZW50IiwiX19HZXRDb21wdXRlZFN0eWxlQnlLZXkiLCJub3JtYWxpemVkT3B0aW9ucyIsIm1ldGhvZE5hbWUiLCJwYXJhbXMiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsIl9fSW52b2tlVUlNZXRob2QiLCJyZXMiLCJKU09OIiwiX19GbHVzaEVsZW1lbnRUcmVlIiwiUGFnZUVsZW1lbnQiLCJfUGFnZUVsZW1lbnQiLCJfX0dldFBhZ2VFbGVtZW50IiwicXVlcnlTZWxlY3RvciIsImNzc1NlbGVjdG9yIiwicGFnZUVsZW1lbnQiLCJxdWVyeVNlbGVjdG9yQWxsIiwiaW5pdEFwaUVudiIsIl9seW54X2NsZWFySW50ZXJ2YWwiLCJseW54IiwiZ2xvYmFsVGhpcyIsInJlcXVlc3RBbmltYXRpb25GcmFtZSIsImNhbGxiYWNrIiwicnVuUnVuT25NYWluVGhyZWFkVGFzayIsInRhc2siLCJyZXNvbHZlSWQiLCJyZXR1cm5WYWx1ZSIsInJ1bldvcmtsZXQiLCJXb3JrbGV0RXZlbnRzIiwicHJvZmlsZSIsInNsaWNlTmFtZSIsImYiLCJfY29uc29sZSIsIl9jb25zb2xlMSIsImltcGwiLCJpbml0V29ya2xldFJlZiIsInVwZGF0ZVdvcmtsZXRSZWYiLCJ1cGRhdGVXb3JrbGV0UmVmSW5pdFZhbHVlQ2hhbmdlcyIsImNsZWFyRmlyc3RTY3JlZW5Xb3JrbGV0UmVmTWFwIiwiY3JlYXRlV29ya2xldFJlZiIsImlkIiwiZ2V0RnJvbVdvcmtsZXRSZWZNYXAiLCJyZWZJbXBsIiwidW5kZWZpbmVkIiwicmVtb3ZlVmFsdWVGcm9tV29ya2xldFJlZk1hcCIsImhhbmRsZSIsInBhdGNoIiwiaW5pdEV2ZW50TGlzdGVuZXJzIiwianNDb250ZXh0IiwiZXZlbnQiLCJkYXRhIiwiaW5pdFJ1bk9uQmFja2dyb3VuZERlbGF5IiwiZGVsYXlSdW5PbkJhY2tncm91bmQiLCJydW5EZWxheWVkQmFja2dyb3VuZEZ1bmN0aW9ucyIsImZuT2JqIiwiX2ZuT2JqIiwiZGVsYXlJbmRpY2VzIiwiZGV0YWlscyIsImluaXRFdmVudERlbGF5IiwiTWFwIiwicnVuRGVsYXllZFdvcmtsZXQiLCJjbGVhckRlbGF5ZWRXb3JrbGV0cyIsImRlbGF5RXhlY1VudGlsSnNSZWFkeSIsImhhc2giLCJtYXAiLCJwYXJhbVZlYyIsIndvcmtsZXQiLCJwYXJhbXNWZWMiLCJsZWZ0UGFyYW1zVmVjIiwiX2ZpcnN0UGFyYW1fY3VycmVudFRhcmdldCIsImZpcnN0UGFyYW0iLCJpbml0RW9tSW1wbCIsIkV2ZW50UmVzdWx0IiwiaXNFdmVudE9iamVjdCIsImN0eCIsIkFycmF5IiwiUnVuV29ya2xldFNvdXJjZSIsImFkZEV2ZW50TWV0aG9kc0lmTmVlZGVkIiwiZXZlbnRDdHgiLCJldmVudE9iaiIsIl9ldmVudEN0eF9fZXZlbnRSZXR1cm5SZXN1bHQiLCJoeWRyYXRlQ3R4IiwiZmlyc3RTY3JlZW5DdHgiLCJoeWRyYXRlQ3R4SW1wbCIsImV4ZWNJZCIsImN0eE9iaiIsImZpcnN0U2NyZWVuQ3R4T2JqIiwiaHlkcmF0ZU1haW5UaHJlYWRSZWYiLCJoeWRyYXRlRGVsYXlSdW5PbkJhY2tncm91bmRUYXNrcyIsImZpcnN0U2NyZWVuVmFsdWUiLCJyZWZJZCIsImx5bnhXb3JrbGV0SW1wbCIsImZuT2JqcyIsImZpcnN0U2NyZWVuRm5PYmpzIiwiZm5OYW1lIiwiZmlyc3RTY3JlZW5Gbk9iaiIsImluZGV4IiwiSnNGdW5jdGlvbkxpZmVjeWNsZU1hbmFnZXIiLCJvYmpUb1JlZiIsIl90aGlzX2V4ZWNJZFJlZkNvdW50X2dldCIsInJjIiwiU2V0IiwiRmluYWxpemF0aW9uUmVnaXN0cnkiLCJpc1J1bk9uQmFja2dyb3VuZEVuYWJsZWQiLCJpbml0V29ya2xldCIsInJlZ2lzdGVyV29ya2xldCIsIl90eXBlIiwidmFsaWRhdGVXb3JrbGV0IiwiY29uc29sZSIsImZpcnN0IiwidCIsIlN0cmluZyIsInJ1bldvcmtsZXRJbXBsIiwidHJhbnNmb3JtV29ya2xldCIsInBhcmFtc18iLCJoYXNFdmVudE1ldGhvZHMiLCJyZXN1bHQiLCJ3b3JrbGV0Q2FjaGUiLCJXZWFrTWFwIiwiaXNXb3JrbGV0IiwidHJhbnNmb3JtV29ya2xldElubmVyIiwiZGVwdGgiLCJvYmoiLCJzdWJPYmoiLCJpc1dvcmtsZXRSZWYiLCJpc0pzRm4iLCJfbHlueFdvcmtsZXRJbXBsX19qc0Z1bmN0aW9uTGlmZWN5Y2xlTWFuYWdlciJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0lBWU8sTUFBTUE7UUFXSixTQUFlO1lBRXBCLE9BQU9DLGlCQUFpQixJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUU7O2dCQUE0QixJQUFJLENBQUMsRUFBRTthQUFDO1FBQzFGO1FBRU8sUUFBYztZQUVuQixPQUFPQSxpQkFBaUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFOztnQkFBMkIsSUFBSSxDQUFDLEVBQUU7YUFBQztRQUN6RjtRQUVPLE9BQWE7WUFFbEIsT0FBT0EsaUJBQWlCLElBQUksQ0FBQyxNQUFN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
|