@sapui5/sap.fe.base 1.132.0 → 1.133.1
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/package.json +1 -1
- package/src/sap/fe/base/.library +1 -1
- package/src/sap/fe/base/BindingToolkit.js +11 -6
- package/src/sap/fe/base/BindingToolkit.ts +10 -3
- package/src/sap/fe/base/BuildingBlockBase.js +2 -4
- package/src/sap/fe/base/BuildingBlockBase.ts +1 -1
- package/src/sap/fe/base/ClassSupport.js +83 -49
- package/src/sap/fe/base/ClassSupport.ts +110 -56
- package/src/sap/fe/base/HookSupport.js +41 -10
- package/src/sap/fe/base/HookSupport.ts +52 -14
- package/src/sap/fe/base/jsx-runtime/jsx-control.js +95 -34
- package/src/sap/fe/base/jsx-runtime/jsx-control.ts +112 -29
- package/src/sap/fe/base/library.js +1 -1
|
@@ -2,7 +2,7 @@ import ObjectPath from "sap/base/util/ObjectPath";
|
|
|
2
2
|
import deepClone from "sap/base/util/deepClone";
|
|
3
3
|
import merge from "sap/base/util/merge";
|
|
4
4
|
import uid from "sap/base/util/uid";
|
|
5
|
-
import { hookable } from "sap/fe/base/HookSupport";
|
|
5
|
+
import { hookable, propagateHookFromMixin } from "sap/fe/base/HookSupport";
|
|
6
6
|
import type { Ref } from "sap/fe/base/jsx-runtime/jsx";
|
|
7
7
|
import type UI5Event from "sap/ui/base/Event";
|
|
8
8
|
import type ManagedObject from "sap/ui/base/ManagedObject";
|
|
@@ -34,7 +34,7 @@ type UI5PropertyMetadata = {
|
|
|
34
34
|
defaultValue?: unknown;
|
|
35
35
|
byValue?: boolean;
|
|
36
36
|
isBindingInfo?: boolean;
|
|
37
|
-
bindToState?:
|
|
37
|
+
bindToState?: boolean;
|
|
38
38
|
expectedAnnotations?: string[];
|
|
39
39
|
expectedTypes?: string[];
|
|
40
40
|
allowedValues?: string[];
|
|
@@ -529,20 +529,14 @@ export function mixin<T extends IInterfaceWithMixin>(interfaceClass: Constructor
|
|
|
529
529
|
throw new Error("The mixinInterface decorator must be placed after `defineUi5Class`");
|
|
530
530
|
}
|
|
531
531
|
const metadata = ensureMetadata(baseCtor.prototype);
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
532
|
+
|
|
533
|
+
let interfaceProtoTypeToMix = interfaceClass.prototype;
|
|
534
|
+
while (interfaceProtoTypeToMix) {
|
|
535
|
+
baseCtor = _addInterfaceProtoTypesToBaseClass(baseCtor, metadata, interfaceProtoTypeToMix);
|
|
536
|
+
interfaceProtoTypeToMix = Object.getPrototypeOf(interfaceProtoTypeToMix);
|
|
535
537
|
}
|
|
538
|
+
propagateHookFromMixin(baseCtor, interfaceClass);
|
|
536
539
|
|
|
537
|
-
Object.getOwnPropertyNames(interfaceClass.prototype).forEach((name) => {
|
|
538
|
-
if (name !== "constructor" && name !== "setupMixin") {
|
|
539
|
-
Object.defineProperty(
|
|
540
|
-
baseCtor.prototype,
|
|
541
|
-
name,
|
|
542
|
-
Object.getOwnPropertyDescriptor(interfaceClass.prototype, name) || Object.create(null)
|
|
543
|
-
);
|
|
544
|
-
}
|
|
545
|
-
});
|
|
546
540
|
// Hook to add potentially more logic to the mixin
|
|
547
541
|
interfaceClass.prototype.setupMixin?.(baseCtor);
|
|
548
542
|
return baseCtor;
|
|
@@ -594,6 +588,34 @@ export function defineReference(): PropertyDecorator {
|
|
|
594
588
|
} as unknown as PropertyDecorator; // This is technically an accessor decorator, but somehow the compiler doesn't like it if i declare it as such.;
|
|
595
589
|
}
|
|
596
590
|
|
|
591
|
+
function _addInterfaceProtoTypesToBaseClass(
|
|
592
|
+
baseCtor: UI5ControlAndMore,
|
|
593
|
+
baseClassMetadata: UI5ControlMetadataDefinition,
|
|
594
|
+
interfaceClassPrototype: Function["prototype"]
|
|
595
|
+
): UI5ControlAndMore {
|
|
596
|
+
const interfaceName = interfaceClassPrototype?.getInterfaceName?.();
|
|
597
|
+
if (interfaceName) {
|
|
598
|
+
baseClassMetadata.interfaces.push(interfaceName);
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
Object.getOwnPropertyNames(interfaceClassPrototype).forEach((name) => {
|
|
602
|
+
if (name !== "constructor" && name !== "setupMixin" && name !== "metadata") {
|
|
603
|
+
if (!baseCtor.prototype[name]) {
|
|
604
|
+
// The base class "wins" over the mixin
|
|
605
|
+
Object.defineProperty(
|
|
606
|
+
baseCtor.prototype,
|
|
607
|
+
name,
|
|
608
|
+
Object.getOwnPropertyDescriptor(interfaceClassPrototype, name) || Object.create(null)
|
|
609
|
+
);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
if (name === "metadata") {
|
|
613
|
+
baseCtor.prototype.metadata = merge(baseCtor.prototype.metadata, interfaceClassPrototype.metadata);
|
|
614
|
+
}
|
|
615
|
+
});
|
|
616
|
+
return baseCtor;
|
|
617
|
+
}
|
|
618
|
+
|
|
597
619
|
function _getHandlerForStateProperty(jsonModel: JSONModel, prop: string): unknown {
|
|
598
620
|
const pathInModel = `/${prop.toString()}`;
|
|
599
621
|
const oObj = deepClone(jsonModel.getObject(pathInModel));
|
|
@@ -635,10 +657,68 @@ function _getHandlerForStateProperty(jsonModel: JSONModel, prop: string): unknow
|
|
|
635
657
|
}
|
|
636
658
|
return oTarget;
|
|
637
659
|
}
|
|
660
|
+
const boundProperties = Symbol("boundProperties");
|
|
661
|
+
|
|
662
|
+
function createStateProxy(
|
|
663
|
+
targetControl: Control & {
|
|
664
|
+
[boundProperties]: string[];
|
|
665
|
+
__stateCreated: boolean;
|
|
666
|
+
_updateState: Function;
|
|
667
|
+
_updateStateDebounced: Function;
|
|
668
|
+
_ignoreStatePropertyUpdate: boolean;
|
|
669
|
+
_updateStateTimer: unknown;
|
|
670
|
+
_changedProps?: string[];
|
|
671
|
+
},
|
|
672
|
+
statePropertyName: string,
|
|
673
|
+
boundToStateProps: string[],
|
|
674
|
+
initialData?: object
|
|
675
|
+
): JSONModel {
|
|
676
|
+
// Lazy initialization of the state property
|
|
677
|
+
targetControl.setModel(new JSONModel(initialData), "$componentState");
|
|
678
|
+
const stateModel = targetControl.getModel("$componentState") as JSONModel;
|
|
679
|
+
stateModel.attachPropertyChange((evt: Model$PropertyChangeEvent) => {
|
|
680
|
+
const path = evt.getParameter("path")?.substring(1); // to remove the first /
|
|
681
|
+
if (path && boundToStateProps.includes(path)) {
|
|
682
|
+
targetControl.setProperty(path, evt.getParameter("value"));
|
|
683
|
+
}
|
|
684
|
+
});
|
|
685
|
+
targetControl.__stateCreated = true;
|
|
686
|
+
const proxy = new Proxy(stateModel, {
|
|
687
|
+
get: (target: JSONModel, prop: string): unknown => {
|
|
688
|
+
return _getHandlerForStateProperty(target, prop);
|
|
689
|
+
},
|
|
690
|
+
set: (setStateModel: JSONModel, prop, value): boolean => {
|
|
691
|
+
// we need to check whether the property is a known bound property in any of the related classes
|
|
692
|
+
const knownBoundProperties = targetControl[boundProperties];
|
|
693
|
+
if (knownBoundProperties.includes(prop.toString())) {
|
|
694
|
+
targetControl._ignoreStatePropertyUpdate = true;
|
|
695
|
+
targetControl.setProperty(prop.toString(), value);
|
|
696
|
+
targetControl._ignoreStatePropertyUpdate = false;
|
|
697
|
+
}
|
|
698
|
+
const setResult = setStateModel.setProperty(`/${prop.toString()}`, value);
|
|
699
|
+
targetControl._updateStateDebounced(prop.toString());
|
|
700
|
+
return setResult;
|
|
701
|
+
}
|
|
702
|
+
});
|
|
703
|
+
Object.defineProperty(targetControl, statePropertyName, {
|
|
704
|
+
configurable: true,
|
|
705
|
+
get: () => {
|
|
706
|
+
return proxy;
|
|
707
|
+
},
|
|
708
|
+
set(value) {
|
|
709
|
+
// Replacing the complete state
|
|
710
|
+
stateModel.setProperty(`/`, value);
|
|
711
|
+
}
|
|
712
|
+
});
|
|
713
|
+
return proxy;
|
|
714
|
+
}
|
|
638
715
|
|
|
639
716
|
function _createStateProperty(
|
|
640
717
|
obj: UI5ControlDefinition,
|
|
641
718
|
targetControl: Control & {
|
|
719
|
+
[boundProperties]: string[];
|
|
720
|
+
__stateCreated: boolean;
|
|
721
|
+
__stateName: string;
|
|
642
722
|
_updateState: Function;
|
|
643
723
|
_updateStateDebounced: Function;
|
|
644
724
|
_ignoreStatePropertyUpdate: boolean;
|
|
@@ -646,12 +726,7 @@ function _createStateProperty(
|
|
|
646
726
|
_changedProps?: string[];
|
|
647
727
|
}
|
|
648
728
|
): void {
|
|
649
|
-
if (obj.metadata?.stateProperty ||
|
|
650
|
-
if (obj.metadata?.stateProperty) {
|
|
651
|
-
targetControl.setModel(new JSONModel(), "$componentState");
|
|
652
|
-
}
|
|
653
|
-
const stateModel = targetControl.getModel("$componentState") as JSONModel;
|
|
654
|
-
|
|
729
|
+
if (obj.metadata?.stateProperty || targetControl[boundProperties]) {
|
|
655
730
|
let updatingState = false;
|
|
656
731
|
const boundToStateProps: string[] = [];
|
|
657
732
|
for (const propertyName in obj.metadata?.properties) {
|
|
@@ -661,15 +736,9 @@ function _createStateProperty(
|
|
|
661
736
|
}
|
|
662
737
|
}
|
|
663
738
|
// as we may have bound properties in parent classes and subclasses, we keep track of those in the model itself
|
|
664
|
-
|
|
665
|
-
|
|
739
|
+
targetControl[boundProperties] ??= [];
|
|
740
|
+
targetControl[boundProperties] = [...targetControl[boundProperties], ...boundToStateProps];
|
|
666
741
|
|
|
667
|
-
stateModel.attachPropertyChange((evt: Model$PropertyChangeEvent) => {
|
|
668
|
-
const path = evt.getParameter("path")?.substring(1); // to remove the first /
|
|
669
|
-
if (path && boundToStateProps.includes(path)) {
|
|
670
|
-
targetControl.setProperty(path, evt.getParameter("value"));
|
|
671
|
-
}
|
|
672
|
-
});
|
|
673
742
|
if (obj.metadata?.stateProperty) {
|
|
674
743
|
// This method can be used to force the state to be applied and wait for it to be applied in tests
|
|
675
744
|
targetControl._updateState = async function (): Promise<void> {
|
|
@@ -692,33 +761,16 @@ function _createStateProperty(
|
|
|
692
761
|
}, 200);
|
|
693
762
|
}
|
|
694
763
|
};
|
|
695
|
-
|
|
764
|
+
const statePropertyName = obj.metadata.stateProperty;
|
|
765
|
+
targetControl.__stateCreated = false;
|
|
766
|
+
targetControl.__stateName = statePropertyName;
|
|
767
|
+
Object.defineProperty(targetControl, statePropertyName, {
|
|
696
768
|
configurable: true,
|
|
697
769
|
get: () => {
|
|
698
|
-
return
|
|
699
|
-
get: (target: JSONModel, prop: string): unknown => {
|
|
700
|
-
return _getHandlerForStateProperty(target, prop);
|
|
701
|
-
},
|
|
702
|
-
set: (setStateModel: JSONModel, prop, value): boolean => {
|
|
703
|
-
// we need to check whether the property is a known bound property in any of the related classes
|
|
704
|
-
const knownBoundProperties = setStateModel.getProperty("/__boundProperties") ?? [];
|
|
705
|
-
if (knownBoundProperties.includes(prop.toString())) {
|
|
706
|
-
targetControl._ignoreStatePropertyUpdate = true;
|
|
707
|
-
targetControl.setProperty(prop.toString(), value);
|
|
708
|
-
targetControl._ignoreStatePropertyUpdate = false;
|
|
709
|
-
}
|
|
710
|
-
const setResult = setStateModel.setProperty(`/${prop.toString()}`, value);
|
|
711
|
-
targetControl._updateStateDebounced(prop.toString());
|
|
712
|
-
return setResult;
|
|
713
|
-
}
|
|
714
|
-
});
|
|
770
|
+
return createStateProxy(targetControl, statePropertyName, targetControl[boundProperties]);
|
|
715
771
|
},
|
|
716
|
-
set:
|
|
717
|
-
|
|
718
|
-
// Replacing the complete state
|
|
719
|
-
stateModel.setProperty(`/`, value);
|
|
720
|
-
// restoring the boundProperties references
|
|
721
|
-
stateModel.setProperty("/__boundProperties", knownBoundProperties);
|
|
772
|
+
set: (value) => {
|
|
773
|
+
createStateProxy(targetControl, statePropertyName, targetControl[boundProperties], value);
|
|
722
774
|
}
|
|
723
775
|
});
|
|
724
776
|
if (obj.metadata.statePropertyDefaultValue) {
|
|
@@ -731,11 +783,13 @@ function _createStateProperty(
|
|
|
731
783
|
};
|
|
732
784
|
}
|
|
733
785
|
const fnSetProperty = targetControl.setProperty;
|
|
734
|
-
|
|
735
|
-
if (boundToStateProps.length > 0) {
|
|
786
|
+
if (targetControl[boundProperties].length > 0) {
|
|
736
787
|
targetControl.setProperty = function (sPropertyName: string, oValue: unknown, bSuppressInvalidate): typeof targetControl {
|
|
737
|
-
if (
|
|
738
|
-
|
|
788
|
+
if (targetControl[boundProperties].includes(sPropertyName) && !this._ignoreStatePropertyUpdate) {
|
|
789
|
+
if (!this.__stateCreated) {
|
|
790
|
+
createStateProxy(targetControl, targetControl.__stateName, targetControl[boundProperties]);
|
|
791
|
+
}
|
|
792
|
+
(this.getModel("$componentState") as JSONModel).setProperty(`/${sPropertyName}`, oValue);
|
|
739
793
|
targetControl._updateStateDebounced(sPropertyName);
|
|
740
794
|
}
|
|
741
795
|
return fnSetProperty.call(this, sPropertyName, oValue, bSuppressInvalidate);
|
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
* SAP UI development toolkit for HTML5 (SAPUI5)
|
|
3
3
|
* (c) Copyright 2009-2024 SAP SE. All rights reserved
|
|
4
4
|
*/
|
|
5
|
-
sap.ui.define([], function () {
|
|
5
|
+
sap.ui.define(["sap/base/util/deepClone"], function (deepClone) {
|
|
6
6
|
"use strict";
|
|
7
7
|
|
|
8
8
|
var _exports = {};
|
|
9
9
|
/**
|
|
10
10
|
* This type is to be extended with all controller extensions and methods that are hookable.
|
|
11
11
|
*/
|
|
12
|
+
|
|
12
13
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
14
|
+
|
|
13
15
|
// Use two arrays as we cannot index a map through an arbitrary object instance
|
|
14
16
|
const registeredInstances = [];
|
|
15
17
|
const registeredHandlers = [];
|
|
@@ -87,6 +89,7 @@ sap.ui.define([], function () {
|
|
|
87
89
|
function isAlreadyRegistered(existingRegistrations, newRegistration) {
|
|
88
90
|
return !!existingRegistrations.find(r => r.name === newRegistration.name && r.method === newRegistration.method && r.targetMethod === newRegistration.targetMethod);
|
|
89
91
|
}
|
|
92
|
+
const hooks = Symbol("hooks");
|
|
90
93
|
|
|
91
94
|
/**
|
|
92
95
|
* Registers a method as controller extension hook handler.
|
|
@@ -96,6 +99,7 @@ sap.ui.define([], function () {
|
|
|
96
99
|
* @param method Method to hook into
|
|
97
100
|
* @returns A method decorator
|
|
98
101
|
*/
|
|
102
|
+
_exports.hooks = hooks;
|
|
99
103
|
function controllerExtensionHandler(name, method) {
|
|
100
104
|
return function (target, propertyKey) {
|
|
101
105
|
const newRegistration = {
|
|
@@ -104,7 +108,12 @@ sap.ui.define([], function () {
|
|
|
104
108
|
targetMethod: propertyKey
|
|
105
109
|
};
|
|
106
110
|
const index = registeredInstances.indexOf(target.constructor);
|
|
107
|
-
|
|
111
|
+
if (!target.constructor[hooks]) {
|
|
112
|
+
Object.defineProperty(target.constructor, hooks, {
|
|
113
|
+
value: []
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
target.constructor[hooks]?.push(newRegistration);
|
|
108
117
|
// We need to check if this exact handler is already registered as handlers are registered statically (on the constructor)
|
|
109
118
|
if (index !== -1 && !isAlreadyRegistered(registeredHandlers[index], newRegistration)) {
|
|
110
119
|
registeredHandlers[index].push(newRegistration);
|
|
@@ -123,20 +132,42 @@ sap.ui.define([], function () {
|
|
|
123
132
|
*/
|
|
124
133
|
_exports.controllerExtensionHandler = controllerExtensionHandler;
|
|
125
134
|
function initControllerExtensionHookHandlers(target, controller) {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
135
|
+
if (target.constructor[hooks]) {
|
|
136
|
+
let registeredHooks = target.constructor[hooks];
|
|
137
|
+
target[hooks] = deepClone(registeredHooks);
|
|
138
|
+
registeredHooks = target[hooks];
|
|
129
139
|
const indexableTarget = target;
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
140
|
+
const indexableController = controller;
|
|
141
|
+
for (const registeredHook of registeredHooks) {
|
|
142
|
+
registeredHook.handlerFunction = indexableTarget[registeredHook.targetMethod].bind(target);
|
|
143
|
+
indexableController[registeredHook.name][`attach${String(registeredHook.method)}`](registeredHook.handlerFunction);
|
|
133
144
|
controller.getView()?.attachBeforeExit(() => {
|
|
134
|
-
indexableController[
|
|
145
|
+
indexableController[registeredHook.name][`detach${String(registeredHook.method)}`](registeredHook.handlerFunction);
|
|
135
146
|
});
|
|
136
147
|
}
|
|
137
148
|
}
|
|
138
149
|
}
|
|
139
150
|
_exports.initControllerExtensionHookHandlers = initControllerExtensionHookHandlers;
|
|
151
|
+
function removeControllerExtensionHookHandlers(target, controller) {
|
|
152
|
+
if (target[hooks]) {
|
|
153
|
+
const registeredHooks = target[hooks];
|
|
154
|
+
const indexableController = controller;
|
|
155
|
+
for (const registeredHook of registeredHooks) {
|
|
156
|
+
indexableController[registeredHook.name]?.[`detach${String(registeredHook.method)}`]?.(registeredHook.handlerFunction);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
_exports.removeControllerExtensionHookHandlers = removeControllerExtensionHookHandlers;
|
|
161
|
+
function propagateHookFromMixin(target, source) {
|
|
162
|
+
if (source[hooks]) {
|
|
163
|
+
if (target[hooks]) {
|
|
164
|
+
target[hooks].splice(0, 0, ...source[hooks]);
|
|
165
|
+
} else {
|
|
166
|
+
Object.defineProperty(target, hooks, Object.getOwnPropertyDescriptor(source, hooks) || Object.create([]));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
_exports.propagateHookFromMixin = propagateHookFromMixin;
|
|
140
171
|
function xmlViewPreprocessor(source, _caller, _settings) {
|
|
141
172
|
const sourceView = source;
|
|
142
173
|
const controller = sourceView.getController();
|
|
@@ -150,4 +181,4 @@ sap.ui.define([], function () {
|
|
|
150
181
|
_exports.xmlViewPreprocessor = xmlViewPreprocessor;
|
|
151
182
|
return _exports;
|
|
152
183
|
}, false);
|
|
153
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJyZWdpc3RlcmVkSW5zdGFuY2VzIiwicmVnaXN0ZXJlZEhhbmRsZXJzIiwiaG9va2FibGUiLCJleGVjdXRpb24iLCJ0YXJnZXQiLCJwcm9wZXJ0eUtleSIsImRlc2NyaXB0b3IiLCJpbmRleGFibGVUYXJnZXQiLCJ0b1N0cmluZyIsImZuIiwiY0V4VEluc3RhbmNlSG9va01hcCIsImhvb2tlZEhhbmRsZXJzIiwicHVzaCIsImhhbmRsZXJzIiwiaW5kZXgiLCJpbmRleE9mIiwic3BsaWNlIiwib2xkVmFsdWUiLCJ2YWx1ZSIsInJldHVyblZhbHVlIiwiYmluZCIsImFyZ3VtZW50cyIsImhhbmRsZXIiLCJfZXhwb3J0cyIsImlzQWxyZWFkeVJlZ2lzdGVyZWQiLCJleGlzdGluZ1JlZ2lzdHJhdGlvbnMiLCJuZXdSZWdpc3RyYXRpb24iLCJmaW5kIiwiciIsIm5hbWUiLCJtZXRob2QiLCJ0YXJnZXRNZXRob2QiLCJjb250cm9sbGVyRXh0ZW5zaW9uSGFuZGxlciIsIlN0cmluZyIsImNvbnN0cnVjdG9yIiwiaW5pdENvbnRyb2xsZXJFeHRlbnNpb25Ib29rSGFuZGxlcnMiLCJjb250cm9sbGVyIiwiaW5kZXhhYmxlQ29udHJvbGxlciIsInJlZ2lzdGVyZWRIYW5kbGVyIiwiaGFuZGxlckZ1bmN0aW9uIiwiZ2V0VmlldyIsImF0dGFjaEJlZm9yZUV4aXQiLCJ4bWxWaWV3UHJlcHJvY2Vzc29yIiwic291cmNlIiwiX2NhbGxlciIsIl9zZXR0aW5ncyIsInNvdXJjZVZpZXciLCJnZXRDb250cm9sbGVyIiwibWFjcm9BUElDaGlsZCIsImZpbmRBZ2dyZWdhdGVkT2JqZWN0cyIsInMiLCJpc0EiLCJtYW5hZ2VkT2JqZWN0Il0sInNvdXJjZVJvb3QiOiIuIiwic291cmNlcyI6WyJIb29rU3VwcG9ydC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IEV4dGVuc2lvbk92ZXJyaWRlRXhlY3V0aW9uIH0gZnJvbSBcInNhcC9mZS9iYXNlL0NsYXNzU3VwcG9ydFwiO1xuaW1wb3J0IHR5cGUgQ29udHJvbGxlciBmcm9tIFwic2FwL3VpL2NvcmUvbXZjL0NvbnRyb2xsZXJcIjtcbmltcG9ydCB0eXBlIFhNTFZpZXcgZnJvbSBcInNhcC91aS9jb3JlL212Yy9YTUxWaWV3XCI7XG5cbi8qKlxuICogVGhpcyB0eXBlIGlzIHRvIGJlIGV4dGVuZGVkIHdpdGggYWxsIGNvbnRyb2xsZXIgZXh0ZW5zaW9ucyBhbmQgbWV0aG9kcyB0aGF0IGFyZSBob29rYWJsZS5cbiAqL1xudHlwZSBIb29rYWJsZUNvbnRyb2xsZXJFeHRlbnNpb25zID0ge1xuXHRlZGl0Rmxvdzoge1xuXHRcdG9uQWZ0ZXJTYXZlOiB0cnVlO1xuXHRcdG9uQmVmb3JlU2F2ZTogdHJ1ZTtcblx0fTtcblx0Y29sbGFib3JhdGlvbk1hbmFnZXI6IHtcblx0XHRjb2xsZWN0QXZhaWxhYmxlQ2FyZHM6IHRydWU7XG5cdH07XG5cdHBhZ2luYXRvcjoge1xuXHRcdGluaXRpYWxpemU6IHRydWU7XG5cdH07XG5cdHJvdXRpbmc6IHtcblx0XHRvbkFmdGVyQmluZGluZzogdHJ1ZTtcblx0fTtcbn07XG5cbnR5cGUgSGFuZGxlckNvbmZpZ3VyYXRpb248Q0V4dE5hbWUgZXh0ZW5kcyBrZXlvZiBIb29rYWJsZUNvbnRyb2xsZXJFeHRlbnNpb25zPiA9IHtcblx0bmFtZTogQ0V4dE5hbWU7XG5cdG1ldGhvZDoga2V5b2YgSG9va2FibGVDb250cm9sbGVyRXh0ZW5zaW9uc1tDRXh0TmFtZV07XG59O1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbnR5cGUgSGFuZGxlclJlZ2lzdHJhdGlvbiA9IEhhbmRsZXJDb25maWd1cmF0aW9uPGFueT4gJiB7IHRhcmdldE1ldGhvZDogc3RyaW5nIH07XG5cbnR5cGUgRnVuY3Rpb25NYXAgPSB7XG5cdFtrZXk6IHN0cmluZ106IEZ1bmN0aW9uO1xufTtcbnR5cGUgRGVlcEZ1bmN0aW9uTWFwID0ge1xuXHRba2V5OiBzdHJpbmddOiBGdW5jdGlvbk1hcDtcbn07XG50eXBlIEhvb2tNYXAgPSB7XG5cdGhvb2tlZEhhbmRsZXJzOiB7XG5cdFx0W2tleTogc3RyaW5nXTogRnVuY3Rpb25bXTtcblx0fTtcbn07XG5cbi8vIFVzZSB0d28gYXJyYXlzIGFzIHdlIGNhbm5vdCBpbmRleCBhIG1hcCB0aHJvdWdoIGFuIGFyYml0cmFyeSBvYmplY3QgaW5zdGFuY2VcbmNvbnN0IHJlZ2lzdGVyZWRJbnN0YW5jZXM6IEZ1bmN0aW9uW10gPSBbXTtcbmNvbnN0IHJlZ2lzdGVyZWRIYW5kbGVyczogSGFuZGxlclJlZ2lzdHJhdGlvbltdW10gPSBbXTtcblxuLyoqXG4gKiBNYXJrcyBhIGNvbnRyb2xsZXIgZXh0ZW5zaW9uIG1ldGhvZCB0byBiZSBob29rYWJsZSBieSBnZW5lcmF0aW5nIGFkZGl0aW9uYWwgbWV0aG9kcyB0aGF0IGNhbiBiZSB1c2VkIHRvIGF0dGFjaCBhbmQgZGV0YWNoIGhhbmRsZXJzIGF0IHJ1bnRpbWUuXG4gKiBAcGFyYW0gZXhlY3V0aW9uXG4gKiBAcmV0dXJucyBBIG1ldGhvZCBkZWNvcmF0b3JcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhvb2thYmxlKGV4ZWN1dGlvbjogRXh0ZW5zaW9uT3ZlcnJpZGVFeGVjdXRpb24pOiBNZXRob2REZWNvcmF0b3Ige1xuXHRyZXR1cm4gZnVuY3Rpb24gKHRhcmdldDogdW5rbm93biwgcHJvcGVydHlLZXk6IHN0cmluZyB8IHN5bWJvbCwgZGVzY3JpcHRvcjogUHJvcGVydHlEZXNjcmlwdG9yKSB7XG5cdFx0Y29uc3QgaW5kZXhhYmxlVGFyZ2V0ID0gdGFyZ2V0IGFzIEZ1bmN0aW9uTWFwO1xuXG5cdFx0aW5kZXhhYmxlVGFyZ2V0W2BhdHRhY2gke3Byb3BlcnR5S2V5LnRvU3RyaW5nKCl9YF0gPSBmdW5jdGlvbiAoZm46IEZ1bmN0aW9uKTogdm9pZCB7XG5cdFx0XHRjb25zdCBjRXhUSW5zdGFuY2VIb29rTWFwID0gdGhpcyBhcyB1bmtub3duIGFzIEhvb2tNYXA7XG5cdFx0XHRpZiAoIWNFeFRJbnN0YW5jZUhvb2tNYXAuaG9va2VkSGFuZGxlcnMpIHtcblx0XHRcdFx0Y0V4VEluc3RhbmNlSG9va01hcC5ob29rZWRIYW5kbGVycyA9IHt9O1xuXHRcdFx0fVxuXHRcdFx0aWYgKCFjRXhUSW5zdGFuY2VIb29rTWFwLmhvb2tlZEhhbmRsZXJzW3Byb3BlcnR5S2V5LnRvU3RyaW5nKCldKSB7XG5cdFx0XHRcdGNFeFRJbnN0YW5jZUhvb2tNYXAuaG9va2VkSGFuZGxlcnNbcHJvcGVydHlLZXkudG9TdHJpbmcoKV0gPSBbXTtcblx0XHRcdH1cblx0XHRcdGNFeFRJbnN0YW5jZUhvb2tNYXAuaG9va2VkSGFuZGxlcnNbcHJvcGVydHlLZXkudG9TdHJpbmcoKV0ucHVzaChmbik7XG5cdFx0fTtcblx0XHRpbmRleGFibGVUYXJnZXRbYGRldGFjaCR7cHJvcGVydHlLZXkudG9TdHJpbmcoKX1gXSA9IGZ1bmN0aW9uIChmbjogRnVuY3Rpb24pOiB2b2lkIHtcblx0XHRcdGNvbnN0IGNFeFRJbnN0YW5jZUhvb2tNYXAgPSB0aGlzIGFzIHVua25vd24gYXMgSG9va01hcDtcblx0XHRcdGNvbnN0IGhhbmRsZXJzID0gY0V4VEluc3RhbmNlSG9va01hcC5ob29rZWRIYW5kbGVyc1twcm9wZXJ0eUtleS50b1N0cmluZygpXTtcblx0XHRcdGNvbnN0IGluZGV4ID0gaGFuZGxlcnMuaW5kZXhPZihmbik7XG5cdFx0XHRpZiAoaW5kZXggIT09IC0xKSB7XG5cdFx0XHRcdGhhbmRsZXJzLnNwbGljZShpbmRleCwgMSk7XG5cdFx0XHR9XG5cdFx0fTtcblxuXHRcdGNvbnN0IG9sZFZhbHVlID0gZGVzY3JpcHRvci52YWx1ZTtcblx0XHRpZiAoZXhlY3V0aW9uID09PSBcIkJlZm9yZUFzeW5jXCIgfHwgZXhlY3V0aW9uID09PSBcIkFmdGVyQXN5bmNcIikge1xuXHRcdFx0ZGVzY3JpcHRvci52YWx1ZSA9IGFzeW5jIGZ1bmN0aW9uICguLi5hcmdzOiB1bmtub3duW10pOiBQcm9taXNlPHVua25vd24+IHtcblx0XHRcdFx0Y29uc3QgY0V4VEluc3RhbmNlSG9va01hcCA9IHRoaXMgYXMgdW5rbm93biBhcyBIb29rTWFwO1xuXHRcdFx0XHRjb25zdCBoYW5kbGVycyA9IChjRXhUSW5zdGFuY2VIb29rTWFwPy5ob29rZWRIYW5kbGVycyAmJiBjRXhUSW5zdGFuY2VIb29rTWFwPy5ob29rZWRIYW5kbGVyc1twcm9wZXJ0eUtleS50b1N0cmluZygpXSkgfHwgW107XG5cdFx0XHRcdGxldCByZXR1cm5WYWx1ZTogdW5rbm93bjtcblx0XHRcdFx0aWYgKGV4ZWN1dGlvbiA9PT0gXCJBZnRlckFzeW5jXCIpIHtcblx0XHRcdFx0XHRyZXR1cm5WYWx1ZSA9IGF3YWl0IG9sZFZhbHVlLmJpbmQodGhpcykoLi4uYXJncyk7XG5cdFx0XHRcdH1cblx0XHRcdFx0Zm9yIChjb25zdCBoYW5kbGVyIG9mIGhhbmRsZXJzKSB7XG5cdFx0XHRcdFx0YXdhaXQgaGFuZGxlci5iaW5kKHRoaXMpKC4uLmFyZ3MpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChleGVjdXRpb24gPT09IFwiQmVmb3JlQXN5bmNcIikge1xuXHRcdFx0XHRcdHJldHVyblZhbHVlID0gYXdhaXQgb2xkVmFsdWUuYmluZCh0aGlzKSguLi5hcmdzKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gcmV0dXJuVmFsdWU7XG5cdFx0XHR9O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRkZXNjcmlwdG9yLnZhbHVlID0gZnVuY3Rpb24gKC4uLmFyZ3M6IHVua25vd25bXSk6IHVua25vd24ge1xuXHRcdFx0XHRjb25zdCBjRXhUSW5zdGFuY2VIb29rTWFwID0gdGhpcyBhcyB1bmtub3duIGFzIEhvb2tNYXA7XG5cdFx0XHRcdGNvbnN0IGhhbmRsZXJzID0gKGNFeFRJbnN0YW5jZUhvb2tNYXA/Lmhvb2tlZEhhbmRsZXJzICYmIGNFeFRJbnN0YW5jZUhvb2tNYXA/Lmhvb2tlZEhhbmRsZXJzW3Byb3BlcnR5S2V5LnRvU3RyaW5nKCldKSB8fCBbXTtcblx0XHRcdFx0bGV0IHJldHVyblZhbHVlOiB1bmtub3duO1xuXHRcdFx0XHRpZiAoZXhlY3V0aW9uID09PSBcIkFmdGVyXCIpIHtcblx0XHRcdFx0XHRyZXR1cm5WYWx1ZSA9IG9sZFZhbHVlLmJpbmQodGhpcykoLi4uYXJncyk7XG5cdFx0XHRcdH1cblx0XHRcdFx0Zm9yIChjb25zdCBoYW5kbGVyIG9mIGhhbmRsZXJzKSB7XG5cdFx0XHRcdFx0aGFuZGxlci5iaW5kKHRoaXMpKC4uLmFyZ3MpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChleGVjdXRpb24gPT09IFwiQmVmb3JlXCIpIHtcblx0XHRcdFx0XHRyZXR1cm5WYWx1ZSA9IG9sZFZhbHVlLmJpbmQodGhpcykoLi4uYXJncyk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHJldHVyblZhbHVlO1xuXHRcdFx0fTtcblx0XHR9XG5cdH07XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSBuZXdSZWdpc3RyYXRpb24gaXMgYWxyZWFkeSBpbmNsdWRlZCBpbiBzb21lIGV4aXN0aW5nUmVnaXN0cmF0aW9ucyBieSBjb21wYXJpbmcgYWxsIHJlbGV2YW50IGF0dHJpYnV0ZXMuXG4gKiBAcGFyYW0gZXhpc3RpbmdSZWdpc3RyYXRpb25zXG4gKiBAcGFyYW0gbmV3UmVnaXN0cmF0aW9uXG4gKiBAcmV0dXJucyBSZXN1bHQgb2YgdGhlIGNoZWNrXG4gKi9cbmZ1bmN0aW9uIGlzQWxyZWFkeVJlZ2lzdGVyZWQoZXhpc3RpbmdSZWdpc3RyYXRpb25zOiBIYW5kbGVyUmVnaXN0cmF0aW9uW10sIG5ld1JlZ2lzdHJhdGlvbjogSGFuZGxlclJlZ2lzdHJhdGlvbik6IGJvb2xlYW4ge1xuXHRyZXR1cm4gISFleGlzdGluZ1JlZ2lzdHJhdGlvbnMuZmluZChcblx0XHQocikgPT4gci5uYW1lID09PSBuZXdSZWdpc3RyYXRpb24ubmFtZSAmJiByLm1ldGhvZCA9PT0gbmV3UmVnaXN0cmF0aW9uLm1ldGhvZCAmJiByLnRhcmdldE1ldGhvZCA9PT0gbmV3UmVnaXN0cmF0aW9uLnRhcmdldE1ldGhvZFxuXHQpO1xufVxuXG4vKipcbiAqIFJlZ2lzdGVycyBhIG1ldGhvZCBhcyBjb250cm9sbGVyIGV4dGVuc2lvbiBob29rIGhhbmRsZXIuXG4gKlxuICogQ3VycmVudGx5LCBvbmx5IG1ldGhvZHMgb2YgcnVudGltZSBidWlsZGluZyBibG9ja3MgYXJlIHN1cHBvcnRlZC5cbiAqIEBwYXJhbSBuYW1lIENvbnRyb2xsZXIgZXh0ZW5zaW9uIHRvIGhvb2sgaW50b1xuICogQHBhcmFtIG1ldGhvZCBNZXRob2QgdG8gaG9vayBpbnRvXG4gKiBAcmV0dXJucyBBIG1ldGhvZCBkZWNvcmF0b3JcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbnRyb2xsZXJFeHRlbnNpb25IYW5kbGVyPENFeHROYW1lIGV4dGVuZHMga2V5b2YgSG9va2FibGVDb250cm9sbGVyRXh0ZW5zaW9ucz4oXG5cdG5hbWU6IENFeHROYW1lLFxuXHRtZXRob2Q6IGtleW9mIEhvb2thYmxlQ29udHJvbGxlckV4dGVuc2lvbnNbQ0V4dE5hbWVdXG4pOiBNZXRob2REZWNvcmF0b3Ige1xuXHRyZXR1cm4gZnVuY3Rpb24gKHRhcmdldDogeyBjb25zdHJ1Y3RvcjogRnVuY3Rpb24gfSwgcHJvcGVydHlLZXk6IHN0cmluZykge1xuXHRcdGNvbnN0IG5ld1JlZ2lzdHJhdGlvbiA9IHsgbmFtZSwgbWV0aG9kOiBTdHJpbmcobWV0aG9kKSwgdGFyZ2V0TWV0aG9kOiBwcm9wZXJ0eUtleSB9O1xuXHRcdGNvbnN0IGluZGV4ID0gcmVnaXN0ZXJlZEluc3RhbmNlcy5pbmRleE9mKHRhcmdldC5jb25zdHJ1Y3Rvcik7XG5cblx0XHQvLyBXZSBuZWVkIHRvIGNoZWNrIGlmIHRoaXMgZXhhY3QgaGFuZGxlciBpcyBhbHJlYWR5IHJlZ2lzdGVyZWQgYXMgaGFuZGxlcnMgYXJlIHJlZ2lzdGVyZWQgc3RhdGljYWxseSAob24gdGhlIGNvbnN0cnVjdG9yKVxuXHRcdGlmIChpbmRleCAhPT0gLTEgJiYgIWlzQWxyZWFkeVJlZ2lzdGVyZWQocmVnaXN0ZXJlZEhhbmRsZXJzW2luZGV4XSwgbmV3UmVnaXN0cmF0aW9uKSkge1xuXHRcdFx0cmVnaXN0ZXJlZEhhbmRsZXJzW2luZGV4XS5wdXNoKG5ld1JlZ2lzdHJhdGlvbik7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJlZ2lzdGVyZWRJbnN0YW5jZXMucHVzaCh0YXJnZXQuY29uc3RydWN0b3IpO1xuXHRcdFx0cmVnaXN0ZXJlZEhhbmRsZXJzLnB1c2goW25ld1JlZ2lzdHJhdGlvbl0pO1xuXHRcdH1cblx0fSBhcyBNZXRob2REZWNvcmF0b3I7XG59XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgYWxsIGNvbnRyb2xsZXIgZXh0ZW5zaW9uIGhhbmRsZXJzIHJlZ2lzdGVyZWQgZm9yIGEgZ2l2ZW4gdGFyZ2V0LlxuICogQHBhcmFtIHRhcmdldCBUYXJnZXQgY2xhc3MgdG8gaW5pdGlhbGl6ZSB0aGUgaGFuZGxlcnMgZm9yXG4gKiBAcGFyYW0gdGFyZ2V0LmNvbnN0cnVjdG9yXG4gKiBAcGFyYW0gY29udHJvbGxlciBQYWdlQ29udHJvbGxlciBpbnN0YW5jZSB0byBnZXQgdGhlIGNvbnRyb2xsZXIgZXh0ZW5zaW9ucyBpbnN0YW5jZXMgZnJvbVxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5pdENvbnRyb2xsZXJFeHRlbnNpb25Ib29rSGFuZGxlcnModGFyZ2V0OiB7IGNvbnN0cnVjdG9yOiBGdW5jdGlvbiB9LCBjb250cm9sbGVyOiBDb250cm9sbGVyKTogdm9pZCB7XG5cdGNvbnN0IGluZGV4ID0gcmVnaXN0ZXJlZEluc3RhbmNlcy5pbmRleE9mKHRhcmdldC5jb25zdHJ1Y3Rvcik7XG5cdGlmIChpbmRleCAhPT0gLTEpIHtcblx0XHRjb25zdCBpbmRleGFibGVDb250cm9sbGVyID0gY29udHJvbGxlciBhcyB1bmtub3duIGFzIERlZXBGdW5jdGlvbk1hcDtcblx0XHRjb25zdCBpbmRleGFibGVUYXJnZXQgPSB0YXJnZXQgYXMgdW5rbm93biBhcyBGdW5jdGlvbk1hcDtcblxuXHRcdGZvciAoY29uc3QgcmVnaXN0ZXJlZEhhbmRsZXIgb2YgcmVnaXN0ZXJlZEhhbmRsZXJzW2luZGV4XSkge1xuXHRcdFx0Y29uc3QgaGFuZGxlckZ1bmN0aW9uID0gaW5kZXhhYmxlVGFyZ2V0W3JlZ2lzdGVyZWRIYW5kbGVyLnRhcmdldE1ldGhvZF0uYmluZCh0YXJnZXQpO1xuXG5cdFx0XHRpbmRleGFibGVDb250cm9sbGVyW3JlZ2lzdGVyZWRIYW5kbGVyLm5hbWVdW2BhdHRhY2gke1N0cmluZyhyZWdpc3RlcmVkSGFuZGxlci5tZXRob2QpfWBdKGhhbmRsZXJGdW5jdGlvbik7XG5cdFx0XHRjb250cm9sbGVyLmdldFZpZXcoKT8uYXR0YWNoQmVmb3JlRXhpdCgoKSA9PiB7XG5cdFx0XHRcdGluZGV4YWJsZUNvbnRyb2xsZXJbcmVnaXN0ZXJlZEhhbmRsZXIubmFtZV1bYGRldGFjaCR7U3RyaW5nKHJlZ2lzdGVyZWRIYW5kbGVyLm1ldGhvZCl9YF0oaGFuZGxlckZ1bmN0aW9uKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgZnVuY3Rpb24geG1sVmlld1ByZXByb2Nlc3Nvcihzb3VyY2U6IG9iamVjdCwgX2NhbGxlcj86IHVua25vd24sIF9zZXR0aW5ncz86IG9iamVjdCk6IHZvaWQge1xuXHRjb25zdCBzb3VyY2VWaWV3ID0gc291cmNlIGFzIFhNTFZpZXc7XG5cdGNvbnN0IGNvbnRyb2xsZXIgPSBzb3VyY2VWaWV3LmdldENvbnRyb2xsZXIoKSBhcyBDb250cm9sbGVyIHwgdW5kZWZpbmVkO1xuXHRpZiAoY29udHJvbGxlcikge1xuXHRcdGNvbnN0IG1hY3JvQVBJQ2hpbGQgPSBzb3VyY2VWaWV3LmZpbmRBZ2dyZWdhdGVkT2JqZWN0cyh0cnVlLCAocykgPT4gcy5pc0EoXCJzYXAuZmUubWFjcm9zLk1hY3JvQVBJXCIpKTtcblx0XHRmb3IgKGNvbnN0IG1hbmFnZWRPYmplY3Qgb2YgbWFjcm9BUElDaGlsZCkge1xuXHRcdFx0aW5pdENvbnRyb2xsZXJFeHRlbnNpb25Ib29rSGFuZGxlcnMo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
|
|
184
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJyZWdpc3RlcmVkSW5zdGFuY2VzIiwicmVnaXN0ZXJlZEhhbmRsZXJzIiwiaG9va2FibGUiLCJleGVjdXRpb24iLCJ0YXJnZXQiLCJwcm9wZXJ0eUtleSIsImRlc2NyaXB0b3IiLCJpbmRleGFibGVUYXJnZXQiLCJ0b1N0cmluZyIsImZuIiwiY0V4VEluc3RhbmNlSG9va01hcCIsImhvb2tlZEhhbmRsZXJzIiwicHVzaCIsImhhbmRsZXJzIiwiaW5kZXgiLCJpbmRleE9mIiwic3BsaWNlIiwib2xkVmFsdWUiLCJ2YWx1ZSIsInJldHVyblZhbHVlIiwiYmluZCIsImFyZ3VtZW50cyIsImhhbmRsZXIiLCJfZXhwb3J0cyIsImlzQWxyZWFkeVJlZ2lzdGVyZWQiLCJleGlzdGluZ1JlZ2lzdHJhdGlvbnMiLCJuZXdSZWdpc3RyYXRpb24iLCJmaW5kIiwiciIsIm5hbWUiLCJtZXRob2QiLCJ0YXJnZXRNZXRob2QiLCJob29rcyIsIlN5bWJvbCIsImNvbnRyb2xsZXJFeHRlbnNpb25IYW5kbGVyIiwiU3RyaW5nIiwiY29uc3RydWN0b3IiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImluaXRDb250cm9sbGVyRXh0ZW5zaW9uSG9va0hhbmRsZXJzIiwiY29udHJvbGxlciIsInJlZ2lzdGVyZWRIb29rcyIsImRlZXBDbG9uZSIsImluZGV4YWJsZUNvbnRyb2xsZXIiLCJyZWdpc3RlcmVkSG9vayIsImhhbmRsZXJGdW5jdGlvbiIsImdldFZpZXciLCJhdHRhY2hCZWZvcmVFeGl0IiwicmVtb3ZlQ29udHJvbGxlckV4dGVuc2lvbkhvb2tIYW5kbGVycyIsInByb3BhZ2F0ZUhvb2tGcm9tTWl4aW4iLCJzb3VyY2UiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJjcmVhdGUiLCJ4bWxWaWV3UHJlcHJvY2Vzc29yIiwiX2NhbGxlciIsIl9zZXR0aW5ncyIsInNvdXJjZVZpZXciLCJnZXRDb250cm9sbGVyIiwibWFjcm9BUElDaGlsZCIsImZpbmRBZ2dyZWdhdGVkT2JqZWN0cyIsInMiLCJpc0EiLCJtYW5hZ2VkT2JqZWN0Il0sInNvdXJjZVJvb3QiOiIuIiwic291cmNlcyI6WyJIb29rU3VwcG9ydC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZGVlcENsb25lIGZyb20gXCJzYXAvYmFzZS91dGlsL2RlZXBDbG9uZVwiO1xuaW1wb3J0IHR5cGUgeyBFeHRlbnNpb25PdmVycmlkZUV4ZWN1dGlvbiB9IGZyb20gXCJzYXAvZmUvYmFzZS9DbGFzc1N1cHBvcnRcIjtcbmltcG9ydCB0eXBlIENvbnRyb2xsZXIgZnJvbSBcInNhcC91aS9jb3JlL212Yy9Db250cm9sbGVyXCI7XG5pbXBvcnQgdHlwZSBYTUxWaWV3IGZyb20gXCJzYXAvdWkvY29yZS9tdmMvWE1MVmlld1wiO1xuLyoqXG4gKiBUaGlzIHR5cGUgaXMgdG8gYmUgZXh0ZW5kZWQgd2l0aCBhbGwgY29udHJvbGxlciBleHRlbnNpb25zIGFuZCBtZXRob2RzIHRoYXQgYXJlIGhvb2thYmxlLlxuICovXG50eXBlIEhvb2thYmxlQ29udHJvbGxlckV4dGVuc2lvbnMgPSB7XG5cdGVkaXRGbG93OiB7XG5cdFx0aW5saW5lRWRpdEVuZDogdHJ1ZTtcblx0XHRpbmxpbmVFZGl0U3RhcnQ6IHRydWU7XG5cdFx0b25BZnRlclNhdmU6IHRydWU7XG5cdFx0b25CZWZvcmVTYXZlOiB0cnVlO1xuXHR9O1xuXHRjb2xsYWJvcmF0aW9uTWFuYWdlcjoge1xuXHRcdGNvbGxlY3RBdmFpbGFibGVDYXJkczogdHJ1ZTtcblx0fTtcblx0cGFnaW5hdG9yOiB7XG5cdFx0aW5pdGlhbGl6ZTogdHJ1ZTtcblx0fTtcblx0cm91dGluZzoge1xuXHRcdG9uQWZ0ZXJCaW5kaW5nOiB0cnVlO1xuXHR9O1xufTtcblxudHlwZSBIYW5kbGVyQ29uZmlndXJhdGlvbjxDRXh0TmFtZSBleHRlbmRzIGtleW9mIEhvb2thYmxlQ29udHJvbGxlckV4dGVuc2lvbnM+ID0ge1xuXHRuYW1lOiBDRXh0TmFtZTtcblx0bWV0aG9kOiBrZXlvZiBIb29rYWJsZUNvbnRyb2xsZXJFeHRlbnNpb25zW0NFeHROYW1lXTtcbn07XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxudHlwZSBIYW5kbGVyUmVnaXN0cmF0aW9uID0gSGFuZGxlckNvbmZpZ3VyYXRpb248YW55PiAmIHsgdGFyZ2V0TWV0aG9kOiBzdHJpbmc7IGhhbmRsZXJGdW5jdGlvbj86IEZ1bmN0aW9uIH07XG5cbnR5cGUgRnVuY3Rpb25NYXAgPSB7XG5cdFtrZXk6IHN0cmluZ106IEZ1bmN0aW9uO1xufTtcbnR5cGUgRGVlcEZ1bmN0aW9uTWFwID0ge1xuXHRba2V5OiBzdHJpbmddOiBGdW5jdGlvbk1hcDtcbn07XG50eXBlIEhvb2tNYXAgPSB7XG5cdGhvb2tlZEhhbmRsZXJzOiB7XG5cdFx0W2tleTogc3RyaW5nXTogRnVuY3Rpb25bXTtcblx0fTtcbn07XG5cbi8vIFVzZSB0d28gYXJyYXlzIGFzIHdlIGNhbm5vdCBpbmRleCBhIG1hcCB0aHJvdWdoIGFuIGFyYml0cmFyeSBvYmplY3QgaW5zdGFuY2VcbmNvbnN0IHJlZ2lzdGVyZWRJbnN0YW5jZXM6IEZ1bmN0aW9uW10gPSBbXTtcbmNvbnN0IHJlZ2lzdGVyZWRIYW5kbGVyczogSGFuZGxlclJlZ2lzdHJhdGlvbltdW10gPSBbXTtcblxuLyoqXG4gKiBNYXJrcyBhIGNvbnRyb2xsZXIgZXh0ZW5zaW9uIG1ldGhvZCB0byBiZSBob29rYWJsZSBieSBnZW5lcmF0aW5nIGFkZGl0aW9uYWwgbWV0aG9kcyB0aGF0IGNhbiBiZSB1c2VkIHRvIGF0dGFjaCBhbmQgZGV0YWNoIGhhbmRsZXJzIGF0IHJ1bnRpbWUuXG4gKiBAcGFyYW0gZXhlY3V0aW9uXG4gKiBAcmV0dXJucyBBIG1ldGhvZCBkZWNvcmF0b3JcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhvb2thYmxlKGV4ZWN1dGlvbjogRXh0ZW5zaW9uT3ZlcnJpZGVFeGVjdXRpb24pOiBNZXRob2REZWNvcmF0b3Ige1xuXHRyZXR1cm4gZnVuY3Rpb24gKHRhcmdldDogdW5rbm93biwgcHJvcGVydHlLZXk6IHN0cmluZyB8IHN5bWJvbCwgZGVzY3JpcHRvcjogUHJvcGVydHlEZXNjcmlwdG9yKSB7XG5cdFx0Y29uc3QgaW5kZXhhYmxlVGFyZ2V0ID0gdGFyZ2V0IGFzIEZ1bmN0aW9uTWFwO1xuXG5cdFx0aW5kZXhhYmxlVGFyZ2V0W2BhdHRhY2gke3Byb3BlcnR5S2V5LnRvU3RyaW5nKCl9YF0gPSBmdW5jdGlvbiAoZm46IEZ1bmN0aW9uKTogdm9pZCB7XG5cdFx0XHRjb25zdCBjRXhUSW5zdGFuY2VIb29rTWFwID0gdGhpcyBhcyB1bmtub3duIGFzIEhvb2tNYXA7XG5cdFx0XHRpZiAoIWNFeFRJbnN0YW5jZUhvb2tNYXAuaG9va2VkSGFuZGxlcnMpIHtcblx0XHRcdFx0Y0V4VEluc3RhbmNlSG9va01hcC5ob29rZWRIYW5kbGVycyA9IHt9O1xuXHRcdFx0fVxuXHRcdFx0aWYgKCFjRXhUSW5zdGFuY2VIb29rTWFwLmhvb2tlZEhhbmRsZXJzW3Byb3BlcnR5S2V5LnRvU3RyaW5nKCldKSB7XG5cdFx0XHRcdGNFeFRJbnN0YW5jZUhvb2tNYXAuaG9va2VkSGFuZGxlcnNbcHJvcGVydHlLZXkudG9TdHJpbmcoKV0gPSBbXTtcblx0XHRcdH1cblx0XHRcdGNFeFRJbnN0YW5jZUhvb2tNYXAuaG9va2VkSGFuZGxlcnNbcHJvcGVydHlLZXkudG9TdHJpbmcoKV0ucHVzaChmbik7XG5cdFx0fTtcblx0XHRpbmRleGFibGVUYXJnZXRbYGRldGFjaCR7cHJvcGVydHlLZXkudG9TdHJpbmcoKX1gXSA9IGZ1bmN0aW9uIChmbjogRnVuY3Rpb24pOiB2b2lkIHtcblx0XHRcdGNvbnN0IGNFeFRJbnN0YW5jZUhvb2tNYXAgPSB0aGlzIGFzIHVua25vd24gYXMgSG9va01hcDtcblx0XHRcdGNvbnN0IGhhbmRsZXJzID0gY0V4VEluc3RhbmNlSG9va01hcC5ob29rZWRIYW5kbGVyc1twcm9wZXJ0eUtleS50b1N0cmluZygpXTtcblx0XHRcdGNvbnN0IGluZGV4ID0gaGFuZGxlcnMuaW5kZXhPZihmbik7XG5cdFx0XHRpZiAoaW5kZXggIT09IC0xKSB7XG5cdFx0XHRcdGhhbmRsZXJzLnNwbGljZShpbmRleCwgMSk7XG5cdFx0XHR9XG5cdFx0fTtcblxuXHRcdGNvbnN0IG9sZFZhbHVlID0gZGVzY3JpcHRvci52YWx1ZTtcblx0XHRpZiAoZXhlY3V0aW9uID09PSBcIkJlZm9yZUFzeW5jXCIgfHwgZXhlY3V0aW9uID09PSBcIkFmdGVyQXN5bmNcIikge1xuXHRcdFx0ZGVzY3JpcHRvci52YWx1ZSA9IGFzeW5jIGZ1bmN0aW9uICguLi5hcmdzOiB1bmtub3duW10pOiBQcm9taXNlPHVua25vd24+IHtcblx0XHRcdFx0Y29uc3QgY0V4VEluc3RhbmNlSG9va01hcCA9IHRoaXMgYXMgdW5rbm93biBhcyBIb29rTWFwO1xuXHRcdFx0XHRjb25zdCBoYW5kbGVycyA9IChjRXhUSW5zdGFuY2VIb29rTWFwPy5ob29rZWRIYW5kbGVycyAmJiBjRXhUSW5zdGFuY2VIb29rTWFwPy5ob29rZWRIYW5kbGVyc1twcm9wZXJ0eUtleS50b1N0cmluZygpXSkgfHwgW107XG5cdFx0XHRcdGxldCByZXR1cm5WYWx1ZTogdW5rbm93bjtcblx0XHRcdFx0aWYgKGV4ZWN1dGlvbiA9PT0gXCJBZnRlckFzeW5jXCIpIHtcblx0XHRcdFx0XHRyZXR1cm5WYWx1ZSA9IGF3YWl0IG9sZFZhbHVlLmJpbmQodGhpcykoLi4uYXJncyk7XG5cdFx0XHRcdH1cblx0XHRcdFx0Zm9yIChjb25zdCBoYW5kbGVyIG9mIGhhbmRsZXJzKSB7XG5cdFx0XHRcdFx0YXdhaXQgaGFuZGxlci5iaW5kKHRoaXMpKC4uLmFyZ3MpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChleGVjdXRpb24gPT09IFwiQmVmb3JlQXN5bmNcIikge1xuXHRcdFx0XHRcdHJldHVyblZhbHVlID0gYXdhaXQgb2xkVmFsdWUuYmluZCh0aGlzKSguLi5hcmdzKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gcmV0dXJuVmFsdWU7XG5cdFx0XHR9O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRkZXNjcmlwdG9yLnZhbHVlID0gZnVuY3Rpb24gKC4uLmFyZ3M6IHVua25vd25bXSk6IHVua25vd24ge1xuXHRcdFx0XHRjb25zdCBjRXhUSW5zdGFuY2VIb29rTWFwID0gdGhpcyBhcyB1bmtub3duIGFzIEhvb2tNYXA7XG5cdFx0XHRcdGNvbnN0IGhhbmRsZXJzID0gKGNFeFRJbnN0YW5jZUhvb2tNYXA/Lmhvb2tlZEhhbmRsZXJzICYmIGNFeFRJbnN0YW5jZUhvb2tNYXA/Lmhvb2tlZEhhbmRsZXJzW3Byb3BlcnR5S2V5LnRvU3RyaW5nKCldKSB8fCBbXTtcblx0XHRcdFx0bGV0IHJldHVyblZhbHVlOiB1bmtub3duO1xuXHRcdFx0XHRpZiAoZXhlY3V0aW9uID09PSBcIkFmdGVyXCIpIHtcblx0XHRcdFx0XHRyZXR1cm5WYWx1ZSA9IG9sZFZhbHVlLmJpbmQodGhpcykoLi4uYXJncyk7XG5cdFx0XHRcdH1cblx0XHRcdFx0Zm9yIChjb25zdCBoYW5kbGVyIG9mIGhhbmRsZXJzKSB7XG5cdFx0XHRcdFx0aGFuZGxlci5iaW5kKHRoaXMpKC4uLmFyZ3MpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChleGVjdXRpb24gPT09IFwiQmVmb3JlXCIpIHtcblx0XHRcdFx0XHRyZXR1cm5WYWx1ZSA9IG9sZFZhbHVlLmJpbmQodGhpcykoLi4uYXJncyk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHJldHVyblZhbHVlO1xuXHRcdFx0fTtcblx0XHR9XG5cdH07XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSBuZXdSZWdpc3RyYXRpb24gaXMgYWxyZWFkeSBpbmNsdWRlZCBpbiBzb21lIGV4aXN0aW5nUmVnaXN0cmF0aW9ucyBieSBjb21wYXJpbmcgYWxsIHJlbGV2YW50IGF0dHJpYnV0ZXMuXG4gKiBAcGFyYW0gZXhpc3RpbmdSZWdpc3RyYXRpb25zXG4gKiBAcGFyYW0gbmV3UmVnaXN0cmF0aW9uXG4gKiBAcmV0dXJucyBSZXN1bHQgb2YgdGhlIGNoZWNrXG4gKi9cbmZ1bmN0aW9uIGlzQWxyZWFkeVJlZ2lzdGVyZWQoZXhpc3RpbmdSZWdpc3RyYXRpb25zOiBIYW5kbGVyUmVnaXN0cmF0aW9uW10sIG5ld1JlZ2lzdHJhdGlvbjogSGFuZGxlclJlZ2lzdHJhdGlvbik6IGJvb2xlYW4ge1xuXHRyZXR1cm4gISFleGlzdGluZ1JlZ2lzdHJhdGlvbnMuZmluZChcblx0XHQocikgPT4gci5uYW1lID09PSBuZXdSZWdpc3RyYXRpb24ubmFtZSAmJiByLm1ldGhvZCA9PT0gbmV3UmVnaXN0cmF0aW9uLm1ldGhvZCAmJiByLnRhcmdldE1ldGhvZCA9PT0gbmV3UmVnaXN0cmF0aW9uLnRhcmdldE1ldGhvZFxuXHQpO1xufVxuXG5leHBvcnQgY29uc3QgaG9va3MgPSBTeW1ib2woXCJob29rc1wiKTtcblxuLyoqXG4gKiBSZWdpc3RlcnMgYSBtZXRob2QgYXMgY29udHJvbGxlciBleHRlbnNpb24gaG9vayBoYW5kbGVyLlxuICpcbiAqIEN1cnJlbnRseSwgb25seSBtZXRob2RzIG9mIHJ1bnRpbWUgYnVpbGRpbmcgYmxvY2tzIGFyZSBzdXBwb3J0ZWQuXG4gKiBAcGFyYW0gbmFtZSBDb250cm9sbGVyIGV4dGVuc2lvbiB0byBob29rIGludG9cbiAqIEBwYXJhbSBtZXRob2QgTWV0aG9kIHRvIGhvb2sgaW50b1xuICogQHJldHVybnMgQSBtZXRob2QgZGVjb3JhdG9yXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb250cm9sbGVyRXh0ZW5zaW9uSGFuZGxlcjxDRXh0TmFtZSBleHRlbmRzIGtleW9mIEhvb2thYmxlQ29udHJvbGxlckV4dGVuc2lvbnM+KFxuXHRuYW1lOiBDRXh0TmFtZSxcblx0bWV0aG9kOiBrZXlvZiBIb29rYWJsZUNvbnRyb2xsZXJFeHRlbnNpb25zW0NFeHROYW1lXVxuKTogTWV0aG9kRGVjb3JhdG9yIHtcblx0cmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQ6IHsgY29uc3RydWN0b3I6IEZ1bmN0aW9uICYgeyBbaG9va3NdPzogSGFuZGxlclJlZ2lzdHJhdGlvbltdIH0gfSwgcHJvcGVydHlLZXk6IHN0cmluZykge1xuXHRcdGNvbnN0IG5ld1JlZ2lzdHJhdGlvbiA9IHsgbmFtZSwgbWV0aG9kOiBTdHJpbmcobWV0aG9kKSwgdGFyZ2V0TWV0aG9kOiBwcm9wZXJ0eUtleSB9O1xuXHRcdGNvbnN0IGluZGV4ID0gcmVnaXN0ZXJlZEluc3RhbmNlcy5pbmRleE9mKHRhcmdldC5jb25zdHJ1Y3Rvcik7XG5cdFx0aWYgKCF0YXJnZXQuY29uc3RydWN0b3JbaG9va3NdKSB7XG5cdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LmNvbnN0cnVjdG9yLCBob29rcywge1xuXHRcdFx0XHR2YWx1ZTogW11cblx0XHRcdH0pO1xuXHRcdH1cblx0XHR0YXJnZXQuY29uc3RydWN0b3JbaG9va3NdPy5wdXNoKG5ld1JlZ2lzdHJhdGlvbik7XG5cdFx0Ly8gV2UgbmVlZCB0byBjaGVjayBpZiB0aGlzIGV4YWN0IGhhbmRsZXIgaXMgYWxyZWFkeSByZWdpc3RlcmVkIGFzIGhhbmRsZXJzIGFyZSByZWdpc3RlcmVkIHN0YXRpY2FsbHkgKG9uIHRoZSBjb25zdHJ1Y3Rvcilcblx0XHRpZiAoaW5kZXggIT09IC0xICYmICFpc0FscmVhZHlSZWdpc3RlcmVkKHJlZ2lzdGVyZWRIYW5kbGVyc1tpbmRleF0sIG5ld1JlZ2lzdHJhdGlvbikpIHtcblx0XHRcdHJlZ2lzdGVyZWRIYW5kbGVyc1tpbmRleF0ucHVzaChuZXdSZWdpc3RyYXRpb24pO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZWdpc3RlcmVkSW5zdGFuY2VzLnB1c2godGFyZ2V0LmNvbnN0cnVjdG9yKTtcblx0XHRcdHJlZ2lzdGVyZWRIYW5kbGVycy5wdXNoKFtuZXdSZWdpc3RyYXRpb25dKTtcblx0XHR9XG5cdH0gYXMgTWV0aG9kRGVjb3JhdG9yO1xufVxuXG4vKipcbiAqIEluaXRpYWxpemVzIGFsbCBjb250cm9sbGVyIGV4dGVuc2lvbiBoYW5kbGVycyByZWdpc3RlcmVkIGZvciBhIGdpdmVuIHRhcmdldC5cbiAqIEBwYXJhbSB0YXJnZXQgVGFyZ2V0IGNsYXNzIHRvIGluaXRpYWxpemUgdGhlIGhhbmRsZXJzIGZvclxuICogQHBhcmFtIHRhcmdldC5jb25zdHJ1Y3RvclxuICogQHBhcmFtIGNvbnRyb2xsZXIgUGFnZUNvbnRyb2xsZXIgaW5zdGFuY2UgdG8gZ2V0IHRoZSBjb250cm9sbGVyIGV4dGVuc2lvbnMgaW5zdGFuY2VzIGZyb21cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluaXRDb250cm9sbGVyRXh0ZW5zaW9uSG9va0hhbmRsZXJzKFxuXHR0YXJnZXQ6IHsgY29uc3RydWN0b3I6IEZ1bmN0aW9uICYgeyBbaG9va3NdPzogSGFuZGxlclJlZ2lzdHJhdGlvbltdIH0gfSAmIHsgW2hvb2tzXT86IEhhbmRsZXJSZWdpc3RyYXRpb25bXSB9LFxuXHRjb250cm9sbGVyOiBDb250cm9sbGVyXG4pOiB2b2lkIHtcblx0aWYgKHRhcmdldC5jb25zdHJ1Y3Rvcltob29rc10pIHtcblx0XHRsZXQgcmVnaXN0ZXJlZEhvb2tzID0gdGFyZ2V0LmNvbnN0cnVjdG9yW2hvb2tzXTtcblx0XHR0YXJnZXRbaG9va3NdID0gZGVlcENsb25lKHJlZ2lzdGVyZWRIb29rcyk7XG5cdFx0cmVnaXN0ZXJlZEhvb2tzID0gdGFyZ2V0W2hvb2tzXSE7XG5cdFx0Y29uc3QgaW5kZXhhYmxlVGFyZ2V0ID0gdGFyZ2V0IGFzIHVua25vd24gYXMgRnVuY3Rpb25NYXA7XG5cdFx0Y29uc3QgaW5kZXhhYmxlQ29udHJvbGxlciA9IGNvbnRyb2xsZXIgYXMgdW5rbm93biBhcyBEZWVwRnVuY3Rpb25NYXA7XG5cdFx0Zm9yIChjb25zdCByZWdpc3RlcmVkSG9vayBvZiByZWdpc3RlcmVkSG9va3MpIHtcblx0XHRcdHJlZ2lzdGVyZWRIb29rLmhhbmRsZXJGdW5jdGlvbiA9IGluZGV4YWJsZVRhcmdldFtyZWdpc3RlcmVkSG9vay50YXJnZXRNZXRob2RdLmJpbmQodGFyZ2V0KTtcblx0XHRcdGluZGV4YWJsZUNvbnRyb2xsZXJbcmVnaXN0ZXJlZEhvb2submFtZV1bYGF0dGFjaCR7U3RyaW5nKHJlZ2lzdGVyZWRIb29rLm1ldGhvZCl9YF0ocmVnaXN0ZXJlZEhvb2suaGFuZGxlckZ1bmN0aW9uKTtcblx0XHRcdGNvbnRyb2xsZXIuZ2V0VmlldygpPy5hdHRhY2hCZWZvcmVFeGl0KCgpID0+IHtcblx0XHRcdFx0aW5kZXhhYmxlQ29udHJvbGxlcltyZWdpc3RlcmVkSG9vay5uYW1lXVtgZGV0YWNoJHtTdHJpbmcocmVnaXN0ZXJlZEhvb2subWV0aG9kKX1gXShyZWdpc3RlcmVkSG9vay5oYW5kbGVyRnVuY3Rpb24pO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVDb250cm9sbGVyRXh0ZW5zaW9uSG9va0hhbmRsZXJzKFxuXHR0YXJnZXQ6IHsgY29uc3RydWN0b3I6IEZ1bmN0aW9uICYgeyBbaG9va3NdPzogSGFuZGxlclJlZ2lzdHJhdGlvbltdIH0gfSAmIHsgW2hvb2tzXT86IEhhbmRsZXJSZWdpc3RyYXRpb25bXSB9LFxuXHRjb250cm9sbGVyOiBDb250cm9sbGVyXG4pOiB2b2lkIHtcblx0aWYgKHRhcmdldFtob29rc10pIHtcblx0XHRjb25zdCByZWdpc3RlcmVkSG9va3MgPSB0YXJnZXRbaG9va3NdO1xuXHRcdGNvbnN0IGluZGV4YWJsZUNvbnRyb2xsZXIgPSBjb250cm9sbGVyIGFzIHVua25vd24gYXMgRGVlcEZ1bmN0aW9uTWFwO1xuXHRcdGZvciAoY29uc3QgcmVnaXN0ZXJlZEhvb2sgb2YgcmVnaXN0ZXJlZEhvb2tzKSB7XG5cdFx0XHRpbmRleGFibGVDb250cm9sbGVyW3JlZ2lzdGVyZWRIb29rLm5hbWVdPy5bYGRldGFjaCR7U3RyaW5nKHJlZ2lzdGVyZWRIb29rLm1ldGhvZCl9YF0/LihyZWdpc3RlcmVkSG9vay5oYW5kbGVyRnVuY3Rpb24pO1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcHJvcGFnYXRlSG9va0Zyb21NaXhpbihcblx0dGFyZ2V0OiBGdW5jdGlvbiAmIHsgW2hvb2tzXT86IEhhbmRsZXJSZWdpc3RyYXRpb25bXSB9LFxuXHRzb3VyY2U6IEZ1bmN0aW9uICYgeyBbaG9va3NdPzogSGFuZGxlclJlZ2lzdHJhdGlvbltdIH1cbik6IHZvaWQge1xuXHRpZiAoc291cmNlW2hvb2tzXSkge1xuXHRcdGlmICh0YXJnZXRbaG9va3NdKSB7XG5cdFx0XHR0YXJnZXRbaG9va3NdIS5zcGxpY2UoMCwgMCwgLi4uc291cmNlW2hvb2tzXSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGhvb2tzLCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHNvdXJjZSwgaG9va3MpIHx8IE9iamVjdC5jcmVhdGUoW10pKTtcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHhtbFZpZXdQcmVwcm9jZXNzb3Ioc291cmNlOiBvYmplY3QsIF9jYWxsZXI/OiB1bmtub3duLCBfc2V0dGluZ3M/OiBvYmplY3QpOiB2b2lkIHtcblx0Y29uc3Qgc291cmNlVmlldyA9IHNvdXJjZSBhcyBYTUxWaWV3O1xuXHRjb25zdCBjb250cm9sbGVyID0gc291cmNlVmlldy5nZXRDb250cm9sbGVyKCkgYXMgQ29udHJvbGxlciB8IHVuZGVmaW5lZDtcblx0aWYgKGNvbnRyb2xsZXIpIHtcblx0XHRjb25zdCBtYWNyb0FQSUNoaWxkID0gc291cmNlVmlldy5maW5kQWdncmVnYXRlZE9iamVjdHModHJ1ZSwgKHMpID0+IHMuaXNBKFwic2FwLmZlLm1hY3Jvcy5NYWNyb0FQSVwiKSk7XG5cdFx0Zm9yIChjb25zdCBtYW5hZ2VkT2JqZWN0IG9mIG1hY3JvQVBJQ2hpbGQpIHtcblx0XHRcdGluaXRDb250cm9sbGVyRXh0ZW5zaW9uSG9va0hhbmRsZXJzKG1hbmFnZWRPYmplY3QsIGNvbnRyb2xsZXIpO1xuXHRcdH1cblx0fVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztFQUlBO0FBQ0E7QUFDQTs7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QUFLLE1BQU1JLGNBQWMsSUFBSUgsZUFBZSxFQUFFO1FBQzdDRSxtQkFBbUIsQ0FBQ0MsY0FBYyxDQUFDZixJQUFJLENBQUMsR0FBRyxTQUFTTSxNQUFNLENBQUNTLGNBQWMsQ0FBQ2QsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHYyxjQUFjLENBQUNDLGVBQWUsQ0FBQztNQUN2SDtJQUNEO0VBQ0Q7RUFBQ3RCLFFBQUEsQ0FBQXlCLHFDQUFBLEdBQUFBLHFDQUFBO0VBRU0sU0FBU0Msc0JBQXNCQSxDQUNyQzdDLE1BQXNELEVBQ3REOEMsTUFBc0QsRUFDL0M7SUFDUCxJQUFJQSxNQUFNLENBQUNsQixLQUFLLENBQUMsRUFBRTtNQUNsQixJQUFJNUIsTUFBTSxDQUFDNEIsS0FBSyxDQUFDLEVBQUU7UUFDbEI1QixNQUFNLENBQUM0QixLQUFLLENBQUMsQ0FBRWhCLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUdrQyxNQUFNLENBQUNsQixLQUFLLENBQUMsQ0FBQztNQUM5QyxDQUFDLE1BQU07UUFDTkssTUFBTSxDQUFDQyxjQUFjLENBQUNsQyxNQUFNLEVBQUU0QixLQUFLLEVBQUVLLE1BQU0sQ0FBQ2Msd0JBQXdCLENBQUNELE1BQU0sRUFBRWxCLEtBQUssQ0FBQyxJQUFJSyxNQUFNLENBQUNlLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztNQUMxRztJQUNEO0VBQ0Q7RUFBQzdCLFFBQUEsQ0FBQTBCLHNCQUFBLEdBQUFBLHNCQUFBO0VBRU0sU0FBU0ksbUJBQW1CQSxDQUFDSCxNQUFjLEVBQUVJLE9BQWlCLEVBQUVDLFNBQWtCLEVBQVE7SUFDaEcsTUFBTUMsVUFBVSxHQUFHTixNQUFpQjtJQUNwQyxNQUFNVixVQUFVLEdBQUdnQixVQUFVLENBQUNDLGFBQWEsQ0FBQyxDQUEyQjtJQUN2RSxJQUFJakIsVUFBVSxFQUFFO01BQ2YsTUFBTWtCLGFBQWEsR0FBR0YsVUFBVSxDQUFDRyxxQkFBcUIsQ0FBQyxJQUFJLEVBQUdDLENBQUMsSUFBS0EsQ0FBQyxDQUFDQyxHQUFHLENBQUMsd0JBQXdCLENBQUMsQ0FBQztNQUNwRyxLQUFLLE1BQU1DLGFBQWEsSUFBSUosYUFBYSxFQUFFO1FBQzFDbkIsbUNBQW1DLENBQUN1QixhQUFhLEVBQUV0QixVQUFVLENBQUM7TUFDL0Q7SUFDRDtFQUNEO0VBQUNqQixRQUFBLENBQUE4QixtQkFBQSxHQUFBQSxtQkFBQTtFQUFBLE9BQUE5QixRQUFBO0FBQUEiLCJpZ25vcmVMaXN0IjpbXX0=
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
import deepClone from "sap/base/util/deepClone";
|
|
1
2
|
import type { ExtensionOverrideExecution } from "sap/fe/base/ClassSupport";
|
|
2
3
|
import type Controller from "sap/ui/core/mvc/Controller";
|
|
3
4
|
import type XMLView from "sap/ui/core/mvc/XMLView";
|
|
4
|
-
|
|
5
5
|
/**
|
|
6
6
|
* This type is to be extended with all controller extensions and methods that are hookable.
|
|
7
7
|
*/
|
|
8
8
|
type HookableControllerExtensions = {
|
|
9
9
|
editFlow: {
|
|
10
|
+
inlineEditEnd: true;
|
|
11
|
+
inlineEditStart: true;
|
|
10
12
|
onAfterSave: true;
|
|
11
13
|
onBeforeSave: true;
|
|
12
14
|
};
|
|
@@ -26,7 +28,7 @@ type HandlerConfiguration<CExtName extends keyof HookableControllerExtensions> =
|
|
|
26
28
|
method: keyof HookableControllerExtensions[CExtName];
|
|
27
29
|
};
|
|
28
30
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
29
|
-
type HandlerRegistration = HandlerConfiguration<any> & { targetMethod: string };
|
|
31
|
+
type HandlerRegistration = HandlerConfiguration<any> & { targetMethod: string; handlerFunction?: Function };
|
|
30
32
|
|
|
31
33
|
type FunctionMap = {
|
|
32
34
|
[key: string]: Function;
|
|
@@ -121,6 +123,8 @@ function isAlreadyRegistered(existingRegistrations: HandlerRegistration[], newRe
|
|
|
121
123
|
);
|
|
122
124
|
}
|
|
123
125
|
|
|
126
|
+
export const hooks = Symbol("hooks");
|
|
127
|
+
|
|
124
128
|
/**
|
|
125
129
|
* Registers a method as controller extension hook handler.
|
|
126
130
|
*
|
|
@@ -133,10 +137,15 @@ export function controllerExtensionHandler<CExtName extends keyof HookableContro
|
|
|
133
137
|
name: CExtName,
|
|
134
138
|
method: keyof HookableControllerExtensions[CExtName]
|
|
135
139
|
): MethodDecorator {
|
|
136
|
-
return function (target: { constructor: Function }, propertyKey: string) {
|
|
140
|
+
return function (target: { constructor: Function & { [hooks]?: HandlerRegistration[] } }, propertyKey: string) {
|
|
137
141
|
const newRegistration = { name, method: String(method), targetMethod: propertyKey };
|
|
138
142
|
const index = registeredInstances.indexOf(target.constructor);
|
|
139
|
-
|
|
143
|
+
if (!target.constructor[hooks]) {
|
|
144
|
+
Object.defineProperty(target.constructor, hooks, {
|
|
145
|
+
value: []
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
target.constructor[hooks]?.push(newRegistration);
|
|
140
149
|
// We need to check if this exact handler is already registered as handlers are registered statically (on the constructor)
|
|
141
150
|
if (index !== -1 && !isAlreadyRegistered(registeredHandlers[index], newRegistration)) {
|
|
142
151
|
registeredHandlers[index].push(newRegistration);
|
|
@@ -153,23 +162,52 @@ export function controllerExtensionHandler<CExtName extends keyof HookableContro
|
|
|
153
162
|
* @param target.constructor
|
|
154
163
|
* @param controller PageController instance to get the controller extensions instances from
|
|
155
164
|
*/
|
|
156
|
-
export function initControllerExtensionHookHandlers(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
165
|
+
export function initControllerExtensionHookHandlers(
|
|
166
|
+
target: { constructor: Function & { [hooks]?: HandlerRegistration[] } } & { [hooks]?: HandlerRegistration[] },
|
|
167
|
+
controller: Controller
|
|
168
|
+
): void {
|
|
169
|
+
if (target.constructor[hooks]) {
|
|
170
|
+
let registeredHooks = target.constructor[hooks];
|
|
171
|
+
target[hooks] = deepClone(registeredHooks);
|
|
172
|
+
registeredHooks = target[hooks]!;
|
|
160
173
|
const indexableTarget = target as unknown as FunctionMap;
|
|
161
|
-
|
|
162
|
-
for (const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
indexableController[registeredHandler.name][`attach${String(registeredHandler.method)}`](handlerFunction);
|
|
174
|
+
const indexableController = controller as unknown as DeepFunctionMap;
|
|
175
|
+
for (const registeredHook of registeredHooks) {
|
|
176
|
+
registeredHook.handlerFunction = indexableTarget[registeredHook.targetMethod].bind(target);
|
|
177
|
+
indexableController[registeredHook.name][`attach${String(registeredHook.method)}`](registeredHook.handlerFunction);
|
|
166
178
|
controller.getView()?.attachBeforeExit(() => {
|
|
167
|
-
indexableController[
|
|
179
|
+
indexableController[registeredHook.name][`detach${String(registeredHook.method)}`](registeredHook.handlerFunction);
|
|
168
180
|
});
|
|
169
181
|
}
|
|
170
182
|
}
|
|
171
183
|
}
|
|
172
184
|
|
|
185
|
+
export function removeControllerExtensionHookHandlers(
|
|
186
|
+
target: { constructor: Function & { [hooks]?: HandlerRegistration[] } } & { [hooks]?: HandlerRegistration[] },
|
|
187
|
+
controller: Controller
|
|
188
|
+
): void {
|
|
189
|
+
if (target[hooks]) {
|
|
190
|
+
const registeredHooks = target[hooks];
|
|
191
|
+
const indexableController = controller as unknown as DeepFunctionMap;
|
|
192
|
+
for (const registeredHook of registeredHooks) {
|
|
193
|
+
indexableController[registeredHook.name]?.[`detach${String(registeredHook.method)}`]?.(registeredHook.handlerFunction);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export function propagateHookFromMixin(
|
|
199
|
+
target: Function & { [hooks]?: HandlerRegistration[] },
|
|
200
|
+
source: Function & { [hooks]?: HandlerRegistration[] }
|
|
201
|
+
): void {
|
|
202
|
+
if (source[hooks]) {
|
|
203
|
+
if (target[hooks]) {
|
|
204
|
+
target[hooks]!.splice(0, 0, ...source[hooks]);
|
|
205
|
+
} else {
|
|
206
|
+
Object.defineProperty(target, hooks, Object.getOwnPropertyDescriptor(source, hooks) || Object.create([]));
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
173
211
|
export function xmlViewPreprocessor(source: object, _caller?: unknown, _settings?: object): void {
|
|
174
212
|
const sourceView = source as XMLView;
|
|
175
213
|
const controller = sourceView.getController() as Controller | undefined;
|