@sapui5/sap.fe.core 1.120.16 → 1.120.18
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/core/.library +1 -1
- package/src/sap/fe/core/AppStateHandler.js +138 -45
- package/src/sap/fe/core/AppStateHandler.ts +135 -38
- package/src/sap/fe/core/ExtensionAPI.js +6 -2
- package/src/sap/fe/core/ExtensionAPI.ts +5 -1
- package/src/sap/fe/core/controllerextensions/EditFlow.js +3 -3
- package/src/sap/fe/core/controllerextensions/EditFlow.ts +4 -2
- package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +105 -98
- package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +16 -2
- package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.js +4 -3
- package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.ts +5 -3
- package/src/sap/fe/core/converters/controls/Common/Table.js +5 -2
- package/src/sap/fe/core/converters/controls/Common/Table.ts +4 -1
- package/src/sap/fe/core/fpm/manifest.json +1 -1
- package/src/sap/fe/core/helpers/AppStartupHelper.js +31 -1
- package/src/sap/fe/core/helpers/AppStartupHelper.ts +31 -0
- package/src/sap/fe/core/library.js +1 -1
- package/src/sap/fe/core/messagebundle_es.properties +1 -1
- package/src/sap/fe/core/messagebundle_fr.properties +2 -2
- package/src/sap/fe/core/rootView/Fcl.controller.js +5 -4
- package/src/sap/fe/core/rootView/Fcl.controller.ts +5 -4
- package/src/sap/fe/core/rootView/RootViewBaseController.js +4 -1
- package/src/sap/fe/core/rootView/RootViewBaseController.ts +4 -0
- package/src/sap/fe/core/services/RoutingServiceFactory.js +16 -3
- package/src/sap/fe/core/services/RoutingServiceFactory.ts +38 -8
- package/src/sap/fe/core/templating/UIFormatters.js +17 -1
- package/src/sap/fe/core/templating/UIFormatters.ts +23 -2
package/package.json
CHANGED
package/src/sap/fe/core/.library
CHANGED
|
@@ -11,6 +11,7 @@ sap.ui.define(["sap/base/Log", "sap/base/util/deepEqual", "sap/fe/core/helpers/C
|
|
|
11
11
|
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
|
12
12
|
const NavType = library.NavType;
|
|
13
13
|
const SKIP_MERGE_KEY = "skipMerge";
|
|
14
|
+
const REPLACE_COMPLETE_APPSTATE = "REPLACE_COMPLETE_APPSTATE";
|
|
14
15
|
let AppStateHandler = (_dec = defineUI5Class("sap.fe.core.AppStateHandler"), _dec(_class = /*#__PURE__*/function (_BaseObject) {
|
|
15
16
|
_inheritsLoose(AppStateHandler, _BaseObject);
|
|
16
17
|
function AppStateHandler(oAppComponent) {
|
|
@@ -19,7 +20,7 @@ sap.ui.define(["sap/base/Log", "sap/base/util/deepEqual", "sap/fe/core/helpers/C
|
|
|
19
20
|
_this._mCurrentAppState = {};
|
|
20
21
|
_this.oAppComponent = oAppComponent;
|
|
21
22
|
_this.sId = `${oAppComponent.getId()}/AppStateHandler`;
|
|
22
|
-
_this.
|
|
23
|
+
_this.simultaneousCreateRequest = {};
|
|
23
24
|
_this.bNoRouteChange = false;
|
|
24
25
|
Log.info("APPSTATE : Appstate handler initialized");
|
|
25
26
|
return _this;
|
|
@@ -29,6 +30,116 @@ sap.ui.define(["sap/base/Log", "sap/base/util/deepEqual", "sap/fe/core/helpers/C
|
|
|
29
30
|
return this.sId;
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Get the view-specific appstate.
|
|
35
|
+
*
|
|
36
|
+
* @param innerAppState Overall appstate
|
|
37
|
+
* @param stateIdentifier State identifier, id of the local view
|
|
38
|
+
* @returns Inner appstate
|
|
39
|
+
*/;
|
|
40
|
+
_proto._getInnerAppStateForView = function _getInnerAppStateForView(innerAppState, stateIdentifier) {
|
|
41
|
+
if (stateIdentifier === REPLACE_COMPLETE_APPSTATE || !innerAppState) {
|
|
42
|
+
// overall app state needs to be considered.
|
|
43
|
+
return innerAppState;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// we take the subset of the app state wrt to the local view id.
|
|
47
|
+
return {
|
|
48
|
+
[stateIdentifier]: innerAppState[stateIdentifier] || {}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Add appstate in hash.
|
|
54
|
+
*
|
|
55
|
+
* @param appStateKey Appstate key
|
|
56
|
+
* @param stateIdentifier State identifier, Id of the local view
|
|
57
|
+
*/;
|
|
58
|
+
_proto._addAppStateInHash = function _addAppStateInHash(appStateKey, stateIdentifier) {
|
|
59
|
+
const appComponent = this.oAppComponent,
|
|
60
|
+
navigationService = appComponent.getNavigationService(),
|
|
61
|
+
routerProxy = appComponent.getRouterProxy(),
|
|
62
|
+
hash = routerProxy.getHash(),
|
|
63
|
+
isStickyMode = ModelHelper.isStickySessionSupported(appComponent.getMetaModel()),
|
|
64
|
+
newHash = navigationService.replaceInnerAppStateKey(routerProxy.getFullHash(), appStateKey);
|
|
65
|
+
if (this.simultaneousCreateRequest[stateIdentifier] === 0 && newHash !== hash) {
|
|
66
|
+
routerProxy.navToHash(newHash, undefined, undefined, undefined, !isStickyMode);
|
|
67
|
+
this.bNoRouteChange = true;
|
|
68
|
+
}
|
|
69
|
+
Log.info("APPSTATE: navToHash");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Create Appstate Key.
|
|
74
|
+
*
|
|
75
|
+
* @param appStateData Appstate
|
|
76
|
+
* @param stateIdentifier State identifier, Id of the local view
|
|
77
|
+
* @returns Appstate Key
|
|
78
|
+
*/;
|
|
79
|
+
_proto._createAppStateKey = async function _createAppStateKey(appStateData, stateIdentifier) {
|
|
80
|
+
const appComponent = this.oAppComponent,
|
|
81
|
+
navigationService = appComponent.getNavigationService();
|
|
82
|
+
if (this.simultaneousCreateRequest[stateIdentifier]) {
|
|
83
|
+
// any other value
|
|
84
|
+
this.simultaneousCreateRequest[stateIdentifier]++;
|
|
85
|
+
} else {
|
|
86
|
+
// 0 or undefined
|
|
87
|
+
this.simultaneousCreateRequest[stateIdentifier] = 1;
|
|
88
|
+
}
|
|
89
|
+
const appStateKey = await navigationService.storeInnerAppStateAsync(appStateData, true, true);
|
|
90
|
+
this.simultaneousCreateRequest[stateIdentifier]--;
|
|
91
|
+
Log.info("APPSTATE: Appstate stored");
|
|
92
|
+
return appStateKey;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Creates appstate info.
|
|
97
|
+
*
|
|
98
|
+
* @param innerAppState
|
|
99
|
+
* @param createAppParameters Parameters for creating a new appstate
|
|
100
|
+
* @param createAppParameters.replaceHash A Boolean that determines whether to replace the hash with the newly generated key
|
|
101
|
+
* @param createAppParameters.viewId Id of the view for which we need to create the app state. This allows us to create or update view-specific appstate.
|
|
102
|
+
* @returns A promise that resolves the stored data or appstate keys
|
|
103
|
+
*/;
|
|
104
|
+
_proto._getAppStateInfo = async function _getAppStateInfo(innerAppState, createAppParameters) {
|
|
105
|
+
const appComponent = this.oAppComponent;
|
|
106
|
+
const {
|
|
107
|
+
replaceHash = true,
|
|
108
|
+
viewId: stateIdentifier = REPLACE_COMPLETE_APPSTATE
|
|
109
|
+
} = createAppParameters ?? {};
|
|
110
|
+
let appStateKey = null;
|
|
111
|
+
let appStateData = {
|
|
112
|
+
appState: this._mCurrentAppState
|
|
113
|
+
};
|
|
114
|
+
const currentStateToUpdate = this._getInnerAppStateForView(this._mCurrentAppState, stateIdentifier);
|
|
115
|
+
if (innerAppState && !deepEqual(currentStateToUpdate, innerAppState)) {
|
|
116
|
+
//
|
|
117
|
+
this._mCurrentAppState = {
|
|
118
|
+
...this._mCurrentAppState,
|
|
119
|
+
...innerAppState
|
|
120
|
+
};
|
|
121
|
+
appStateData = {
|
|
122
|
+
appState: this._mCurrentAppState
|
|
123
|
+
};
|
|
124
|
+
try {
|
|
125
|
+
appStateKey = await this._createAppStateKey(appStateData, stateIdentifier);
|
|
126
|
+
if (replaceHash === true) {
|
|
127
|
+
this._addAppStateInHash(appStateKey, stateIdentifier);
|
|
128
|
+
}
|
|
129
|
+
} catch (oError) {
|
|
130
|
+
Log.error(oError);
|
|
131
|
+
}
|
|
132
|
+
} else {
|
|
133
|
+
const routerProxy = appComponent.getRouterProxy(),
|
|
134
|
+
hash = routerProxy.getHash();
|
|
135
|
+
appStateKey = routerProxy.findAppStateInHash(hash);
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
appStateData,
|
|
139
|
+
appStateKey
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
32
143
|
/**
|
|
33
144
|
* Creates or updates the appstate.
|
|
34
145
|
* Replaces the hash with the new appstate based on replaceHash
|
|
@@ -36,25 +147,32 @@ sap.ui.define(["sap/base/Log", "sap/base/util/deepEqual", "sap/fe/core/helpers/C
|
|
|
36
147
|
* @param createAppParameters Parameters for creating new appstate
|
|
37
148
|
* @param createAppParameters.replaceHash Boolean which determines to replace the hash with the new generated key
|
|
38
149
|
* @param createAppParameters.skipMerge Boolean which determines to skip the key user shine through
|
|
39
|
-
* @
|
|
150
|
+
* @param createAppParameters.viewId Id of the view for which we need to create the app state. This allows us to create or update view-specific appstate.
|
|
151
|
+
* @returns A promise resolving the stored data or appstate key
|
|
40
152
|
*/;
|
|
41
153
|
_proto.createAppState = async function createAppState(createAppParameters) {
|
|
42
|
-
|
|
154
|
+
const appComponent = this.oAppComponent;
|
|
155
|
+
if (!appComponent.getEnvironmentCapabilities().getCapabilities().AppState || BusyLocker.isLocked(this)) {
|
|
43
156
|
return;
|
|
44
157
|
}
|
|
45
158
|
const {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
controller = this.oAppComponent.getRootControl().getController(),
|
|
53
|
-
isStickyMode = ModelHelper.isStickySessionSupported(this.oAppComponent.getMetaModel());
|
|
54
|
-
if (!controller.viewState) {
|
|
55
|
-
throw new Error(`viewState controller extension not available for controller: ${controller.getMetadata().getName()}`);
|
|
159
|
+
skipMerge = false,
|
|
160
|
+
viewId: stateIdentifier = REPLACE_COMPLETE_APPSTATE
|
|
161
|
+
} = createAppParameters ?? {},
|
|
162
|
+
rootController = appComponent.getRootControl().getController();
|
|
163
|
+
if (!rootController.viewState) {
|
|
164
|
+
throw new Error(`viewState controller extension not available for controller: ${rootController.getMetadata().getName()}`);
|
|
56
165
|
}
|
|
57
|
-
|
|
166
|
+
|
|
167
|
+
// In case, on load of FCL app we have multiple views(LR, OP, sub-OP...) and url has iAppState(1).
|
|
168
|
+
// The LR view loads with applied iAppState(1) and calls createAppState(example: onSearch event in LR) before OP is loaded.
|
|
169
|
+
// This creates iAppState(2) before iAppState(1) is applied to OP.
|
|
170
|
+
// So, we try to wait till the routing is complete.
|
|
171
|
+
await rootController.routingIsComplete();
|
|
172
|
+
|
|
173
|
+
// Get appState to update
|
|
174
|
+
let innerAppState = await rootController.viewState.retrieveViewState();
|
|
175
|
+
innerAppState = this._getInnerAppStateForView(innerAppState, stateIdentifier);
|
|
58
176
|
if (skipMerge) {
|
|
59
177
|
innerAppState = {
|
|
60
178
|
...innerAppState,
|
|
@@ -63,35 +181,7 @@ sap.ui.define(["sap/base/Log", "sap/base/util/deepEqual", "sap/fe/core/helpers/C
|
|
|
63
181
|
}
|
|
64
182
|
};
|
|
65
183
|
}
|
|
66
|
-
|
|
67
|
-
appState: innerAppState
|
|
68
|
-
};
|
|
69
|
-
let appStateKey = null;
|
|
70
|
-
if (innerAppState && !deepEqual(this._mCurrentAppState, innerAppState)) {
|
|
71
|
-
this._mCurrentAppState = innerAppState;
|
|
72
|
-
try {
|
|
73
|
-
this.nbSimultaneousCreateRequest++;
|
|
74
|
-
appStateKey = await navigationService.storeInnerAppStateAsync(appStateData, true, true);
|
|
75
|
-
Log.info("APPSTATE: Appstate stored");
|
|
76
|
-
if (replaceHash === true) {
|
|
77
|
-
const sNewHash = navigationService.replaceInnerAppStateKey(hash, appStateKey);
|
|
78
|
-
this.nbSimultaneousCreateRequest--;
|
|
79
|
-
if (this.nbSimultaneousCreateRequest === 0 && sNewHash !== hash) {
|
|
80
|
-
routerProxy.navToHash(sNewHash, undefined, undefined, undefined, !isStickyMode);
|
|
81
|
-
this.bNoRouteChange = true;
|
|
82
|
-
}
|
|
83
|
-
Log.info("APPSTATE: navToHash");
|
|
84
|
-
}
|
|
85
|
-
} catch (oError) {
|
|
86
|
-
Log.error(oError);
|
|
87
|
-
}
|
|
88
|
-
} else {
|
|
89
|
-
appStateKey = routerProxy.findAppStateInHash(hash);
|
|
90
|
-
}
|
|
91
|
-
return {
|
|
92
|
-
appStateData: appStateData,
|
|
93
|
-
appStateKey: appStateKey
|
|
94
|
-
};
|
|
184
|
+
return this._getAppStateInfo(innerAppState, createAppParameters);
|
|
95
185
|
};
|
|
96
186
|
_proto._createNavigationParameters = function _createNavigationParameters(oAppData, sNavType) {
|
|
97
187
|
return Object.assign({}, oAppData, {
|
|
@@ -182,7 +272,10 @@ sap.ui.define(["sap/base/Log", "sap/base/util/deepEqual", "sap/fe/core/helpers/C
|
|
|
182
272
|
const appStateData = this._getAppStateData(oAppData, viewId, sNavType);
|
|
183
273
|
// fetch the skipMerge flag from appState for save as tile
|
|
184
274
|
const skipMerge = oAppData === null || oAppData === void 0 ? void 0 : (_oAppData$appState = oAppData.appState) === null || _oAppData$appState === void 0 ? void 0 : _oAppData$appState[SKIP_MERGE_KEY];
|
|
185
|
-
this._mCurrentAppState = sNavType === NavType.iAppState || sNavType === NavType.hybrid ?
|
|
275
|
+
this._mCurrentAppState = sNavType === NavType.iAppState || sNavType === NavType.hybrid ? {
|
|
276
|
+
...this._mCurrentAppState,
|
|
277
|
+
...appStateData
|
|
278
|
+
} : {};
|
|
186
279
|
let shouldApplyState = true;
|
|
187
280
|
if (!oRootController.viewState) {
|
|
188
281
|
throw new Error(`viewState extension required for controller ${oRootController.getMetadata().getName()}`);
|
|
@@ -232,4 +325,4 @@ sap.ui.define(["sap/base/Log", "sap/base/util/deepEqual", "sap/fe/core/helpers/C
|
|
|
232
325
|
*/
|
|
233
326
|
return AppStateHandler;
|
|
234
327
|
}, true);
|
|
235
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJOYXZUeXBlIiwibGlicmFyeSIsIlNLSVBfTUVSR0VfS0VZIiwiQXBwU3RhdGVIYW5kbGVyIiwiZGVmaW5lVUk1Q2xhc3MiLCJvQXBwQ29tcG9uZW50IiwiX21DdXJyZW50QXBwU3RhdGUiLCJzSWQiLCJnZXRJZCIsIm5iU2ltdWx0YW5lb3VzQ3JlYXRlUmVxdWVzdCIsImJOb1JvdXRlQ2hhbmdlIiwiTG9nIiwiaW5mbyIsImNyZWF0ZUFwcFN0YXRlIiwiY3JlYXRlQXBwUGFyYW1ldGVycyIsImdldEVudmlyb25tZW50Q2FwYWJpbGl0aWVzIiwiZ2V0Q2FwYWJpbGl0aWVzIiwiQXBwU3RhdGUiLCJCdXN5TG9ja2VyIiwiaXNMb2NrZWQiLCJyZXBsYWNlSGFzaCIsInNraXBNZXJnZSIsIm5hdmlnYXRpb25TZXJ2aWNlIiwiZ2V0TmF2aWdhdGlvblNlcnZpY2UiLCJyb3V0ZXJQcm94eSIsImdldFJvdXRlclByb3h5IiwiaGFzaCIsImdldEhhc2giLCJjb250cm9sbGVyIiwiZ2V0Um9vdENvbnRyb2wiLCJnZXRDb250cm9sbGVyIiwiaXNTdGlja3lNb2RlIiwiTW9kZWxIZWxwZXIiLCJpc1N0aWNreVNlc3Npb25TdXBwb3J0ZWQiLCJnZXRNZXRhTW9kZWwiLCJ2aWV3U3RhdGUiLCJFcnJvciIsImdldE1ldGFkYXRhIiwiZ2V0TmFtZSIsImlubmVyQXBwU3RhdGUiLCJyZXRyaWV2ZVZpZXdTdGF0ZSIsImFwcFN0YXRlRGF0YSIsImFwcFN0YXRlIiwiYXBwU3RhdGVLZXkiLCJkZWVwRXF1YWwiLCJzdG9yZUlubmVyQXBwU3RhdGVBc3luYyIsInNOZXdIYXNoIiwicmVwbGFjZUlubmVyQXBwU3RhdGVLZXkiLCJuYXZUb0hhc2giLCJ1bmRlZmluZWQiLCJvRXJyb3IiLCJlcnJvciIsImZpbmRBcHBTdGF0ZUluSGFzaCIsIl9jcmVhdGVOYXZpZ2F0aW9uUGFyYW1ldGVycyIsIm9BcHBEYXRhIiwic05hdlR5cGUiLCJPYmplY3QiLCJhc3NpZ24iLCJzZWxlY3Rpb25WYXJpYW50RGVmYXVsdHMiLCJvRGVmYXVsdGVkU2VsZWN0aW9uVmFyaWFudCIsInNlbGVjdGlvblZhcmlhbnQiLCJvU2VsZWN0aW9uVmFyaWFudCIsInJlcXVpcmVzU3RhbmRhcmRWYXJpYW50IiwiYk5hdlNlbFZhckhhc0RlZmF1bHRzT25seSIsIm5hdmlnYXRpb25UeXBlIiwiX2NoZWNrSWZMYXN0U2VlblJlY29yZCIsInZpZXciLCJpbnRlcm5hbE1vZGVsQ29udGV4dCIsImdldEJpbmRpbmdDb250ZXh0IiwiZ2V0UHJvcGVydHkiLCJ0ZWNobmljYWxLZXlzT2JqZWN0IiwiYmluZGluZ0NvbnRleHQiLCJwYXRoIiwiZ2V0UGF0aCIsIm1ldGFNb2RlbCIsImdldE1vZGVsIiwibWV0YVBhdGgiLCJnZXRNZXRhUGF0aCIsInRlY2huaWNhbEtleXMiLCJnZXRPYmplY3QiLCJlbGVtZW50Iiwia2V5VmFsdWUiLCJzZXRQcm9wZXJ0eSIsIl9nZXRBcHBTdGF0ZURhdGEiLCJ2aWV3SWQiLCJuYXZUeXBlIiwia2V5IiwiaSIsImh5YnJpZCIsImlBcHBTdGF0ZSIsImtleXMiLCJsZW5ndGgiLCJhcHBseUFwcFN0YXRlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJjaGVja0lmTGFzdFNlZW5SZWNvcmQiLCJsb2NrIiwib05hdmlnYXRpb25TZXJ2aWNlIiwidG9FUzZQcm9taXNlIiwicGFyc2VOYXZpZ2F0aW9uIiwiY2F0Y2giLCJhRXJyb3JEYXRhIiwid2FybmluZyIsInRoZW4iLCJhUmVzdWx0cyIsImluaXRpYWwiLCJvUm9vdENvbnRyb2xsZXIiLCJzaG91bGRBcHBseVN0YXRlIiwiX2lzU3RhdGVFbXB0eUZvcklBcHBTdGF0ZU5hdlR5cGUiLCJfZ2V0SW5pdGlhbFN0YXRlQXBwbGllZCIsIl9zZXRJbml0aWFsU3RhdGVBcHBsaWVkIiwiYXBwbHlWaWV3U3RhdGUiLCJmaW5hbGx5IiwidW5sb2NrIiwiY2hlY2tJZlJvdXRlQ2hhbmdlZEJ5SUFwcCIsInJlc2V0Um91dGVDaGFuZ2VkQnlJQXBwIiwiQmFzZU9iamVjdCJdLCJzb3VyY2VSb290IjoiLiIsInNvdXJjZXMiOlsiQXBwU3RhdGVIYW5kbGVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBMb2cgZnJvbSBcInNhcC9iYXNlL0xvZ1wiO1xuaW1wb3J0IGRlZXBFcXVhbCBmcm9tIFwic2FwL2Jhc2UvdXRpbC9kZWVwRXF1YWxcIjtcbmltcG9ydCB0eXBlIEFwcENvbXBvbmVudCBmcm9tIFwic2FwL2ZlL2NvcmUvQXBwQ29tcG9uZW50XCI7XG5pbXBvcnQgdHlwZSB7IE5hdmlnYXRpb25QYXJhbWV0ZXIgfSBmcm9tIFwic2FwL2ZlL2NvcmUvY29udHJvbGxlcmV4dGVuc2lvbnMvVmlld1N0YXRlXCI7XG5pbXBvcnQgeyBkZWZpbmVVSTVDbGFzcyB9IGZyb20gXCJzYXAvZmUvY29yZS9oZWxwZXJzL0NsYXNzU3VwcG9ydFwiO1xuaW1wb3J0IHR5cGUgeyBJbnRlcm5hbE1vZGVsQ29udGV4dCB9IGZyb20gXCJzYXAvZmUvY29yZS9oZWxwZXJzL01vZGVsSGVscGVyXCI7XG5pbXBvcnQgdG9FUzZQcm9taXNlIGZyb20gXCJzYXAvZmUvY29yZS9oZWxwZXJzL1RvRVM2UHJvbWlzZVwiO1xuaW1wb3J0IHR5cGUgeyBTZWxlY3Rpb25WYXJpYW50IH0gZnJvbSBcInNhcC9mZS9uYXZpZ2F0aW9uL1NlbGVjdGlvblZhcmlhbnRcIjtcbmltcG9ydCBsaWJyYXJ5IGZyb20gXCJzYXAvZmUvbmF2aWdhdGlvbi9saWJyYXJ5XCI7XG5pbXBvcnQgQmFzZU9iamVjdCBmcm9tIFwic2FwL3VpL2Jhc2UvT2JqZWN0XCI7XG5pbXBvcnQgdHlwZSBWaWV3IGZyb20gXCJzYXAvdWkvY29yZS9tdmMvVmlld1wiO1xuaW1wb3J0IHR5cGUgQ29udGV4dCBmcm9tIFwic2FwL3VpL21vZGVsL29kYXRhL3Y0L0NvbnRleHRcIjtcbmltcG9ydCBCdXN5TG9ja2VyIGZyb20gXCIuL2NvbnRyb2xsZXJleHRlbnNpb25zL0J1c3lMb2NrZXJcIjtcbmltcG9ydCBNb2RlbEhlbHBlciBmcm9tIFwiLi9oZWxwZXJzL01vZGVsSGVscGVyXCI7XG5cbmNvbnN0IE5hdlR5cGUgPSBsaWJyYXJ5Lk5hdlR5cGU7XG50eXBlIEFwcFN0YXRlID0ge1xuXHRza2lwTWVyZ2U/OiBib29sZWFuO1xuXHRba2V5OiBzdHJpbmddOiB1bmtub3duO1xufTtcbmV4cG9ydCB0eXBlIEFwcERhdGEgPSB7XG5cdG9EZWZhdWx0ZWRTZWxlY3Rpb25WYXJpYW50OiBTZWxlY3Rpb25WYXJpYW50O1xuXHRvU2VsZWN0aW9uVmFyaWFudDogU2VsZWN0aW9uVmFyaWFudDtcblx0Yk5hdlNlbFZhckhhc0RlZmF1bHRzT25seTogYm9vbGVhbjtcblx0YXBwU3RhdGU6IEFwcFN0YXRlO1xuXHRpQXBwU3RhdGU/OiB7XG5cdFx0YXBwU3RhdGU6IEFwcFN0YXRlO1xuXHR9O1xufTtcbmNvbnN0IFNLSVBfTUVSR0VfS0VZID0gXCJza2lwTWVyZ2VcIjtcbmV4cG9ydCB0eXBlIElBcHBTdGF0ZSA9IHtcblx0YXBwU3RhdGU6IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xufTtcblxuZXhwb3J0IHR5cGUgQXBwRGF0YUluZm8gPSB7XG5cdGFwcFN0YXRlRGF0YTogeyBhcHBTdGF0ZTogb2JqZWN0IHwgdW5kZWZpbmVkIH07XG5cdGFwcFN0YXRlS2V5OiBzdHJpbmcgfCBudWxsO1xufTtcblxuQGRlZmluZVVJNUNsYXNzKFwic2FwLmZlLmNvcmUuQXBwU3RhdGVIYW5kbGVyXCIpXG5jbGFzcyBBcHBTdGF0ZUhhbmRsZXIgZXh0ZW5kcyBCYXNlT2JqZWN0IHtcblx0cHVibGljIHNJZDogc3RyaW5nO1xuXG5cdHB1YmxpYyBvQXBwQ29tcG9uZW50OiBBcHBDb21wb25lbnQ7XG5cblx0cHVibGljIGJOb1JvdXRlQ2hhbmdlOiBib29sZWFuO1xuXG5cdHByaXZhdGUgX21DdXJyZW50QXBwU3RhdGU/OiBBcHBTdGF0ZSA9IHt9O1xuXG5cdG5iU2ltdWx0YW5lb3VzQ3JlYXRlUmVxdWVzdDogbnVtYmVyO1xuXG5cdGNvbnN0cnVjdG9yKG9BcHBDb21wb25lbnQ6IEFwcENvbXBvbmVudCkge1xuXHRcdHN1cGVyKCk7XG5cdFx0dGhpcy5vQXBwQ29tcG9uZW50ID0gb0FwcENvbXBvbmVudDtcblx0XHR0aGlzLnNJZCA9IGAke29BcHBDb21wb25lbnQuZ2V0SWQoKX0vQXBwU3RhdGVIYW5kbGVyYDtcblx0XHR0aGlzLm5iU2ltdWx0YW5lb3VzQ3JlYXRlUmVxdWVzdCA9IDA7XG5cdFx0dGhpcy5iTm9Sb3V0ZUNoYW5nZSA9IGZhbHNlO1xuXHRcdExvZy5pbmZvKFwiQVBQU1RBVEUgOiBBcHBzdGF0ZSBoYW5kbGVyIGluaXRpYWxpemVkXCIpO1xuXHR9XG5cblx0Z2V0SWQoKSB7XG5cdFx0cmV0dXJuIHRoaXMuc0lkO1xuXHR9XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgb3IgdXBkYXRlcyB0aGUgYXBwc3RhdGUuXG5cdCAqIFJlcGxhY2VzIHRoZSBoYXNoIHdpdGggdGhlIG5ldyBhcHBzdGF0ZSBiYXNlZCBvbiByZXBsYWNlSGFzaFxuXHQgKlxuXHQgKiBAcGFyYW0gY3JlYXRlQXBwUGFyYW1ldGVycyBQYXJhbWV0ZXJzIGZvciBjcmVhdGluZyBuZXcgYXBwc3RhdGVcblx0ICogQHBhcmFtIGNyZWF0ZUFwcFBhcmFtZXRlcnMucmVwbGFjZUhhc2ggQm9vbGVhbiB3aGljaCBkZXRlcm1pbmVzIHRvIHJlcGxhY2UgdGhlIGhhc2ggd2l0aCB0aGUgbmV3IGdlbmVyYXRlZCBrZXlcblx0ICogQHBhcmFtIGNyZWF0ZUFwcFBhcmFtZXRlcnMuc2tpcE1lcmdlIEJvb2xlYW4gd2hpY2ggZGV0ZXJtaW5lcyB0byBza2lwIHRoZSBrZXkgdXNlciBzaGluZSB0aHJvdWdoXG5cdCAqIEByZXR1cm5zIEEgcHJvbWlzZSByZXNvbHZpbmcgdGhlIHN0b3JlZCBkYXRhIG9yIGFwcHN0YXRlIGtleSBiYXNlZCBvbiByZXR1cm5LZXkgcHJvcGVydHlcblx0ICovXG5cdGFzeW5jIGNyZWF0ZUFwcFN0YXRlKGNyZWF0ZUFwcFBhcmFtZXRlcnM/OiB7IHJlcGxhY2VIYXNoPzogYm9vbGVhbjsgc2tpcE1lcmdlPzogYm9vbGVhbiB9KTogUHJvbWlzZTx2b2lkIHwgQXBwRGF0YUluZm8+IHtcblx0XHRpZiAoIXRoaXMub0FwcENvbXBvbmVudC5nZXRFbnZpcm9ubWVudENhcGFiaWxpdGllcygpLmdldENhcGFiaWxpdGllcygpLkFwcFN0YXRlIHx8IEJ1c3lMb2NrZXIuaXNMb2NrZWQodGhpcykpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0Y29uc3QgeyByZXBsYWNlSGFzaCA9IHRydWUsIHNraXBNZXJnZSA9IGZhbHNlIH0gPSBjcmVhdGVBcHBQYXJhbWV0ZXJzIHx8IHt9O1xuXG5cdFx0Y29uc3QgbmF2aWdhdGlvblNlcnZpY2UgPSB0aGlzLm9BcHBDb21wb25lbnQuZ2V0TmF2aWdhdGlvblNlcnZpY2UoKSxcblx0XHRcdHJvdXRlclByb3h5ID0gdGhpcy5vQXBwQ29tcG9uZW50LmdldFJvdXRlclByb3h5KCksXG5cdFx0XHRoYXNoID0gcm91dGVyUHJveHkuZ2V0SGFzaCgpLFxuXHRcdFx0Y29udHJvbGxlciA9IHRoaXMub0FwcENvbXBvbmVudC5nZXRSb290Q29udHJvbCgpLmdldENvbnRyb2xsZXIoKSxcblx0XHRcdGlzU3RpY2t5TW9kZSA9IE1vZGVsSGVscGVyLmlzU3RpY2t5U2Vzc2lvblN1cHBvcnRlZCh0aGlzLm9BcHBDb21wb25lbnQuZ2V0TWV0YU1vZGVsKCkpO1xuXG5cdFx0aWYgKCFjb250cm9sbGVyLnZpZXdTdGF0ZSkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKGB2aWV3U3RhdGUgY29udHJvbGxlciBleHRlbnNpb24gbm90IGF2YWlsYWJsZSBmb3IgY29udHJvbGxlcjogJHtjb250cm9sbGVyLmdldE1ldGFkYXRhKCkuZ2V0TmFtZSgpfWApO1xuXHRcdH1cblx0XHRsZXQgaW5uZXJBcHBTdGF0ZSA9IGF3YWl0IGNvbnRyb2xsZXIudmlld1N0YXRlLnJldHJpZXZlVmlld1N0YXRlKCk7XG5cdFx0aWYgKHNraXBNZXJnZSkge1xuXHRcdFx0aW5uZXJBcHBTdGF0ZSA9IHsgLi4uaW5uZXJBcHBTdGF0ZSwgLi4ueyBza2lwTWVyZ2UgfSB9O1xuXHRcdH1cblx0XHRjb25zdCBhcHBTdGF0ZURhdGEgPSB7IGFwcFN0YXRlOiBpbm5lckFwcFN0YXRlIH07XG5cdFx0bGV0IGFwcFN0YXRlS2V5OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblx0XHRpZiAoaW5uZXJBcHBTdGF0ZSAmJiAhZGVlcEVxdWFsKHRoaXMuX21DdXJyZW50QXBwU3RhdGUsIGlubmVyQXBwU3RhdGUpKSB7XG5cdFx0XHR0aGlzLl9tQ3VycmVudEFwcFN0YXRlID0gaW5uZXJBcHBTdGF0ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcblx0XHRcdHRyeSB7XG5cdFx0XHRcdHRoaXMubmJTaW11bHRhbmVvdXNDcmVhdGVSZXF1ZXN0Kys7XG5cdFx0XHRcdGFwcFN0YXRlS2V5ID0gYXdhaXQgbmF2aWdhdGlvblNlcnZpY2Uuc3RvcmVJbm5lckFwcFN0YXRlQXN5bmMoYXBwU3RhdGVEYXRhLCB0cnVlLCB0cnVlKTtcblx0XHRcdFx0TG9nLmluZm8oXCJBUFBTVEFURTogQXBwc3RhdGUgc3RvcmVkXCIpO1xuXHRcdFx0XHRpZiAocmVwbGFjZUhhc2ggPT09IHRydWUpIHtcblx0XHRcdFx0XHRjb25zdCBzTmV3SGFzaCA9IG5hdmlnYXRpb25TZXJ2aWNlLnJlcGxhY2VJbm5lckFwcFN0YXRlS2V5KGhhc2gsIGFwcFN0YXRlS2V5KTtcblx0XHRcdFx0XHR0aGlzLm5iU2ltdWx0YW5lb3VzQ3JlYXRlUmVxdWVzdC0tO1xuXHRcdFx0XHRcdGlmICh0aGlzLm5iU2ltdWx0YW5lb3VzQ3JlYXRlUmVxdWVzdCA9PT0gMCAmJiBzTmV3SGFzaCAhPT0gaGFzaCkge1xuXHRcdFx0XHRcdFx0cm91dGVyUHJveHkubmF2VG9IYXNoKHNOZXdIYXNoLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCAhaXNTdGlja3lNb2RlKTtcblx0XHRcdFx0XHRcdHRoaXMuYk5vUm91dGVDaGFuZ2UgPSB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRMb2cuaW5mbyhcIkFQUFNUQVRFOiBuYXZUb0hhc2hcIik7XG5cdFx0XHRcdH1cblx0XHRcdH0gY2F0Y2ggKG9FcnJvcjogdW5rbm93bikge1xuXHRcdFx0XHRMb2cuZXJyb3Iob0Vycm9yIGFzIHN0cmluZyk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdGFwcFN0YXRlS2V5ID0gcm91dGVyUHJveHkuZmluZEFwcFN0YXRlSW5IYXNoKGhhc2gpIGFzIHN0cmluZztcblx0XHR9XG5cdFx0cmV0dXJuIHtcblx0XHRcdGFwcFN0YXRlRGF0YTogYXBwU3RhdGVEYXRhLFxuXHRcdFx0YXBwU3RhdGVLZXk6IGFwcFN0YXRlS2V5XG5cdFx0fTtcblx0fVxuXG5cdF9jcmVhdGVOYXZpZ2F0aW9uUGFyYW1ldGVycyhvQXBwRGF0YTogQXBwRGF0YSwgc05hdlR5cGU6IHN0cmluZyk6IE5hdmlnYXRpb25QYXJhbWV0ZXIge1xuXHRcdHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBvQXBwRGF0YSwge1xuXHRcdFx0c2VsZWN0aW9uVmFyaWFudERlZmF1bHRzOiBvQXBwRGF0YS5vRGVmYXVsdGVkU2VsZWN0aW9uVmFyaWFudCxcblx0XHRcdHNlbGVjdGlvblZhcmlhbnQ6IG9BcHBEYXRhLm9TZWxlY3Rpb25WYXJpYW50LFxuXHRcdFx0cmVxdWlyZXNTdGFuZGFyZFZhcmlhbnQ6ICFvQXBwRGF0YS5iTmF2U2VsVmFySGFzRGVmYXVsdHNPbmx5LFxuXHRcdFx0bmF2aWdhdGlvblR5cGU6IHNOYXZUeXBlXG5cdFx0fSk7XG5cdH1cblxuXHRfY2hlY2tJZkxhc3RTZWVuUmVjb3JkKHZpZXc/OiBWaWV3KSB7XG5cdFx0Ly9nZXR0aW5nIHRoZSBpbnRlcm5hbCBtb2RlbCBjb250ZXh0IGluIG9yZGVyIHRvIGZldGNoIHRoZSB0ZWNobmljYWxrZXlzIG9mIGxhc3Qgc2VlbiByZWNvcmQgYW5kIGNsb3NlIGNvbHVtbiBmbGFnIHNldCBpbiB0aGUgaW50ZXJuYWxyb3V0aW5nIGZvciByZXRhaW5pbmcgc2V0dGluZ3MgaW4gcGVyc2lzdGVuY2UgbW9kZVxuXHRcdGNvbnN0IGludGVybmFsTW9kZWxDb250ZXh0ID0gdmlldyAmJiAodmlldy5nZXRCaW5kaW5nQ29udGV4dChcImludGVybmFsXCIpIGFzIEludGVybmFsTW9kZWxDb250ZXh0KTtcblx0XHRpZiAoaW50ZXJuYWxNb2RlbENvbnRleHQgJiYgaW50ZXJuYWxNb2RlbENvbnRleHQuZ2V0UHJvcGVydHkoXCJmY2xDb2x1bW5DbG9zZWRcIikgPT09IHRydWUpIHtcblx0XHRcdGNvbnN0IHRlY2huaWNhbEtleXNPYmplY3QgPSBpbnRlcm5hbE1vZGVsQ29udGV4dC5nZXRQcm9wZXJ0eShcInRlY2huaWNhbEtleXNPZkxhc3RTZWVuUmVjb3JkXCIpO1xuXHRcdFx0Y29uc3QgYmluZGluZ0NvbnRleHQgPSB2aWV3Py5nZXRCaW5kaW5nQ29udGV4dCgpIGFzIENvbnRleHQ7XG5cdFx0XHRjb25zdCBwYXRoID0gKGJpbmRpbmdDb250ZXh0ICYmIGJpbmRpbmdDb250ZXh0LmdldFBhdGgoKSkgfHwgXCJcIjtcblx0XHRcdGNvbnN0IG1ldGFNb2RlbCA9IGJpbmRpbmdDb250ZXh0Py5nZXRNb2RlbCgpLmdldE1ldGFNb2RlbCgpO1xuXHRcdFx0Y29uc3QgbWV0YVBhdGggPSBtZXRhTW9kZWw/LmdldE1ldGFQYXRoKHBhdGgpO1xuXHRcdFx0Y29uc3QgdGVjaG5pY2FsS2V5cyA9IG1ldGFNb2RlbD8uZ2V0T2JqZWN0KGAke21ldGFQYXRofS8kVHlwZS8kS2V5YCk7XG5cdFx0XHRmb3IgKGNvbnN0IGVsZW1lbnQgb2YgdGVjaG5pY2FsS2V5cykge1xuXHRcdFx0XHRjb25zdCBrZXlWYWx1ZSA9IGJpbmRpbmdDb250ZXh0LmdldE9iamVjdCgpW2VsZW1lbnRdO1xuXHRcdFx0XHRpZiAoa2V5VmFsdWUgIT09IHRlY2huaWNhbEtleXNPYmplY3RbZWxlbWVudF0pIHtcblx0XHRcdFx0XHRpbnRlcm5hbE1vZGVsQ29udGV4dC5zZXRQcm9wZXJ0eShcImZjbENvbHVtbkNsb3NlZFwiLCBmYWxzZSk7XG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdC8vdGhlIHJlY29yZCBvcGVuZWQgaXMgbm90IHRoZSBsYXN0IHNlZW4gb25lIDogbm8gbmVlZCB0byBwZXJzaXN0IHRoZSBjaGFuZ2VzLCByZXNldCB0byBkZWZhdWx0IGluc3RlYWRcblx0XHR9XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0X2dldEFwcFN0YXRlRGF0YShvQXBwRGF0YTogQXBwRGF0YSwgdmlld0lkPzogc3RyaW5nLCBuYXZUeXBlPzogc3RyaW5nKSB7XG5cdFx0bGV0IGtleSA9IFwiXCIsXG5cdFx0XHRpID0gMDtcblx0XHRjb25zdCBhcHBTdGF0ZURhdGEgPSBuYXZUeXBlID09PSBOYXZUeXBlLmh5YnJpZCA/IG9BcHBEYXRhLmlBcHBTdGF0ZSA6IG9BcHBEYXRhO1xuXG5cdFx0aWYgKGFwcFN0YXRlRGF0YT8uYXBwU3RhdGUpIHtcblx0XHRcdGZvciAoaTsgaSA8IE9iamVjdC5rZXlzKGFwcFN0YXRlRGF0YS5hcHBTdGF0ZSkubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0aWYgKE9iamVjdC5rZXlzKGFwcFN0YXRlRGF0YS5hcHBTdGF0ZSlbaV0gPT09IHZpZXdJZCkge1xuXHRcdFx0XHRcdGtleSA9IE9iamVjdC5rZXlzKGFwcFN0YXRlRGF0YS5hcHBTdGF0ZSlbaV07XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0aWYgKGFwcFN0YXRlRGF0YT8uYXBwU3RhdGUpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFtPYmplY3Qua2V5cyhhcHBTdGF0ZURhdGEuYXBwU3RhdGUpW2ldXTogYXBwU3RhdGVEYXRhLmFwcFN0YXRlW2tleV0gfHwge31cblx0XHRcdH07XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEFwcGxpZXMgYW4gYXBwc3RhdGUgYnkgZmV0Y2hpbmcgYXBwZGF0YSBhbmQgcGFzc2luZyBpdCB0byBfYXBwbHlBcHBzdGF0ZVRvUGFnZS5cblx0ICpcblx0ICogQHBhcmFtIHZpZXdJZFxuXHQgKiBAcGFyYW0gdmlld1xuXHQgKiBAcmV0dXJucyBBIHByb21pc2UgZm9yIGFzeW5jIGhhbmRsaW5nXG5cdCAqL1xuXHRhc3luYyBhcHBseUFwcFN0YXRlKHZpZXdJZD86IHN0cmluZywgdmlldz86IFZpZXcpIHtcblx0XHRpZiAoIXRoaXMub0FwcENvbXBvbmVudC5nZXRFbnZpcm9ubWVudENhcGFiaWxpdGllcygpLmdldENhcGFiaWxpdGllcygpLkFwcFN0YXRlIHx8IEJ1c3lMb2NrZXIuaXNMb2NrZWQodGhpcykpIHtcblx0XHRcdHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcblx0XHR9XG5cblx0XHRjb25zdCBjaGVja0lmTGFzdFNlZW5SZWNvcmQgPSB0aGlzLl9jaGVja0lmTGFzdFNlZW5SZWNvcmQodmlldyk7XG5cdFx0aWYgKGNoZWNrSWZMYXN0U2VlblJlY29yZCA9PT0gdHJ1ZSkge1xuXHRcdFx0cmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuXHRcdH1cblxuXHRcdEJ1c3lMb2NrZXIubG9jayh0aGlzKTtcblx0XHQvLyBEb25lIGZvciBidXN5IGluZGljYXRvclxuXHRcdEJ1c3lMb2NrZXIubG9jayh0aGlzLm9BcHBDb21wb25lbnQuZ2V0Um9vdENvbnRyb2woKSk7XG5cdFx0Y29uc3Qgb05hdmlnYXRpb25TZXJ2aWNlID0gdGhpcy5vQXBwQ29tcG9uZW50LmdldE5hdmlnYXRpb25TZXJ2aWNlKCk7XG5cdFx0Ly8gVE9ETyBvTmF2aWdhdGlvblNlcnZpY2UucGFyc2VOYXZpZ2F0aW9uKCkgc2hvdWxkIHJldHVybiBFUzYgcHJvbWlzZSBpbnN0ZWFkIGpRdWVyeS5wcm9taXNlXG5cdFx0cmV0dXJuIHRvRVM2UHJvbWlzZShvTmF2aWdhdGlvblNlcnZpY2UucGFyc2VOYXZpZ2F0aW9uKCkpXG5cdFx0XHQuY2F0Y2goZnVuY3Rpb24gKGFFcnJvckRhdGE6IHVua25vd25bXSkge1xuXHRcdFx0XHRpZiAoIWFFcnJvckRhdGEpIHtcblx0XHRcdFx0XHRhRXJyb3JEYXRhID0gW107XG5cdFx0XHRcdH1cblx0XHRcdFx0TG9nLndhcm5pbmcoXCJBUFBTVEFURTogUGFyc2UgTmF2aWdhdGlvbiBmYWlsZWRcIiwgYUVycm9yRGF0YVswXSBhcyBzdHJpbmcpO1xuXHRcdFx0XHRyZXR1cm4gW1xuXHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdC8qIGFwcCBkYXRhICovXG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRhRXJyb3JEYXRhWzFdLFxuXHRcdFx0XHRcdGFFcnJvckRhdGFbMl1cblx0XHRcdFx0XTtcblx0XHRcdH0pXG5cdFx0XHQudGhlbihhc3luYyAoYVJlc3VsdHM6IHVua25vd25bXSkgPT4ge1xuXHRcdFx0XHRMb2cuaW5mbyhcIkFQUFNUQVRFOiBQYXJzZSBOYXZpZ2F0aW9uIGRvbmVcIik7XG5cblx0XHRcdFx0Ly8gYVJlc3VsdHNbMV0gPT4gb1N0YXJ0dXBQYXJhbWV0ZXJzIChub3QgZXZhbHVhdGVkKVxuXHRcdFx0XHRjb25zdCBvQXBwRGF0YSA9IChhUmVzdWx0c1swXSB8fCB7fSkgYXMgQXBwRGF0YSxcblx0XHRcdFx0XHRzTmF2VHlwZSA9IChhUmVzdWx0c1syXSBhcyBzdHJpbmcpIHx8IE5hdlR5cGUuaW5pdGlhbCxcblx0XHRcdFx0XHRvUm9vdENvbnRyb2xsZXIgPSB0aGlzLm9BcHBDb21wb25lbnQuZ2V0Um9vdENvbnRyb2woKS5nZXRDb250cm9sbGVyKCk7XG5cdFx0XHRcdC8vIGFwcGx5IHRoZSBhcHBzdGF0ZSBkZXBlbmRpbmcgdXBvbiB0aGUgdmlldyAoTFIvT1ApXG5cdFx0XHRcdGNvbnN0IGFwcFN0YXRlRGF0YSA9IHRoaXMuX2dldEFwcFN0YXRlRGF0YShvQXBwRGF0YSwgdmlld0lkLCBzTmF2VHlwZSk7XG5cdFx0XHRcdC8vIGZldGNoIHRoZSBza2lwTWVyZ2UgZmxhZyBmcm9tIGFwcFN0YXRlIGZvciBzYXZlIGFzIHRpbGVcblx0XHRcdFx0Y29uc3Qgc2tpcE1lcmdlOiBib29sZWFuIHwgdW5kZWZpbmVkID0gb0FwcERhdGE/LmFwcFN0YXRlPy5bU0tJUF9NRVJHRV9LRVldO1xuXHRcdFx0XHR0aGlzLl9tQ3VycmVudEFwcFN0YXRlID0gc05hdlR5cGUgPT09IE5hdlR5cGUuaUFwcFN0YXRlIHx8IHNOYXZUeXBlID09PSBOYXZUeXBlLmh5YnJpZCA/IGFwcFN0YXRlRGF0YSA6IHVuZGVmaW5lZDtcblx0XHRcdFx0bGV0IHNob3VsZEFwcGx5U3RhdGUgPSB0cnVlO1xuXG5cdFx0XHRcdGlmICghb1Jvb3RDb250cm9sbGVyLnZpZXdTdGF0ZSkge1xuXHRcdFx0XHRcdHRocm93IG5ldyBFcnJvcihgdmlld1N0YXRlIGV4dGVuc2lvbiByZXF1aXJlZCBmb3IgY29udHJvbGxlciAke29Sb290Q29udHJvbGxlci5nZXRNZXRhZGF0YSgpLmdldE5hbWUoKX1gKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAob1Jvb3RDb250cm9sbGVyLnZpZXdTdGF0ZS5faXNTdGF0ZUVtcHR5Rm9ySUFwcFN0YXRlTmF2VHlwZShvQXBwRGF0YSwgc05hdlR5cGUpKSB7XG5cdFx0XHRcdFx0aWYgKCFvUm9vdENvbnRyb2xsZXIudmlld1N0YXRlLl9nZXRJbml0aWFsU3RhdGVBcHBsaWVkKCkpIHtcblx0XHRcdFx0XHRcdG9Sb290Q29udHJvbGxlci52aWV3U3RhdGUuX3NldEluaXRpYWxTdGF0ZUFwcGxpZWQoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0c2hvdWxkQXBwbHlTdGF0ZSA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGNvbnN0IGFwcGx5Vmlld1N0YXRlID0gYXdhaXQgb1Jvb3RDb250cm9sbGVyLnZpZXdTdGF0ZS5hcHBseVZpZXdTdGF0ZShcblx0XHRcdFx0XHR0aGlzLl9tQ3VycmVudEFwcFN0YXRlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuXHRcdFx0XHRcdHRoaXMuX2NyZWF0ZU5hdmlnYXRpb25QYXJhbWV0ZXJzKG9BcHBEYXRhLCBzTmF2VHlwZSksXG5cdFx0XHRcdFx0c2tpcE1lcmdlXG5cdFx0XHRcdCk7XG5cdFx0XHRcdGlmICghc2hvdWxkQXBwbHlTdGF0ZSkge1xuXHRcdFx0XHRcdHJldHVybiB7fTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXR1cm4gYXBwbHlWaWV3U3RhdGU7XG5cdFx0XHRcdH1cblx0XHRcdH0pXG5cdFx0XHQuY2F0Y2goZnVuY3Rpb24gKG9FcnJvcjogdW5rbm93bikge1xuXHRcdFx0XHRMb2cuZXJyb3IoXCJhcHBTdGF0ZSBjb3VsZCBub3QgYmUgYXBwbGllZFwiLCBvRXJyb3IgYXMgc3RyaW5nKTtcblx0XHRcdFx0dGhyb3cgb0Vycm9yO1xuXHRcdFx0fSlcblx0XHRcdC5maW5hbGx5KCgpID0+IHtcblx0XHRcdFx0QnVzeUxvY2tlci51bmxvY2sodGhpcyk7XG5cdFx0XHRcdEJ1c3lMb2NrZXIudW5sb2NrKHRoaXMub0FwcENvbXBvbmVudC5nZXRSb290Q29udHJvbCgpKTtcblx0XHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRvIGNoZWNrIGlzIHJvdXRlIGlzIGNoYW5nZWQgYnkgY2hhbmdlIGluIHRoZSBpQVBQU3RhdGUuXG5cdCAqXG5cdCAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgcm91dGUgaGFzIGNobmFnZWRcblx0ICovXG5cdGNoZWNrSWZSb3V0ZUNoYW5nZWRCeUlBcHAoKSB7XG5cdFx0cmV0dXJuIHRoaXMuYk5vUm91dGVDaGFuZ2U7XG5cdH1cblxuXHQvKipcblx0ICogUmVzZXQgdGhlIHJvdXRlIGNoYW5nZWQgYnkgaUFQUFN0YXRlLlxuXHQgKi9cblx0cmVzZXRSb3V0ZUNoYW5nZWRCeUlBcHAoKSB7XG5cdFx0aWYgKHRoaXMuYk5vUm91dGVDaGFuZ2UpIHtcblx0XHRcdHRoaXMuYk5vUm91dGVDaGFuZ2UgPSBmYWxzZTtcblx0XHR9XG5cdH1cbn1cblxuLyoqXG4gKiBAZ2xvYmFsXG4gKi9cbmV4cG9ydCBkZWZhdWx0IEFwcFN0YXRlSGFuZGxlcjtcbiJd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
|
|
328
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJOYXZUeXBlIiwibGlicmFyeSIsIlNLSVBfTUVSR0VfS0VZIiwiUkVQTEFDRV9DT01QTEVURV9BUFBTVEFURSIsIkFwcFN0YXRlSGFuZGxlciIsImRlZmluZVVJNUNsYXNzIiwib0FwcENvbXBvbmVudCIsIl9tQ3VycmVudEFwcFN0YXRlIiwic0lkIiwiZ2V0SWQiLCJzaW11bHRhbmVvdXNDcmVhdGVSZXF1ZXN0IiwiYk5vUm91dGVDaGFuZ2UiLCJMb2ciLCJpbmZvIiwiX2dldElubmVyQXBwU3RhdGVGb3JWaWV3IiwiaW5uZXJBcHBTdGF0ZSIsInN0YXRlSWRlbnRpZmllciIsIl9hZGRBcHBTdGF0ZUluSGFzaCIsImFwcFN0YXRlS2V5IiwiYXBwQ29tcG9uZW50IiwibmF2aWdhdGlvblNlcnZpY2UiLCJnZXROYXZpZ2F0aW9uU2VydmljZSIsInJvdXRlclByb3h5IiwiZ2V0Um91dGVyUHJveHkiLCJoYXNoIiwiZ2V0SGFzaCIsImlzU3RpY2t5TW9kZSIsIk1vZGVsSGVscGVyIiwiaXNTdGlja3lTZXNzaW9uU3VwcG9ydGVkIiwiZ2V0TWV0YU1vZGVsIiwibmV3SGFzaCIsInJlcGxhY2VJbm5lckFwcFN0YXRlS2V5IiwiZ2V0RnVsbEhhc2giLCJuYXZUb0hhc2giLCJ1bmRlZmluZWQiLCJfY3JlYXRlQXBwU3RhdGVLZXkiLCJhcHBTdGF0ZURhdGEiLCJzdG9yZUlubmVyQXBwU3RhdGVBc3luYyIsIl9nZXRBcHBTdGF0ZUluZm8iLCJjcmVhdGVBcHBQYXJhbWV0ZXJzIiwicmVwbGFjZUhhc2giLCJ2aWV3SWQiLCJhcHBTdGF0ZSIsImN1cnJlbnRTdGF0ZVRvVXBkYXRlIiwiZGVlcEVxdWFsIiwib0Vycm9yIiwiZXJyb3IiLCJmaW5kQXBwU3RhdGVJbkhhc2giLCJjcmVhdGVBcHBTdGF0ZSIsImdldEVudmlyb25tZW50Q2FwYWJpbGl0aWVzIiwiZ2V0Q2FwYWJpbGl0aWVzIiwiQXBwU3RhdGUiLCJCdXN5TG9ja2VyIiwiaXNMb2NrZWQiLCJza2lwTWVyZ2UiLCJyb290Q29udHJvbGxlciIsImdldFJvb3RDb250cm9sIiwiZ2V0Q29udHJvbGxlciIsInZpZXdTdGF0ZSIsIkVycm9yIiwiZ2V0TWV0YWRhdGEiLCJnZXROYW1lIiwicm91dGluZ0lzQ29tcGxldGUiLCJyZXRyaWV2ZVZpZXdTdGF0ZSIsIl9jcmVhdGVOYXZpZ2F0aW9uUGFyYW1ldGVycyIsIm9BcHBEYXRhIiwic05hdlR5cGUiLCJPYmplY3QiLCJhc3NpZ24iLCJzZWxlY3Rpb25WYXJpYW50RGVmYXVsdHMiLCJvRGVmYXVsdGVkU2VsZWN0aW9uVmFyaWFudCIsInNlbGVjdGlvblZhcmlhbnQiLCJvU2VsZWN0aW9uVmFyaWFudCIsInJlcXVpcmVzU3RhbmRhcmRWYXJpYW50IiwiYk5hdlNlbFZhckhhc0RlZmF1bHRzT25seSIsIm5hdmlnYXRpb25UeXBlIiwiX2NoZWNrSWZMYXN0U2VlblJlY29yZCIsInZpZXciLCJpbnRlcm5hbE1vZGVsQ29udGV4dCIsImdldEJpbmRpbmdDb250ZXh0IiwiZ2V0UHJvcGVydHkiLCJ0ZWNobmljYWxLZXlzT2JqZWN0IiwiYmluZGluZ0NvbnRleHQiLCJwYXRoIiwiZ2V0UGF0aCIsIm1ldGFNb2RlbCIsImdldE1vZGVsIiwibWV0YVBhdGgiLCJnZXRNZXRhUGF0aCIsInRlY2huaWNhbEtleXMiLCJnZXRPYmplY3QiLCJlbGVtZW50Iiwia2V5VmFsdWUiLCJzZXRQcm9wZXJ0eSIsIl9nZXRBcHBTdGF0ZURhdGEiLCJuYXZUeXBlIiwia2V5IiwiaSIsImh5YnJpZCIsImlBcHBTdGF0ZSIsImtleXMiLCJsZW5ndGgiLCJhcHBseUFwcFN0YXRlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJjaGVja0lmTGFzdFNlZW5SZWNvcmQiLCJsb2NrIiwib05hdmlnYXRpb25TZXJ2aWNlIiwidG9FUzZQcm9taXNlIiwicGFyc2VOYXZpZ2F0aW9uIiwiY2F0Y2giLCJhRXJyb3JEYXRhIiwid2FybmluZyIsInRoZW4iLCJhUmVzdWx0cyIsImluaXRpYWwiLCJvUm9vdENvbnRyb2xsZXIiLCJzaG91bGRBcHBseVN0YXRlIiwiX2lzU3RhdGVFbXB0eUZvcklBcHBTdGF0ZU5hdlR5cGUiLCJfZ2V0SW5pdGlhbFN0YXRlQXBwbGllZCIsIl9zZXRJbml0aWFsU3RhdGVBcHBsaWVkIiwiYXBwbHlWaWV3U3RhdGUiLCJmaW5hbGx5IiwidW5sb2NrIiwiY2hlY2tJZlJvdXRlQ2hhbmdlZEJ5SUFwcCIsInJlc2V0Um91dGVDaGFuZ2VkQnlJQXBwIiwiQmFzZU9iamVjdCJdLCJzb3VyY2VSb290IjoiLiIsInNvdXJjZXMiOlsiQXBwU3RhdGVIYW5kbGVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBMb2cgZnJvbSBcInNhcC9iYXNlL0xvZ1wiO1xuaW1wb3J0IGRlZXBFcXVhbCBmcm9tIFwic2FwL2Jhc2UvdXRpbC9kZWVwRXF1YWxcIjtcbmltcG9ydCB0eXBlIEFwcENvbXBvbmVudCBmcm9tIFwic2FwL2ZlL2NvcmUvQXBwQ29tcG9uZW50XCI7XG5pbXBvcnQgdHlwZSB7IE5hdmlnYXRpb25QYXJhbWV0ZXIgfSBmcm9tIFwic2FwL2ZlL2NvcmUvY29udHJvbGxlcmV4dGVuc2lvbnMvVmlld1N0YXRlXCI7XG5pbXBvcnQgeyBkZWZpbmVVSTVDbGFzcyB9IGZyb20gXCJzYXAvZmUvY29yZS9oZWxwZXJzL0NsYXNzU3VwcG9ydFwiO1xuaW1wb3J0IHR5cGUgeyBJbnRlcm5hbE1vZGVsQ29udGV4dCB9IGZyb20gXCJzYXAvZmUvY29yZS9oZWxwZXJzL01vZGVsSGVscGVyXCI7XG5pbXBvcnQgdG9FUzZQcm9taXNlIGZyb20gXCJzYXAvZmUvY29yZS9oZWxwZXJzL1RvRVM2UHJvbWlzZVwiO1xuaW1wb3J0IHR5cGUgeyBJbm5lckFwcERhdGEgfSBmcm9tIFwic2FwL2ZlL25hdmlnYXRpb24vTmF2aWdhdGlvbkhhbmRsZXJcIjtcbmltcG9ydCB0eXBlIHsgU2VsZWN0aW9uVmFyaWFudCB9IGZyb20gXCJzYXAvZmUvbmF2aWdhdGlvbi9TZWxlY3Rpb25WYXJpYW50XCI7XG5pbXBvcnQgbGlicmFyeSBmcm9tIFwic2FwL2ZlL25hdmlnYXRpb24vbGlicmFyeVwiO1xuaW1wb3J0IEJhc2VPYmplY3QgZnJvbSBcInNhcC91aS9iYXNlL09iamVjdFwiO1xuaW1wb3J0IHR5cGUgVmlldyBmcm9tIFwic2FwL3VpL2NvcmUvbXZjL1ZpZXdcIjtcbmltcG9ydCB0eXBlIENvbnRleHQgZnJvbSBcInNhcC91aS9tb2RlbC9vZGF0YS92NC9Db250ZXh0XCI7XG5pbXBvcnQgQnVzeUxvY2tlciBmcm9tIFwiLi9jb250cm9sbGVyZXh0ZW5zaW9ucy9CdXN5TG9ja2VyXCI7XG5pbXBvcnQgTW9kZWxIZWxwZXIgZnJvbSBcIi4vaGVscGVycy9Nb2RlbEhlbHBlclwiO1xuXG5jb25zdCBOYXZUeXBlID0gbGlicmFyeS5OYXZUeXBlO1xudHlwZSBBcHBTdGF0ZSA9IHtcblx0c2tpcE1lcmdlPzogYm9vbGVhbjtcblx0W2tleTogc3RyaW5nXTogdW5rbm93bjtcbn07XG5leHBvcnQgdHlwZSBBcHBEYXRhID0ge1xuXHRvRGVmYXVsdGVkU2VsZWN0aW9uVmFyaWFudDogU2VsZWN0aW9uVmFyaWFudDtcblx0b1NlbGVjdGlvblZhcmlhbnQ6IFNlbGVjdGlvblZhcmlhbnQ7XG5cdGJOYXZTZWxWYXJIYXNEZWZhdWx0c09ubHk6IGJvb2xlYW47XG5cdGFwcFN0YXRlOiBBcHBTdGF0ZTtcblx0aUFwcFN0YXRlPzoge1xuXHRcdGFwcFN0YXRlOiBBcHBTdGF0ZTtcblx0fTtcbn07XG5jb25zdCBTS0lQX01FUkdFX0tFWSA9IFwic2tpcE1lcmdlXCI7XG5leHBvcnQgdHlwZSBJQXBwU3RhdGUgPSB7XG5cdGFwcFN0YXRlOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbn07XG5cbmV4cG9ydCB0eXBlIEFwcERhdGFJbmZvID0ge1xuXHRhcHBTdGF0ZURhdGE6IHsgYXBwU3RhdGU6IG9iamVjdCB8IHVuZGVmaW5lZCB9O1xuXHRhcHBTdGF0ZUtleTogc3RyaW5nIHwgbnVsbDtcbn07XG5cbmV4cG9ydCB0eXBlIENyZWF0ZUFwcFBhcmFtZXRlcnMgPSB7XG5cdHJlcGxhY2VIYXNoPzogYm9vbGVhbjtcblx0c2tpcE1lcmdlPzogYm9vbGVhbjtcblx0dmlld0lkPzogc3RyaW5nO1xufTtcblxuY29uc3QgUkVQTEFDRV9DT01QTEVURV9BUFBTVEFURSA9IFwiUkVQTEFDRV9DT01QTEVURV9BUFBTVEFURVwiO1xuXG5AZGVmaW5lVUk1Q2xhc3MoXCJzYXAuZmUuY29yZS5BcHBTdGF0ZUhhbmRsZXJcIilcbmNsYXNzIEFwcFN0YXRlSGFuZGxlciBleHRlbmRzIEJhc2VPYmplY3Qge1xuXHRwdWJsaWMgc0lkOiBzdHJpbmc7XG5cblx0cHVibGljIG9BcHBDb21wb25lbnQ6IEFwcENvbXBvbmVudDtcblxuXHRwdWJsaWMgYk5vUm91dGVDaGFuZ2U6IGJvb2xlYW47XG5cblx0cHJpdmF0ZSBfbUN1cnJlbnRBcHBTdGF0ZT86IEFwcFN0YXRlID0ge307XG5cblx0c2ltdWx0YW5lb3VzQ3JlYXRlUmVxdWVzdDogUmVjb3JkPHN0cmluZywgbnVtYmVyPjtcblxuXHRjb25zdHJ1Y3RvcihvQXBwQ29tcG9uZW50OiBBcHBDb21wb25lbnQpIHtcblx0XHRzdXBlcigpO1xuXHRcdHRoaXMub0FwcENvbXBvbmVudCA9IG9BcHBDb21wb25lbnQ7XG5cdFx0dGhpcy5zSWQgPSBgJHtvQXBwQ29tcG9uZW50LmdldElkKCl9L0FwcFN0YXRlSGFuZGxlcmA7XG5cdFx0dGhpcy5zaW11bHRhbmVvdXNDcmVhdGVSZXF1ZXN0ID0ge307XG5cdFx0dGhpcy5iTm9Sb3V0ZUNoYW5nZSA9IGZhbHNlO1xuXHRcdExvZy5pbmZvKFwiQVBQU1RBVEUgOiBBcHBzdGF0ZSBoYW5kbGVyIGluaXRpYWxpemVkXCIpO1xuXHR9XG5cblx0Z2V0SWQoKSB7XG5cdFx0cmV0dXJuIHRoaXMuc0lkO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldCB0aGUgdmlldy1zcGVjaWZpYyBhcHBzdGF0ZS5cblx0ICpcblx0ICogQHBhcmFtIGlubmVyQXBwU3RhdGUgT3ZlcmFsbCBhcHBzdGF0ZVxuXHQgKiBAcGFyYW0gc3RhdGVJZGVudGlmaWVyIFN0YXRlIGlkZW50aWZpZXIsIGlkIG9mIHRoZSBsb2NhbCB2aWV3XG5cdCAqIEByZXR1cm5zIElubmVyIGFwcHN0YXRlXG5cdCAqL1xuXHRfZ2V0SW5uZXJBcHBTdGF0ZUZvclZpZXcoaW5uZXJBcHBTdGF0ZTogSW5uZXJBcHBEYXRhIHwgdW5kZWZpbmVkLCBzdGF0ZUlkZW50aWZpZXI6IHN0cmluZyk6IElubmVyQXBwRGF0YSB8IHVuZGVmaW5lZCB7XG5cdFx0aWYgKHN0YXRlSWRlbnRpZmllciA9PT0gUkVQTEFDRV9DT01QTEVURV9BUFBTVEFURSB8fCAhaW5uZXJBcHBTdGF0ZSkge1xuXHRcdFx0Ly8gb3ZlcmFsbCBhcHAgc3RhdGUgbmVlZHMgdG8gYmUgY29uc2lkZXJlZC5cblx0XHRcdHJldHVybiBpbm5lckFwcFN0YXRlO1xuXHRcdH1cblxuXHRcdC8vIHdlIHRha2UgdGhlIHN1YnNldCBvZiB0aGUgYXBwIHN0YXRlIHdydCB0byB0aGUgbG9jYWwgdmlldyBpZC5cblx0XHRyZXR1cm4ge1xuXHRcdFx0W3N0YXRlSWRlbnRpZmllcl06IGlubmVyQXBwU3RhdGVbc3RhdGVJZGVudGlmaWVyIGFzIGtleW9mIHR5cGVvZiBpbm5lckFwcFN0YXRlXSB8fCB7fVxuXHRcdH07XG5cdH1cblxuXHQvKipcblx0ICogQWRkIGFwcHN0YXRlIGluIGhhc2guXG5cdCAqXG5cdCAqIEBwYXJhbSBhcHBTdGF0ZUtleSBBcHBzdGF0ZSBrZXlcblx0ICogQHBhcmFtIHN0YXRlSWRlbnRpZmllciBTdGF0ZSBpZGVudGlmaWVyLCBJZCBvZiB0aGUgbG9jYWwgdmlld1xuXHQgKi9cblx0X2FkZEFwcFN0YXRlSW5IYXNoKGFwcFN0YXRlS2V5OiBzdHJpbmcsIHN0YXRlSWRlbnRpZmllcjogc3RyaW5nKTogdm9pZCB7XG5cdFx0Y29uc3QgYXBwQ29tcG9uZW50ID0gdGhpcy5vQXBwQ29tcG9uZW50LFxuXHRcdFx0bmF2aWdhdGlvblNlcnZpY2UgPSBhcHBDb21wb25lbnQuZ2V0TmF2aWdhdGlvblNlcnZpY2UoKSxcblx0XHRcdHJvdXRlclByb3h5ID0gYXBwQ29tcG9uZW50LmdldFJvdXRlclByb3h5KCksXG5cdFx0XHRoYXNoID0gcm91dGVyUHJveHkuZ2V0SGFzaCgpLFxuXHRcdFx0aXNTdGlja3lNb2RlID0gTW9kZWxIZWxwZXIuaXNTdGlja3lTZXNzaW9uU3VwcG9ydGVkKGFwcENvbXBvbmVudC5nZXRNZXRhTW9kZWwoKSksXG5cdFx0XHRuZXdIYXNoID0gbmF2aWdhdGlvblNlcnZpY2UucmVwbGFjZUlubmVyQXBwU3RhdGVLZXkocm91dGVyUHJveHkuZ2V0RnVsbEhhc2goKSwgYXBwU3RhdGVLZXkpO1xuXG5cdFx0aWYgKHRoaXMuc2ltdWx0YW5lb3VzQ3JlYXRlUmVxdWVzdFtzdGF0ZUlkZW50aWZpZXJdID09PSAwICYmIG5ld0hhc2ggIT09IGhhc2gpIHtcblx0XHRcdHJvdXRlclByb3h5Lm5hdlRvSGFzaChuZXdIYXNoLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCAhaXNTdGlja3lNb2RlKTtcblx0XHRcdHRoaXMuYk5vUm91dGVDaGFuZ2UgPSB0cnVlO1xuXHRcdH1cblx0XHRMb2cuaW5mbyhcIkFQUFNUQVRFOiBuYXZUb0hhc2hcIik7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlIEFwcHN0YXRlIEtleS5cblx0ICpcblx0ICogQHBhcmFtIGFwcFN0YXRlRGF0YSBBcHBzdGF0ZVxuXHQgKiBAcGFyYW0gc3RhdGVJZGVudGlmaWVyIFN0YXRlIGlkZW50aWZpZXIsIElkIG9mIHRoZSBsb2NhbCB2aWV3XG5cdCAqIEByZXR1cm5zIEFwcHN0YXRlIEtleVxuXHQgKi9cblx0YXN5bmMgX2NyZWF0ZUFwcFN0YXRlS2V5KGFwcFN0YXRlRGF0YTogSW5uZXJBcHBEYXRhLCBzdGF0ZUlkZW50aWZpZXI6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG5cdFx0Y29uc3QgYXBwQ29tcG9uZW50ID0gdGhpcy5vQXBwQ29tcG9uZW50LFxuXHRcdFx0bmF2aWdhdGlvblNlcnZpY2UgPSBhcHBDb21wb25lbnQuZ2V0TmF2aWdhdGlvblNlcnZpY2UoKTtcblxuXHRcdGlmICh0aGlzLnNpbXVsdGFuZW91c0NyZWF0ZVJlcXVlc3Rbc3RhdGVJZGVudGlmaWVyXSkge1xuXHRcdFx0Ly8gYW55IG90aGVyIHZhbHVlXG5cdFx0XHR0aGlzLnNpbXVsdGFuZW91c0NyZWF0ZVJlcXVlc3Rbc3RhdGVJZGVudGlmaWVyXSsrO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyAwIG9yIHVuZGVmaW5lZFxuXHRcdFx0dGhpcy5zaW11bHRhbmVvdXNDcmVhdGVSZXF1ZXN0W3N0YXRlSWRlbnRpZmllcl0gPSAxO1xuXHRcdH1cblxuXHRcdGNvbnN0IGFwcFN0YXRlS2V5ID0gYXdhaXQgbmF2aWdhdGlvblNlcnZpY2Uuc3RvcmVJbm5lckFwcFN0YXRlQXN5bmMoYXBwU3RhdGVEYXRhLCB0cnVlLCB0cnVlKTtcblxuXHRcdHRoaXMuc2ltdWx0YW5lb3VzQ3JlYXRlUmVxdWVzdFtzdGF0ZUlkZW50aWZpZXJdLS07XG5cblx0XHRMb2cuaW5mbyhcIkFQUFNUQVRFOiBBcHBzdGF0ZSBzdG9yZWRcIik7XG5cdFx0cmV0dXJuIGFwcFN0YXRlS2V5O1xuXHR9XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYXBwc3RhdGUgaW5mby5cblx0ICpcblx0ICogQHBhcmFtIGlubmVyQXBwU3RhdGVcblx0ICogQHBhcmFtIGNyZWF0ZUFwcFBhcmFtZXRlcnMgUGFyYW1ldGVycyBmb3IgY3JlYXRpbmcgYSBuZXcgYXBwc3RhdGVcblx0ICogQHBhcmFtIGNyZWF0ZUFwcFBhcmFtZXRlcnMucmVwbGFjZUhhc2ggQSBCb29sZWFuIHRoYXQgZGV0ZXJtaW5lcyB3aGV0aGVyIHRvIHJlcGxhY2UgdGhlIGhhc2ggd2l0aCB0aGUgbmV3bHkgZ2VuZXJhdGVkIGtleVxuXHQgKiBAcGFyYW0gY3JlYXRlQXBwUGFyYW1ldGVycy52aWV3SWQgSWQgb2YgdGhlIHZpZXcgZm9yIHdoaWNoIHdlIG5lZWQgdG8gY3JlYXRlIHRoZSBhcHAgc3RhdGUuIFRoaXMgYWxsb3dzIHVzIHRvIGNyZWF0ZSBvciB1cGRhdGUgdmlldy1zcGVjaWZpYyBhcHBzdGF0ZS5cblx0ICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdGhlIHN0b3JlZCBkYXRhIG9yIGFwcHN0YXRlIGtleXNcblx0ICovXG5cdGFzeW5jIF9nZXRBcHBTdGF0ZUluZm8oaW5uZXJBcHBTdGF0ZTogSW5uZXJBcHBEYXRhIHwgdW5kZWZpbmVkLCBjcmVhdGVBcHBQYXJhbWV0ZXJzPzogQ3JlYXRlQXBwUGFyYW1ldGVycyk6IFByb21pc2U8QXBwRGF0YUluZm8+IHtcblx0XHRjb25zdCBhcHBDb21wb25lbnQgPSB0aGlzLm9BcHBDb21wb25lbnQ7XG5cdFx0Y29uc3QgeyByZXBsYWNlSGFzaCA9IHRydWUsIHZpZXdJZDogc3RhdGVJZGVudGlmaWVyID0gUkVQTEFDRV9DT01QTEVURV9BUFBTVEFURSB9ID0gY3JlYXRlQXBwUGFyYW1ldGVycyA/PyB7fTtcblxuXHRcdGxldCBhcHBTdGF0ZUtleTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cdFx0bGV0IGFwcFN0YXRlRGF0YSA9IHsgYXBwU3RhdGU6IHRoaXMuX21DdXJyZW50QXBwU3RhdGUgfTtcblxuXHRcdGNvbnN0IGN1cnJlbnRTdGF0ZVRvVXBkYXRlID0gdGhpcy5fZ2V0SW5uZXJBcHBTdGF0ZUZvclZpZXcodGhpcy5fbUN1cnJlbnRBcHBTdGF0ZSwgc3RhdGVJZGVudGlmaWVyKTtcblx0XHRpZiAoaW5uZXJBcHBTdGF0ZSAmJiAhZGVlcEVxdWFsKGN1cnJlbnRTdGF0ZVRvVXBkYXRlLCBpbm5lckFwcFN0YXRlKSkge1xuXHRcdFx0Ly9cblx0XHRcdHRoaXMuX21DdXJyZW50QXBwU3RhdGUgPSB7IC4uLnRoaXMuX21DdXJyZW50QXBwU3RhdGUsIC4uLihpbm5lckFwcFN0YXRlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KSB9O1xuXHRcdFx0YXBwU3RhdGVEYXRhID0geyBhcHBTdGF0ZTogdGhpcy5fbUN1cnJlbnRBcHBTdGF0ZSB9O1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0YXBwU3RhdGVLZXkgPSBhd2FpdCB0aGlzLl9jcmVhdGVBcHBTdGF0ZUtleShhcHBTdGF0ZURhdGEsIHN0YXRlSWRlbnRpZmllcik7XG5cdFx0XHRcdGlmIChyZXBsYWNlSGFzaCA9PT0gdHJ1ZSkge1xuXHRcdFx0XHRcdHRoaXMuX2FkZEFwcFN0YXRlSW5IYXNoKGFwcFN0YXRlS2V5LCBzdGF0ZUlkZW50aWZpZXIpO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGNhdGNoIChvRXJyb3I6IHVua25vd24pIHtcblx0XHRcdFx0TG9nLmVycm9yKG9FcnJvciBhcyBzdHJpbmcpO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRjb25zdCByb3V0ZXJQcm94eSA9IGFwcENvbXBvbmVudC5nZXRSb3V0ZXJQcm94eSgpLFxuXHRcdFx0XHRoYXNoID0gcm91dGVyUHJveHkuZ2V0SGFzaCgpO1xuXHRcdFx0YXBwU3RhdGVLZXkgPSByb3V0ZXJQcm94eS5maW5kQXBwU3RhdGVJbkhhc2goaGFzaCkgYXMgc3RyaW5nO1xuXHRcdH1cblx0XHRyZXR1cm4ge1xuXHRcdFx0YXBwU3RhdGVEYXRhLFxuXHRcdFx0YXBwU3RhdGVLZXlcblx0XHR9O1xuXHR9XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgb3IgdXBkYXRlcyB0aGUgYXBwc3RhdGUuXG5cdCAqIFJlcGxhY2VzIHRoZSBoYXNoIHdpdGggdGhlIG5ldyBhcHBzdGF0ZSBiYXNlZCBvbiByZXBsYWNlSGFzaFxuXHQgKlxuXHQgKiBAcGFyYW0gY3JlYXRlQXBwUGFyYW1ldGVycyBQYXJhbWV0ZXJzIGZvciBjcmVhdGluZyBuZXcgYXBwc3RhdGVcblx0ICogQHBhcmFtIGNyZWF0ZUFwcFBhcmFtZXRlcnMucmVwbGFjZUhhc2ggQm9vbGVhbiB3aGljaCBkZXRlcm1pbmVzIHRvIHJlcGxhY2UgdGhlIGhhc2ggd2l0aCB0aGUgbmV3IGdlbmVyYXRlZCBrZXlcblx0ICogQHBhcmFtIGNyZWF0ZUFwcFBhcmFtZXRlcnMuc2tpcE1lcmdlIEJvb2xlYW4gd2hpY2ggZGV0ZXJtaW5lcyB0byBza2lwIHRoZSBrZXkgdXNlciBzaGluZSB0aHJvdWdoXG5cdCAqIEBwYXJhbSBjcmVhdGVBcHBQYXJhbWV0ZXJzLnZpZXdJZCBJZCBvZiB0aGUgdmlldyBmb3Igd2hpY2ggd2UgbmVlZCB0byBjcmVhdGUgdGhlIGFwcCBzdGF0ZS4gVGhpcyBhbGxvd3MgdXMgdG8gY3JlYXRlIG9yIHVwZGF0ZSB2aWV3LXNwZWNpZmljIGFwcHN0YXRlLlxuXHQgKiBAcmV0dXJucyBBIHByb21pc2UgcmVzb2x2aW5nIHRoZSBzdG9yZWQgZGF0YSBvciBhcHBzdGF0ZSBrZXlcblx0ICovXG5cdGFzeW5jIGNyZWF0ZUFwcFN0YXRlKGNyZWF0ZUFwcFBhcmFtZXRlcnM/OiBDcmVhdGVBcHBQYXJhbWV0ZXJzKTogUHJvbWlzZTx2b2lkIHwgQXBwRGF0YUluZm8+IHtcblx0XHRjb25zdCBhcHBDb21wb25lbnQgPSB0aGlzLm9BcHBDb21wb25lbnQ7XG5cdFx0aWYgKCFhcHBDb21wb25lbnQuZ2V0RW52aXJvbm1lbnRDYXBhYmlsaXRpZXMoKS5nZXRDYXBhYmlsaXRpZXMoKS5BcHBTdGF0ZSB8fCBCdXN5TG9ja2VyLmlzTG9ja2VkKHRoaXMpKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGNvbnN0IHsgc2tpcE1lcmdlID0gZmFsc2UsIHZpZXdJZDogc3RhdGVJZGVudGlmaWVyID0gUkVQTEFDRV9DT01QTEVURV9BUFBTVEFURSB9ID0gY3JlYXRlQXBwUGFyYW1ldGVycyA/PyB7fSxcblx0XHRcdHJvb3RDb250cm9sbGVyID0gYXBwQ29tcG9uZW50LmdldFJvb3RDb250cm9sKCkuZ2V0Q29udHJvbGxlcigpO1xuXG5cdFx0aWYgKCFyb290Q29udHJvbGxlci52aWV3U3RhdGUpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcihgdmlld1N0YXRlIGNvbnRyb2xsZXIgZXh0ZW5zaW9uIG5vdCBhdmFpbGFibGUgZm9yIGNvbnRyb2xsZXI6ICR7cm9vdENvbnRyb2xsZXIuZ2V0TWV0YWRhdGEoKS5nZXROYW1lKCl9YCk7XG5cdFx0fVxuXG5cdFx0Ly8gSW4gY2FzZSwgb24gbG9hZCBvZiBGQ0wgYXBwIHdlIGhhdmUgbXVsdGlwbGUgdmlld3MoTFIsIE9QLCBzdWItT1AuLi4pIGFuZCB1cmwgaGFzIGlBcHBTdGF0ZSgxKS5cblx0XHQvLyBUaGUgTFIgdmlldyBsb2FkcyB3aXRoIGFwcGxpZWQgaUFwcFN0YXRlKDEpIGFuZCBjYWxscyBjcmVhdGVBcHBTdGF0ZShleGFtcGxlOiBvblNlYXJjaCBldmVudCBpbiBMUikgYmVmb3JlIE9QIGlzIGxvYWRlZC5cblx0XHQvLyBUaGlzIGNyZWF0ZXMgaUFwcFN0YXRlKDIpIGJlZm9yZSBpQXBwU3RhdGUoMSkgaXMgYXBwbGllZCB0byBPUC5cblx0XHQvLyBTbywgd2UgdHJ5IHRvIHdhaXQgdGlsbCB0aGUgcm91dGluZyBpcyBjb21wbGV0ZS5cblx0XHRhd2FpdCByb290Q29udHJvbGxlci5yb3V0aW5nSXNDb21wbGV0ZSgpO1xuXG5cdFx0Ly8gR2V0IGFwcFN0YXRlIHRvIHVwZGF0ZVxuXHRcdGxldCBpbm5lckFwcFN0YXRlID0gKGF3YWl0IHJvb3RDb250cm9sbGVyLnZpZXdTdGF0ZS5yZXRyaWV2ZVZpZXdTdGF0ZSgpKSBhcyBJbm5lckFwcERhdGEgfCB1bmRlZmluZWQ7XG5cdFx0aW5uZXJBcHBTdGF0ZSA9IHRoaXMuX2dldElubmVyQXBwU3RhdGVGb3JWaWV3KGlubmVyQXBwU3RhdGUsIHN0YXRlSWRlbnRpZmllcik7XG5cdFx0aWYgKHNraXBNZXJnZSkge1xuXHRcdFx0aW5uZXJBcHBTdGF0ZSA9IHsgLi4uaW5uZXJBcHBTdGF0ZSwgLi4ueyBza2lwTWVyZ2UgfSB9O1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLl9nZXRBcHBTdGF0ZUluZm8oaW5uZXJBcHBTdGF0ZSwgY3JlYXRlQXBwUGFyYW1ldGVycyk7XG5cdH1cblxuXHRfY3JlYXRlTmF2aWdhdGlvblBhcmFtZXRlcnMob0FwcERhdGE6IEFwcERhdGEsIHNOYXZUeXBlOiBzdHJpbmcpOiBOYXZpZ2F0aW9uUGFyYW1ldGVyIHtcblx0XHRyZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgb0FwcERhdGEsIHtcblx0XHRcdHNlbGVjdGlvblZhcmlhbnREZWZhdWx0czogb0FwcERhdGEub0RlZmF1bHRlZFNlbGVjdGlvblZhcmlhbnQsXG5cdFx0XHRzZWxlY3Rpb25WYXJpYW50OiBvQXBwRGF0YS5vU2VsZWN0aW9uVmFyaWFudCxcblx0XHRcdHJlcXVpcmVzU3RhbmRhcmRWYXJpYW50OiAhb0FwcERhdGEuYk5hdlNlbFZhckhhc0RlZmF1bHRzT25seSxcblx0XHRcdG5hdmlnYXRpb25UeXBlOiBzTmF2VHlwZVxuXHRcdH0pO1xuXHR9XG5cblx0X2NoZWNrSWZMYXN0U2VlblJlY29yZCh2aWV3PzogVmlldykge1xuXHRcdC8vZ2V0dGluZyB0aGUgaW50ZXJuYWwgbW9kZWwgY29udGV4dCBpbiBvcmRlciB0byBmZXRjaCB0aGUgdGVjaG5pY2Fsa2V5cyBvZiBsYXN0IHNlZW4gcmVjb3JkIGFuZCBjbG9zZSBjb2x1bW4gZmxhZyBzZXQgaW4gdGhlIGludGVybmFscm91dGluZyBmb3IgcmV0YWluaW5nIHNldHRpbmdzIGluIHBlcnNpc3RlbmNlIG1vZGVcblx0XHRjb25zdCBpbnRlcm5hbE1vZGVsQ29udGV4dCA9IHZpZXcgJiYgKHZpZXcuZ2V0QmluZGluZ0NvbnRleHQoXCJpbnRlcm5hbFwiKSBhcyBJbnRlcm5hbE1vZGVsQ29udGV4dCk7XG5cdFx0aWYgKGludGVybmFsTW9kZWxDb250ZXh0ICYmIGludGVybmFsTW9kZWxDb250ZXh0LmdldFByb3BlcnR5KFwiZmNsQ29sdW1uQ2xvc2VkXCIpID09PSB0cnVlKSB7XG5cdFx0XHRjb25zdCB0ZWNobmljYWxLZXlzT2JqZWN0ID0gaW50ZXJuYWxNb2RlbENvbnRleHQuZ2V0UHJvcGVydHkoXCJ0ZWNobmljYWxLZXlzT2ZMYXN0U2VlblJlY29yZFwiKTtcblx0XHRcdGNvbnN0IGJpbmRpbmdDb250ZXh0ID0gdmlldz8uZ2V0QmluZGluZ0NvbnRleHQoKSBhcyBDb250ZXh0O1xuXHRcdFx0Y29uc3QgcGF0aCA9IChiaW5kaW5nQ29udGV4dCAmJiBiaW5kaW5nQ29udGV4dC5nZXRQYXRoKCkpIHx8IFwiXCI7XG5cdFx0XHRjb25zdCBtZXRhTW9kZWwgPSBiaW5kaW5nQ29udGV4dD8uZ2V0TW9kZWwoKS5nZXRNZXRhTW9kZWwoKTtcblx0XHRcdGNvbnN0IG1ldGFQYXRoID0gbWV0YU1vZGVsPy5nZXRNZXRhUGF0aChwYXRoKTtcblx0XHRcdGNvbnN0IHRlY2huaWNhbEtleXMgPSBtZXRhTW9kZWw/LmdldE9iamVjdChgJHttZXRhUGF0aH0vJFR5cGUvJEtleWApO1xuXHRcdFx0Zm9yIChjb25zdCBlbGVtZW50IG9mIHRlY2huaWNhbEtleXMpIHtcblx0XHRcdFx0Y29uc3Qga2V5VmFsdWUgPSBiaW5kaW5nQ29udGV4dC5nZXRPYmplY3QoKVtlbGVtZW50XTtcblx0XHRcdFx0aWYgKGtleVZhbHVlICE9PSB0ZWNobmljYWxLZXlzT2JqZWN0W2VsZW1lbnRdKSB7XG5cdFx0XHRcdFx0aW50ZXJuYWxNb2RlbENvbnRleHQuc2V0UHJvcGVydHkoXCJmY2xDb2x1bW5DbG9zZWRcIiwgZmFsc2UpO1xuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHQvL3RoZSByZWNvcmQgb3BlbmVkIGlzIG5vdCB0aGUgbGFzdCBzZWVuIG9uZSA6IG5vIG5lZWQgdG8gcGVyc2lzdCB0aGUgY2hhbmdlcywgcmVzZXQgdG8gZGVmYXVsdCBpbnN0ZWFkXG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdF9nZXRBcHBTdGF0ZURhdGEob0FwcERhdGE6IEFwcERhdGEsIHZpZXdJZD86IHN0cmluZywgbmF2VHlwZT86IHN0cmluZykge1xuXHRcdGxldCBrZXkgPSBcIlwiLFxuXHRcdFx0aSA9IDA7XG5cdFx0Y29uc3QgYXBwU3RhdGVEYXRhID0gbmF2VHlwZSA9PT0gTmF2VHlwZS5oeWJyaWQgPyBvQXBwRGF0YS5pQXBwU3RhdGUgOiBvQXBwRGF0YTtcblxuXHRcdGlmIChhcHBTdGF0ZURhdGE/LmFwcFN0YXRlKSB7XG5cdFx0XHRmb3IgKGk7IGkgPCBPYmplY3Qua2V5cyhhcHBTdGF0ZURhdGEuYXBwU3RhdGUpLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdGlmIChPYmplY3Qua2V5cyhhcHBTdGF0ZURhdGEuYXBwU3RhdGUpW2ldID09PSB2aWV3SWQpIHtcblx0XHRcdFx0XHRrZXkgPSBPYmplY3Qua2V5cyhhcHBTdGF0ZURhdGEuYXBwU3RhdGUpW2ldO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmIChhcHBTdGF0ZURhdGE/LmFwcFN0YXRlKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRbT2JqZWN0LmtleXMoYXBwU3RhdGVEYXRhLmFwcFN0YXRlKVtpXV06IGFwcFN0YXRlRGF0YS5hcHBTdGF0ZVtrZXldIHx8IHt9XG5cdFx0XHR9O1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBBcHBsaWVzIGFuIGFwcHN0YXRlIGJ5IGZldGNoaW5nIGFwcGRhdGEgYW5kIHBhc3NpbmcgaXQgdG8gX2FwcGx5QXBwc3RhdGVUb1BhZ2UuXG5cdCAqXG5cdCAqIEBwYXJhbSB2aWV3SWRcblx0ICogQHBhcmFtIHZpZXdcblx0ICogQHJldHVybnMgQSBwcm9taXNlIGZvciBhc3luYyBoYW5kbGluZ1xuXHQgKi9cblx0YXN5bmMgYXBwbHlBcHBTdGF0ZSh2aWV3SWQ/OiBzdHJpbmcsIHZpZXc/OiBWaWV3KSB7XG5cdFx0aWYgKCF0aGlzLm9BcHBDb21wb25lbnQuZ2V0RW52aXJvbm1lbnRDYXBhYmlsaXRpZXMoKS5nZXRDYXBhYmlsaXRpZXMoKS5BcHBTdGF0ZSB8fCBCdXN5TG9ja2VyLmlzTG9ja2VkKHRoaXMpKSB7XG5cdFx0XHRyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG5cdFx0fVxuXG5cdFx0Y29uc3QgY2hlY2tJZkxhc3RTZWVuUmVjb3JkID0gdGhpcy5fY2hlY2tJZkxhc3RTZWVuUmVjb3JkKHZpZXcpO1xuXHRcdGlmIChjaGVja0lmTGFzdFNlZW5SZWNvcmQgPT09IHRydWUpIHtcblx0XHRcdHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcblx0XHR9XG5cblx0XHRCdXN5TG9ja2VyLmxvY2sodGhpcyk7XG5cdFx0Ly8gRG9uZSBmb3IgYnVzeSBpbmRpY2F0b3Jcblx0XHRCdXN5TG9ja2VyLmxvY2sodGhpcy5vQXBwQ29tcG9uZW50LmdldFJvb3RDb250cm9sKCkpO1xuXHRcdGNvbnN0IG9OYXZpZ2F0aW9uU2VydmljZSA9IHRoaXMub0FwcENvbXBvbmVudC5nZXROYXZpZ2F0aW9uU2VydmljZSgpO1xuXHRcdC8vIFRPRE8gb05hdmlnYXRpb25TZXJ2aWNlLnBhcnNlTmF2aWdhdGlvbigpIHNob3VsZCByZXR1cm4gRVM2IHByb21pc2UgaW5zdGVhZCBqUXVlcnkucHJvbWlzZVxuXHRcdHJldHVybiB0b0VTNlByb21pc2Uob05hdmlnYXRpb25TZXJ2aWNlLnBhcnNlTmF2aWdhdGlvbigpKVxuXHRcdFx0LmNhdGNoKGZ1bmN0aW9uIChhRXJyb3JEYXRhOiB1bmtub3duW10pIHtcblx0XHRcdFx0aWYgKCFhRXJyb3JEYXRhKSB7XG5cdFx0XHRcdFx0YUVycm9yRGF0YSA9IFtdO1xuXHRcdFx0XHR9XG5cdFx0XHRcdExvZy53YXJuaW5nKFwiQVBQU1RBVEU6IFBhcnNlIE5hdmlnYXRpb24gZmFpbGVkXCIsIGFFcnJvckRhdGFbMF0gYXMgc3RyaW5nKTtcblx0XHRcdFx0cmV0dXJuIFtcblx0XHRcdFx0XHR7XG5cdFx0XHRcdFx0XHQvKiBhcHAgZGF0YSAqL1xuXHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0YUVycm9yRGF0YVsxXSxcblx0XHRcdFx0XHRhRXJyb3JEYXRhWzJdXG5cdFx0XHRcdF07XG5cdFx0XHR9KVxuXHRcdFx0LnRoZW4oYXN5bmMgKGFSZXN1bHRzOiB1bmtub3duW10pID0+IHtcblx0XHRcdFx0TG9nLmluZm8oXCJBUFBTVEFURTogUGFyc2UgTmF2aWdhdGlvbiBkb25lXCIpO1xuXG5cdFx0XHRcdC8vIGFSZXN1bHRzWzFdID0+IG9TdGFydHVwUGFyYW1ldGVycyAobm90IGV2YWx1YXRlZClcblx0XHRcdFx0Y29uc3Qgb0FwcERhdGEgPSAoYVJlc3VsdHNbMF0gfHwge30pIGFzIEFwcERhdGEsXG5cdFx0XHRcdFx0c05hdlR5cGUgPSAoYVJlc3VsdHNbMl0gYXMgc3RyaW5nKSB8fCBOYXZUeXBlLmluaXRpYWwsXG5cdFx0XHRcdFx0b1Jvb3RDb250cm9sbGVyID0gdGhpcy5vQXBwQ29tcG9uZW50LmdldFJvb3RDb250cm9sKCkuZ2V0Q29udHJvbGxlcigpO1xuXHRcdFx0XHQvLyBhcHBseSB0aGUgYXBwc3RhdGUgZGVwZW5kaW5nIHVwb24gdGhlIHZpZXcgKExSL09QKVxuXHRcdFx0XHRjb25zdCBhcHBTdGF0ZURhdGEgPSB0aGlzLl9nZXRBcHBTdGF0ZURhdGEob0FwcERhdGEsIHZpZXdJZCwgc05hdlR5cGUpO1xuXHRcdFx0XHQvLyBmZXRjaCB0aGUgc2tpcE1lcmdlIGZsYWcgZnJvbSBhcHBTdGF0ZSBmb3Igc2F2ZSBhcyB0aWxlXG5cdFx0XHRcdGNvbnN0IHNraXBNZXJnZTogYm9vbGVhbiB8IHVuZGVmaW5lZCA9IG9BcHBEYXRhPy5hcHBTdGF0ZT8uW1NLSVBfTUVSR0VfS0VZXTtcblx0XHRcdFx0dGhpcy5fbUN1cnJlbnRBcHBTdGF0ZSA9XG5cdFx0XHRcdFx0c05hdlR5cGUgPT09IE5hdlR5cGUuaUFwcFN0YXRlIHx8IHNOYXZUeXBlID09PSBOYXZUeXBlLmh5YnJpZCA/IHsgLi4udGhpcy5fbUN1cnJlbnRBcHBTdGF0ZSwgLi4uYXBwU3RhdGVEYXRhIH0gOiB7fTtcblx0XHRcdFx0bGV0IHNob3VsZEFwcGx5U3RhdGUgPSB0cnVlO1xuXHRcdFx0XHRpZiAoIW9Sb290Q29udHJvbGxlci52aWV3U3RhdGUpIHtcblx0XHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoYHZpZXdTdGF0ZSBleHRlbnNpb24gcmVxdWlyZWQgZm9yIGNvbnRyb2xsZXIgJHtvUm9vdENvbnRyb2xsZXIuZ2V0TWV0YWRhdGEoKS5nZXROYW1lKCl9YCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKG9Sb290Q29udHJvbGxlci52aWV3U3RhdGUuX2lzU3RhdGVFbXB0eUZvcklBcHBTdGF0ZU5hdlR5cGUob0FwcERhdGEsIHNOYXZUeXBlKSkge1xuXHRcdFx0XHRcdGlmICghb1Jvb3RDb250cm9sbGVyLnZpZXdTdGF0ZS5fZ2V0SW5pdGlhbFN0YXRlQXBwbGllZCgpKSB7XG5cdFx0XHRcdFx0XHRvUm9vdENvbnRyb2xsZXIudmlld1N0YXRlLl9zZXRJbml0aWFsU3RhdGVBcHBsaWVkKCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHNob3VsZEFwcGx5U3RhdGUgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRjb25zdCBhcHBseVZpZXdTdGF0ZSA9IGF3YWl0IG9Sb290Q29udHJvbGxlci52aWV3U3RhdGUuYXBwbHlWaWV3U3RhdGUoXG5cdFx0XHRcdFx0dGhpcy5fbUN1cnJlbnRBcHBTdGF0ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcblx0XHRcdFx0XHR0aGlzLl9jcmVhdGVOYXZpZ2F0aW9uUGFyYW1ldGVycyhvQXBwRGF0YSwgc05hdlR5cGUpLFxuXHRcdFx0XHRcdHNraXBNZXJnZVxuXHRcdFx0XHQpO1xuXHRcdFx0XHRpZiAoIXNob3VsZEFwcGx5U3RhdGUpIHtcblx0XHRcdFx0XHRyZXR1cm4ge307XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmV0dXJuIGFwcGx5Vmlld1N0YXRlO1xuXHRcdFx0XHR9XG5cdFx0XHR9KVxuXHRcdFx0LmNhdGNoKGZ1bmN0aW9uIChvRXJyb3I6IHVua25vd24pIHtcblx0XHRcdFx0TG9nLmVycm9yKFwiYXBwU3RhdGUgY291bGQgbm90IGJlIGFwcGxpZWRcIiwgb0Vycm9yIGFzIHN0cmluZyk7XG5cdFx0XHRcdHRocm93IG9FcnJvcjtcblx0XHRcdH0pXG5cdFx0XHQuZmluYWxseSgoKSA9PiB7XG5cdFx0XHRcdEJ1c3lMb2NrZXIudW5sb2NrKHRoaXMpO1xuXHRcdFx0XHRCdXN5TG9ja2VyLnVubG9jayh0aGlzLm9BcHBDb21wb25lbnQuZ2V0Um9vdENvbnRyb2woKSk7XG5cdFx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUbyBjaGVjayBpcyByb3V0ZSBpcyBjaGFuZ2VkIGJ5IGNoYW5nZSBpbiB0aGUgaUFQUFN0YXRlLlxuXHQgKlxuXHQgKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHJvdXRlIGhhcyBjaG5hZ2VkXG5cdCAqL1xuXHRjaGVja0lmUm91dGVDaGFuZ2VkQnlJQXBwKCkge1xuXHRcdHJldHVybiB0aGlzLmJOb1JvdXRlQ2hhbmdlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlc2V0IHRoZSByb3V0ZSBjaGFuZ2VkIGJ5IGlBUFBTdGF0ZS5cblx0ICovXG5cdHJlc2V0Um91dGVDaGFuZ2VkQnlJQXBwKCkge1xuXHRcdGlmICh0aGlzLmJOb1JvdXRlQ2hhbmdlKSB7XG5cdFx0XHR0aGlzLmJOb1JvdXRlQ2hhbmdlID0gZmFsc2U7XG5cdFx0fVxuXHR9XG59XG5cbi8qKlxuICogQGdsb2JhbFxuICovXG5leHBvcnQgZGVmYXVsdCBBcHBTdGF0ZUhhbmRsZXI7XG4iXSwibWFwcGluZ3MiOiI7QUFBQTtBQUFBO0FBQUE7Ozs7Ozs7O0VBZ0JBLE1BQU1BLE9BQU8sR0FBR0MsT0FBTyxDQUFDRCxPQUFPO0VBYy9CLE1BQU1FLGNBQWMsR0FBRyxXQUFXO0VBZ0JsQyxNQUFNQyx5QkFBeUIsR0FBRywyQkFBMkI7RUFBQyxJQUd4REMsZUFBZSxXQURwQkMsY0FBYyxDQUFDLDZCQUE2QixDQUFDO0lBQUE7SUFZN0MseUJBQVlDLGFBQTJCLEVBQUU7TUFBQTtNQUN4Qyw4QkFBTztNQUFDLE1BTERDLGlCQUFpQixHQUFjLENBQUMsQ0FBQztNQU14QyxNQUFLRCxhQUFhLEdBQUdBLGFBQWE7TUFDbEMsTUFBS0UsR0FBRyxHQUFJLEdBQUVGLGFBQWEsQ0FBQ0csS0FBSyxFQUFHLGtCQUFpQjtNQUNy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
|
|
@@ -5,6 +5,7 @@ import type { NavigationParameter } from "sap/fe/core/controllerextensions/ViewS
|
|
|
5
5
|
import { defineUI5Class } from "sap/fe/core/helpers/ClassSupport";
|
|
6
6
|
import type { InternalModelContext } from "sap/fe/core/helpers/ModelHelper";
|
|
7
7
|
import toES6Promise from "sap/fe/core/helpers/ToES6Promise";
|
|
8
|
+
import type { InnerAppData } from "sap/fe/navigation/NavigationHandler";
|
|
8
9
|
import type { SelectionVariant } from "sap/fe/navigation/SelectionVariant";
|
|
9
10
|
import library from "sap/fe/navigation/library";
|
|
10
11
|
import BaseObject from "sap/ui/base/Object";
|
|
@@ -37,6 +38,14 @@ export type AppDataInfo = {
|
|
|
37
38
|
appStateKey: string | null;
|
|
38
39
|
};
|
|
39
40
|
|
|
41
|
+
export type CreateAppParameters = {
|
|
42
|
+
replaceHash?: boolean;
|
|
43
|
+
skipMerge?: boolean;
|
|
44
|
+
viewId?: string;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const REPLACE_COMPLETE_APPSTATE = "REPLACE_COMPLETE_APPSTATE";
|
|
48
|
+
|
|
40
49
|
@defineUI5Class("sap.fe.core.AppStateHandler")
|
|
41
50
|
class AppStateHandler extends BaseObject {
|
|
42
51
|
public sId: string;
|
|
@@ -47,13 +56,13 @@ class AppStateHandler extends BaseObject {
|
|
|
47
56
|
|
|
48
57
|
private _mCurrentAppState?: AppState = {};
|
|
49
58
|
|
|
50
|
-
|
|
59
|
+
simultaneousCreateRequest: Record<string, number>;
|
|
51
60
|
|
|
52
61
|
constructor(oAppComponent: AppComponent) {
|
|
53
62
|
super();
|
|
54
63
|
this.oAppComponent = oAppComponent;
|
|
55
64
|
this.sId = `${oAppComponent.getId()}/AppStateHandler`;
|
|
56
|
-
this.
|
|
65
|
+
this.simultaneousCreateRequest = {};
|
|
57
66
|
this.bNoRouteChange = false;
|
|
58
67
|
Log.info("APPSTATE : Appstate handler initialized");
|
|
59
68
|
}
|
|
@@ -63,62 +72,150 @@ class AppStateHandler extends BaseObject {
|
|
|
63
72
|
}
|
|
64
73
|
|
|
65
74
|
/**
|
|
66
|
-
*
|
|
67
|
-
* Replaces the hash with the new appstate based on replaceHash
|
|
75
|
+
* Get the view-specific appstate.
|
|
68
76
|
*
|
|
69
|
-
* @param
|
|
70
|
-
* @param
|
|
71
|
-
* @
|
|
72
|
-
* @returns A promise resolving the stored data or appstate key based on returnKey property
|
|
77
|
+
* @param innerAppState Overall appstate
|
|
78
|
+
* @param stateIdentifier State identifier, id of the local view
|
|
79
|
+
* @returns Inner appstate
|
|
73
80
|
*/
|
|
74
|
-
|
|
75
|
-
if (
|
|
76
|
-
|
|
81
|
+
_getInnerAppStateForView(innerAppState: InnerAppData | undefined, stateIdentifier: string): InnerAppData | undefined {
|
|
82
|
+
if (stateIdentifier === REPLACE_COMPLETE_APPSTATE || !innerAppState) {
|
|
83
|
+
// overall app state needs to be considered.
|
|
84
|
+
return innerAppState;
|
|
77
85
|
}
|
|
78
|
-
const { replaceHash = true, skipMerge = false } = createAppParameters || {};
|
|
79
86
|
|
|
80
|
-
|
|
81
|
-
|
|
87
|
+
// we take the subset of the app state wrt to the local view id.
|
|
88
|
+
return {
|
|
89
|
+
[stateIdentifier]: innerAppState[stateIdentifier as keyof typeof innerAppState] || {}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Add appstate in hash.
|
|
95
|
+
*
|
|
96
|
+
* @param appStateKey Appstate key
|
|
97
|
+
* @param stateIdentifier State identifier, Id of the local view
|
|
98
|
+
*/
|
|
99
|
+
_addAppStateInHash(appStateKey: string, stateIdentifier: string): void {
|
|
100
|
+
const appComponent = this.oAppComponent,
|
|
101
|
+
navigationService = appComponent.getNavigationService(),
|
|
102
|
+
routerProxy = appComponent.getRouterProxy(),
|
|
82
103
|
hash = routerProxy.getHash(),
|
|
83
|
-
|
|
84
|
-
|
|
104
|
+
isStickyMode = ModelHelper.isStickySessionSupported(appComponent.getMetaModel()),
|
|
105
|
+
newHash = navigationService.replaceInnerAppStateKey(routerProxy.getFullHash(), appStateKey);
|
|
85
106
|
|
|
86
|
-
if (
|
|
87
|
-
|
|
107
|
+
if (this.simultaneousCreateRequest[stateIdentifier] === 0 && newHash !== hash) {
|
|
108
|
+
routerProxy.navToHash(newHash, undefined, undefined, undefined, !isStickyMode);
|
|
109
|
+
this.bNoRouteChange = true;
|
|
88
110
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
111
|
+
Log.info("APPSTATE: navToHash");
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Create Appstate Key.
|
|
116
|
+
*
|
|
117
|
+
* @param appStateData Appstate
|
|
118
|
+
* @param stateIdentifier State identifier, Id of the local view
|
|
119
|
+
* @returns Appstate Key
|
|
120
|
+
*/
|
|
121
|
+
async _createAppStateKey(appStateData: InnerAppData, stateIdentifier: string): Promise<string> {
|
|
122
|
+
const appComponent = this.oAppComponent,
|
|
123
|
+
navigationService = appComponent.getNavigationService();
|
|
124
|
+
|
|
125
|
+
if (this.simultaneousCreateRequest[stateIdentifier]) {
|
|
126
|
+
// any other value
|
|
127
|
+
this.simultaneousCreateRequest[stateIdentifier]++;
|
|
128
|
+
} else {
|
|
129
|
+
// 0 or undefined
|
|
130
|
+
this.simultaneousCreateRequest[stateIdentifier] = 1;
|
|
92
131
|
}
|
|
93
|
-
|
|
132
|
+
|
|
133
|
+
const appStateKey = await navigationService.storeInnerAppStateAsync(appStateData, true, true);
|
|
134
|
+
|
|
135
|
+
this.simultaneousCreateRequest[stateIdentifier]--;
|
|
136
|
+
|
|
137
|
+
Log.info("APPSTATE: Appstate stored");
|
|
138
|
+
return appStateKey;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Creates appstate info.
|
|
143
|
+
*
|
|
144
|
+
* @param innerAppState
|
|
145
|
+
* @param createAppParameters Parameters for creating a new appstate
|
|
146
|
+
* @param createAppParameters.replaceHash A Boolean that determines whether to replace the hash with the newly generated key
|
|
147
|
+
* @param createAppParameters.viewId Id of the view for which we need to create the app state. This allows us to create or update view-specific appstate.
|
|
148
|
+
* @returns A promise that resolves the stored data or appstate keys
|
|
149
|
+
*/
|
|
150
|
+
async _getAppStateInfo(innerAppState: InnerAppData | undefined, createAppParameters?: CreateAppParameters): Promise<AppDataInfo> {
|
|
151
|
+
const appComponent = this.oAppComponent;
|
|
152
|
+
const { replaceHash = true, viewId: stateIdentifier = REPLACE_COMPLETE_APPSTATE } = createAppParameters ?? {};
|
|
153
|
+
|
|
94
154
|
let appStateKey: string | null = null;
|
|
95
|
-
|
|
96
|
-
|
|
155
|
+
let appStateData = { appState: this._mCurrentAppState };
|
|
156
|
+
|
|
157
|
+
const currentStateToUpdate = this._getInnerAppStateForView(this._mCurrentAppState, stateIdentifier);
|
|
158
|
+
if (innerAppState && !deepEqual(currentStateToUpdate, innerAppState)) {
|
|
159
|
+
//
|
|
160
|
+
this._mCurrentAppState = { ...this._mCurrentAppState, ...(innerAppState as Record<string, unknown>) };
|
|
161
|
+
appStateData = { appState: this._mCurrentAppState };
|
|
97
162
|
try {
|
|
98
|
-
this.
|
|
99
|
-
appStateKey = await navigationService.storeInnerAppStateAsync(appStateData, true, true);
|
|
100
|
-
Log.info("APPSTATE: Appstate stored");
|
|
163
|
+
appStateKey = await this._createAppStateKey(appStateData, stateIdentifier);
|
|
101
164
|
if (replaceHash === true) {
|
|
102
|
-
|
|
103
|
-
this.nbSimultaneousCreateRequest--;
|
|
104
|
-
if (this.nbSimultaneousCreateRequest === 0 && sNewHash !== hash) {
|
|
105
|
-
routerProxy.navToHash(sNewHash, undefined, undefined, undefined, !isStickyMode);
|
|
106
|
-
this.bNoRouteChange = true;
|
|
107
|
-
}
|
|
108
|
-
Log.info("APPSTATE: navToHash");
|
|
165
|
+
this._addAppStateInHash(appStateKey, stateIdentifier);
|
|
109
166
|
}
|
|
110
167
|
} catch (oError: unknown) {
|
|
111
168
|
Log.error(oError as string);
|
|
112
169
|
}
|
|
113
170
|
} else {
|
|
171
|
+
const routerProxy = appComponent.getRouterProxy(),
|
|
172
|
+
hash = routerProxy.getHash();
|
|
114
173
|
appStateKey = routerProxy.findAppStateInHash(hash) as string;
|
|
115
174
|
}
|
|
116
175
|
return {
|
|
117
|
-
appStateData
|
|
118
|
-
appStateKey
|
|
176
|
+
appStateData,
|
|
177
|
+
appStateKey
|
|
119
178
|
};
|
|
120
179
|
}
|
|
121
180
|
|
|
181
|
+
/**
|
|
182
|
+
* Creates or updates the appstate.
|
|
183
|
+
* Replaces the hash with the new appstate based on replaceHash
|
|
184
|
+
*
|
|
185
|
+
* @param createAppParameters Parameters for creating new appstate
|
|
186
|
+
* @param createAppParameters.replaceHash Boolean which determines to replace the hash with the new generated key
|
|
187
|
+
* @param createAppParameters.skipMerge Boolean which determines to skip the key user shine through
|
|
188
|
+
* @param createAppParameters.viewId Id of the view for which we need to create the app state. This allows us to create or update view-specific appstate.
|
|
189
|
+
* @returns A promise resolving the stored data or appstate key
|
|
190
|
+
*/
|
|
191
|
+
async createAppState(createAppParameters?: CreateAppParameters): Promise<void | AppDataInfo> {
|
|
192
|
+
const appComponent = this.oAppComponent;
|
|
193
|
+
if (!appComponent.getEnvironmentCapabilities().getCapabilities().AppState || BusyLocker.isLocked(this)) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
const { skipMerge = false, viewId: stateIdentifier = REPLACE_COMPLETE_APPSTATE } = createAppParameters ?? {},
|
|
197
|
+
rootController = appComponent.getRootControl().getController();
|
|
198
|
+
|
|
199
|
+
if (!rootController.viewState) {
|
|
200
|
+
throw new Error(`viewState controller extension not available for controller: ${rootController.getMetadata().getName()}`);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// In case, on load of FCL app we have multiple views(LR, OP, sub-OP...) and url has iAppState(1).
|
|
204
|
+
// The LR view loads with applied iAppState(1) and calls createAppState(example: onSearch event in LR) before OP is loaded.
|
|
205
|
+
// This creates iAppState(2) before iAppState(1) is applied to OP.
|
|
206
|
+
// So, we try to wait till the routing is complete.
|
|
207
|
+
await rootController.routingIsComplete();
|
|
208
|
+
|
|
209
|
+
// Get appState to update
|
|
210
|
+
let innerAppState = (await rootController.viewState.retrieveViewState()) as InnerAppData | undefined;
|
|
211
|
+
innerAppState = this._getInnerAppStateForView(innerAppState, stateIdentifier);
|
|
212
|
+
if (skipMerge) {
|
|
213
|
+
innerAppState = { ...innerAppState, ...{ skipMerge } };
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return this._getAppStateInfo(innerAppState, createAppParameters);
|
|
217
|
+
}
|
|
218
|
+
|
|
122
219
|
_createNavigationParameters(oAppData: AppData, sNavType: string): NavigationParameter {
|
|
123
220
|
return Object.assign({}, oAppData, {
|
|
124
221
|
selectionVariantDefaults: oAppData.oDefaultedSelectionVariant,
|
|
@@ -217,9 +314,9 @@ class AppStateHandler extends BaseObject {
|
|
|
217
314
|
const appStateData = this._getAppStateData(oAppData, viewId, sNavType);
|
|
218
315
|
// fetch the skipMerge flag from appState for save as tile
|
|
219
316
|
const skipMerge: boolean | undefined = oAppData?.appState?.[SKIP_MERGE_KEY];
|
|
220
|
-
this._mCurrentAppState =
|
|
317
|
+
this._mCurrentAppState =
|
|
318
|
+
sNavType === NavType.iAppState || sNavType === NavType.hybrid ? { ...this._mCurrentAppState, ...appStateData } : {};
|
|
221
319
|
let shouldApplyState = true;
|
|
222
|
-
|
|
223
320
|
if (!oRootController.viewState) {
|
|
224
321
|
throw new Error(`viewState extension required for controller ${oRootController.getMetadata().getName()}`);
|
|
225
322
|
}
|