@angular/core 17.0.0-next.7 → 17.0.0-rc.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/esm2022/primitives/signals/index.mjs +15 -0
- package/esm2022/primitives/signals/src/computed.mjs +92 -0
- package/esm2022/primitives/signals/src/equality.mjs +14 -0
- package/esm2022/primitives/signals/src/errors.mjs +18 -0
- package/esm2022/primitives/signals/src/graph.mjs +291 -0
- package/esm2022/primitives/signals/src/signal.mjs +78 -0
- package/esm2022/primitives/signals/src/watch.mjs +82 -0
- package/esm2022/primitives/signals/src/weak_ref.mjs +11 -0
- package/esm2022/rxjs-interop/src/to_signal.mjs +45 -14
- package/esm2022/src/application_init.mjs +50 -2
- package/esm2022/src/application_ref.mjs +8 -2
- package/esm2022/src/application_tokens.mjs +16 -1
- package/esm2022/src/core_private_export.mjs +7 -6
- package/esm2022/src/core_reactivity_export_internal.mjs +6 -2
- package/esm2022/src/core_render3_private_export.mjs +3 -3
- package/esm2022/src/debug/debug_node.mjs +5 -9
- package/esm2022/src/defer/cleanup.mjs +70 -0
- package/esm2022/src/defer/discovery.mjs +47 -0
- package/esm2022/src/defer/dom_triggers.mjs +256 -0
- package/esm2022/src/defer/idle_scheduler.mjs +109 -0
- package/esm2022/src/defer/instructions.mjs +641 -0
- package/esm2022/src/defer/interfaces.mjs +79 -0
- package/esm2022/src/defer/timer_scheduler.mjs +192 -0
- package/esm2022/src/defer/utils.mjs +134 -0
- package/esm2022/src/errors.mjs +1 -1
- package/esm2022/src/hydration/api.mjs +1 -2
- package/esm2022/src/hydration/utils.mjs +2 -2
- package/esm2022/src/image_performance_warning.mjs +154 -0
- package/esm2022/src/linker/compiler.mjs +1 -1
- package/esm2022/src/metadata/directives.mjs +1 -1
- package/esm2022/src/render/api.mjs +1 -1
- package/esm2022/src/render3/after_render_hooks.mjs +35 -1
- package/esm2022/src/render3/assert.mjs +16 -1
- package/esm2022/src/render3/component_ref.mjs +12 -3
- package/esm2022/src/render3/debug/framework_injector_profiler.mjs +33 -4
- package/esm2022/src/render3/debug/injector_profiler.mjs +1 -1
- package/esm2022/src/render3/debug/set_debug_info.mjs +20 -0
- package/esm2022/src/render3/definition.mjs +2 -1
- package/esm2022/src/render3/deps_tracker/api.mjs +1 -1
- package/esm2022/src/render3/deps_tracker/deps_tracker.mjs +13 -2
- package/esm2022/src/render3/features/host_directives_feature.mjs +3 -8
- package/esm2022/src/render3/hooks.mjs +5 -5
- package/esm2022/src/render3/index.mjs +4 -2
- package/esm2022/src/render3/instructions/all.mjs +2 -2
- package/esm2022/src/render3/instructions/change_detection.mjs +31 -14
- package/esm2022/src/render3/instructions/control_flow.mjs +42 -23
- package/esm2022/src/render3/instructions/shared.mjs +5 -4
- package/esm2022/src/render3/interfaces/container.mjs +5 -7
- package/esm2022/src/render3/interfaces/definition.mjs +2 -4
- package/esm2022/src/render3/interfaces/i18n.mjs +1 -4
- package/esm2022/src/render3/interfaces/injector.mjs +1 -4
- package/esm2022/src/render3/interfaces/node.mjs +1 -4
- package/esm2022/src/render3/interfaces/projection.mjs +2 -4
- package/esm2022/src/render3/interfaces/query.mjs +2 -4
- package/esm2022/src/render3/interfaces/renderer.mjs +2 -4
- package/esm2022/src/render3/interfaces/renderer_dom.mjs +2 -4
- package/esm2022/src/render3/interfaces/view.mjs +5 -7
- package/esm2022/src/render3/jit/environment.mjs +3 -1
- package/esm2022/src/render3/list_reconciliation.mjs +58 -34
- package/esm2022/src/render3/node_manipulation.mjs +4 -6
- package/esm2022/src/render3/reactive_lview_consumer.mjs +3 -8
- package/esm2022/src/render3/reactivity/api.mjs +15 -0
- package/esm2022/src/render3/reactivity/asserts.mjs +26 -0
- package/esm2022/src/render3/reactivity/computed.mjs +19 -0
- package/esm2022/src/render3/reactivity/effect.mjs +7 -6
- package/esm2022/src/render3/reactivity/signal.mjs +32 -0
- package/esm2022/src/render3/reactivity/untracked.mjs +24 -0
- package/esm2022/src/render3/util/injector_discovery_utils.mjs +43 -14
- package/esm2022/src/render3/util/stringify_utils.mjs +28 -1
- package/esm2022/src/render3/util/view_utils.mjs +41 -25
- package/esm2022/src/render3/view_ref.mjs +3 -2
- package/esm2022/src/util/stringify.mjs +16 -1
- package/esm2022/src/version.mjs +1 -1
- package/esm2022/testing/src/logger.mjs +3 -3
- package/fesm2022/core.mjs +2881 -2270
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/primitives/signals.mjs +539 -0
- package/fesm2022/primitives/signals.mjs.map +1 -0
- package/fesm2022/rxjs-interop.mjs +45 -14
- package/fesm2022/rxjs-interop.mjs.map +1 -1
- package/fesm2022/testing.mjs +1 -1
- package/index.d.ts +204 -168
- package/package.json +7 -1
- package/primitives/signals/index.d.ts +281 -0
- package/rxjs-interop/index.d.ts +15 -101
- package/schematics/collection.json +12 -2
- package/schematics/migrations/block-template-entities/bundle.js +551 -197
- package/schematics/migrations/block-template-entities/bundle.js.map +4 -4
- package/schematics/migrations/compiler-options/bundle.js +582 -0
- package/schematics/migrations/compiler-options/bundle.js.map +7 -0
- package/schematics/migrations/transfer-state/bundle.js +592 -0
- package/schematics/migrations/transfer-state/bundle.js.map +7 -0
- package/schematics/migrations.json +10 -0
- package/schematics/ng-generate/control-flow-migration/bundle.js +24309 -0
- package/schematics/ng-generate/control-flow-migration/bundle.js.map +7 -0
- package/schematics/ng-generate/control-flow-migration/schema.json +7 -0
- package/schematics/ng-generate/standalone-migration/bundle.js +1496 -924
- package/schematics/ng-generate/standalone-migration/bundle.js.map +4 -4
- package/testing/index.d.ts +1 -1
- package/esm2022/src/render3/instructions/defer.mjs +0 -1091
- package/esm2022/src/render3/instructions/defer_events.mjs +0 -164
- package/esm2022/src/render3/interfaces/defer.mjs +0 -72
- package/esm2022/src/signals/index.mjs +0 -16
- package/esm2022/src/signals/src/api.mjs +0 -39
- package/esm2022/src/signals/src/computed.mjs +0 -95
- package/esm2022/src/signals/src/errors.mjs +0 -18
- package/esm2022/src/signals/src/graph.mjs +0 -280
- package/esm2022/src/signals/src/signal.mjs +0 -92
- package/esm2022/src/signals/src/untracked.mjs +0 -26
- package/esm2022/src/signals/src/watch.mjs +0 -81
- package/esm2022/src/signals/src/weak_ref.mjs +0 -11
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
8
|
+
import { CONTAINER_HEADER_OFFSET } from '../render3/interfaces/container';
|
|
9
|
+
import { isLContainer, isLView } from '../render3/interfaces/type_checks';
|
|
10
|
+
import { HEADER_OFFSET, TVIEW } from '../render3/interfaces/view';
|
|
11
|
+
import { getTDeferBlockDetails, isTDeferBlockDetails } from './utils';
|
|
12
|
+
/**
|
|
13
|
+
* Retrieves all defer blocks in a given LView.
|
|
14
|
+
*
|
|
15
|
+
* @param lView lView with defer blocks
|
|
16
|
+
* @param deferBlocks defer block aggregator array
|
|
17
|
+
*/
|
|
18
|
+
export function getDeferBlocks(lView, deferBlocks) {
|
|
19
|
+
const tView = lView[TVIEW];
|
|
20
|
+
for (let i = HEADER_OFFSET; i < tView.bindingStartIndex; i++) {
|
|
21
|
+
if (isLContainer(lView[i])) {
|
|
22
|
+
const lContainer = lView[i];
|
|
23
|
+
// An LContainer may represent an instance of a defer block, in which case
|
|
24
|
+
// we store it as a result. Otherwise, keep iterating over LContainer views and
|
|
25
|
+
// look for defer blocks.
|
|
26
|
+
const isLast = i === tView.bindingStartIndex - 1;
|
|
27
|
+
if (!isLast) {
|
|
28
|
+
const tNode = tView.data[i];
|
|
29
|
+
const tDetails = getTDeferBlockDetails(tView, tNode);
|
|
30
|
+
if (isTDeferBlockDetails(tDetails)) {
|
|
31
|
+
deferBlocks.push({ lContainer, lView, tNode, tDetails });
|
|
32
|
+
// This LContainer represents a defer block, so we exit
|
|
33
|
+
// this iteration and don't inspect views in this LContainer.
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
|
|
38
|
+
getDeferBlocks(lContainer[i], deferBlocks);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
else if (isLView(lView[i])) {
|
|
42
|
+
// This is a component, enter the `getDeferBlocks` recursively.
|
|
43
|
+
getDeferBlocks(lView[i], deferBlocks);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzY292ZXJ5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29yZS9zcmMvZGVmZXIvZGlzY292ZXJ5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFBQyx1QkFBdUIsRUFBYSxNQUFNLGlDQUFpQyxDQUFDO0FBRXBGLE9BQU8sRUFBQyxZQUFZLEVBQUUsT0FBTyxFQUFDLE1BQU0sbUNBQW1DLENBQUM7QUFDeEUsT0FBTyxFQUFDLGFBQWEsRUFBUyxLQUFLLEVBQUMsTUFBTSw0QkFBNEIsQ0FBQztBQUd2RSxPQUFPLEVBQUMscUJBQXFCLEVBQUUsb0JBQW9CLEVBQUMsTUFBTSxTQUFTLENBQUM7QUFZcEU7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsY0FBYyxDQUFDLEtBQVksRUFBRSxXQUFnQztJQUMzRSxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDM0IsS0FBSyxJQUFJLENBQUMsR0FBRyxhQUFhLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUM1RCxJQUFJLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUMxQixNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDNUIsMEVBQTBFO1lBQzFFLCtFQUErRTtZQUMvRSx5QkFBeUI7WUFDekIsTUFBTSxNQUFNLEdBQUcsQ0FBQyxLQUFLLEtBQUssQ0FBQyxpQkFBaUIsR0FBRyxDQUFDLENBQUM7WUFDakQsSUFBSSxDQUFDLE1BQU0sRUFBRTtnQkFDWCxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBVSxDQUFDO2dCQUNyQyxNQUFNLFFBQVEsR0FBRyxxQkFBcUIsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBQ3JELElBQUksb0JBQW9CLENBQUMsUUFBUSxDQUFDLEVBQUU7b0JBQ2xDLFdBQVcsQ0FBQyxJQUFJLENBQUMsRUFBQyxVQUFVLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUMsQ0FBQyxDQUFDO29CQUN2RCx1REFBdUQ7b0JBQ3ZELDZEQUE2RDtvQkFDN0QsU0FBUztpQkFDVjthQUNGO1lBQ0QsS0FBSyxJQUFJLENBQUMsR0FBRyx1QkFBdUIsRUFBRSxDQUFDLEdBQUcsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDaEUsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQVUsRUFBRSxXQUFXLENBQUMsQ0FBQzthQUNyRDtTQUNGO2FBQU0sSUFBSSxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDNUIsK0RBQStEO1lBQy9ELGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUM7U0FDdkM7S0FDRjtBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHtDT05UQUlORVJfSEVBREVSX09GRlNFVCwgTENvbnRhaW5lcn0gZnJvbSAnLi4vcmVuZGVyMy9pbnRlcmZhY2VzL2NvbnRhaW5lcic7XG5pbXBvcnQge1ROb2RlfSBmcm9tICcuLi9yZW5kZXIzL2ludGVyZmFjZXMvbm9kZSc7XG5pbXBvcnQge2lzTENvbnRhaW5lciwgaXNMVmlld30gZnJvbSAnLi4vcmVuZGVyMy9pbnRlcmZhY2VzL3R5cGVfY2hlY2tzJztcbmltcG9ydCB7SEVBREVSX09GRlNFVCwgTFZpZXcsIFRWSUVXfSBmcm9tICcuLi9yZW5kZXIzL2ludGVyZmFjZXMvdmlldyc7XG5cbmltcG9ydCB7VERlZmVyQmxvY2tEZXRhaWxzfSBmcm9tICcuL2ludGVyZmFjZXMnO1xuaW1wb3J0IHtnZXRURGVmZXJCbG9ja0RldGFpbHMsIGlzVERlZmVyQmxvY2tEZXRhaWxzfSBmcm9tICcuL3V0aWxzJztcblxuLyoqXG4gKiBEZWZlciBibG9jayBpbnN0YW5jZSBmb3IgdGVzdGluZy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEZWZlckJsb2NrRGV0YWlscyB7XG4gIGxDb250YWluZXI6IExDb250YWluZXI7XG4gIGxWaWV3OiBMVmlldztcbiAgdE5vZGU6IFROb2RlO1xuICB0RGV0YWlsczogVERlZmVyQmxvY2tEZXRhaWxzO1xufVxuXG4vKipcbiAqIFJldHJpZXZlcyBhbGwgZGVmZXIgYmxvY2tzIGluIGEgZ2l2ZW4gTFZpZXcuXG4gKlxuICogQHBhcmFtIGxWaWV3IGxWaWV3IHdpdGggZGVmZXIgYmxvY2tzXG4gKiBAcGFyYW0gZGVmZXJCbG9ja3MgZGVmZXIgYmxvY2sgYWdncmVnYXRvciBhcnJheVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGVmZXJCbG9ja3MobFZpZXc6IExWaWV3LCBkZWZlckJsb2NrczogRGVmZXJCbG9ja0RldGFpbHNbXSkge1xuICBjb25zdCB0VmlldyA9IGxWaWV3W1RWSUVXXTtcbiAgZm9yIChsZXQgaSA9IEhFQURFUl9PRkZTRVQ7IGkgPCB0Vmlldy5iaW5kaW5nU3RhcnRJbmRleDsgaSsrKSB7XG4gICAgaWYgKGlzTENvbnRhaW5lcihsVmlld1tpXSkpIHtcbiAgICAgIGNvbnN0IGxDb250YWluZXIgPSBsVmlld1tpXTtcbiAgICAgIC8vIEFuIExDb250YWluZXIgbWF5IHJlcHJlc2VudCBhbiBpbnN0YW5jZSBvZiBhIGRlZmVyIGJsb2NrLCBpbiB3aGljaCBjYXNlXG4gICAgICAvLyB3ZSBzdG9yZSBpdCBhcyBhIHJlc3VsdC4gT3RoZXJ3aXNlLCBrZWVwIGl0ZXJhdGluZyBvdmVyIExDb250YWluZXIgdmlld3MgYW5kXG4gICAgICAvLyBsb29rIGZvciBkZWZlciBibG9ja3MuXG4gICAgICBjb25zdCBpc0xhc3QgPSBpID09PSB0Vmlldy5iaW5kaW5nU3RhcnRJbmRleCAtIDE7XG4gICAgICBpZiAoIWlzTGFzdCkge1xuICAgICAgICBjb25zdCB0Tm9kZSA9IHRWaWV3LmRhdGFbaV0gYXMgVE5vZGU7XG4gICAgICAgIGNvbnN0IHREZXRhaWxzID0gZ2V0VERlZmVyQmxvY2tEZXRhaWxzKHRWaWV3LCB0Tm9kZSk7XG4gICAgICAgIGlmIChpc1REZWZlckJsb2NrRGV0YWlscyh0RGV0YWlscykpIHtcbiAgICAgICAgICBkZWZlckJsb2Nrcy5wdXNoKHtsQ29udGFpbmVyLCBsVmlldywgdE5vZGUsIHREZXRhaWxzfSk7XG4gICAgICAgICAgLy8gVGhpcyBMQ29udGFpbmVyIHJlcHJlc2VudHMgYSBkZWZlciBibG9jaywgc28gd2UgZXhpdFxuICAgICAgICAgIC8vIHRoaXMgaXRlcmF0aW9uIGFuZCBkb24ndCBpbnNwZWN0IHZpZXdzIGluIHRoaXMgTENvbnRhaW5lci5cbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZm9yIChsZXQgaSA9IENPTlRBSU5FUl9IRUFERVJfT0ZGU0VUOyBpIDwgbENvbnRhaW5lci5sZW5ndGg7IGkrKykge1xuICAgICAgICBnZXREZWZlckJsb2NrcyhsQ29udGFpbmVyW2ldIGFzIExWaWV3LCBkZWZlckJsb2Nrcyk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChpc0xWaWV3KGxWaWV3W2ldKSkge1xuICAgICAgLy8gVGhpcyBpcyBhIGNvbXBvbmVudCwgZW50ZXIgdGhlIGBnZXREZWZlckJsb2Nrc2AgcmVjdXJzaXZlbHkuXG4gICAgICBnZXREZWZlckJsb2NrcyhsVmlld1tpXSwgZGVmZXJCbG9ja3MpO1xuICAgIH1cbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
8
|
+
import { internalAfterNextRender } from '../render3/after_render_hooks';
|
|
9
|
+
import { assertLContainer, assertLView } from '../render3/assert';
|
|
10
|
+
import { CONTAINER_HEADER_OFFSET } from '../render3/interfaces/container';
|
|
11
|
+
import { isDestroyed } from '../render3/interfaces/type_checks';
|
|
12
|
+
import { HEADER_OFFSET, INJECTOR } from '../render3/interfaces/view';
|
|
13
|
+
import { getNativeByIndex, removeLViewOnDestroy, storeLViewOnDestroy, walkUpViews } from '../render3/util/view_utils';
|
|
14
|
+
import { assertElement, assertEqual } from '../util/assert';
|
|
15
|
+
import { NgZone } from '../zone';
|
|
16
|
+
import { DEFER_BLOCK_STATE, DeferBlockInternalState, DeferBlockState } from './interfaces';
|
|
17
|
+
import { getLDeferBlockDetails } from './utils';
|
|
18
|
+
/** Configuration object used to register passive and capturing events. */
|
|
19
|
+
const eventListenerOptions = {
|
|
20
|
+
passive: true,
|
|
21
|
+
capture: true
|
|
22
|
+
};
|
|
23
|
+
/** Keeps track of the currently-registered `on hover` triggers. */
|
|
24
|
+
const hoverTriggers = new WeakMap();
|
|
25
|
+
/** Keeps track of the currently-registered `on interaction` triggers. */
|
|
26
|
+
const interactionTriggers = new WeakMap();
|
|
27
|
+
/** Currently-registered `viewport` triggers. */
|
|
28
|
+
const viewportTriggers = new WeakMap();
|
|
29
|
+
/** Names of the events considered as interaction events. */
|
|
30
|
+
const interactionEventNames = ['click', 'keydown'];
|
|
31
|
+
/** Names of the events considered as hover events. */
|
|
32
|
+
const hoverEventNames = ['mouseenter', 'focusin'];
|
|
33
|
+
/** `IntersectionObserver` used to observe `viewport` triggers. */
|
|
34
|
+
let intersectionObserver = null;
|
|
35
|
+
/** Number of elements currently observed with `viewport` triggers. */
|
|
36
|
+
let observedViewportElements = 0;
|
|
37
|
+
/** Object keeping track of registered callbacks for a deferred block trigger. */
|
|
38
|
+
class DeferEventEntry {
|
|
39
|
+
constructor() {
|
|
40
|
+
this.callbacks = new Set();
|
|
41
|
+
this.listener = () => {
|
|
42
|
+
for (const callback of this.callbacks) {
|
|
43
|
+
callback();
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Registers an interaction trigger.
|
|
50
|
+
* @param trigger Element that is the trigger.
|
|
51
|
+
* @param callback Callback to be invoked when the trigger is interacted with.
|
|
52
|
+
* @param injector Injector that can be used by the trigger to resolve DI tokens.
|
|
53
|
+
*/
|
|
54
|
+
export function onInteraction(trigger, callback, injector) {
|
|
55
|
+
let entry = interactionTriggers.get(trigger);
|
|
56
|
+
// If this is the first entry for this element, add the listeners.
|
|
57
|
+
if (!entry) {
|
|
58
|
+
// Note that managing events centrally like this lends itself well to using global
|
|
59
|
+
// event delegation. It currently does delegation at the element level, rather than the
|
|
60
|
+
// document level, because:
|
|
61
|
+
// 1. Global delegation is the most effective when there are a lot of events being registered
|
|
62
|
+
// at the same time. Deferred blocks are unlikely to be used in such a way.
|
|
63
|
+
// 2. Matching events to their target isn't free. For each `click` and `keydown` event we
|
|
64
|
+
// would have look through all the triggers and check if the target either is the element
|
|
65
|
+
// itself or it's contained within the element. Given that `click` and `keydown` are some
|
|
66
|
+
// of the most common events, this may end up introducing a lot of runtime overhead.
|
|
67
|
+
// 3. We're still registering only two events per element, no matter how many deferred blocks
|
|
68
|
+
// are referencing it.
|
|
69
|
+
entry = new DeferEventEntry();
|
|
70
|
+
interactionTriggers.set(trigger, entry);
|
|
71
|
+
// Ensure that the handler runs in the NgZone
|
|
72
|
+
ngDevMode && NgZone.assertInAngularZone();
|
|
73
|
+
for (const name of interactionEventNames) {
|
|
74
|
+
trigger.addEventListener(name, entry.listener, eventListenerOptions);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
entry.callbacks.add(callback);
|
|
78
|
+
return () => {
|
|
79
|
+
const { callbacks, listener } = entry;
|
|
80
|
+
callbacks.delete(callback);
|
|
81
|
+
if (callbacks.size === 0) {
|
|
82
|
+
interactionTriggers.delete(trigger);
|
|
83
|
+
for (const name of interactionEventNames) {
|
|
84
|
+
trigger.removeEventListener(name, listener, eventListenerOptions);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Registers a hover trigger.
|
|
91
|
+
* @param trigger Element that is the trigger.
|
|
92
|
+
* @param callback Callback to be invoked when the trigger is hovered over.
|
|
93
|
+
* @param injector Injector that can be used by the trigger to resolve DI tokens.
|
|
94
|
+
*/
|
|
95
|
+
export function onHover(trigger, callback, injector) {
|
|
96
|
+
let entry = hoverTriggers.get(trigger);
|
|
97
|
+
// If this is the first entry for this element, add the listener.
|
|
98
|
+
if (!entry) {
|
|
99
|
+
entry = new DeferEventEntry();
|
|
100
|
+
hoverTriggers.set(trigger, entry);
|
|
101
|
+
// Ensure that the handler runs in the NgZone
|
|
102
|
+
ngDevMode && NgZone.assertInAngularZone();
|
|
103
|
+
for (const name of hoverEventNames) {
|
|
104
|
+
trigger.addEventListener(name, entry.listener, eventListenerOptions);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
entry.callbacks.add(callback);
|
|
108
|
+
return () => {
|
|
109
|
+
const { callbacks, listener } = entry;
|
|
110
|
+
callbacks.delete(callback);
|
|
111
|
+
if (callbacks.size === 0) {
|
|
112
|
+
for (const name of hoverEventNames) {
|
|
113
|
+
trigger.removeEventListener(name, listener, eventListenerOptions);
|
|
114
|
+
}
|
|
115
|
+
hoverTriggers.delete(trigger);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Registers a viewport trigger.
|
|
121
|
+
* @param trigger Element that is the trigger.
|
|
122
|
+
* @param callback Callback to be invoked when the trigger comes into the viewport.
|
|
123
|
+
* @param injector Injector that can be used by the trigger to resolve DI tokens.
|
|
124
|
+
*/
|
|
125
|
+
export function onViewport(trigger, callback, injector) {
|
|
126
|
+
const ngZone = injector.get(NgZone);
|
|
127
|
+
let entry = viewportTriggers.get(trigger);
|
|
128
|
+
intersectionObserver = intersectionObserver || ngZone.runOutsideAngular(() => {
|
|
129
|
+
return new IntersectionObserver(entries => {
|
|
130
|
+
for (const current of entries) {
|
|
131
|
+
// Only invoke the callbacks if the specific element is intersecting.
|
|
132
|
+
if (current.isIntersecting && viewportTriggers.has(current.target)) {
|
|
133
|
+
ngZone.run(viewportTriggers.get(current.target).listener);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
if (!entry) {
|
|
139
|
+
entry = new DeferEventEntry();
|
|
140
|
+
ngZone.runOutsideAngular(() => intersectionObserver.observe(trigger));
|
|
141
|
+
viewportTriggers.set(trigger, entry);
|
|
142
|
+
observedViewportElements++;
|
|
143
|
+
}
|
|
144
|
+
entry.callbacks.add(callback);
|
|
145
|
+
return () => {
|
|
146
|
+
// It's possible that a different cleanup callback fully removed this element already.
|
|
147
|
+
if (!viewportTriggers.has(trigger)) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
entry.callbacks.delete(callback);
|
|
151
|
+
if (entry.callbacks.size === 0) {
|
|
152
|
+
intersectionObserver?.unobserve(trigger);
|
|
153
|
+
viewportTriggers.delete(trigger);
|
|
154
|
+
observedViewportElements--;
|
|
155
|
+
}
|
|
156
|
+
if (observedViewportElements === 0) {
|
|
157
|
+
intersectionObserver?.disconnect();
|
|
158
|
+
intersectionObserver = null;
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Helper function to get the LView in which a deferred block's trigger is rendered.
|
|
164
|
+
* @param deferredHostLView LView in which the deferred block is defined.
|
|
165
|
+
* @param deferredTNode TNode defining the deferred block.
|
|
166
|
+
* @param walkUpTimes Number of times to go up in the view hierarchy to find the trigger's view.
|
|
167
|
+
* A negative value means that the trigger is inside the block's placeholder, while an undefined
|
|
168
|
+
* value means that the trigger is in the same LView as the deferred block.
|
|
169
|
+
*/
|
|
170
|
+
export function getTriggerLView(deferredHostLView, deferredTNode, walkUpTimes) {
|
|
171
|
+
// The trigger is in the same view, we don't need to traverse.
|
|
172
|
+
if (walkUpTimes == null) {
|
|
173
|
+
return deferredHostLView;
|
|
174
|
+
}
|
|
175
|
+
// A positive value or zero means that the trigger is in a parent view.
|
|
176
|
+
if (walkUpTimes >= 0) {
|
|
177
|
+
return walkUpViews(walkUpTimes, deferredHostLView);
|
|
178
|
+
}
|
|
179
|
+
// If the value is negative, it means that the trigger is inside the placeholder.
|
|
180
|
+
const deferredContainer = deferredHostLView[deferredTNode.index];
|
|
181
|
+
ngDevMode && assertLContainer(deferredContainer);
|
|
182
|
+
const triggerLView = deferredContainer[CONTAINER_HEADER_OFFSET] ?? null;
|
|
183
|
+
// We need to null check, because the placeholder might not have been rendered yet.
|
|
184
|
+
if (ngDevMode && triggerLView !== null) {
|
|
185
|
+
const lDetails = getLDeferBlockDetails(deferredHostLView, deferredTNode);
|
|
186
|
+
const renderedState = lDetails[DEFER_BLOCK_STATE];
|
|
187
|
+
assertEqual(renderedState, DeferBlockState.Placeholder, 'Expected a placeholder to be rendered in this defer block.');
|
|
188
|
+
assertLView(triggerLView);
|
|
189
|
+
}
|
|
190
|
+
return triggerLView;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Gets the element that a deferred block's trigger is pointing to.
|
|
194
|
+
* @param triggerLView LView in which the trigger is defined.
|
|
195
|
+
* @param triggerIndex Index at which the trigger element should've been rendered.
|
|
196
|
+
*/
|
|
197
|
+
export function getTriggerElement(triggerLView, triggerIndex) {
|
|
198
|
+
const element = getNativeByIndex(HEADER_OFFSET + triggerIndex, triggerLView);
|
|
199
|
+
ngDevMode && assertElement(element);
|
|
200
|
+
return element;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Registers a DOM-node based trigger.
|
|
204
|
+
* @param initialLView LView in which the defer block is rendered.
|
|
205
|
+
* @param tNode TNode representing the defer block.
|
|
206
|
+
* @param triggerIndex Index at which to find the trigger element.
|
|
207
|
+
* @param walkUpTimes Number of times to go up/down in the view hierarchy to find the trigger.
|
|
208
|
+
* @param registerFn Function that will register the DOM events.
|
|
209
|
+
* @param callback Callback to be invoked when the trigger receives the event that should render
|
|
210
|
+
* the deferred block.
|
|
211
|
+
*/
|
|
212
|
+
export function registerDomTrigger(initialLView, tNode, triggerIndex, walkUpTimes, registerFn, callback) {
|
|
213
|
+
const injector = initialLView[INJECTOR];
|
|
214
|
+
function pollDomTrigger() {
|
|
215
|
+
// If the initial view was destroyed, we don't need to do anything.
|
|
216
|
+
if (isDestroyed(initialLView)) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
const lDetails = getLDeferBlockDetails(initialLView, tNode);
|
|
220
|
+
const renderedState = lDetails[DEFER_BLOCK_STATE];
|
|
221
|
+
// If the block was loaded before the trigger was resolved, we don't need to do anything.
|
|
222
|
+
if (renderedState !== DeferBlockInternalState.Initial &&
|
|
223
|
+
renderedState !== DeferBlockState.Placeholder) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
const triggerLView = getTriggerLView(initialLView, tNode, walkUpTimes);
|
|
227
|
+
// Keep polling until we resolve the trigger's LView.
|
|
228
|
+
if (!triggerLView) {
|
|
229
|
+
internalAfterNextRender(pollDomTrigger, { injector });
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
// It's possible that the trigger's view was destroyed before we resolved the trigger element.
|
|
233
|
+
if (isDestroyed(triggerLView)) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
// TODO: add integration with `DeferBlockCleanupManager`.
|
|
237
|
+
const element = getTriggerElement(triggerLView, triggerIndex);
|
|
238
|
+
const cleanup = registerFn(element, () => {
|
|
239
|
+
callback();
|
|
240
|
+
removeLViewOnDestroy(triggerLView, cleanup);
|
|
241
|
+
if (initialLView !== triggerLView) {
|
|
242
|
+
removeLViewOnDestroy(initialLView, cleanup);
|
|
243
|
+
}
|
|
244
|
+
cleanup();
|
|
245
|
+
}, injector);
|
|
246
|
+
storeLViewOnDestroy(triggerLView, cleanup);
|
|
247
|
+
// Since the trigger and deferred block might be in different
|
|
248
|
+
// views, we have to register the callback in both locations.
|
|
249
|
+
if (initialLView !== triggerLView) {
|
|
250
|
+
storeLViewOnDestroy(initialLView, cleanup);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// Begin polling for the trigger.
|
|
254
|
+
internalAfterNextRender(pollDomTrigger, { injector });
|
|
255
|
+
}
|
|
256
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9tX3RyaWdnZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29yZS9zcmMvZGVmZXIvZG9tX3RyaWdnZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUdILE9BQU8sRUFBQyx1QkFBdUIsRUFBQyxNQUFNLCtCQUErQixDQUFDO0FBQ3RFLE9BQU8sRUFBQyxnQkFBZ0IsRUFBRSxXQUFXLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUNoRSxPQUFPLEVBQUMsdUJBQXVCLEVBQUMsTUFBTSxpQ0FBaUMsQ0FBQztBQUV4RSxPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0sbUNBQW1DLENBQUM7QUFDOUQsT0FBTyxFQUFDLGFBQWEsRUFBRSxRQUFRLEVBQVEsTUFBTSw0QkFBNEIsQ0FBQztBQUMxRSxPQUFPLEVBQUMsZ0JBQWdCLEVBQUUsb0JBQW9CLEVBQUUsbUJBQW1CLEVBQUUsV0FBVyxFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFDcEgsT0FBTyxFQUFDLGFBQWEsRUFBRSxXQUFXLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUMxRCxPQUFPLEVBQUMsTUFBTSxFQUFDLE1BQU0sU0FBUyxDQUFDO0FBRS9CLE9BQU8sRUFBQyxpQkFBaUIsRUFBRSx1QkFBdUIsRUFBRSxlQUFlLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFDekYsT0FBTyxFQUFDLHFCQUFxQixFQUFDLE1BQU0sU0FBUyxDQUFDO0FBRTlDLDBFQUEwRTtBQUMxRSxNQUFNLG9CQUFvQixHQUE0QjtJQUNwRCxPQUFPLEVBQUUsSUFBSTtJQUNiLE9BQU8sRUFBRSxJQUFJO0NBQ2QsQ0FBQztBQUVGLG1FQUFtRTtBQUNuRSxNQUFNLGFBQWEsR0FBRyxJQUFJLE9BQU8sRUFBNEIsQ0FBQztBQUU5RCx5RUFBeUU7QUFDekUsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLE9BQU8sRUFBNEIsQ0FBQztBQUVwRSxnREFBZ0Q7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QUFFLFFBQVEsQ0FBQyxDQUFDO1FBRWIsbUJBQW1CLENBQUMsWUFBWSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBRTNDLDZEQUE2RDtRQUM3RCw2REFBNkQ7UUFDN0QsSUFBSSxZQUFZLEtBQUssWUFBWSxFQUFFO1lBQ2pDLG1CQUFtQixDQUFDLFlBQVksRUFBRSxPQUFPLENBQUMsQ0FBQztTQUM1QztJQUNILENBQUM7SUFFRCxpQ0FBaUM7SUFDakMsdUJBQXVCLENBQUMsY0FBYyxFQUFFLEVBQUMsUUFBUSxFQUFDLENBQUMsQ0FBQztBQUN0RCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyohXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB0eXBlIHtJbmplY3Rvcn0gZnJvbSAnLi4vZGknO1xuaW1wb3J0IHtpbnRlcm5hbEFmdGVyTmV4dFJlbmRlcn0gZnJvbSAnLi4vcmVuZGVyMy9hZnRlcl9yZW5kZXJfaG9va3MnO1xuaW1wb3J0IHthc3NlcnRMQ29udGFpbmVyLCBhc3NlcnRMVmlld30gZnJvbSAnLi4vcmVuZGVyMy9hc3NlcnQnO1xuaW1wb3J0IHtDT05UQUlORVJfSEVBREVSX09GRlNFVH0gZnJvbSAnLi4vcmVuZGVyMy9pbnRlcmZhY2VzL2NvbnRhaW5lcic7XG5pbXBvcnQge1ROb2RlfSBmcm9tICcuLi9yZW5kZXIzL2ludGVyZmFjZXMvbm9kZSc7XG5pbXBvcnQge2lzRGVzdHJveWVkfSBmcm9tICcuLi9yZW5kZXIzL2ludGVyZmFjZXMvdHlwZV9jaGVja3MnO1xuaW1wb3J0IHtIRUFERVJfT0ZGU0VULCBJTkpFQ1RPUiwgTFZpZXd9IGZyb20gJy4uL3JlbmRlcjMvaW50ZXJmYWNlcy92aWV3JztcbmltcG9ydCB7Z2V0TmF0aXZlQnlJbmRleCwgcmVtb3ZlTFZpZXdPbkRlc3Ryb3ksIHN0b3JlTFZpZXdPbkRlc3Ryb3ksIHdhbGtVcFZpZXdzfSBmcm9tICcuLi9yZW5kZXIzL3V0aWwvdmlld191dGlscyc7XG5pbXBvcnQge2Fzc2VydEVsZW1lbnQsIGFzc2VydEVxdWFsfSBmcm9tICcuLi91dGlsL2Fzc2VydCc7XG5pbXBvcnQge05nWm9uZX0gZnJvbSAnLi4vem9uZSc7XG5cbmltcG9ydCB7REVGRVJfQkxPQ0tfU1RBVEUsIERlZmVyQmxvY2tJbnRlcm5hbFN0YXRlLCBEZWZlckJsb2NrU3RhdGV9IGZyb20gJy4vaW50ZXJmYWNlcyc7XG5pbXBvcnQge2dldExEZWZlckJsb2NrRGV0YWlsc30gZnJvbSAnLi91dGlscyc7XG5cbi8qKiBDb25maWd1cmF0aW9uIG9iamVjdCB1c2VkIHRvIHJlZ2lzdGVyIHBhc3NpdmUgYW5kIGNhcHR1cmluZyBldmVudHMuICovXG5jb25zdCBldmVudExpc3RlbmVyT3B0aW9uczogQWRkRXZlbnRMaXN0ZW5lck9wdGlvbnMgPSB7XG4gIHBhc3NpdmU6IHRydWUsXG4gIGNhcHR1cmU6IHRydWVcbn07XG5cbi8qKiBLZWVwcyB0cmFjayBvZiB0aGUgY3VycmVudGx5LXJlZ2lzdGVyZWQgYG9uIGhvdmVyYCB0cmlnZ2Vycy4gKi9cbmNvbnN0IGhvdmVyVHJpZ2dlcnMgPSBuZXcgV2Vha01hcDxFbGVtZW50LCBEZWZlckV2ZW50RW50cnk+KCk7XG5cbi8qKiBLZWVwcyB0cmFjayBvZiB0aGUgY3VycmVudGx5LXJlZ2lzdGVyZWQgYG9uIGludGVyYWN0aW9uYCB0cmlnZ2Vycy4gKi9cbmNvbnN0IGludGVyYWN0aW9uVHJpZ2dlcnMgPSBuZXcgV2Vha01hcDxFbGVtZW50LCBEZWZlckV2ZW50RW50cnk+KCk7XG5cbi8qKiBDdXJyZW50bHktcmVnaXN0ZXJlZCBgdmlld3BvcnRgIHRyaWdnZXJzLiAqL1xuY29uc3Qgdmlld3BvcnRUcmlnZ2VycyA9IG5ldyBXZWFrTWFwPEVsZW1lbnQsIERlZmVyRXZlbnRFbnRyeT4oKTtcblxuLyoqIE5hbWVzIG9mIHRoZSBldmVudHMgY29uc2lkZXJlZCBhcyBpbnRlcmFjdGlvbiBldmVudHMuICovXG5jb25zdCBpbnRlcmFjdGlvbkV2ZW50TmFtZXMgPSBbJ2NsaWNrJywgJ2tleWRvd24nXSBhcyBjb25zdDtcblxuLyoqIE5hbWVzIG9mIHRoZSBldmVudHMgY29uc2lkZXJlZCBhcyBob3ZlciBldmVudHMuICovXG5jb25zdCBob3ZlckV2ZW50TmFtZXMgPSBbJ21vdXNlZW50ZXInLCAnZm9jdXNpbiddIGFzIGNvbnN0O1xuXG4vKiogYEludGVyc2VjdGlvbk9ic2VydmVyYCB1c2VkIHRvIG9ic2VydmUgYHZpZXdwb3J0YCB0cmlnZ2Vycy4gKi9cbmxldCBpbnRlcnNlY3Rpb25PYnNlcnZlcjogSW50ZXJzZWN0aW9uT2JzZXJ2ZXJ8bnVsbCA9IG51bGw7XG5cbi8qKiBOdW1iZXIgb2YgZWxlbWVudHMgY3VycmVudGx5IG9ic2VydmVkIHdpdGggYHZpZXdwb3J0YCB0cmlnZ2Vycy4gKi9cbmxldCBvYnNlcnZlZFZpZXdwb3J0RWxlbWVudHMgPSAwO1xuXG4vKiogT2JqZWN0IGtlZXBpbmcgdHJhY2sgb2YgcmVnaXN0ZXJlZCBjYWxsYmFja3MgZm9yIGEgZGVmZXJyZWQgYmxvY2sgdHJpZ2dlci4gKi9cbmNsYXNzIERlZmVyRXZlbnRFbnRyeSB7XG4gIGNhbGxiYWNrcyA9IG5ldyBTZXQ8Vm9pZEZ1bmN0aW9uPigpO1xuXG4gIGxpc3RlbmVyID0gKCkgPT4ge1xuICAgIGZvciAoY29uc3QgY2FsbGJhY2sgb2YgdGhpcy5jYWxsYmFja3MpIHtcbiAgICAgIGNhbGxiYWNrKCk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogUmVnaXN0ZXJzIGFuIGludGVyYWN0aW9uIHRyaWdnZXIuXG4gKiBAcGFyYW0gdHJpZ2dlciBFbGVtZW50IHRoYXQgaXMgdGhlIHRyaWdnZXIuXG4gKiBAcGFyYW0gY2FsbGJhY2sgQ2FsbGJhY2sgdG8gYmUgaW52b2tlZCB3aGVuIHRoZSB0cmlnZ2VyIGlzIGludGVyYWN0ZWQgd2l0aC5cbiAqIEBwYXJhbSBpbmplY3RvciBJbmplY3RvciB0aGF0IGNhbiBiZSB1c2VkIGJ5IHRoZSB0cmlnZ2VyIHRvIHJlc29sdmUgREkgdG9rZW5zLlxuICovXG5leHBvcnQgZnVuY3Rpb24gb25JbnRlcmFjdGlvbihcbiAgICB0cmlnZ2VyOiBFbGVtZW50LCBjYWxsYmFjazogVm9pZEZ1bmN0aW9uLCBpbmplY3RvcjogSW5qZWN0b3IpOiBWb2lkRnVuY3Rpb24ge1xuICBsZXQgZW50cnkgPSBpbnRlcmFjdGlvblRyaWdnZXJzLmdldCh0cmlnZ2VyKTtcblxuICAvLyBJZiB0aGlzIGlzIHRoZSBmaXJzdCBlbnRyeSBmb3IgdGhpcyBlbGVtZW50LCBhZGQgdGhlIGxpc3RlbmVycy5cbiAgaWYgKCFlbnRyeSkge1xuICAgIC8vIE5vdGUgdGhhdCBtYW5hZ2luZyBldmVudHMgY2VudHJhbGx5IGxpa2UgdGhpcyBsZW5kcyBpdHNlbGYgd2VsbCB0byB1c2luZyBnbG9iYWxcbiAgICAvLyBldmVudCBkZWxlZ2F0aW9uLiBJdCBjdXJyZW50bHkgZG9lcyBkZWxlZ2F0aW9uIGF0IHRoZSBlbGVtZW50IGxldmVsLCByYXRoZXIgdGhhbiB0aGVcbiAgICAvLyBkb2N1bWVudCBsZXZlbCwgYmVjYXVzZTpcbiAgICAvLyAxLiBHbG9iYWwgZGVsZWdhdGlvbiBpcyB0aGUgbW9zdCBlZmZlY3RpdmUgd2hlbiB0aGVyZSBhcmUgYSBsb3Qgb2YgZXZlbnRzIGJlaW5nIHJlZ2lzdGVyZWRcbiAgICAvLyBhdCB0aGUgc2FtZSB0aW1lLiBEZWZlcnJlZCBibG9ja3MgYXJlIHVubGlrZWx5IHRvIGJlIHVzZWQgaW4gc3VjaCBhIHdheS5cbiAgICAvLyAyLiBNYXRjaGluZyBldmVudHMgdG8gdGhlaXIgdGFyZ2V0IGlzbid0IGZyZWUuIEZvciBlYWNoIGBjbGlja2AgYW5kIGBrZXlkb3duYCBldmVudCB3ZVxuICAgIC8vIHdvdWxkIGhhdmUgbG9vayB0aHJvdWdoIGFsbCB0aGUgdHJpZ2dlcnMgYW5kIGNoZWNrIGlmIHRoZSB0YXJnZXQgZWl0aGVyIGlzIHRoZSBlbGVtZW50XG4gICAgLy8gaXRzZWxmIG9yIGl0J3MgY29udGFpbmVkIHdpdGhpbiB0aGUgZWxlbWVudC4gR2l2ZW4gdGhhdCBgY2xpY2tgIGFuZCBga2V5ZG93bmAgYXJlIHNvbWVcbiAgICAvLyBvZiB0aGUgbW9zdCBjb21tb24gZXZlbnRzLCB0aGlzIG1heSBlbmQgdXAgaW50cm9kdWNpbmcgYSBsb3Qgb2YgcnVudGltZSBvdmVyaGVhZC5cbiAgICAvLyAzLiBXZSdyZSBzdGlsbCByZWdpc3RlcmluZyBvbmx5IHR3byBldmVudHMgcGVyIGVsZW1lbnQsIG5vIG1hdHRlciBob3cgbWFueSBkZWZlcnJlZCBibG9ja3NcbiAgICAvLyBhcmUgcmVmZXJlbmNpbmcgaXQuXG4gICAgZW50cnkgPSBuZXcgRGVmZXJFdmVudEVudHJ5KCk7XG4gICAgaW50ZXJhY3Rpb25UcmlnZ2Vycy5zZXQodHJpZ2dlciwgZW50cnkpO1xuXG4gICAgLy8gRW5zdXJlIHRoYXQgdGhlIGhhbmRsZXIgcnVucyBpbiB0aGUgTmdab25lXG4gICAgbmdEZXZNb2RlICYmIE5nWm9uZS5hc3NlcnRJbkFuZ3VsYXJab25lKCk7XG5cbiAgICBmb3IgKGNvbnN0IG5hbWUgb2YgaW50ZXJhY3Rpb25FdmVudE5hbWVzKSB7XG4gICAgICB0cmlnZ2VyLmFkZEV2ZW50TGlzdGVuZXIobmFtZSwgZW50cnkhLmxpc3RlbmVyLCBldmVudExpc3RlbmVyT3B0aW9ucyk7XG4gICAgfVxuICB9XG5cbiAgZW50cnkuY2FsbGJhY2tzLmFkZChjYWxsYmFjayk7XG5cbiAgcmV0dXJuICgpID0+IHtcbiAgICBjb25zdCB7Y2FsbGJhY2tzLCBsaXN0ZW5lcn0gPSBlbnRyeSE7XG4gICAgY2FsbGJhY2tzLmRlbGV0ZShjYWxsYmFjayk7XG5cbiAgICBpZiAoY2FsbGJhY2tzLnNpemUgPT09IDApIHtcbiAgICAgIGludGVyYWN0aW9uVHJpZ2dlcnMuZGVsZXRlKHRyaWdnZXIpO1xuXG4gICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgaW50ZXJhY3Rpb25FdmVudE5hbWVzKSB7XG4gICAgICAgIHRyaWdnZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihuYW1lLCBsaXN0ZW5lciwgZXZlbnRMaXN0ZW5lck9wdGlvbnMpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbn1cblxuLyoqXG4gKiBSZWdpc3RlcnMgYSBob3ZlciB0cmlnZ2VyLlxuICogQHBhcmFtIHRyaWdnZXIgRWxlbWVudCB0aGF0IGlzIHRoZSB0cmlnZ2VyLlxuICogQHBhcmFtIGNhbGxiYWNrIENhbGxiYWNrIHRvIGJlIGludm9rZWQgd2hlbiB0aGUgdHJpZ2dlciBpcyBob3ZlcmVkIG92ZXIuXG4gKiBAcGFyYW0gaW5qZWN0b3IgSW5qZWN0b3IgdGhhdCBjYW4gYmUgdXNlZCBieSB0aGUgdHJpZ2dlciB0byByZXNvbHZlIERJIHRva2Vucy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uSG92ZXIoXG4gICAgdHJpZ2dlcjogRWxlbWVudCwgY2FsbGJhY2s6IFZvaWRGdW5jdGlvbiwgaW5qZWN0b3I6IEluamVjdG9yKTogVm9pZEZ1bmN0aW9uIHtcbiAgbGV0IGVudHJ5ID0gaG92ZXJUcmlnZ2Vycy5nZXQodHJpZ2dlcik7XG5cbiAgLy8gSWYgdGhpcyBpcyB0aGUgZmlyc3QgZW50cnkgZm9yIHRoaXMgZWxlbWVudCwgYWRkIHRoZSBsaXN0ZW5lci5cbiAgaWYgKCFlbnRyeSkge1xuICAgIGVudHJ5ID0gbmV3IERlZmVyRXZlbnRFbnRyeSgpO1xuICAgIGhvdmVyVHJpZ2dlcnMuc2V0KHRyaWdnZXIsIGVudHJ5KTtcblxuICAgIC8vIEVuc3VyZSB0aGF0IHRoZSBoYW5kbGVyIHJ1bnMgaW4gdGhlIE5nWm9uZVxuICAgIG5nRGV2TW9kZSAmJiBOZ1pvbmUuYXNzZXJ0SW5Bbmd1bGFyWm9uZSgpO1xuXG4gICAgZm9yIChjb25zdCBuYW1lIG9mIGhvdmVyRXZlbnROYW1lcykge1xuICAgICAgdHJpZ2dlci5hZGRFdmVudExpc3RlbmVyKG5hbWUsIGVudHJ5IS5saXN0ZW5lciwgZXZlbnRMaXN0ZW5lck9wdGlvbnMpO1xuICAgIH1cbiAgfVxuXG4gIGVudHJ5LmNhbGxiYWNrcy5hZGQoY2FsbGJhY2spO1xuXG4gIHJldHVybiAoKSA9PiB7XG4gICAgY29uc3Qge2NhbGxiYWNrcywgbGlzdGVuZXJ9ID0gZW50cnkhO1xuICAgIGNhbGxiYWNrcy5kZWxldGUoY2FsbGJhY2spO1xuXG4gICAgaWYgKGNhbGxiYWNrcy5zaXplID09PSAwKSB7XG4gICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgaG92ZXJFdmVudE5hbWVzKSB7XG4gICAgICAgIHRyaWdnZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihuYW1lLCBsaXN0ZW5lciwgZXZlbnRMaXN0ZW5lck9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgaG92ZXJUcmlnZ2Vycy5kZWxldGUodHJpZ2dlcik7XG4gICAgfVxuICB9O1xufVxuXG4vKipcbiAqIFJlZ2lzdGVycyBhIHZpZXdwb3J0IHRyaWdnZXIuXG4gKiBAcGFyYW0gdHJpZ2dlciBFbGVtZW50IHRoYXQgaXMgdGhlIHRyaWdnZXIuXG4gKiBAcGFyYW0gY2FsbGJhY2sgQ2FsbGJhY2sgdG8gYmUgaW52b2tlZCB3aGVuIHRoZSB0cmlnZ2VyIGNvbWVzIGludG8gdGhlIHZpZXdwb3J0LlxuICogQHBhcmFtIGluamVjdG9yIEluamVjdG9yIHRoYXQgY2FuIGJlIHVzZWQgYnkgdGhlIHRyaWdnZXIgdG8gcmVzb2x2ZSBESSB0b2tlbnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvblZpZXdwb3J0KFxuICAgIHRyaWdnZXI6IEVsZW1lbnQsIGNhbGxiYWNrOiBWb2lkRnVuY3Rpb24sIGluamVjdG9yOiBJbmplY3Rvcik6IFZvaWRGdW5jdGlvbiB7XG4gIGNvbnN0IG5nWm9uZSA9IGluamVjdG9yLmdldChOZ1pvbmUpO1xuICBsZXQgZW50cnkgPSB2aWV3cG9ydFRyaWdnZXJzLmdldCh0cmlnZ2VyKTtcblxuICBpbnRlcnNlY3Rpb25PYnNlcnZlciA9IGludGVyc2VjdGlvbk9ic2VydmVyIHx8IG5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBJbnRlcnNlY3Rpb25PYnNlcnZlcihlbnRyaWVzID0+IHtcbiAgICAgIGZvciAoY29uc3QgY3VycmVudCBvZiBlbnRyaWVzKSB7XG4gICAgICAgIC8vIE9ubHkgaW52b2tlIHRoZSBjYWxsYmFja3MgaWYgdGhlIHNwZWNpZmljIGVsZW1lbnQgaXMgaW50ZXJzZWN0aW5nLlxuICAgICAgICBpZiAoY3VycmVudC5pc0ludGVyc2VjdGluZyAmJiB2aWV3cG9ydFRyaWdnZXJzLmhhcyhjdXJyZW50LnRhcmdldCkpIHtcbiAgICAgICAgICBuZ1pvbmUucnVuKHZpZXdwb3J0VHJpZ2dlcnMuZ2V0KGN1cnJlbnQudGFyZ2V0KSEubGlzdGVuZXIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIGlmICghZW50cnkpIHtcbiAgICBlbnRyeSA9IG5ldyBEZWZlckV2ZW50RW50cnkoKTtcbiAgICBuZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4gaW50ZXJzZWN0aW9uT2JzZXJ2ZXIhLm9ic2VydmUodHJpZ2dlcikpO1xuICAgIHZpZXdwb3J0VHJpZ2dlcnMuc2V0KHRyaWdnZXIsIGVudHJ5KTtcbiAgICBvYnNlcnZlZFZpZXdwb3J0RWxlbWVudHMrKztcbiAgfVxuXG4gIGVudHJ5LmNhbGxiYWNrcy5hZGQoY2FsbGJhY2spO1xuXG4gIHJldHVybiAoKSA9PiB7XG4gICAgLy8gSXQncyBwb3NzaWJsZSB0aGF0IGEgZGlmZmVyZW50IGNsZWFudXAgY2FsbGJhY2sgZnVsbHkgcmVtb3ZlZCB0aGlzIGVsZW1lbnQgYWxyZWFkeS5cbiAgICBpZiAoIXZpZXdwb3J0VHJpZ2dlcnMuaGFzKHRyaWdnZXIpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZW50cnkhLmNhbGxiYWNrcy5kZWxldGUoY2FsbGJhY2spO1xuXG4gICAgaWYgKGVudHJ5IS5jYWxsYmFja3Muc2l6ZSA9PT0gMCkge1xuICAgICAgaW50ZXJzZWN0aW9uT2JzZXJ2ZXI/LnVub2JzZXJ2ZSh0cmlnZ2VyKTtcbiAgICAgIHZpZXdwb3J0VHJpZ2dlcnMuZGVsZXRlKHRyaWdnZXIpO1xuICAgICAgb2JzZXJ2ZWRWaWV3cG9ydEVsZW1lbnRzLS07XG4gICAgfVxuXG4gICAgaWYgKG9ic2VydmVkVmlld3BvcnRFbGVtZW50cyA9PT0gMCkge1xuICAgICAgaW50ZXJzZWN0aW9uT2JzZXJ2ZXI/LmRpc2Nvbm5lY3QoKTtcbiAgICAgIGludGVyc2VjdGlvbk9ic2VydmVyID0gbnVsbDtcbiAgICB9XG4gIH07XG59XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIHRvIGdldCB0aGUgTFZpZXcgaW4gd2hpY2ggYSBkZWZlcnJlZCBibG9jaydzIHRyaWdnZXIgaXMgcmVuZGVyZWQuXG4gKiBAcGFyYW0gZGVmZXJyZWRIb3N0TFZpZXcgTFZpZXcgaW4gd2hpY2ggdGhlIGRlZmVycmVkIGJsb2NrIGlzIGRlZmluZWQuXG4gKiBAcGFyYW0gZGVmZXJyZWRUTm9kZSBUTm9kZSBkZWZpbmluZyB0aGUgZGVmZXJyZWQgYmxvY2suXG4gKiBAcGFyYW0gd2Fsa1VwVGltZXMgTnVtYmVyIG9mIHRpbWVzIHRvIGdvIHVwIGluIHRoZSB2aWV3IGhpZXJhcmNoeSB0byBmaW5kIHRoZSB0cmlnZ2VyJ3Mgdmlldy5cbiAqICAgQSBuZWdhdGl2ZSB2YWx1ZSBtZWFucyB0aGF0IHRoZSB0cmlnZ2VyIGlzIGluc2lkZSB0aGUgYmxvY2sncyBwbGFjZWhvbGRlciwgd2hpbGUgYW4gdW5kZWZpbmVkXG4gKiAgIHZhbHVlIG1lYW5zIHRoYXQgdGhlIHRyaWdnZXIgaXMgaW4gdGhlIHNhbWUgTFZpZXcgYXMgdGhlIGRlZmVycmVkIGJsb2NrLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VHJpZ2dlckxWaWV3KFxuICAgIGRlZmVycmVkSG9zdExWaWV3OiBMVmlldywgZGVmZXJyZWRUTm9kZTogVE5vZGUsIHdhbGtVcFRpbWVzOiBudW1iZXJ8dW5kZWZpbmVkKTogTFZpZXd8bnVsbCB7XG4gIC8vIFRoZSB0cmlnZ2VyIGlzIGluIHRoZSBzYW1lIHZpZXcsIHdlIGRvbid0IG5lZWQgdG8gdHJhdmVyc2UuXG4gIGlmICh3YWxrVXBUaW1lcyA9PSBudWxsKSB7XG4gICAgcmV0dXJuIGRlZmVycmVkSG9zdExWaWV3O1xuICB9XG5cbiAgLy8gQSBwb3NpdGl2ZSB2YWx1ZSBvciB6ZXJvIG1lYW5zIHRoYXQgdGhlIHRyaWdnZXIgaXMgaW4gYSBwYXJlbnQgdmlldy5cbiAgaWYgKHdhbGtVcFRpbWVzID49IDApIHtcbiAgICByZXR1cm4gd2Fsa1VwVmlld3Mod2Fsa1VwVGltZXMsIGRlZmVycmVkSG9zdExWaWV3KTtcbiAgfVxuXG4gIC8vIElmIHRoZSB2YWx1ZSBpcyBuZWdhdGl2ZSwgaXQgbWVhbnMgdGhhdCB0aGUgdHJpZ2dlciBpcyBpbnNpZGUgdGhlIHBsYWNlaG9sZGVyLlxuICBjb25zdCBkZWZlcnJlZENvbnRhaW5lciA9IGRlZmVycmVkSG9zdExWaWV3W2RlZmVycmVkVE5vZGUuaW5kZXhdO1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0TENvbnRhaW5lcihkZWZlcnJlZENvbnRhaW5lcik7XG4gIGNvbnN0IHRyaWdnZXJMVmlldyA9IGRlZmVycmVkQ29udGFpbmVyW0NPTlRBSU5FUl9IRUFERVJfT0ZGU0VUXSA/PyBudWxsO1xuXG4gIC8vIFdlIG5lZWQgdG8gbnVsbCBjaGVjaywgYmVjYXVzZSB0aGUgcGxhY2Vob2xkZXIgbWlnaHQgbm90IGhhdmUgYmVlbiByZW5kZXJlZCB5ZXQuXG4gIGlmIChuZ0Rldk1vZGUgJiYgdHJpZ2dlckxWaWV3ICE9PSBudWxsKSB7XG4gICAgY29uc3QgbERldGFpbHMgPSBnZXRMRGVmZXJCbG9ja0RldGFpbHMoZGVmZXJyZWRIb3N0TFZpZXcsIGRlZmVycmVkVE5vZGUpO1xuICAgIGNvbnN0IHJlbmRlcmVkU3RhdGUgPSBsRGV0YWlsc1tERUZFUl9CTE9DS19TVEFURV07XG4gICAgYXNzZXJ0RXF1YWwoXG4gICAgICAgIHJlbmRlcmVkU3RhdGUsIERlZmVyQmxvY2tTdGF0ZS5QbGFjZWhvbGRlcixcbiAgICAgICAgJ0V4cGVjdGVkIGEgcGxhY2Vob2xkZXIgdG8gYmUgcmVuZGVyZWQgaW4gdGhpcyBkZWZlciBibG9jay4nKTtcbiAgICBhc3NlcnRMVmlldyh0cmlnZ2VyTFZpZXcpO1xuICB9XG5cbiAgcmV0dXJuIHRyaWdnZXJMVmlldztcbn1cblxuLyoqXG4gKiBHZXRzIHRoZSBlbGVtZW50IHRoYXQgYSBkZWZlcnJlZCBibG9jaydzIHRyaWdnZXIgaXMgcG9pbnRpbmcgdG8uXG4gKiBAcGFyYW0gdHJpZ2dlckxWaWV3IExWaWV3IGluIHdoaWNoIHRoZSB0cmlnZ2VyIGlzIGRlZmluZWQuXG4gKiBAcGFyYW0gdHJpZ2dlckluZGV4IEluZGV4IGF0IHdoaWNoIHRoZSB0cmlnZ2VyIGVsZW1lbnQgc2hvdWxkJ3ZlIGJlZW4gcmVuZGVyZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRUcmlnZ2VyRWxlbWVudCh0cmlnZ2VyTFZpZXc6IExWaWV3LCB0cmlnZ2VySW5kZXg6IG51bWJlcik6IEVsZW1lbnQge1xuICBjb25zdCBlbGVtZW50ID0gZ2V0TmF0aXZlQnlJbmRleChIRUFERVJfT0ZGU0VUICsgdHJpZ2dlckluZGV4LCB0cmlnZ2VyTFZpZXcpO1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0RWxlbWVudChlbGVtZW50KTtcbiAgcmV0dXJuIGVsZW1lbnQgYXMgRWxlbWVudDtcbn1cblxuLyoqXG4gKiBSZWdpc3RlcnMgYSBET00tbm9kZSBiYXNlZCB0cmlnZ2VyLlxuICogQHBhcmFtIGluaXRpYWxMVmlldyBMVmlldyBpbiB3aGljaCB0aGUgZGVmZXIgYmxvY2sgaXMgcmVuZGVyZWQuXG4gKiBAcGFyYW0gdE5vZGUgVE5vZGUgcmVwcmVzZW50aW5nIHRoZSBkZWZlciBibG9jay5cbiAqIEBwYXJhbSB0cmlnZ2VySW5kZXggSW5kZXggYXQgd2hpY2ggdG8gZmluZCB0aGUgdHJpZ2dlciBlbGVtZW50LlxuICogQHBhcmFtIHdhbGtVcFRpbWVzIE51bWJlciBvZiB0aW1lcyB0byBnbyB1cC9kb3duIGluIHRoZSB2aWV3IGhpZXJhcmNoeSB0byBmaW5kIHRoZSB0cmlnZ2VyLlxuICogQHBhcmFtIHJlZ2lzdGVyRm4gRnVuY3Rpb24gdGhhdCB3aWxsIHJlZ2lzdGVyIHRoZSBET00gZXZlbnRzLlxuICogQHBhcmFtIGNhbGxiYWNrIENhbGxiYWNrIHRvIGJlIGludm9rZWQgd2hlbiB0aGUgdHJpZ2dlciByZWNlaXZlcyB0aGUgZXZlbnQgdGhhdCBzaG91bGQgcmVuZGVyXG4gKiAgICAgdGhlIGRlZmVycmVkIGJsb2NrLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJEb21UcmlnZ2VyKFxuICAgIGluaXRpYWxMVmlldzogTFZpZXcsIHROb2RlOiBUTm9kZSwgdHJpZ2dlckluZGV4OiBudW1iZXIsIHdhbGtVcFRpbWVzOiBudW1iZXJ8dW5kZWZpbmVkLFxuICAgIHJlZ2lzdGVyRm46IChlbGVtZW50OiBFbGVtZW50LCBjYWxsYmFjazogVm9pZEZ1bmN0aW9uLCBpbmplY3RvcjogSW5qZWN0b3IpID0+IFZvaWRGdW5jdGlvbixcbiAgICBjYWxsYmFjazogVm9pZEZ1bmN0aW9uKSB7XG4gIGNvbnN0IGluamVjdG9yID0gaW5pdGlhbExWaWV3W0lOSkVDVE9SXSE7XG4gIGZ1bmN0aW9uIHBvbGxEb21UcmlnZ2VyKCkge1xuICAgIC8vIElmIHRoZSBpbml0aWFsIHZpZXcgd2FzIGRlc3Ryb3llZCwgd2UgZG9uJ3QgbmVlZCB0byBkbyBhbnl0aGluZy5cbiAgICBpZiAoaXNEZXN0cm95ZWQoaW5pdGlhbExWaWV3KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGxEZXRhaWxzID0gZ2V0TERlZmVyQmxvY2tEZXRhaWxzKGluaXRpYWxMVmlldywgdE5vZGUpO1xuICAgIGNvbnN0IHJlbmRlcmVkU3RhdGUgPSBsRGV0YWlsc1tERUZFUl9CTE9DS19TVEFURV07XG5cbiAgICAvLyBJZiB0aGUgYmxvY2sgd2FzIGxvYWRlZCBiZWZvcmUgdGhlIHRyaWdnZXIgd2FzIHJlc29sdmVkLCB3ZSBkb24ndCBuZWVkIHRvIGRvIGFueXRoaW5nLlxuICAgIGlmIChyZW5kZXJlZFN0YXRlICE9PSBEZWZlckJsb2NrSW50ZXJuYWxTdGF0ZS5Jbml0aWFsICYmXG4gICAgICAgIHJlbmRlcmVkU3RhdGUgIT09IERlZmVyQmxvY2tTdGF0ZS5QbGFjZWhvbGRlcikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHRyaWdnZXJMVmlldyA9IGdldFRyaWdnZXJMVmlldyhpbml0aWFsTFZpZXcsIHROb2RlLCB3YWxrVXBUaW1lcyk7XG5cbiAgICAvLyBLZWVwIHBvbGxpbmcgdW50aWwgd2UgcmVzb2x2ZSB0aGUgdHJpZ2dlcidzIExWaWV3LlxuICAgIGlmICghdHJpZ2dlckxWaWV3KSB7XG4gICAgICBpbnRlcm5hbEFmdGVyTmV4dFJlbmRlcihwb2xsRG9tVHJpZ2dlciwge2luamVjdG9yfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gSXQncyBwb3NzaWJsZSB0aGF0IHRoZSB0cmlnZ2VyJ3MgdmlldyB3YXMgZGVzdHJveWVkIGJlZm9yZSB3ZSByZXNvbHZlZCB0aGUgdHJpZ2dlciBlbGVtZW50LlxuICAgIGlmIChpc0Rlc3Ryb3llZCh0cmlnZ2VyTFZpZXcpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gVE9ETzogYWRkIGludGVncmF0aW9uIHdpdGggYERlZmVyQmxvY2tDbGVhbnVwTWFuYWdlcmAuXG4gICAgY29uc3QgZWxlbWVudCA9IGdldFRyaWdnZXJFbGVtZW50KHRyaWdnZXJMVmlldywgdHJpZ2dlckluZGV4KTtcbiAgICBjb25zdCBjbGVhbnVwID0gcmVnaXN0ZXJGbihlbGVtZW50LCAoKSA9PiB7XG4gICAgICBjYWxsYmFjaygpO1xuICAgICAgcmVtb3ZlTFZpZXdPbkRlc3Ryb3kodHJpZ2dlckxWaWV3LCBjbGVhbnVwKTtcbiAgICAgIGlmIChpbml0aWFsTFZpZXcgIT09IHRyaWdnZXJMVmlldykge1xuICAgICAgICByZW1vdmVMVmlld09uRGVzdHJveShpbml0aWFsTFZpZXcsIGNsZWFudXApO1xuICAgICAgfVxuICAgICAgY2xlYW51cCgpO1xuICAgIH0sIGluamVjdG9yKTtcblxuICAgIHN0b3JlTFZpZXdPbkRlc3Ryb3kodHJpZ2dlckxWaWV3LCBjbGVhbnVwKTtcblxuICAgIC8vIFNpbmNlIHRoZSB0cmlnZ2VyIGFuZCBkZWZlcnJlZCBibG9jayBtaWdodCBiZSBpbiBkaWZmZXJlbnRcbiAgICAvLyB2aWV3cywgd2UgaGF2ZSB0byByZWdpc3RlciB0aGUgY2FsbGJhY2sgaW4gYm90aCBsb2NhdGlvbnMuXG4gICAgaWYgKGluaXRpYWxMVmlldyAhPT0gdHJpZ2dlckxWaWV3KSB7XG4gICAgICBzdG9yZUxWaWV3T25EZXN0cm95KGluaXRpYWxMVmlldywgY2xlYW51cCk7XG4gICAgfVxuICB9XG5cbiAgLy8gQmVnaW4gcG9sbGluZyBmb3IgdGhlIHRyaWdnZXIuXG4gIGludGVybmFsQWZ0ZXJOZXh0UmVuZGVyKHBvbGxEb21UcmlnZ2VyLCB7aW5qZWN0b3J9KTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
8
|
+
import { inject, ɵɵdefineInjectable } from '../di';
|
|
9
|
+
import { INJECTOR } from '../render3/interfaces/view';
|
|
10
|
+
import { NgZone } from '../zone';
|
|
11
|
+
import { wrapWithLViewCleanup } from './utils';
|
|
12
|
+
/**
|
|
13
|
+
* Helper function to schedule a callback to be invoked when a browser becomes idle.
|
|
14
|
+
*
|
|
15
|
+
* @param callback A function to be invoked when a browser becomes idle.
|
|
16
|
+
* @param lView LView that hosts an instance of a defer block.
|
|
17
|
+
* @param withLViewCleanup A flag that indicates whether a scheduled callback
|
|
18
|
+
* should be cancelled in case an LView is destroyed before a callback
|
|
19
|
+
* was invoked.
|
|
20
|
+
*/
|
|
21
|
+
export function onIdle(callback, lView, withLViewCleanup) {
|
|
22
|
+
const injector = lView[INJECTOR];
|
|
23
|
+
const scheduler = injector.get(IdleScheduler);
|
|
24
|
+
const cleanupFn = () => scheduler.remove(callback);
|
|
25
|
+
const wrappedCallback = withLViewCleanup ? wrapWithLViewCleanup(callback, lView, cleanupFn) : callback;
|
|
26
|
+
scheduler.add(wrappedCallback);
|
|
27
|
+
return cleanupFn;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Use shims for the `requestIdleCallback` and `cancelIdleCallback` functions for
|
|
31
|
+
* environments where those functions are not available (e.g. Node.js and Safari).
|
|
32
|
+
*
|
|
33
|
+
* Note: we wrap the `requestIdleCallback` call into a function, so that it can be
|
|
34
|
+
* overridden/mocked in test environment and picked up by the runtime code.
|
|
35
|
+
*/
|
|
36
|
+
const _requestIdleCallback = () => typeof requestIdleCallback !== 'undefined' ? requestIdleCallback : setTimeout;
|
|
37
|
+
const _cancelIdleCallback = () => typeof requestIdleCallback !== 'undefined' ? cancelIdleCallback : clearTimeout;
|
|
38
|
+
/**
|
|
39
|
+
* Helper service to schedule `requestIdleCallback`s for batches of defer blocks,
|
|
40
|
+
* to avoid calling `requestIdleCallback` for each defer block (e.g. if
|
|
41
|
+
* defer blocks are defined inside a for loop).
|
|
42
|
+
*/
|
|
43
|
+
export class IdleScheduler {
|
|
44
|
+
constructor() {
|
|
45
|
+
// Indicates whether current callbacks are being invoked.
|
|
46
|
+
this.executingCallbacks = false;
|
|
47
|
+
// Currently scheduled idle callback id.
|
|
48
|
+
this.idleId = null;
|
|
49
|
+
// Set of callbacks to be invoked next.
|
|
50
|
+
this.current = new Set();
|
|
51
|
+
// Set of callbacks collected while invoking current set of callbacks.
|
|
52
|
+
// Those callbacks are scheduled for the next idle period.
|
|
53
|
+
this.deferred = new Set();
|
|
54
|
+
this.ngZone = inject(NgZone);
|
|
55
|
+
this.requestIdleCallback = _requestIdleCallback().bind(globalThis);
|
|
56
|
+
this.cancelIdleCallback = _cancelIdleCallback().bind(globalThis);
|
|
57
|
+
}
|
|
58
|
+
add(callback) {
|
|
59
|
+
const target = this.executingCallbacks ? this.deferred : this.current;
|
|
60
|
+
target.add(callback);
|
|
61
|
+
if (this.idleId === null) {
|
|
62
|
+
this.scheduleIdleCallback();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
remove(callback) {
|
|
66
|
+
this.current.delete(callback);
|
|
67
|
+
this.deferred.delete(callback);
|
|
68
|
+
}
|
|
69
|
+
scheduleIdleCallback() {
|
|
70
|
+
const callback = () => {
|
|
71
|
+
this.cancelIdleCallback(this.idleId);
|
|
72
|
+
this.idleId = null;
|
|
73
|
+
this.executingCallbacks = true;
|
|
74
|
+
for (const callback of this.current) {
|
|
75
|
+
callback();
|
|
76
|
+
}
|
|
77
|
+
this.current.clear();
|
|
78
|
+
this.executingCallbacks = false;
|
|
79
|
+
// If there are any callbacks added during an invocation
|
|
80
|
+
// of the current ones - make them "current" and schedule
|
|
81
|
+
// a new idle callback.
|
|
82
|
+
if (this.deferred.size > 0) {
|
|
83
|
+
for (const callback of this.deferred) {
|
|
84
|
+
this.current.add(callback);
|
|
85
|
+
}
|
|
86
|
+
this.deferred.clear();
|
|
87
|
+
this.scheduleIdleCallback();
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
// Ensure that the callback runs in the NgZone since
|
|
91
|
+
// the `requestIdleCallback` is not currently patched by Zone.js.
|
|
92
|
+
this.idleId = this.requestIdleCallback(() => this.ngZone.run(callback));
|
|
93
|
+
}
|
|
94
|
+
ngOnDestroy() {
|
|
95
|
+
if (this.idleId !== null) {
|
|
96
|
+
this.cancelIdleCallback(this.idleId);
|
|
97
|
+
this.idleId = null;
|
|
98
|
+
}
|
|
99
|
+
this.current.clear();
|
|
100
|
+
this.deferred.clear();
|
|
101
|
+
}
|
|
102
|
+
/** @nocollapse */
|
|
103
|
+
static { this.ɵprov = ɵɵdefineInjectable({
|
|
104
|
+
token: IdleScheduler,
|
|
105
|
+
providedIn: 'root',
|
|
106
|
+
factory: () => new IdleScheduler(),
|
|
107
|
+
}); }
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWRsZV9zY2hlZHVsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9kZWZlci9pZGxlX3NjaGVkdWxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSCxPQUFPLEVBQUMsTUFBTSxFQUFFLGtCQUFrQixFQUFDLE1BQU0sT0FBTyxDQUFDO0FBQ2pELE9BQU8sRUFBQyxRQUFRLEVBQVEsTUFBTSw0QkFBNEIsQ0FBQztBQUMzRCxPQUFPLEVBQUMsTUFBTSxFQUFDLE1BQU0sU0FBUyxDQUFDO0FBRS9CLE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLFNBQVMsQ0FBQztBQUU3Qzs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sVUFBVSxNQUFNLENBQUMsUUFBc0IsRUFBRSxLQUFZLEVBQUUsZ0JBQXlCO0lBQ3BGLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUUsQ0FBQztJQUNsQyxNQUFNLFNBQVMsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQzlDLE1BQU0sU0FBUyxHQUFHLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDbkQsTUFBTSxlQUFlLEdBQ2pCLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLEVBQUUsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7SUFDbkYsU0FBUyxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUMvQixPQUFPLFNBQVMsQ0FBQztBQUNuQixDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxvQkFBb0IsR0FBRyxHQUFHLEVBQUUsQ0FDOUIsT0FBTyxtQkFBbUIsS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUM7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Q0FBQztTQUNwQjtRQUNELElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDckIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBRUQsa0JBQWtCO2FBQ1gsVUFBSyxHQUE2QixrQkFBa0IsQ0FBQztRQUMxRCxLQUFLLEVBQUUsYUFBYTtRQUNwQixVQUFVLEVBQUUsTUFBTTtRQUNsQixPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxhQUFhLEVBQUU7S0FDbkMsQ0FBQyxBQUpVLENBSVQiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHtpbmplY3QsIMm1ybVkZWZpbmVJbmplY3RhYmxlfSBmcm9tICcuLi9kaSc7XG5pbXBvcnQge0lOSkVDVE9SLCBMVmlld30gZnJvbSAnLi4vcmVuZGVyMy9pbnRlcmZhY2VzL3ZpZXcnO1xuaW1wb3J0IHtOZ1pvbmV9IGZyb20gJy4uL3pvbmUnO1xuXG5pbXBvcnQge3dyYXBXaXRoTFZpZXdDbGVhbnVwfSBmcm9tICcuL3V0aWxzJztcblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gc2NoZWR1bGUgYSBjYWxsYmFjayB0byBiZSBpbnZva2VkIHdoZW4gYSBicm93c2VyIGJlY29tZXMgaWRsZS5cbiAqXG4gKiBAcGFyYW0gY2FsbGJhY2sgQSBmdW5jdGlvbiB0byBiZSBpbnZva2VkIHdoZW4gYSBicm93c2VyIGJlY29tZXMgaWRsZS5cbiAqIEBwYXJhbSBsVmlldyBMVmlldyB0aGF0IGhvc3RzIGFuIGluc3RhbmNlIG9mIGEgZGVmZXIgYmxvY2suXG4gKiBAcGFyYW0gd2l0aExWaWV3Q2xlYW51cCBBIGZsYWcgdGhhdCBpbmRpY2F0ZXMgd2hldGhlciBhIHNjaGVkdWxlZCBjYWxsYmFja1xuICogICAgICAgICAgIHNob3VsZCBiZSBjYW5jZWxsZWQgaW4gY2FzZSBhbiBMVmlldyBpcyBkZXN0cm95ZWQgYmVmb3JlIGEgY2FsbGJhY2tcbiAqICAgICAgICAgICB3YXMgaW52b2tlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uSWRsZShjYWxsYmFjazogVm9pZEZ1bmN0aW9uLCBsVmlldzogTFZpZXcsIHdpdGhMVmlld0NsZWFudXA6IGJvb2xlYW4pIHtcbiAgY29uc3QgaW5qZWN0b3IgPSBsVmlld1tJTkpFQ1RPUl0hO1xuICBjb25zdCBzY2hlZHVsZXIgPSBpbmplY3Rvci5nZXQoSWRsZVNjaGVkdWxlcik7XG4gIGNvbnN0IGNsZWFudXBGbiA9ICgpID0+IHNjaGVkdWxlci5yZW1vdmUoY2FsbGJhY2spO1xuICBjb25zdCB3cmFwcGVkQ2FsbGJhY2sgPVxuICAgICAgd2l0aExWaWV3Q2xlYW51cCA/IHdyYXBXaXRoTFZpZXdDbGVhbnVwKGNhbGxiYWNrLCBsVmlldywgY2xlYW51cEZuKSA6IGNhbGxiYWNrO1xuICBzY2hlZHVsZXIuYWRkKHdyYXBwZWRDYWxsYmFjayk7XG4gIHJldHVybiBjbGVhbnVwRm47XG59XG5cbi8qKlxuICogVXNlIHNoaW1zIGZvciB0aGUgYHJlcXVlc3RJZGxlQ2FsbGJhY2tgIGFuZCBgY2FuY2VsSWRsZUNhbGxiYWNrYCBmdW5jdGlvbnMgZm9yXG4gKiBlbnZpcm9ubWVudHMgd2hlcmUgdGhvc2UgZnVuY3Rpb25zIGFyZSBub3QgYXZhaWxhYmxlIChlLmcuIE5vZGUuanMgYW5kIFNhZmFyaSkuXG4gKlxuICogTm90ZTogd2Ugd3JhcCB0aGUgYHJlcXVlc3RJZGxlQ2FsbGJhY2tgIGNhbGwgaW50byBhIGZ1bmN0aW9uLCBzbyB0aGF0IGl0IGNhbiBiZVxuICogb3ZlcnJpZGRlbi9tb2NrZWQgaW4gdGVzdCBlbnZpcm9ubWVudCBhbmQgcGlja2VkIHVwIGJ5IHRoZSBydW50aW1lIGNvZGUuXG4gKi9cbmNvbnN0IF9yZXF1ZXN0SWRsZUNhbGxiYWNrID0gKCkgPT5cbiAgICB0eXBlb2YgcmVxdWVzdElkbGVDYWxsYmFjayAhPT0gJ3VuZGVmaW5lZCcgPyByZXF1ZXN0SWRsZUNhbGxiYWNrIDogc2V0VGltZW91dDtcbmNvbnN0IF9jYW5jZWxJZGxlQ2FsbGJhY2sgPSAoKSA9PlxuICAgIHR5cGVvZiByZXF1ZXN0SWRsZUNhbGxiYWNrICE9PSAndW5kZWZpbmVkJyA/IGNhbmNlbElkbGVDYWxsYmFjayA6IGNsZWFyVGltZW91dDtcblxuLyoqXG4gKiBIZWxwZXIgc2VydmljZSB0byBzY2hlZHVsZSBgcmVxdWVzdElkbGVDYWxsYmFja2BzIGZvciBiYXRjaGVzIG9mIGRlZmVyIGJsb2NrcyxcbiAqIHRvIGF2b2lkIGNhbGxpbmcgYHJlcXVlc3RJZGxlQ2FsbGJhY2tgIGZvciBlYWNoIGRlZmVyIGJsb2NrIChlLmcuIGlmXG4gKiBkZWZlciBibG9ja3MgYXJlIGRlZmluZWQgaW5zaWRlIGEgZm9yIGxvb3ApLlxuICovXG5leHBvcnQgY2xhc3MgSWRsZVNjaGVkdWxlciB7XG4gIC8vIEluZGljYXRlcyB3aGV0aGVyIGN1cnJlbnQgY2FsbGJhY2tzIGFyZSBiZWluZyBpbnZva2VkLlxuICBleGVjdXRpbmdDYWxsYmFja3MgPSBmYWxzZTtcblxuICAvLyBDdXJyZW50bHkgc2NoZWR1bGVkIGlkbGUgY2FsbGJhY2sgaWQuXG4gIGlkbGVJZDogbnVtYmVyfG51bGwgPSBudWxsO1xuXG4gIC8vIFNldCBvZiBjYWxsYmFja3MgdG8gYmUgaW52b2tlZCBuZXh0LlxuICBjdXJyZW50ID0gbmV3IFNldDxWb2lkRnVuY3Rpb24+KCk7XG5cbiAgLy8gU2V0IG9mIGNhbGxiYWNrcyBjb2xsZWN0ZWQgd2hpbGUgaW52b2tpbmcgY3VycmVudCBzZXQgb2YgY2FsbGJhY2tzLlxuICAvLyBUaG9zZSBjYWxsYmFja3MgYXJlIHNjaGVkdWxlZCBmb3IgdGhlIG5leHQgaWRsZSBwZXJpb2QuXG4gIGRlZmVycmVkID0gbmV3IFNldDxWb2lkRnVuY3Rpb24+KCk7XG5cbiAgbmdab25lID0gaW5qZWN0KE5nWm9uZSk7XG5cbiAgcmVxdWVzdElkbGVDYWxsYmFjayA9IF9yZXF1ZXN0SWRsZUNhbGxiYWNrKCkuYmluZChnbG9iYWxUaGlzKTtcbiAgY2FuY2VsSWRsZUNhbGxiYWNrID0gX2NhbmNlbElkbGVDYWxsYmFjaygpLmJpbmQoZ2xvYmFsVGhpcyk7XG5cbiAgYWRkKGNhbGxiYWNrOiBWb2lkRnVuY3Rpb24pIHtcbiAgICBjb25zdCB0YXJnZXQgPSB0aGlzLmV4ZWN1dGluZ0NhbGxiYWNrcyA/IHRoaXMuZGVmZXJyZWQgOiB0aGlzLmN1cnJlbnQ7XG4gICAgdGFyZ2V0LmFkZChjYWxsYmFjayk7XG4gICAgaWYgKHRoaXMuaWRsZUlkID09PSBudWxsKSB7XG4gICAgICB0aGlzLnNjaGVkdWxlSWRsZUNhbGxiYWNrKCk7XG4gICAgfVxuICB9XG5cbiAgcmVtb3ZlKGNhbGxiYWNrOiBWb2lkRnVuY3Rpb24pIHtcbiAgICB0aGlzLmN1cnJlbnQuZGVsZXRlKGNhbGxiYWNrKTtcbiAgICB0aGlzLmRlZmVycmVkLmRlbGV0ZShjYWxsYmFjayk7XG4gIH1cblxuICBwcml2YXRlIHNjaGVkdWxlSWRsZUNhbGxiYWNrKCkge1xuICAgIGNvbnN0IGNhbGxiYWNrID0gKCkgPT4ge1xuICAgICAgdGhpcy5jYW5jZWxJZGxlQ2FsbGJhY2sodGhpcy5pZGxlSWQhKTtcbiAgICAgIHRoaXMuaWRsZUlkID0gbnVsbDtcblxuICAgICAgdGhpcy5leGVjdXRpbmdDYWxsYmFja3MgPSB0cnVlO1xuXG4gICAgICBmb3IgKGNvbnN0IGNhbGxiYWNrIG9mIHRoaXMuY3VycmVudCkge1xuICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgfVxuICAgICAgdGhpcy5jdXJyZW50LmNsZWFyKCk7XG5cbiAgICAgIHRoaXMuZXhlY3V0aW5nQ2FsbGJhY2tzID0gZmFsc2U7XG5cbiAgICAgIC8vIElmIHRoZXJlIGFyZSBhbnkgY2FsbGJhY2tzIGFkZGVkIGR1cmluZyBhbiBpbnZvY2F0aW9uXG4gICAgICAvLyBvZiB0aGUgY3VycmVudCBvbmVzIC0gbWFrZSB0aGVtIFwiY3VycmVudFwiIGFuZCBzY2hlZHVsZVxuICAgICAgLy8gYSBuZXcgaWRsZSBjYWxsYmFjay5cbiAgICAgIGlmICh0aGlzLmRlZmVycmVkLnNpemUgPiAwKSB7XG4gICAgICAgIGZvciAoY29uc3QgY2FsbGJhY2sgb2YgdGhpcy5kZWZlcnJlZCkge1xuICAgICAgICAgIHRoaXMuY3VycmVudC5hZGQoY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZGVmZXJyZWQuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5zY2hlZHVsZUlkbGVDYWxsYmFjaygpO1xuICAgICAgfVxuICAgIH07XG4gICAgLy8gRW5zdXJlIHRoYXQgdGhlIGNhbGxiYWNrIHJ1bnMgaW4gdGhlIE5nWm9uZSBzaW5jZVxuICAgIC8vIHRoZSBgcmVxdWVzdElkbGVDYWxsYmFja2AgaXMgbm90IGN1cnJlbnRseSBwYXRjaGVkIGJ5IFpvbmUuanMuXG4gICAgdGhpcy5pZGxlSWQgPSB0aGlzLnJlcXVlc3RJZGxlQ2FsbGJhY2soKCkgPT4gdGhpcy5uZ1pvbmUucnVuKGNhbGxiYWNrKSkgYXMgbnVtYmVyO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgaWYgKHRoaXMuaWRsZUlkICE9PSBudWxsKSB7XG4gICAgICB0aGlzLmNhbmNlbElkbGVDYWxsYmFjayh0aGlzLmlkbGVJZCk7XG4gICAgICB0aGlzLmlkbGVJZCA9IG51bGw7XG4gICAgfVxuICAgIHRoaXMuY3VycmVudC5jbGVhcigpO1xuICAgIHRoaXMuZGVmZXJyZWQuY2xlYXIoKTtcbiAgfVxuXG4gIC8qKiBAbm9jb2xsYXBzZSAqL1xuICBzdGF0aWMgybVwcm92ID0gLyoqIEBwdXJlT3JCcmVha015Q29kZSAqLyDJtcm1ZGVmaW5lSW5qZWN0YWJsZSh7XG4gICAgdG9rZW46IElkbGVTY2hlZHVsZXIsXG4gICAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxuICAgIGZhY3Rvcnk6ICgpID0+IG5ldyBJZGxlU2NoZWR1bGVyKCksXG4gIH0pO1xufVxuIl19
|