studiokit-scaffolding-js 7.0.12-next.1.3 → 7.0.12-next.2.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.
Files changed (258) hide show
  1. package/lib/components/ActionList.js +164 -37
  2. package/lib/components/AlertDialog.js +128 -12
  3. package/lib/components/AlertWithIcon.js +88 -29
  4. package/lib/components/ConnectedModal.js +35 -12
  5. package/lib/components/Dropdowns/GroupsDropdown.js +63 -45
  6. package/lib/components/Dropdowns/ManagedNavDropdown.js +92 -67
  7. package/lib/components/Dropdowns/UserDropdown.js +105 -24
  8. package/lib/components/Dropdowns/index.js +4 -10
  9. package/lib/components/EntityOwnerList.js +47 -21
  10. package/lib/components/Error.js +101 -12
  11. package/lib/components/ErrorBoundary.js +127 -38
  12. package/lib/components/ErrorMessage.js +39 -12
  13. package/lib/components/Forms/DateField.js +56 -45
  14. package/lib/components/Forms/TimeField.js +76 -45
  15. package/lib/components/Forms/index.js +3 -5
  16. package/lib/components/Groups/CreateEditCopySaveButtons.js +109 -14
  17. package/lib/components/Groups/ExternalGroups/Attach.js +206 -151
  18. package/lib/components/Groups/ExternalGroups/Table.js +176 -48
  19. package/lib/components/Groups/GroupCreateOrEditCommonProps.js +2 -2
  20. package/lib/components/Groups/RosterSyncInfo.js +142 -23
  21. package/lib/components/HOC/AccessibleAppComponent.js +88 -72
  22. package/lib/components/HOC/ActivityRequiredComponent.js +68 -33
  23. package/lib/components/HOC/AsyncComponent.js +49 -41
  24. package/lib/components/HOC/AuthenticatedComponent.js +55 -44
  25. package/lib/components/HOC/CollectionComponent.js +154 -104
  26. package/lib/components/HOC/CollectionFirstItemComponent.js +45 -40
  27. package/lib/components/HOC/CollectionItemComponent.js +152 -100
  28. package/lib/components/HOC/ConnectedModalComponent.js +87 -69
  29. package/lib/components/HOC/DataDependentComponent.js +26 -27
  30. package/lib/components/HOC/EntityComponent.js +57 -53
  31. package/lib/components/HOC/FullscreenModalComponent.js +139 -108
  32. package/lib/components/HOC/GroupActivityRequiredComponent.js +27 -20
  33. package/lib/components/HOC/GuidComponent.js +20 -20
  34. package/lib/components/HOC/ModelContextDependencyVerifyComponent.js +32 -29
  35. package/lib/components/HOC/ModelErrorRedirectComponent.js +37 -39
  36. package/lib/components/HOC/SearchPersistorComponent.js +237 -173
  37. package/lib/components/HOC/UnauthenticatedComponent.js +32 -30
  38. package/lib/components/HOC/UserComponent.js +6 -8
  39. package/lib/components/Icons/IconAlphaList.js +28 -8
  40. package/lib/components/Icons/IconExternalUser.js +28 -8
  41. package/lib/components/Icons/IconImpersonation.js +28 -8
  42. package/lib/components/Icons/IconStopImpersonating.js +28 -8
  43. package/lib/components/Icons/IconTable.js +29 -9
  44. package/lib/components/Icons/IconTableDeleteCol.js +28 -8
  45. package/lib/components/Icons/IconTableDeleteRow.js +28 -8
  46. package/lib/components/Icons/IconTableInsertCol.js +28 -8
  47. package/lib/components/Icons/IconTableInsertRow.js +28 -8
  48. package/lib/components/Impersonation/Button.js +71 -16
  49. package/lib/components/Impersonation/Link.js +72 -16
  50. package/lib/components/Impersonation/UserDetail.js +60 -11
  51. package/lib/components/Loading.js +23 -8
  52. package/lib/components/LockDownBrowser/Check.js +188 -51
  53. package/lib/components/LockDownBrowser/ExitButton.js +22 -13
  54. package/lib/components/LockDownBrowser/Launch.js +64 -64
  55. package/lib/components/Lti/Confirm.js +147 -14
  56. package/lib/components/Lti/CreateNonLtiGroupAlertDialog.js +165 -36
  57. package/lib/components/Lti/Launch.js +99 -25
  58. package/lib/components/Lti/LaunchGroup.js +81 -16
  59. package/lib/components/ManageTable.js +304 -90
  60. package/lib/components/ManageTableNoDataComponent.js +38 -7
  61. package/lib/components/NewVersionAlert.js +76 -49
  62. package/lib/components/NotFound.js +81 -11
  63. package/lib/components/Notifications.js +179 -129
  64. package/lib/components/PaginationNextButton.js +28 -9
  65. package/lib/components/PaginationPreviousButton.js +28 -9
  66. package/lib/components/Quill/CustomToolbar.js +427 -222
  67. package/lib/components/Quill/Formats/Image.js +67 -67
  68. package/lib/components/Quill/Formats/List.js +38 -47
  69. package/lib/components/Quill/Formats/Video.js +23 -26
  70. package/lib/components/Quill/ImageDropModule.js +136 -114
  71. package/lib/components/Quill/ImageWarning.js +41 -12
  72. package/lib/components/Quill/ImageWithAltTextModal.js +420 -89
  73. package/lib/components/Quill/Specs/CustomImageSpec.js +32 -31
  74. package/lib/components/Quill/Specs/CustomVideoSpec.js +22 -23
  75. package/lib/components/Quill/TableModule/Blots/BaseTableBlot.js +89 -97
  76. package/lib/components/Quill/TableModule/Blots/TableBlot.js +47 -50
  77. package/lib/components/Quill/TableModule/Blots/TableBodyBlot.js +48 -51
  78. package/lib/components/Quill/TableModule/Blots/TableCellBlot.js +219 -224
  79. package/lib/components/Quill/TableModule/Blots/TableContainer.js +75 -86
  80. package/lib/components/Quill/TableModule/Blots/TableRowBlot.js +70 -73
  81. package/lib/components/Quill/TableModule/constants.js +40 -42
  82. package/lib/components/Quill/TableModule/index.js +357 -305
  83. package/lib/components/Quill/TableModule/utils.js +39 -48
  84. package/lib/components/Quill/accessibilityFix.js +219 -223
  85. package/lib/components/Quill/index.js +30 -33
  86. package/lib/components/RefreshIndicator/Bordered.js +44 -10
  87. package/lib/components/RefreshIndicator/Inline.js +43 -12
  88. package/lib/components/RefreshIndicator/index.js +257 -62
  89. package/lib/components/SearchControls.js +211 -14
  90. package/lib/components/SentryRoute.js +5 -7
  91. package/lib/components/Tables/RoleFilter.js +66 -38
  92. package/lib/components/Tables/TextFilter.js +58 -18
  93. package/lib/components/UserRoles/Add.js +193 -99
  94. package/lib/components/UserRoles/Context.js +3 -6
  95. package/lib/components/UserRoles/RoleCell.js +176 -75
  96. package/lib/components/UserRoles/Select.js +151 -20
  97. package/lib/components/UserRoles/Table.js +215 -82
  98. package/lib/components/UserRoles/index.js +526 -386
  99. package/lib/config/eslint/index.js +26 -29
  100. package/lib/config/eslint/lib/order.js +21 -28
  101. package/lib/config/eslint/lib/prettier.js +15 -19
  102. package/lib/config/eslint/lib/typescript.js +87 -113
  103. package/lib/config/eslint/react.js +18 -15
  104. package/lib/constants/baseActivity.js +26 -28
  105. package/lib/constants/baseRole.js +10 -12
  106. package/lib/constants/configuration.js +43 -55
  107. package/lib/constants/externalProviderType.js +6 -8
  108. package/lib/constants/fetchErrorData.js +10 -12
  109. package/lib/constants/index.js +13 -15
  110. package/lib/constants/lockDownBrowser.js +23 -25
  111. package/lib/constants/mockData.js +370 -300
  112. package/lib/constants/modelStatus.js +11 -13
  113. package/lib/constants/notificationType.js +8 -10
  114. package/lib/constants/operatingSystem.js +8 -10
  115. package/lib/constants/shard.js +7 -9
  116. package/lib/constants/table.js +18 -22
  117. package/lib/constants/tier.js +8 -10
  118. package/lib/constants/userRole.js +11 -8
  119. package/lib/endpointMappings.js +191 -182
  120. package/lib/hooks/useCollection.js +79 -65
  121. package/lib/hooks/useCollectionConfiguration.js +220 -80
  122. package/lib/hooks/useCollectionItem.js +151 -57
  123. package/lib/hooks/useGuid.js +16 -9
  124. package/lib/hooks/usePrevious.js +14 -13
  125. package/lib/index.js +11 -26
  126. package/lib/redux/actionCreator.js +44 -35
  127. package/lib/redux/actions/AuthAction.js +45 -32
  128. package/lib/redux/actions/ModalAction.js +6 -8
  129. package/lib/redux/actions/ModelAction.js +95 -43
  130. package/lib/redux/actions/NotificationAction.js +6 -8
  131. package/lib/redux/actions/SearchAction.js +5 -7
  132. package/lib/redux/actions/index.js +6 -8
  133. package/lib/redux/configureReducers.js +48 -46
  134. package/lib/redux/configureStore.js +77 -91
  135. package/lib/redux/helpers.js +2 -5
  136. package/lib/redux/reducers/authReducer.js +44 -43
  137. package/lib/redux/reducers/index.js +7 -14
  138. package/lib/redux/reducers/modalsReducer.js +43 -31
  139. package/lib/redux/reducers/modelsReducer.js +131 -137
  140. package/lib/redux/reducers/notificationsReducer.js +20 -20
  141. package/lib/redux/reducers/searchReducer.js +13 -13
  142. package/lib/redux/sagas/appInsightsSaga.js +19 -21
  143. package/lib/redux/sagas/authSaga.js +248 -234
  144. package/lib/redux/sagas/caliperSaga.js +142 -131
  145. package/lib/redux/sagas/clockOffsetSaga.js +29 -32
  146. package/lib/redux/sagas/configurationSaga.js +8 -10
  147. package/lib/redux/sagas/downtimeApiErrorSaga.js +16 -19
  148. package/lib/redux/sagas/errorSaga.js +23 -24
  149. package/lib/redux/sagas/googleAnalyticsSaga.js +24 -27
  150. package/lib/redux/sagas/identityProviderSaga.js +19 -21
  151. package/lib/redux/sagas/initialDataLoadSaga.js +34 -31
  152. package/lib/redux/sagas/lockDownBrowserErrorSaga.js +25 -22
  153. package/lib/redux/sagas/modelFetchSaga.js +302 -286
  154. package/lib/redux/sagas/noStoreSaga.js +60 -61
  155. package/lib/redux/sagas/postLoginDataSaga.js +37 -32
  156. package/lib/redux/sagas/postLoginRedirectSaga.js +22 -27
  157. package/lib/redux/sagas/rootSaga.js +77 -60
  158. package/lib/redux/sagas/sentrySaga.js +25 -28
  159. package/lib/redux/sagas/userIdSaga.js +13 -15
  160. package/lib/services/codeProviderService.js +21 -21
  161. package/lib/services/dateService.js +6 -8
  162. package/lib/services/documentService.js +10 -11
  163. package/lib/services/fetchService.js +103 -95
  164. package/lib/services/persistenceService.js +27 -30
  165. package/lib/services/ticketProviderService.js +25 -25
  166. package/lib/services/tokenPersistenceService.js +8 -10
  167. package/lib/services/windowService.js +14 -16
  168. package/lib/startup.js +110 -101
  169. package/lib/types/AppConfiguration.js +2 -2
  170. package/lib/types/Artifact.js +7 -9
  171. package/lib/types/BaseReduxState.js +2 -2
  172. package/lib/types/Client.js +2 -2
  173. package/lib/types/Collection.js +2 -2
  174. package/lib/types/Configuration.js +2 -2
  175. package/lib/types/DeepLinkingResponseRequest.js +2 -2
  176. package/lib/types/DeletableModel.js +2 -2
  177. package/lib/types/Event.js +2 -2
  178. package/lib/types/ExternalGroup.js +2 -2
  179. package/lib/types/ExternalProvider.js +2 -2
  180. package/lib/types/ExternalTerm.js +2 -2
  181. package/lib/types/Group.js +2 -2
  182. package/lib/types/IdentityProvider.js +2 -2
  183. package/lib/types/LtiLaunch.js +2 -2
  184. package/lib/types/NameOnlyEntity.js +2 -2
  185. package/lib/types/Notification.js +2 -2
  186. package/lib/types/OptionalRecord.js +2 -2
  187. package/lib/types/OwnerSchedule.js +2 -2
  188. package/lib/types/PropertyOfType.js +2 -2
  189. package/lib/types/Quill.js +2 -2
  190. package/lib/types/RoleDescription.js +2 -2
  191. package/lib/types/Search.js +2 -2
  192. package/lib/types/SimpleLocation.js +2 -2
  193. package/lib/types/UniTime.js +2 -2
  194. package/lib/types/User.js +2 -2
  195. package/lib/types/UserRole.js +2 -2
  196. package/lib/types/auth/AuthState.js +2 -2
  197. package/lib/types/auth/CasV1LoginRequestBody.js +2 -2
  198. package/lib/types/auth/ClientCredentials.js +2 -2
  199. package/lib/types/auth/CodeProviderService.js +2 -2
  200. package/lib/types/auth/LocalLoginRequestBody.js +2 -2
  201. package/lib/types/auth/TicketProviderService.js +2 -2
  202. package/lib/types/auth/TokenPersistenceService.js +2 -2
  203. package/lib/types/auth/index.js +8 -10
  204. package/lib/types/externals.d.js +2 -0
  205. package/lib/types/index.js +29 -31
  206. package/lib/types/net/EndpointConfig.js +2 -2
  207. package/lib/types/net/EndpointMapping.js +2 -2
  208. package/lib/types/net/EndpointMappings.js +2 -2
  209. package/lib/types/net/ErrorHandler.js +2 -2
  210. package/lib/types/net/FetchConfig.js +2 -2
  211. package/lib/types/net/FetchErrorData.js +6 -8
  212. package/lib/types/net/FetchResult.js +2 -2
  213. package/lib/types/net/HTTPMethod.js +2 -2
  214. package/lib/types/net/HTTPStatusCode.js +12 -14
  215. package/lib/types/net/Metadata.js +2 -2
  216. package/lib/types/net/Model.js +2 -2
  217. package/lib/types/net/ModelCollection.js +2 -2
  218. package/lib/types/net/ModelsState.js +2 -2
  219. package/lib/types/net/OAuthToken.js +2 -2
  220. package/lib/types/net/OAuthTokenOrNull.js +2 -2
  221. package/lib/types/net/TokenAccessFunction.js +2 -2
  222. package/lib/types/net/index.js +17 -19
  223. package/lib/utils/baseActivity.js +83 -85
  224. package/lib/utils/baseRole.js +32 -36
  225. package/lib/utils/collection.js +403 -297
  226. package/lib/utils/cookies.js +19 -23
  227. package/lib/utils/date.js +188 -205
  228. package/lib/utils/dom.js +130 -131
  229. package/lib/utils/domainIdentifier.js +4 -8
  230. package/lib/utils/entityUserRole.js +2 -5
  231. package/lib/utils/error.js +14 -19
  232. package/lib/utils/events.js +32 -31
  233. package/lib/utils/externalGroup.js +20 -25
  234. package/lib/utils/externalProviders.js +4 -7
  235. package/lib/utils/externalTerms.js +6 -6
  236. package/lib/utils/fetch.js +168 -176
  237. package/lib/utils/group.js +14 -11
  238. package/lib/utils/groupDates.js +38 -46
  239. package/lib/utils/groupRoles.js +23 -32
  240. package/lib/utils/lockDownBrowser.js +12 -15
  241. package/lib/utils/logger.js +23 -28
  242. package/lib/utils/lti.js +4 -7
  243. package/lib/utils/model.js +28 -43
  244. package/lib/utils/number.js +9 -13
  245. package/lib/utils/promise.js +23 -26
  246. package/lib/utils/quill.js +55 -60
  247. package/lib/utils/route.js +52 -60
  248. package/lib/utils/search.js +72 -87
  249. package/lib/utils/shard.js +33 -42
  250. package/lib/utils/sort.js +47 -50
  251. package/lib/utils/string.js +10 -12
  252. package/lib/utils/table.js +29 -33
  253. package/lib/utils/timezone.js +7 -12
  254. package/lib/utils/url.js +130 -144
  255. package/lib/utils/user.js +54 -64
  256. package/lib/utils/userAgent.js +7 -14
  257. package/lib/utils/userRole.js +36 -39
  258. package/package.json +17 -3
@@ -1,275 +1,366 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.selectCollectionItemFromState = selectCollectionItemFromState;
4
- exports.selectCollectionFromState = selectCollectionFromState;
5
- exports.stopCollectionPeriodicLoad = stopCollectionPeriodicLoad;
6
- exports.loadCollection = loadCollection;
7
- exports.loadCollectionItem = loadCollectionItem;
8
- exports.createItemInCollection = createItemInCollection;
9
- exports.createCollectionItem = createCollectionItem;
10
- exports.updateItemInCollection = updateItemInCollection;
11
- exports.updateCollectionItem = updateCollectionItem;
12
- exports.deleteItemFromCollection = deleteItemFromCollection;
13
- exports.deleteCollectionItem = deleteCollectionItem;
14
- exports.initializeCollectionItem = initializeCollectionItem;
15
- exports.initializeCollection = initializeCollection;
16
- exports.handleCollectionItemParamsChange = handleCollectionItemParamsChange;
17
- exports.handleCollectionParamsChange = handleCollectionParamsChange;
18
- exports.cleanupCollectionGuidKey = cleanupCollectionGuidKey;
19
- const tslib_1 = require("tslib");
20
- const lodash_1 = require("lodash");
21
- const memoize_one_1 = tslib_1.__importDefault(require("memoize-one"));
22
- const constants_1 = require("../constants");
23
- const actionCreator_1 = require("../redux/actionCreator");
24
- const route_1 = require("./route");
1
+ import { concat, find, get, includes, isEqual, values } from 'lodash';
2
+ import memoizeOne from 'memoize-one';
3
+ import { MODEL_STATUS } from '../constants';
4
+ import { dispatchModelFetchRequest, dispatchModelRemoveKeyAction, dispatchPeriodicModelFetchRequest, dispatchPeriodicModelFetchTerminateAction } from '../redux/actionCreator';
5
+ import { getMinRequiredPathParamsCount, getPathParamsFromRouteMatchParams, getReduxModelName } from './route';
6
+
25
7
  //#region Redux Methods
26
- const getPathParams = (0, memoize_one_1.default)((pathParams, routeMatchParams, modelName) => pathParams || (0, route_1.getPathParamsFromRouteMatchParams)(routeMatchParams, modelName));
27
- function selectCollectionItemFromState(params) {
28
- const { guid, modelName, pathParams, routeMatchParams, state } = params;
29
- const modelNameLevelCount = (0, route_1.getMinRequiredPathParamsCount)(modelName);
30
- const p = getPathParams(pathParams, routeMatchParams, modelName);
31
- const reduxModelName = (0, route_1.getReduxModelName)(p, modelName);
32
- let model = {};
33
- // find `model` using `guid` as its key, to match new item created in `create()`
34
- if (p.length === modelNameLevelCount) {
35
- const collection = ((0, lodash_1.get)(state.models, reduxModelName) || {});
36
- if (Object.prototype.hasOwnProperty.call(collection, guid)) {
37
- model = collection[guid];
38
- }
39
- else {
40
- const modelByGuid = (0, lodash_1.find)((0, lodash_1.values)(collection), (m) => !!m && 'guid' in m && m.guid === guid);
41
- model = modelByGuid || model;
42
- }
43
- }
44
- else {
45
- // find `model` using pathParams
46
- const reduxModel = ((0, lodash_1.get)(state.models, reduxModelName) || {});
47
- model = (Object.keys(reduxModel).length > 0 ? reduxModel : {});
8
+
9
+ const getPathParams = memoizeOne((pathParams, routeMatchParams, modelName) => pathParams || getPathParamsFromRouteMatchParams(routeMatchParams, modelName));
10
+ export function selectCollectionItemFromState(params) {
11
+ const {
12
+ guid,
13
+ modelName,
14
+ pathParams,
15
+ routeMatchParams,
16
+ state
17
+ } = params;
18
+ const modelNameLevelCount = getMinRequiredPathParamsCount(modelName);
19
+ const p = getPathParams(pathParams, routeMatchParams, modelName);
20
+ const reduxModelName = getReduxModelName(p, modelName);
21
+ let model = {};
22
+ // find `model` using `guid` as its key, to match new item created in `create()`
23
+ if (p.length === modelNameLevelCount) {
24
+ const collection = get(state.models, reduxModelName) || {};
25
+ if (Object.prototype.hasOwnProperty.call(collection, guid)) {
26
+ model = collection[guid];
27
+ } else {
28
+ const modelByGuid = find(values(collection), m => !!m && 'guid' in m && m.guid === guid);
29
+ model = modelByGuid || model;
48
30
  }
49
- return {
50
- modelName,
51
- pathParams: p,
52
- model,
53
- isCollectionItem: true
54
- };
31
+ } else {
32
+ // find `model` using pathParams
33
+ const reduxModel = get(state.models, reduxModelName) || {};
34
+ model = Object.keys(reduxModel).length > 0 ? reduxModel : {};
35
+ }
36
+ return {
37
+ modelName,
38
+ pathParams: p,
39
+ model,
40
+ isCollectionItem: true
41
+ };
55
42
  }
56
- function selectCollectionFromState(params) {
57
- const { modelName, pathParams, routeMatchParams, state } = params;
58
- const p = getPathParams(pathParams, routeMatchParams, modelName);
59
- const reduxModelName = (0, route_1.getReduxModelName)(p, modelName);
60
- let model = (0, lodash_1.get)(state.models, reduxModelName);
61
- model = model && Object.keys(model).length > 0 ? model : {};
62
- return {
63
- modelName,
64
- pathParams: p,
65
- model,
66
- isCollectionItem: false
67
- };
43
+ export function selectCollectionFromState(params) {
44
+ const {
45
+ modelName,
46
+ pathParams,
47
+ routeMatchParams,
48
+ state
49
+ } = params;
50
+ const p = getPathParams(pathParams, routeMatchParams, modelName);
51
+ const reduxModelName = getReduxModelName(p, modelName);
52
+ let model = get(state.models, reduxModelName);
53
+ model = model && Object.keys(model).length > 0 ? model : {};
54
+ return {
55
+ modelName,
56
+ pathParams: p,
57
+ model,
58
+ isCollectionItem: false
59
+ };
68
60
  }
61
+
69
62
  //#endregion Redux Methods
63
+
70
64
  //#region Collection/Item CRUD Methods
65
+
71
66
  //#region Load
72
- function stopCollectionPeriodicLoad(taskId) {
73
- (0, actionCreator_1.dispatchPeriodicModelFetchTerminateAction)({
74
- taskId
75
- });
67
+
68
+ export function stopCollectionPeriodicLoad(taskId) {
69
+ dispatchPeriodicModelFetchTerminateAction({
70
+ taskId
71
+ });
76
72
  }
77
- function loadCollection(config, params = {}) {
78
- const { modelName, isInitialized, pathParams: configPathParams, queryParams: configQueryParams, changeModelStatus } = config;
79
- const { id, pathParams, queryParams, period, taskId, replaceValue } = params;
80
- const p = (0, lodash_1.concat)([], pathParams || configPathParams, id ? [id] : []);
81
- if (p.length !== (0, route_1.getMinRequiredPathParamsCount)(modelName) + (id ? 1 : 0)) {
82
- throw new Error('pathParams length does not match length of path components');
83
- }
84
- if (isInitialized) {
85
- changeModelStatus(constants_1.MODEL_STATUS.LOADING, id);
86
- }
87
- if (!period) {
88
- (0, actionCreator_1.dispatchModelFetchRequest)({
89
- modelName,
90
- method: 'GET',
91
- pathParams: p,
92
- queryParams: queryParams || configQueryParams,
93
- replaceValue
94
- });
95
- }
96
- else {
97
- if (!taskId)
98
- throw new Error('taskId is required for periodic data requests');
99
- (0, actionCreator_1.dispatchPeriodicModelFetchRequest)({
100
- modelName,
101
- method: 'GET',
102
- pathParams: p,
103
- queryParams: queryParams || configQueryParams,
104
- period,
105
- taskId,
106
- replaceValue
107
- });
108
- }
73
+ export function loadCollection(config) {
74
+ let params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
75
+ const {
76
+ modelName,
77
+ isInitialized,
78
+ pathParams: configPathParams,
79
+ queryParams: configQueryParams,
80
+ changeModelStatus
81
+ } = config;
82
+ const {
83
+ id,
84
+ pathParams,
85
+ queryParams,
86
+ period,
87
+ taskId,
88
+ replaceValue
89
+ } = params;
90
+ const p = concat([], pathParams || configPathParams, id ? [id] : []);
91
+ if (p.length !== getMinRequiredPathParamsCount(modelName) + (id ? 1 : 0)) {
92
+ throw new Error('pathParams length does not match length of path components');
93
+ }
94
+ if (isInitialized) {
95
+ changeModelStatus(MODEL_STATUS.LOADING, id);
96
+ }
97
+ if (!period) {
98
+ dispatchModelFetchRequest({
99
+ modelName,
100
+ method: 'GET',
101
+ pathParams: p,
102
+ queryParams: queryParams || configQueryParams,
103
+ replaceValue
104
+ });
105
+ } else {
106
+ if (!taskId) throw new Error('taskId is required for periodic data requests');
107
+ dispatchPeriodicModelFetchRequest({
108
+ modelName,
109
+ method: 'GET',
110
+ pathParams: p,
111
+ queryParams: queryParams || configQueryParams,
112
+ period,
113
+ taskId,
114
+ replaceValue
115
+ });
116
+ }
109
117
  }
110
- function loadCollectionItem(config, params = {}) {
111
- const { modelName, isInitialized, pathParams: configPathParams, queryParams: configQueryParams, changeModelStatus } = config;
112
- const { pathParams, queryParams, period, taskId, replaceValue } = params;
113
- const p = pathParams || configPathParams;
114
- if (p.length < (0, route_1.getMinRequiredPathParamsCount)(modelName) + 1) {
115
- throw new Error('pathParams length does not match length of path components');
116
- }
117
- if (isInitialized) {
118
- changeModelStatus(constants_1.MODEL_STATUS.LOADING);
119
- }
120
- if (!period) {
121
- (0, actionCreator_1.dispatchModelFetchRequest)({
122
- modelName,
123
- method: 'GET',
124
- pathParams: p,
125
- queryParams: queryParams || configQueryParams,
126
- replaceValue
127
- });
128
- }
129
- else {
130
- if (!taskId)
131
- throw new Error('taskId is required for periodic data requests');
132
- (0, actionCreator_1.dispatchPeriodicModelFetchRequest)({
133
- modelName,
134
- method: 'GET',
135
- pathParams: p,
136
- queryParams: queryParams || configQueryParams,
137
- period,
138
- taskId,
139
- replaceValue
140
- });
141
- }
118
+ export function loadCollectionItem(config) {
119
+ let params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
120
+ const {
121
+ modelName,
122
+ isInitialized,
123
+ pathParams: configPathParams,
124
+ queryParams: configQueryParams,
125
+ changeModelStatus
126
+ } = config;
127
+ const {
128
+ pathParams,
129
+ queryParams,
130
+ period,
131
+ taskId,
132
+ replaceValue
133
+ } = params;
134
+ const p = pathParams || configPathParams;
135
+ if (p.length < getMinRequiredPathParamsCount(modelName) + 1) {
136
+ throw new Error('pathParams length does not match length of path components');
137
+ }
138
+ if (isInitialized) {
139
+ changeModelStatus(MODEL_STATUS.LOADING);
140
+ }
141
+ if (!period) {
142
+ dispatchModelFetchRequest({
143
+ modelName,
144
+ method: 'GET',
145
+ pathParams: p,
146
+ queryParams: queryParams || configQueryParams,
147
+ replaceValue
148
+ });
149
+ } else {
150
+ if (!taskId) throw new Error('taskId is required for periodic data requests');
151
+ dispatchPeriodicModelFetchRequest({
152
+ modelName,
153
+ method: 'GET',
154
+ pathParams: p,
155
+ queryParams: queryParams || configQueryParams,
156
+ period,
157
+ taskId,
158
+ replaceValue
159
+ });
160
+ }
142
161
  }
162
+
143
163
  //#endregion Load
164
+
144
165
  //#region Create
145
- function createItemInCollection(config, params) {
146
- const { guid, modelName, pathParams, queryParams: configQueryParams, changeModelStatus } = config;
147
- const { body, contentType, queryParams } = params;
148
- if (pathParams.length < (0, route_1.getMinRequiredPathParamsCount)(modelName)) {
149
- throw new Error('pathParams length does not match length of path components');
150
- }
151
- changeModelStatus(constants_1.MODEL_STATUS.CREATING, guid);
152
- (0, actionCreator_1.dispatchModelFetchRequest)({
153
- modelName,
154
- guid,
155
- method: 'POST',
156
- body,
157
- pathParams,
158
- contentType,
159
- queryParams: queryParams || configQueryParams
160
- });
166
+
167
+ export function createItemInCollection(config, params) {
168
+ const {
169
+ guid,
170
+ modelName,
171
+ pathParams,
172
+ queryParams: configQueryParams,
173
+ changeModelStatus
174
+ } = config;
175
+ const {
176
+ body,
177
+ contentType,
178
+ queryParams
179
+ } = params;
180
+ if (pathParams.length < getMinRequiredPathParamsCount(modelName)) {
181
+ throw new Error('pathParams length does not match length of path components');
182
+ }
183
+ changeModelStatus(MODEL_STATUS.CREATING, guid);
184
+ dispatchModelFetchRequest({
185
+ modelName,
186
+ guid,
187
+ method: 'POST',
188
+ body,
189
+ pathParams,
190
+ contentType,
191
+ queryParams: queryParams || configQueryParams
192
+ });
161
193
  }
162
- function createCollectionItem(model, config, params) {
163
- if (model.id) {
164
- throw new Error('model already exists');
165
- }
166
- const { guid, modelName, pathParams, queryParams: configQueryParams, changeModelStatus } = config;
167
- const { body, contentType, queryParams } = params;
168
- if (pathParams.length < (0, route_1.getMinRequiredPathParamsCount)(modelName)) {
169
- throw new Error('pathParams length does not match length of path components');
170
- }
171
- changeModelStatus(constants_1.MODEL_STATUS.CREATING);
172
- (0, actionCreator_1.dispatchModelFetchRequest)({
173
- modelName,
174
- guid,
175
- method: 'POST',
176
- body,
177
- pathParams,
178
- contentType,
179
- queryParams: queryParams || configQueryParams
180
- });
194
+ export function createCollectionItem(model, config, params) {
195
+ if (model.id) {
196
+ throw new Error('model already exists');
197
+ }
198
+ const {
199
+ guid,
200
+ modelName,
201
+ pathParams,
202
+ queryParams: configQueryParams,
203
+ changeModelStatus
204
+ } = config;
205
+ const {
206
+ body,
207
+ contentType,
208
+ queryParams
209
+ } = params;
210
+ if (pathParams.length < getMinRequiredPathParamsCount(modelName)) {
211
+ throw new Error('pathParams length does not match length of path components');
212
+ }
213
+ changeModelStatus(MODEL_STATUS.CREATING);
214
+ dispatchModelFetchRequest({
215
+ modelName,
216
+ guid,
217
+ method: 'POST',
218
+ body,
219
+ pathParams,
220
+ contentType,
221
+ queryParams: queryParams || configQueryParams
222
+ });
181
223
  }
224
+
182
225
  //#endregion Create
226
+
183
227
  //#region Update
184
- function updateItemInCollection(config, params) {
185
- const { id, body, contentType, method, queryParams } = params;
186
- if (!id) {
187
- throw new Error(`'id' is required`);
188
- }
189
- if (!body) {
190
- throw new Error(`'body' is required`);
191
- }
192
- const { modelName, pathParams: configPathParams, queryParams: configQueryParams, changeModelStatus } = config;
193
- const pathParams = (0, lodash_1.concat)([], configPathParams, [id]);
194
- if (pathParams.length !== (0, route_1.getMinRequiredPathParamsCount)(modelName) + 1) {
195
- throw new Error('pathParams+id length does not match length of path components');
196
- }
197
- const m = method || 'PUT';
198
- changeModelStatus(constants_1.MODEL_STATUS.UPDATING, id);
199
- (0, actionCreator_1.dispatchModelFetchRequest)({
200
- modelName,
201
- method: m,
202
- pathParams,
203
- queryParams: queryParams || configQueryParams,
204
- body,
205
- contentType
206
- });
228
+
229
+ export function updateItemInCollection(config, params) {
230
+ const {
231
+ id,
232
+ body,
233
+ contentType,
234
+ method,
235
+ queryParams
236
+ } = params;
237
+ if (!id) {
238
+ throw new Error(`'id' is required`);
239
+ }
240
+ if (!body) {
241
+ throw new Error(`'body' is required`);
242
+ }
243
+ const {
244
+ modelName,
245
+ pathParams: configPathParams,
246
+ queryParams: configQueryParams,
247
+ changeModelStatus
248
+ } = config;
249
+ const pathParams = concat([], configPathParams, [id]);
250
+ if (pathParams.length !== getMinRequiredPathParamsCount(modelName) + 1) {
251
+ throw new Error('pathParams+id length does not match length of path components');
252
+ }
253
+ const m = method || 'PUT';
254
+ changeModelStatus(MODEL_STATUS.UPDATING, id);
255
+ dispatchModelFetchRequest({
256
+ modelName,
257
+ method: m,
258
+ pathParams,
259
+ queryParams: queryParams || configQueryParams,
260
+ body,
261
+ contentType
262
+ });
207
263
  }
208
- function updateCollectionItem(model, config, params) {
209
- if (!model.id) {
210
- throw new Error('model does not exist');
211
- }
212
- const { body, contentType, method, queryParams } = params;
213
- if (!body) {
214
- throw new Error(`'body' is required`);
215
- }
216
- const { modelName, pathParams, queryParams: configQueryParams, changeModelStatus } = config;
217
- if (pathParams.length < (0, route_1.getMinRequiredPathParamsCount)(modelName) + 1) {
218
- throw new Error('pathParams length does not match length of path components');
219
- }
220
- const m = method || 'PUT';
221
- changeModelStatus(constants_1.MODEL_STATUS.UPDATING);
222
- (0, actionCreator_1.dispatchModelFetchRequest)({
223
- modelName,
224
- method: m,
225
- pathParams,
226
- body,
227
- contentType,
228
- queryParams: queryParams || configQueryParams
229
- });
264
+ export function updateCollectionItem(model, config, params) {
265
+ if (!model.id) {
266
+ throw new Error('model does not exist');
267
+ }
268
+ const {
269
+ body,
270
+ contentType,
271
+ method,
272
+ queryParams
273
+ } = params;
274
+ if (!body) {
275
+ throw new Error(`'body' is required`);
276
+ }
277
+ const {
278
+ modelName,
279
+ pathParams,
280
+ queryParams: configQueryParams,
281
+ changeModelStatus
282
+ } = config;
283
+ if (pathParams.length < getMinRequiredPathParamsCount(modelName) + 1) {
284
+ throw new Error('pathParams length does not match length of path components');
285
+ }
286
+ const m = method || 'PUT';
287
+ changeModelStatus(MODEL_STATUS.UPDATING);
288
+ dispatchModelFetchRequest({
289
+ modelName,
290
+ method: m,
291
+ pathParams,
292
+ body,
293
+ contentType,
294
+ queryParams: queryParams || configQueryParams
295
+ });
230
296
  }
297
+
231
298
  //#endregion Update
299
+
232
300
  //#region Delete
233
- function deleteItemFromCollection(config, params) {
234
- const { id, body, queryParams } = params;
235
- if (!id) {
236
- throw new Error(`'id' is required`);
237
- }
238
- const { modelName, pathParams, queryParams: configQueryParams, changeModelStatus } = config;
239
- const p = (0, lodash_1.concat)([], pathParams, [id]);
240
- if (p.length !== (0, route_1.getMinRequiredPathParamsCount)(modelName) + 1) {
241
- throw new Error('pathParams+id length does not match length of path components');
242
- }
243
- changeModelStatus(constants_1.MODEL_STATUS.DELETING, id);
244
- (0, actionCreator_1.dispatchModelFetchRequest)({
245
- modelName,
246
- method: 'DELETE',
247
- pathParams: p,
248
- queryParams: queryParams || configQueryParams,
249
- body
250
- });
301
+
302
+ export function deleteItemFromCollection(config, params) {
303
+ const {
304
+ id,
305
+ body,
306
+ queryParams
307
+ } = params;
308
+ if (!id) {
309
+ throw new Error(`'id' is required`);
310
+ }
311
+ const {
312
+ modelName,
313
+ pathParams,
314
+ queryParams: configQueryParams,
315
+ changeModelStatus
316
+ } = config;
317
+ const p = concat([], pathParams, [id]);
318
+ if (p.length !== getMinRequiredPathParamsCount(modelName) + 1) {
319
+ throw new Error('pathParams+id length does not match length of path components');
320
+ }
321
+ changeModelStatus(MODEL_STATUS.DELETING, id);
322
+ dispatchModelFetchRequest({
323
+ modelName,
324
+ method: 'DELETE',
325
+ pathParams: p,
326
+ queryParams: queryParams || configQueryParams,
327
+ body
328
+ });
251
329
  }
252
- function deleteCollectionItem(model, config, params = {}) {
253
- if (!model.id) {
254
- throw new Error('model does not exist');
255
- }
256
- const { body, queryParams } = params;
257
- const { modelName, pathParams, queryParams: configQueryParams, changeModelStatus } = config;
258
- if (pathParams.length < (0, route_1.getMinRequiredPathParamsCount)(modelName) + 1) {
259
- throw new Error('pathParams length does not match length of path components');
260
- }
261
- changeModelStatus(constants_1.MODEL_STATUS.DELETING);
262
- (0, actionCreator_1.dispatchModelFetchRequest)({
263
- modelName,
264
- method: 'DELETE',
265
- pathParams,
266
- body,
267
- queryParams: queryParams || configQueryParams
268
- });
330
+ export function deleteCollectionItem(model, config) {
331
+ let params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
332
+ if (!model.id) {
333
+ throw new Error('model does not exist');
334
+ }
335
+ const {
336
+ body,
337
+ queryParams
338
+ } = params;
339
+ const {
340
+ modelName,
341
+ pathParams,
342
+ queryParams: configQueryParams,
343
+ changeModelStatus
344
+ } = config;
345
+ if (pathParams.length < getMinRequiredPathParamsCount(modelName) + 1) {
346
+ throw new Error('pathParams length does not match length of path components');
347
+ }
348
+ changeModelStatus(MODEL_STATUS.DELETING);
349
+ dispatchModelFetchRequest({
350
+ modelName,
351
+ method: 'DELETE',
352
+ pathParams,
353
+ body,
354
+ queryParams: queryParams || configQueryParams
355
+ });
269
356
  }
357
+
270
358
  //#endregion Delete
359
+
271
360
  //#endregion Collection/Item CRUD Methods
361
+
272
362
  //#region Helper Methods
363
+
273
364
  /**
274
365
  * Automatically call `load`, or `changeModelStatus` to `READY`.
275
366
  *
@@ -278,17 +369,20 @@ function deleteCollectionItem(model, config, params = {}) {
278
369
  * * model is already fetching.
279
370
  * * auto load is disabled.
280
371
  */
281
- function initializeCollectionItem(model, load, config) {
282
- const { modelName, pathParams, disableAutoLoad, changeModelStatus } = config;
283
- if (pathParams.length === (0, route_1.getMinRequiredPathParamsCount)(modelName) + 1 &&
284
- !disableAutoLoad &&
285
- (!model._metadata || !model._metadata.isFetching)) {
286
- load();
287
- }
288
- else {
289
- changeModelStatus(constants_1.MODEL_STATUS.READY);
290
- }
372
+ export function initializeCollectionItem(model, load, config) {
373
+ const {
374
+ modelName,
375
+ pathParams,
376
+ disableAutoLoad,
377
+ changeModelStatus
378
+ } = config;
379
+ if (pathParams.length === getMinRequiredPathParamsCount(modelName) + 1 && !disableAutoLoad && (!model._metadata || !model._metadata.isFetching)) {
380
+ load();
381
+ } else {
382
+ changeModelStatus(MODEL_STATUS.READY);
383
+ }
291
384
  }
385
+
292
386
  /**
293
387
  * Automatically call `load`, or `changeModelStatus` to `READY`.
294
388
  *
@@ -296,59 +390,71 @@ function initializeCollectionItem(model, load, config) {
296
390
  * * model is already fetching.
297
391
  * * auto load is disabled.
298
392
  */
299
- function initializeCollection(model, load, config) {
300
- const { disableAutoLoad, changeModelStatus } = config;
301
- if (!disableAutoLoad && (!model._metadata || !model._metadata.isFetching)) {
302
- load();
303
- }
304
- else if (disableAutoLoad) {
305
- changeModelStatus(constants_1.MODEL_STATUS.READY);
306
- }
393
+ export function initializeCollection(model, load, config) {
394
+ const {
395
+ disableAutoLoad,
396
+ changeModelStatus
397
+ } = config;
398
+ if (!disableAutoLoad && (!model._metadata || !model._metadata.isFetching)) {
399
+ load();
400
+ } else if (disableAutoLoad) {
401
+ changeModelStatus(MODEL_STATUS.READY);
402
+ }
307
403
  }
404
+
308
405
  /**
309
406
  * When `pathParams` or `queryParams` change, call `load`
310
407
  */
311
- function handleCollectionItemParamsChange(modelName, prevModelName, pathParams, prevPathParams, queryParams, prevQueryParams, load) {
312
- if (modelName !== prevModelName ||
313
- (pathParams.length === (0, route_1.getMinRequiredPathParamsCount)(modelName) + 1 && !(0, lodash_1.isEqual)(prevPathParams, pathParams)) ||
314
- !(0, lodash_1.isEqual)(prevQueryParams, queryParams)) {
315
- load({ pathParams, queryParams });
316
- }
408
+ export function handleCollectionItemParamsChange(modelName, prevModelName, pathParams, prevPathParams, queryParams, prevQueryParams, load) {
409
+ if (modelName !== prevModelName || pathParams.length === getMinRequiredPathParamsCount(modelName) + 1 && !isEqual(prevPathParams, pathParams) || !isEqual(prevQueryParams, queryParams)) {
410
+ load({
411
+ pathParams,
412
+ queryParams
413
+ });
414
+ }
317
415
  }
416
+
318
417
  /**
319
418
  * When `pathParams` or `queryParams` change, call `load`
320
419
  */
321
- function handleCollectionParamsChange(modelName, prevModelName, pathParams, prevPathParams, queryParams, prevQueryParams, load) {
322
- if (modelName !== prevModelName ||
323
- (pathParams.length > 0 && !(0, lodash_1.isEqual)(prevPathParams, pathParams)) ||
324
- !(0, lodash_1.isEqual)(prevQueryParams, queryParams)) {
325
- load({ pathParams, queryParams });
326
- }
420
+ export function handleCollectionParamsChange(modelName, prevModelName, pathParams, prevPathParams, queryParams, prevQueryParams, load) {
421
+ if (modelName !== prevModelName || pathParams.length > 0 && !isEqual(prevPathParams, pathParams) || !isEqual(prevQueryParams, queryParams)) {
422
+ load({
423
+ pathParams,
424
+ queryParams
425
+ });
426
+ }
327
427
  }
428
+
328
429
  /**
329
430
  * Delete the guid in the model
330
431
  */
331
- function cleanupCollectionGuidKey(model, config) {
332
- const { guid, modelName, pathParams } = config;
333
- if ((0, lodash_1.includes)(Object.keys(model), guid)) {
334
- const modelNames = modelName.split('.');
335
- const tempPathParams = pathParams.slice();
336
- // should include the guid at the end
337
- tempPathParams.push(guid);
338
- if (modelNames.length === tempPathParams.length) {
339
- let path = '';
340
- modelNames.forEach((m, i) => {
341
- if (i === 0) {
342
- path += `${m}.${tempPathParams[i]}`;
343
- }
344
- else {
345
- path += `.${m}.${tempPathParams[i]}`;
346
- }
347
- });
348
- (0, actionCreator_1.dispatchModelRemoveKeyAction)({
349
- modelPath: path
350
- });
432
+ export function cleanupCollectionGuidKey(model, config) {
433
+ const {
434
+ guid,
435
+ modelName,
436
+ pathParams
437
+ } = config;
438
+ if (includes(Object.keys(model), guid)) {
439
+ const modelNames = modelName.split('.');
440
+ const tempPathParams = pathParams.slice();
441
+ // should include the guid at the end
442
+ tempPathParams.push(guid);
443
+ if (modelNames.length === tempPathParams.length) {
444
+ let path = '';
445
+ modelNames.forEach((m, i) => {
446
+ if (i === 0) {
447
+ path += `${m}.${tempPathParams[i]}`;
448
+ } else {
449
+ path += `.${m}.${tempPathParams[i]}`;
351
450
  }
451
+ });
452
+ dispatchModelRemoveKeyAction({
453
+ modelPath: path
454
+ });
352
455
  }
456
+ }
353
457
  }
458
+
354
459
  //#endregion Helper Methods
460
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjb25jYXQiLCJmaW5kIiwiZ2V0IiwiaW5jbHVkZXMiLCJpc0VxdWFsIiwidmFsdWVzIiwibWVtb2l6ZU9uZSIsIk1PREVMX1NUQVRVUyIsImRpc3BhdGNoTW9kZWxGZXRjaFJlcXVlc3QiLCJkaXNwYXRjaE1vZGVsUmVtb3ZlS2V5QWN0aW9uIiwiZGlzcGF0Y2hQZXJpb2RpY01vZGVsRmV0Y2hSZXF1ZXN0IiwiZGlzcGF0Y2hQZXJpb2RpY01vZGVsRmV0Y2hUZXJtaW5hdGVBY3Rpb24iLCJnZXRNaW5SZXF1aXJlZFBhdGhQYXJhbXNDb3VudCIsImdldFBhdGhQYXJhbXNGcm9tUm91dGVNYXRjaFBhcmFtcyIsImdldFJlZHV4TW9kZWxOYW1lIiwiZ2V0UGF0aFBhcmFtcyIsInBhdGhQYXJhbXMiLCJyb3V0ZU1hdGNoUGFyYW1zIiwibW9kZWxOYW1lIiwic2VsZWN0Q29sbGVjdGlvbkl0ZW1Gcm9tU3RhdGUiLCJwYXJhbXMiLCJndWlkIiwic3RhdGUiLCJtb2RlbE5hbWVMZXZlbENvdW50IiwicCIsInJlZHV4TW9kZWxOYW1lIiwibW9kZWwiLCJsZW5ndGgiLCJjb2xsZWN0aW9uIiwibW9kZWxzIiwiT2JqZWN0IiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwibW9kZWxCeUd1aWQiLCJtIiwicmVkdXhNb2RlbCIsImtleXMiLCJpc0NvbGxlY3Rpb25JdGVtIiwic2VsZWN0Q29sbGVjdGlvbkZyb21TdGF0ZSIsInN0b3BDb2xsZWN0aW9uUGVyaW9kaWNMb2FkIiwidGFza0lkIiwibG9hZENvbGxlY3Rpb24iLCJjb25maWciLCJhcmd1bWVudHMiLCJ1bmRlZmluZWQiLCJpc0luaXRpYWxpemVkIiwiY29uZmlnUGF0aFBhcmFtcyIsInF1ZXJ5UGFyYW1zIiwiY29uZmlnUXVlcnlQYXJhbXMiLCJjaGFuZ2VNb2RlbFN0YXR1cyIsImlkIiwicGVyaW9kIiwicmVwbGFjZVZhbHVlIiwiRXJyb3IiLCJMT0FESU5HIiwibWV0aG9kIiwibG9hZENvbGxlY3Rpb25JdGVtIiwiY3JlYXRlSXRlbUluQ29sbGVjdGlvbiIsImJvZHkiLCJjb250ZW50VHlwZSIsIkNSRUFUSU5HIiwiY3JlYXRlQ29sbGVjdGlvbkl0ZW0iLCJ1cGRhdGVJdGVtSW5Db2xsZWN0aW9uIiwiVVBEQVRJTkciLCJ1cGRhdGVDb2xsZWN0aW9uSXRlbSIsImRlbGV0ZUl0ZW1Gcm9tQ29sbGVjdGlvbiIsIkRFTEVUSU5HIiwiZGVsZXRlQ29sbGVjdGlvbkl0ZW0iLCJpbml0aWFsaXplQ29sbGVjdGlvbkl0ZW0iLCJsb2FkIiwiZGlzYWJsZUF1dG9Mb2FkIiwiX21ldGFkYXRhIiwiaXNGZXRjaGluZyIsIlJFQURZIiwiaW5pdGlhbGl6ZUNvbGxlY3Rpb24iLCJoYW5kbGVDb2xsZWN0aW9uSXRlbVBhcmFtc0NoYW5nZSIsInByZXZNb2RlbE5hbWUiLCJwcmV2UGF0aFBhcmFtcyIsInByZXZRdWVyeVBhcmFtcyIsImhhbmRsZUNvbGxlY3Rpb25QYXJhbXNDaGFuZ2UiLCJjbGVhbnVwQ29sbGVjdGlvbkd1aWRLZXkiLCJtb2RlbE5hbWVzIiwic3BsaXQiLCJ0ZW1wUGF0aFBhcmFtcyIsInNsaWNlIiwicHVzaCIsInBhdGgiLCJmb3JFYWNoIiwiaSIsIm1vZGVsUGF0aCJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9jb2xsZWN0aW9uLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNvbmNhdCwgRGljdGlvbmFyeSwgZmluZCwgZ2V0LCBpbmNsdWRlcywgaXNFcXVhbCwgdmFsdWVzIH0gZnJvbSAnbG9kYXNoJ1xuaW1wb3J0IG1lbW9pemVPbmUgZnJvbSAnbWVtb2l6ZS1vbmUnXG5pbXBvcnQgeyBNT0RFTF9TVEFUVVMgfSBmcm9tICcuLi9jb25zdGFudHMnXG5pbXBvcnQge1xuXHRkaXNwYXRjaE1vZGVsRmV0Y2hSZXF1ZXN0LFxuXHRkaXNwYXRjaE1vZGVsUmVtb3ZlS2V5QWN0aW9uLFxuXHRkaXNwYXRjaFBlcmlvZGljTW9kZWxGZXRjaFJlcXVlc3QsXG5cdGRpc3BhdGNoUGVyaW9kaWNNb2RlbEZldGNoVGVybWluYXRlQWN0aW9uXG59IGZyb20gJy4uL3JlZHV4L2FjdGlvbkNyZWF0b3InXG5pbXBvcnQge1xuXHRDb2xsZWN0aW9uQ3JlYXRlUGFyYW1zLFxuXHRDb2xsZWN0aW9uRGVsZXRlUGFyYW1zLFxuXHRDb2xsZWN0aW9uSXRlbURlbGV0ZVBhcmFtcyxcblx0Q29sbGVjdGlvbkl0ZW1Mb2FkUGFyYW1zLFxuXHRDb2xsZWN0aW9uSXRlbVVwZGF0ZVBhcmFtcyxcblx0Q29sbGVjdGlvbkxvYWRQYXJhbXMsXG5cdENvbGxlY3Rpb25NZXRob2RDb25maWd1cmF0aW9uLFxuXHRDb2xsZWN0aW9uU2VsZWN0b3JNZXRob2RQYXJhbXMsXG5cdENvbGxlY3Rpb25TZWxlY3Rvck1ldGhvZFJlc3BvbnNlLFxuXHRDb2xsZWN0aW9uVXBkYXRlUGFyYW1zLFxuXHRNb2RlbCxcblx0TW9kZWxDb2xsZWN0aW9uXG59IGZyb20gJy4uL3R5cGVzJ1xuaW1wb3J0IHsgZ2V0TWluUmVxdWlyZWRQYXRoUGFyYW1zQ291bnQsIGdldFBhdGhQYXJhbXNGcm9tUm91dGVNYXRjaFBhcmFtcywgZ2V0UmVkdXhNb2RlbE5hbWUgfSBmcm9tICcuL3JvdXRlJ1xuXG4vLyNyZWdpb24gUmVkdXggTWV0aG9kc1xuXG5jb25zdCBnZXRQYXRoUGFyYW1zID0gbWVtb2l6ZU9uZShcblx0KHBhdGhQYXJhbXM6IEFycmF5PHN0cmluZyB8IG51bWJlcj4gfCB1bmRlZmluZWQsIHJvdXRlTWF0Y2hQYXJhbXM6IERpY3Rpb25hcnk8c3RyaW5nPiwgbW9kZWxOYW1lOiBzdHJpbmcpID0+XG5cdFx0cGF0aFBhcmFtcyB8fCBnZXRQYXRoUGFyYW1zRnJvbVJvdXRlTWF0Y2hQYXJhbXMocm91dGVNYXRjaFBhcmFtcywgbW9kZWxOYW1lKVxuKVxuXG5leHBvcnQgZnVuY3Rpb24gc2VsZWN0Q29sbGVjdGlvbkl0ZW1Gcm9tU3RhdGU8VE1vZGVsIGV4dGVuZHMgTW9kZWw+KFxuXHRwYXJhbXM6IENvbGxlY3Rpb25TZWxlY3Rvck1ldGhvZFBhcmFtc1xuKTogQ29sbGVjdGlvblNlbGVjdG9yTWV0aG9kUmVzcG9uc2U8VE1vZGVsPiB7XG5cdGNvbnN0IHsgZ3VpZCwgbW9kZWxOYW1lLCBwYXRoUGFyYW1zLCByb3V0ZU1hdGNoUGFyYW1zLCBzdGF0ZSB9ID0gcGFyYW1zXG5cdGNvbnN0IG1vZGVsTmFtZUxldmVsQ291bnQgPSBnZXRNaW5SZXF1aXJlZFBhdGhQYXJhbXNDb3VudChtb2RlbE5hbWUpXG5cdGNvbnN0IHAgPSBnZXRQYXRoUGFyYW1zKHBhdGhQYXJhbXMsIHJvdXRlTWF0Y2hQYXJhbXMsIG1vZGVsTmFtZSlcblx0Y29uc3QgcmVkdXhNb2RlbE5hbWUgPSBnZXRSZWR1eE1vZGVsTmFtZShwLCBtb2RlbE5hbWUpXG5cblx0bGV0IG1vZGVsID0ge30gYXMgVE1vZGVsXG5cdC8vIGZpbmQgYG1vZGVsYCB1c2luZyBgZ3VpZGAgYXMgaXRzIGtleSwgdG8gbWF0Y2ggbmV3IGl0ZW0gY3JlYXRlZCBpbiBgY3JlYXRlKClgXG5cdGlmIChwLmxlbmd0aCA9PT0gbW9kZWxOYW1lTGV2ZWxDb3VudCkge1xuXHRcdGNvbnN0IGNvbGxlY3Rpb24gPSAoZ2V0KHN0YXRlLm1vZGVscywgcmVkdXhNb2RlbE5hbWUpIHx8IHt9KSBhcyBNb2RlbENvbGxlY3Rpb248VE1vZGVsPlxuXHRcdGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoY29sbGVjdGlvbiwgZ3VpZCkpIHtcblx0XHRcdG1vZGVsID0gY29sbGVjdGlvbltndWlkXSBhcyBUTW9kZWxcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y29uc3QgbW9kZWxCeUd1aWQgPSBmaW5kKHZhbHVlcyhjb2xsZWN0aW9uKSwgKG0pOiBtIGlzIFRNb2RlbCA9PiAhIW0gJiYgJ2d1aWQnIGluIG0gJiYgbS5ndWlkID09PSBndWlkKVxuXHRcdFx0bW9kZWwgPSBtb2RlbEJ5R3VpZCB8fCBtb2RlbFxuXHRcdH1cblx0fSBlbHNlIHtcblx0XHQvLyBmaW5kIGBtb2RlbGAgdXNpbmcgcGF0aFBhcmFtc1xuXHRcdGNvbnN0IHJlZHV4TW9kZWwgPSAoZ2V0KHN0YXRlLm1vZGVscywgcmVkdXhNb2RlbE5hbWUpIHx8IHt9KSBhcyBUTW9kZWxcblx0XHRtb2RlbCA9IChPYmplY3Qua2V5cyhyZWR1eE1vZGVsKS5sZW5ndGggPiAwID8gcmVkdXhNb2RlbCA6IHt9KSBhcyBUTW9kZWxcblx0fVxuXG5cdHJldHVybiB7XG5cdFx0bW9kZWxOYW1lLFxuXHRcdHBhdGhQYXJhbXM6IHAsXG5cdFx0bW9kZWwsXG5cdFx0aXNDb2xsZWN0aW9uSXRlbTogdHJ1ZVxuXHR9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZWxlY3RDb2xsZWN0aW9uRnJvbVN0YXRlPFRNb2RlbCBleHRlbmRzIE1vZGVsPihcblx0cGFyYW1zOiBDb2xsZWN0aW9uU2VsZWN0b3JNZXRob2RQYXJhbXNcbik6IENvbGxlY3Rpb25TZWxlY3Rvck1ldGhvZFJlc3BvbnNlPFRNb2RlbD4ge1xuXHRjb25zdCB7IG1vZGVsTmFtZSwgcGF0aFBhcmFtcywgcm91dGVNYXRjaFBhcmFtcywgc3RhdGUgfSA9IHBhcmFtc1xuXHRjb25zdCBwID0gZ2V0UGF0aFBhcmFtcyhwYXRoUGFyYW1zLCByb3V0ZU1hdGNoUGFyYW1zLCBtb2RlbE5hbWUpXG5cdGNvbnN0IHJlZHV4TW9kZWxOYW1lID0gZ2V0UmVkdXhNb2RlbE5hbWUocCwgbW9kZWxOYW1lKVxuXG5cdGxldCBtb2RlbCA9IGdldChzdGF0ZS5tb2RlbHMsIHJlZHV4TW9kZWxOYW1lKSBhcyBNb2RlbENvbGxlY3Rpb248VE1vZGVsPiB8IHVuZGVmaW5lZFxuXHRtb2RlbCA9IG1vZGVsICYmIE9iamVjdC5rZXlzKG1vZGVsKS5sZW5ndGggPiAwID8gbW9kZWwgOiB7fVxuXG5cdHJldHVybiB7XG5cdFx0bW9kZWxOYW1lLFxuXHRcdHBhdGhQYXJhbXM6IHAsXG5cdFx0bW9kZWwsXG5cdFx0aXNDb2xsZWN0aW9uSXRlbTogZmFsc2Vcblx0fVxufVxuXG4vLyNlbmRyZWdpb24gUmVkdXggTWV0aG9kc1xuXG4vLyNyZWdpb24gQ29sbGVjdGlvbi9JdGVtIENSVUQgTWV0aG9kc1xuXG4vLyNyZWdpb24gTG9hZFxuXG5leHBvcnQgZnVuY3Rpb24gc3RvcENvbGxlY3Rpb25QZXJpb2RpY0xvYWQodGFza0lkOiBzdHJpbmcpIHtcblx0ZGlzcGF0Y2hQZXJpb2RpY01vZGVsRmV0Y2hUZXJtaW5hdGVBY3Rpb24oe1xuXHRcdHRhc2tJZFxuXHR9KVxufVxuXG5leHBvcnQgZnVuY3Rpb24gbG9hZENvbGxlY3Rpb24oY29uZmlnOiBDb2xsZWN0aW9uTWV0aG9kQ29uZmlndXJhdGlvbiwgcGFyYW1zOiBDb2xsZWN0aW9uTG9hZFBhcmFtcyA9IHt9KSB7XG5cdGNvbnN0IHtcblx0XHRtb2RlbE5hbWUsXG5cdFx0aXNJbml0aWFsaXplZCxcblx0XHRwYXRoUGFyYW1zOiBjb25maWdQYXRoUGFyYW1zLFxuXHRcdHF1ZXJ5UGFyYW1zOiBjb25maWdRdWVyeVBhcmFtcyxcblx0XHRjaGFuZ2VNb2RlbFN0YXR1c1xuXHR9ID0gY29uZmlnXG5cdGNvbnN0IHsgaWQsIHBhdGhQYXJhbXMsIHF1ZXJ5UGFyYW1zLCBwZXJpb2QsIHRhc2tJZCwgcmVwbGFjZVZhbHVlIH0gPSBwYXJhbXNcblx0Y29uc3QgcCA9IGNvbmNhdChbXSwgcGF0aFBhcmFtcyB8fCBjb25maWdQYXRoUGFyYW1zLCBpZCA/IFtpZF0gOiBbXSlcblx0aWYgKHAubGVuZ3RoICE9PSBnZXRNaW5SZXF1aXJlZFBhdGhQYXJhbXNDb3VudChtb2RlbE5hbWUpICsgKGlkID8gMSA6IDApKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCdwYXRoUGFyYW1zIGxlbmd0aCBkb2VzIG5vdCBtYXRjaCBsZW5ndGggb2YgcGF0aCBjb21wb25lbnRzJylcblx0fVxuXHRpZiAoaXNJbml0aWFsaXplZCkge1xuXHRcdGNoYW5nZU1vZGVsU3RhdHVzKE1PREVMX1NUQVRVUy5MT0FESU5HLCBpZClcblx0fVxuXHRpZiAoIXBlcmlvZCkge1xuXHRcdGRpc3BhdGNoTW9kZWxGZXRjaFJlcXVlc3Qoe1xuXHRcdFx0bW9kZWxOYW1lLFxuXHRcdFx0bWV0aG9kOiAnR0VUJyxcblx0XHRcdHBhdGhQYXJhbXM6IHAsXG5cdFx0XHRxdWVyeVBhcmFtczogcXVlcnlQYXJhbXMgfHwgY29uZmlnUXVlcnlQYXJhbXMsXG5cdFx0XHRyZXBsYWNlVmFsdWVcblx0XHR9KVxuXHR9IGVsc2Uge1xuXHRcdGlmICghdGFza0lkKSB0aHJvdyBuZXcgRXJyb3IoJ3Rhc2tJZCBpcyByZXF1aXJlZCBmb3IgcGVyaW9kaWMgZGF0YSByZXF1ZXN0cycpXG5cdFx0ZGlzcGF0Y2hQZXJpb2RpY01vZGVsRmV0Y2hSZXF1ZXN0KHtcblx0XHRcdG1vZGVsTmFtZSxcblx0XHRcdG1ldGhvZDogJ0dFVCcsXG5cdFx0XHRwYXRoUGFyYW1zOiBwLFxuXHRcdFx0cXVlcnlQYXJhbXM6IHF1ZXJ5UGFyYW1zIHx8IGNvbmZpZ1F1ZXJ5UGFyYW1zLFxuXHRcdFx0cGVyaW9kLFxuXHRcdFx0dGFza0lkLFxuXHRcdFx0cmVwbGFjZVZhbHVlXG5cdFx0fSlcblx0fVxufVxuXG5leHBvcnQgZnVuY3Rpb24gbG9hZENvbGxlY3Rpb25JdGVtKGNvbmZpZzogQ29sbGVjdGlvbk1ldGhvZENvbmZpZ3VyYXRpb24sIHBhcmFtczogQ29sbGVjdGlvbkl0ZW1Mb2FkUGFyYW1zID0ge30pIHtcblx0Y29uc3Qge1xuXHRcdG1vZGVsTmFtZSxcblx0XHRpc0luaXRpYWxpemVkLFxuXHRcdHBhdGhQYXJhbXM6IGNvbmZpZ1BhdGhQYXJhbXMsXG5cdFx0cXVlcnlQYXJhbXM6IGNvbmZpZ1F1ZXJ5UGFyYW1zLFxuXHRcdGNoYW5nZU1vZGVsU3RhdHVzXG5cdH0gPSBjb25maWdcblx0Y29uc3QgeyBwYXRoUGFyYW1zLCBxdWVyeVBhcmFtcywgcGVyaW9kLCB0YXNrSWQsIHJlcGxhY2VWYWx1ZSB9ID0gcGFyYW1zXG5cdGNvbnN0IHAgPSBwYXRoUGFyYW1zIHx8IGNvbmZpZ1BhdGhQYXJhbXNcblx0aWYgKHAubGVuZ3RoIDwgZ2V0TWluUmVxdWlyZWRQYXRoUGFyYW1zQ291bnQobW9kZWxOYW1lKSArIDEpIHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoJ3BhdGhQYXJhbXMgbGVuZ3RoIGRvZXMgbm90IG1hdGNoIGxlbmd0aCBvZiBwYXRoIGNvbXBvbmVudHMnKVxuXHR9XG5cdGlmIChpc0luaXRpYWxpemVkKSB7XG5cdFx0Y2hhbmdlTW9kZWxTdGF0dXMoTU9ERUxfU1RBVFVTLkxPQURJTkcpXG5cdH1cblx0aWYgKCFwZXJpb2QpIHtcblx0XHRkaXNwYXRjaE1vZGVsRmV0Y2hSZXF1ZXN0KHtcblx0XHRcdG1vZGVsTmFtZSxcblx0XHRcdG1ldGhvZDogJ0dFVCcsXG5cdFx0XHRwYXRoUGFyYW1zOiBwLFxuXHRcdFx0cXVlcnlQYXJhbXM6IHF1ZXJ5UGFyYW1zIHx8IGNvbmZpZ1F1ZXJ5UGFyYW1zLFxuXHRcdFx0cmVwbGFjZVZhbHVlXG5cdFx0fSlcblx0fSBlbHNlIHtcblx0XHRpZiAoIXRhc2tJZCkgdGhyb3cgbmV3IEVycm9yKCd0YXNrSWQgaXMgcmVxdWlyZWQgZm9yIHBlcmlvZGljIGRhdGEgcmVxdWVzdHMnKVxuXHRcdGRpc3BhdGNoUGVyaW9kaWNNb2RlbEZldGNoUmVxdWVzdCh7XG5cdFx0XHRtb2RlbE5hbWUsXG5cdFx0XHRtZXRob2Q6ICdHRVQnLFxuXHRcdFx0cGF0aFBhcmFtczogcCxcblx0XHRcdHF1ZXJ5UGFyYW1zOiBxdWVyeVBhcmFtcyB8fCBjb25maWdRdWVyeVBhcmFtcyxcblx0XHRcdHBlcmlvZCxcblx0XHRcdHRhc2tJZCxcblx0XHRcdHJlcGxhY2VWYWx1ZVxuXHRcdH0pXG5cdH1cbn1cblxuLy8jZW5kcmVnaW9uIExvYWRcblxuLy8jcmVnaW9uIENyZWF0ZVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlSXRlbUluQ29sbGVjdGlvbihjb25maWc6IENvbGxlY3Rpb25NZXRob2RDb25maWd1cmF0aW9uLCBwYXJhbXM6IENvbGxlY3Rpb25DcmVhdGVQYXJhbXMpIHtcblx0Y29uc3QgeyBndWlkLCBtb2RlbE5hbWUsIHBhdGhQYXJhbXMsIHF1ZXJ5UGFyYW1zOiBjb25maWdRdWVyeVBhcmFtcywgY2hhbmdlTW9kZWxTdGF0dXMgfSA9IGNvbmZpZ1xuXHRjb25zdCB7IGJvZHksIGNvbnRlbnRUeXBlLCBxdWVyeVBhcmFtcyB9ID0gcGFyYW1zXG5cdGlmIChwYXRoUGFyYW1zLmxlbmd0aCA8IGdldE1pblJlcXVpcmVkUGF0aFBhcmFtc0NvdW50KG1vZGVsTmFtZSkpIHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoJ3BhdGhQYXJhbXMgbGVuZ3RoIGRvZXMgbm90IG1hdGNoIGxlbmd0aCBvZiBwYXRoIGNvbXBvbmVudHMnKVxuXHR9XG5cdGNoYW5nZU1vZGVsU3RhdHVzKE1PREVMX1NUQVRVUy5DUkVBVElORywgZ3VpZClcblx0ZGlzcGF0Y2hNb2RlbEZldGNoUmVxdWVzdCh7XG5cdFx0bW9kZWxOYW1lLFxuXHRcdGd1aWQsXG5cdFx0bWV0aG9kOiAnUE9TVCcsXG5cdFx0Ym9keSxcblx0XHRwYXRoUGFyYW1zLFxuXHRcdGNvbnRlbnRUeXBlLFxuXHRcdHF1ZXJ5UGFyYW1zOiBxdWVyeVBhcmFtcyB8fCBjb25maWdRdWVyeVBhcmFtc1xuXHR9KVxufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ29sbGVjdGlvbkl0ZW0oXG5cdG1vZGVsOiBNb2RlbCxcblx0Y29uZmlnOiBDb2xsZWN0aW9uTWV0aG9kQ29uZmlndXJhdGlvbixcblx0cGFyYW1zOiBDb2xsZWN0aW9uQ3JlYXRlUGFyYW1zXG4pIHtcblx0aWYgKG1vZGVsLmlkKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCdtb2RlbCBhbHJlYWR5IGV4aXN0cycpXG5cdH1cblx0Y29uc3QgeyBndWlkLCBtb2RlbE5hbWUsIHBhdGhQYXJhbXMsIHF1ZXJ5UGFyYW1zOiBjb25maWdRdWVyeVBhcmFtcywgY2hhbmdlTW9kZWxTdGF0dXMgfSA9IGNvbmZpZ1xuXHRjb25zdCB7IGJvZHksIGNvbnRlbnRUeXBlLCBxdWVyeVBhcmFtcyB9ID0gcGFyYW1zXG5cdGlmIChwYXRoUGFyYW1zLmxlbmd0aCA8IGdldE1pblJlcXVpcmVkUGF0aFBhcmFtc0NvdW50KG1vZGVsTmFtZSkpIHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoJ3BhdGhQYXJhbXMgbGVuZ3RoIGRvZXMgbm90IG1hdGNoIGxlbmd0aCBvZiBwYXRoIGNvbXBvbmVudHMnKVxuXHR9XG5cdGNoYW5nZU1vZGVsU3RhdHVzKE1PREVMX1NUQVRVUy5DUkVBVElORylcblx0ZGlzcGF0Y2hNb2RlbEZldGNoUmVxdWVzdCh7XG5cdFx0bW9kZWxOYW1lLFxuXHRcdGd1aWQsXG5cdFx0bWV0aG9kOiAnUE9TVCcsXG5cdFx0Ym9keSxcblx0XHRwYXRoUGFyYW1zLFxuXHRcdGNvbnRlbnRUeXBlLFxuXHRcdHF1ZXJ5UGFyYW1zOiBxdWVyeVBhcmFtcyB8fCBjb25maWdRdWVyeVBhcmFtc1xuXHR9KVxufVxuXG4vLyNlbmRyZWdpb24gQ3JlYXRlXG5cbi8vI3JlZ2lvbiBVcGRhdGVcblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUl0ZW1JbkNvbGxlY3Rpb24oY29uZmlnOiBDb2xsZWN0aW9uTWV0aG9kQ29uZmlndXJhdGlvbiwgcGFyYW1zOiBDb2xsZWN0aW9uVXBkYXRlUGFyYW1zKSB7XG5cdGNvbnN0IHsgaWQsIGJvZHksIGNvbnRlbnRUeXBlLCBtZXRob2QsIHF1ZXJ5UGFyYW1zIH0gPSBwYXJhbXNcblx0aWYgKCFpZCkge1xuXHRcdHRocm93IG5ldyBFcnJvcihgJ2lkJyBpcyByZXF1aXJlZGApXG5cdH1cblx0aWYgKCFib2R5KSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKGAnYm9keScgaXMgcmVxdWlyZWRgKVxuXHR9XG5cdGNvbnN0IHsgbW9kZWxOYW1lLCBwYXRoUGFyYW1zOiBjb25maWdQYXRoUGFyYW1zLCBxdWVyeVBhcmFtczogY29uZmlnUXVlcnlQYXJhbXMsIGNoYW5nZU1vZGVsU3RhdHVzIH0gPSBjb25maWdcblx0Y29uc3QgcGF0aFBhcmFtcyA9IGNvbmNhdChbXSwgY29uZmlnUGF0aFBhcmFtcywgW2lkXSlcblx0aWYgKHBhdGhQYXJhbXMubGVuZ3RoICE9PSBnZXRNaW5SZXF1aXJlZFBhdGhQYXJhbXNDb3VudChtb2RlbE5hbWUpICsgMSkge1xuXHRcdHRocm93IG5ldyBFcnJvcigncGF0aFBhcmFtcytpZCBsZW5ndGggZG9lcyBub3QgbWF0Y2ggbGVuZ3RoIG9mIHBhdGggY29tcG9uZW50cycpXG5cdH1cblx0Y29uc3QgbSA9IG1ldGhvZCB8fCAnUFVUJ1xuXHRjaGFuZ2VNb2RlbFN0YXR1cyhNT0RFTF9TVEFUVVMuVVBEQVRJTkcsIGlkKVxuXHRkaXNwYXRjaE1vZGVsRmV0Y2hSZXF1ZXN0KHtcblx0XHRtb2RlbE5hbWUsXG5cdFx0bWV0aG9kOiBtLFxuXHRcdHBhdGhQYXJhbXMsXG5cdFx0cXVlcnlQYXJhbXM6IHF1ZXJ5UGFyYW1zIHx8IGNvbmZpZ1F1ZXJ5UGFyYW1zLFxuXHRcdGJvZHksXG5cdFx0Y29udGVudFR5cGVcblx0fSlcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUNvbGxlY3Rpb25JdGVtKFxuXHRtb2RlbDogTW9kZWwsXG5cdGNvbmZpZzogQ29sbGVjdGlvbk1ldGhvZENvbmZpZ3VyYXRpb24sXG5cdHBhcmFtczogQ29sbGVjdGlvbkl0ZW1VcGRhdGVQYXJhbXNcbikge1xuXHRpZiAoIW1vZGVsLmlkKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCdtb2RlbCBkb2VzIG5vdCBleGlzdCcpXG5cdH1cblx0Y29uc3QgeyBib2R5LCBjb250ZW50VHlwZSwgbWV0aG9kLCBxdWVyeVBhcmFtcyB9ID0gcGFyYW1zXG5cdGlmICghYm9keSkge1xuXHRcdHRocm93IG5ldyBFcnJvcihgJ2JvZHknIGlzIHJlcXVpcmVkYClcblx0fVxuXHRjb25zdCB7IG1vZGVsTmFtZSwgcGF0aFBhcmFtcywgcXVlcnlQYXJhbXM6IGNvbmZpZ1F1ZXJ5UGFyYW1zLCBjaGFuZ2VNb2RlbFN0YXR1cyB9ID0gY29uZmlnXG5cdGlmIChwYXRoUGFyYW1zLmxlbmd0aCA8IGdldE1pblJlcXVpcmVkUGF0aFBhcmFtc0NvdW50KG1vZGVsTmFtZSkgKyAxKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCdwYXRoUGFyYW1zIGxlbmd0aCBkb2VzIG5vdCBtYXRjaCBsZW5ndGggb2YgcGF0aCBjb21wb25lbnRzJylcblx0fVxuXHRjb25zdCBtID0gbWV0aG9kIHx8ICdQVVQnXG5cdGNoYW5nZU1vZGVsU3RhdHVzKE1PREVMX1NUQVRVUy5VUERBVElORylcblx0ZGlzcGF0Y2hNb2RlbEZldGNoUmVxdWVzdCh7XG5cdFx0bW9kZWxOYW1lLFxuXHRcdG1ldGhvZDogbSxcblx0XHRwYXRoUGFyYW1zLFxuXHRcdGJvZHksXG5cdFx0Y29udGVudFR5cGUsXG5cdFx0cXVlcnlQYXJhbXM6IHF1ZXJ5UGFyYW1zIHx8IGNvbmZpZ1F1ZXJ5UGFyYW1zXG5cdH0pXG59XG5cbi8vI2VuZHJlZ2lvbiBVcGRhdGVcblxuLy8jcmVnaW9uIERlbGV0ZVxuXG5leHBvcnQgZnVuY3Rpb24gZGVsZXRlSXRlbUZyb21Db2xsZWN0aW9uKGNvbmZpZzogQ29sbGVjdGlvbk1ldGhvZENvbmZpZ3VyYXRpb24sIHBhcmFtczogQ29sbGVjdGlvbkRlbGV0ZVBhcmFtcykge1xuXHRjb25zdCB7IGlkLCBib2R5LCBxdWVyeVBhcmFtcyB9ID0gcGFyYW1zXG5cdGlmICghaWQpIHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoYCdpZCcgaXMgcmVxdWlyZWRgKVxuXHR9XG5cdGNvbnN0IHsgbW9kZWxOYW1lLCBwYXRoUGFyYW1zLCBxdWVyeVBhcmFtczogY29uZmlnUXVlcnlQYXJhbXMsIGNoYW5nZU1vZGVsU3RhdHVzIH0gPSBjb25maWdcblx0Y29uc3QgcCA9IGNvbmNhdChbXSwgcGF0aFBhcmFtcywgW2lkXSlcblx0aWYgKHAubGVuZ3RoICE9PSBnZXRNaW5SZXF1aXJlZFBhdGhQYXJhbXNDb3VudChtb2RlbE5hbWUpICsgMSkge1xuXHRcdHRocm93IG5ldyBFcnJvcigncGF0aFBhcmFtcytpZCBsZW5ndGggZG9lcyBub3QgbWF0Y2ggbGVuZ3RoIG9mIHBhdGggY29tcG9uZW50cycpXG5cdH1cblx0Y2hhbmdlTW9kZWxTdGF0dXMoTU9ERUxfU1RBVFVTLkRFTEVUSU5HLCBpZClcblx0ZGlzcGF0Y2hNb2RlbEZldGNoUmVxdWVzdCh7XG5cdFx0bW9kZWxOYW1lLFxuXHRcdG1ldGhvZDogJ0RFTEVURScsXG5cdFx0cGF0aFBhcmFtczogcCxcblx0XHRxdWVyeVBhcmFtczogcXVlcnlQYXJhbXMgfHwgY29uZmlnUXVlcnlQYXJhbXMsXG5cdFx0Ym9keVxuXHR9KVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVsZXRlQ29sbGVjdGlvbkl0ZW0oXG5cdG1vZGVsOiBNb2RlbCxcblx0Y29uZmlnOiBDb2xsZWN0aW9uTWV0aG9kQ29uZmlndXJhdGlvbixcblx0cGFyYW1zOiBDb2xsZWN0aW9uSXRlbURlbGV0ZVBhcmFtcyA9IHt9XG4pIHtcblx0aWYgKCFtb2RlbC5pZCkge1xuXHRcdHRocm93IG5ldyBFcnJvcignbW9kZWwgZG9lcyBub3QgZXhpc3QnKVxuXHR9XG5cdGNvbnN0IHsgYm9keSwgcXVlcnlQYXJhbXMgfSA9IHBhcmFtc1xuXHRjb25zdCB7IG1vZGVsTmFtZSwgcGF0aFBhcmFtcywgcXVlcnlQYXJhbXM6IGNvbmZpZ1F1ZXJ5UGFyYW1zLCBjaGFuZ2VNb2RlbFN0YXR1cyB9ID0gY29uZmlnXG5cdGlmIChwYXRoUGFyYW1zLmxlbmd0aCA8IGdldE1pblJlcXVpcmVkUGF0aFBhcmFtc0NvdW50KG1vZGVsTmFtZSkgKyAxKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCdwYXRoUGFyYW1zIGxlbmd0aCBkb2VzIG5vdCBtYXRjaCBsZW5ndGggb2YgcGF0aCBjb21wb25lbnRzJylcblx0fVxuXHRjaGFuZ2VNb2RlbFN0YXR1cyhNT0RFTF9TVEFUVVMuREVMRVRJTkcpXG5cdGRpc3BhdGNoTW9kZWxGZXRjaFJlcXVlc3Qoe1xuXHRcdG1vZGVsTmFtZSxcblx0XHRtZXRob2Q6ICdERUxFVEUnLFxuXHRcdHBhdGhQYXJhbXMsXG5cdFx0Ym9keSxcblx0XHRxdWVyeVBhcmFtczogcXVlcnlQYXJhbXMgfHwgY29uZmlnUXVlcnlQYXJhbXNcblx0fSlcbn1cblxuLy8jZW5kcmVnaW9uIERlbGV0ZVxuXG4vLyNlbmRyZWdpb24gQ29sbGVjdGlvbi9JdGVtIENSVUQgTWV0aG9kc1xuXG4vLyNyZWdpb24gSGVscGVyIE1ldGhvZHNcblxuLyoqXG4gKiBBdXRvbWF0aWNhbGx5IGNhbGwgYGxvYWRgLCBvciBgY2hhbmdlTW9kZWxTdGF0dXNgIHRvIGBSRUFEWWAuXG4gKlxuICogRG9lcyBOT1QgYXV0b21hdGljYWxseSBsb2FkIGlmOlxuICogKiBwYXRoUGFyYW1zIGRvZXMgbm90IGNvbnRhaW4gZW5vdWdoIGl0ZW1zLlxuICogKiBtb2RlbCBpcyBhbHJlYWR5IGZldGNoaW5nLlxuICogKiBhdXRvIGxvYWQgaXMgZGlzYWJsZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbml0aWFsaXplQ29sbGVjdGlvbkl0ZW0oXG5cdG1vZGVsOiBNb2RlbCxcblx0bG9hZDogKHBhcmFtcz86IENvbGxlY3Rpb25JdGVtTG9hZFBhcmFtcykgPT4gdm9pZCxcblx0Y29uZmlnOiBDb2xsZWN0aW9uTWV0aG9kQ29uZmlndXJhdGlvblxuKSB7XG5cdGNvbnN0IHsgbW9kZWxOYW1lLCBwYXRoUGFyYW1zLCBkaXNhYmxlQXV0b0xvYWQsIGNoYW5nZU1vZGVsU3RhdHVzIH0gPSBjb25maWdcblx0aWYgKFxuXHRcdHBhdGhQYXJhbXMubGVuZ3RoID09PSBnZXRNaW5SZXF1aXJlZFBhdGhQYXJhbXNDb3VudChtb2RlbE5hbWUpICsgMSAmJlxuXHRcdCFkaXNhYmxlQXV0b0xvYWQgJiZcblx0XHQoIW1vZGVsLl9tZXRhZGF0YSB8fCAhbW9kZWwuX21ldGFkYXRhLmlzRmV0Y2hpbmcpXG5cdCkge1xuXHRcdGxvYWQoKVxuXHR9IGVsc2Uge1xuXHRcdGNoYW5nZU1vZGVsU3RhdHVzKE1PREVMX1NUQVRVUy5SRUFEWSlcblx0fVxufVxuXG4vKipcbiAqIEF1dG9tYXRpY2FsbHkgY2FsbCBgbG9hZGAsIG9yIGBjaGFuZ2VNb2RlbFN0YXR1c2AgdG8gYFJFQURZYC5cbiAqXG4gKiBEb2VzIE5PVCBhdXRvbWF0aWNhbGx5IGxvYWQgaWY6XG4gKiAqIG1vZGVsIGlzIGFscmVhZHkgZmV0Y2hpbmcuXG4gKiAqIGF1dG8gbG9hZCBpcyBkaXNhYmxlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluaXRpYWxpemVDb2xsZWN0aW9uKFxuXHRtb2RlbDogTW9kZWwsXG5cdGxvYWQ6IChwYXJhbXM/OiBDb2xsZWN0aW9uSXRlbUxvYWRQYXJhbXMpID0+IHZvaWQsXG5cdGNvbmZpZzogQ29sbGVjdGlvbk1ldGhvZENvbmZpZ3VyYXRpb25cbikge1xuXHRjb25zdCB7IGRpc2FibGVBdXRvTG9hZCwgY2hhbmdlTW9kZWxTdGF0dXMgfSA9IGNvbmZpZ1xuXHRpZiAoIWRpc2FibGVBdXRvTG9hZCAmJiAoIW1vZGVsLl9tZXRhZGF0YSB8fCAhbW9kZWwuX21ldGFkYXRhLmlzRmV0Y2hpbmcpKSB7XG5cdFx0bG9hZCgpXG5cdH0gZWxzZSBpZiAoZGlzYWJsZUF1dG9Mb2FkKSB7XG5cdFx0Y2hhbmdlTW9kZWxTdGF0dXMoTU9ERUxfU1RBVFVTLlJFQURZKVxuXHR9XG59XG5cbi8qKlxuICogV2hlbiBgcGF0aFBhcmFtc2Agb3IgYHF1ZXJ5UGFyYW1zYCBjaGFuZ2UsIGNhbGwgYGxvYWRgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYW5kbGVDb2xsZWN0aW9uSXRlbVBhcmFtc0NoYW5nZShcblx0bW9kZWxOYW1lOiBzdHJpbmcsXG5cdHByZXZNb2RlbE5hbWU6IHN0cmluZyxcblx0cGF0aFBhcmFtczogQXJyYXk8c3RyaW5nIHwgbnVtYmVyPixcblx0cHJldlBhdGhQYXJhbXM6IEFycmF5PHN0cmluZyB8IG51bWJlcj4gfCB1bmRlZmluZWQsXG5cdHF1ZXJ5UGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuPiB8IHVuZGVmaW5lZCxcblx0cHJldlF1ZXJ5UGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuPiB8IHVuZGVmaW5lZCxcblx0bG9hZDogKHBhcmFtcz86IENvbGxlY3Rpb25JdGVtTG9hZFBhcmFtcykgPT4gdm9pZFxuKSB7XG5cdGlmIChcblx0XHRtb2RlbE5hbWUgIT09IHByZXZNb2RlbE5hbWUgfHxcblx0XHQocGF0aFBhcmFtcy5sZW5ndGggPT09IGdldE1pblJlcXVpcmVkUGF0aFBhcmFtc0NvdW50KG1vZGVsTmFtZSkgKyAxICYmICFpc0VxdWFsKHByZXZQYXRoUGFyYW1zLCBwYXRoUGFyYW1zKSkgfHxcblx0XHQhaXNFcXVhbChwcmV2UXVlcnlQYXJhbXMsIHF1ZXJ5UGFyYW1zKVxuXHQpIHtcblx0XHRsb2FkKHsgcGF0aFBhcmFtcywgcXVlcnlQYXJhbXMgfSlcblx0fVxufVxuXG4vKipcbiAqIFdoZW4gYHBhdGhQYXJhbXNgIG9yIGBxdWVyeVBhcmFtc2AgY2hhbmdlLCBjYWxsIGBsb2FkYFxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFuZGxlQ29sbGVjdGlvblBhcmFtc0NoYW5nZShcblx0bW9kZWxOYW1lOiBzdHJpbmcsXG5cdHByZXZNb2RlbE5hbWU6IHN0cmluZyxcblx0cGF0aFBhcmFtczogQXJyYXk8c3RyaW5nIHwgbnVtYmVyPixcblx0cHJldlBhdGhQYXJhbXM6IEFycmF5PHN0cmluZyB8IG51bWJlcj4gfCB1bmRlZmluZWQsXG5cdHF1ZXJ5UGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuPiB8IHVuZGVmaW5lZCxcblx0cHJldlF1ZXJ5UGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuPiB8IHVuZGVmaW5lZCxcblx0bG9hZDogKHBhcmFtcz86IENvbGxlY3Rpb25Mb2FkUGFyYW1zKSA9PiB2b2lkXG4pIHtcblx0aWYgKFxuXHRcdG1vZGVsTmFtZSAhPT0gcHJldk1vZGVsTmFtZSB8fFxuXHRcdChwYXRoUGFyYW1zLmxlbmd0aCA+IDAgJiYgIWlzRXF1YWwocHJldlBhdGhQYXJhbXMsIHBhdGhQYXJhbXMpKSB8fFxuXHRcdCFpc0VxdWFsKHByZXZRdWVyeVBhcmFtcywgcXVlcnlQYXJhbXMpXG5cdCkge1xuXHRcdGxvYWQoeyBwYXRoUGFyYW1zLCBxdWVyeVBhcmFtcyB9KVxuXHR9XG59XG5cbi8qKlxuICogRGVsZXRlIHRoZSBndWlkIGluIHRoZSBtb2RlbFxuICovXG5leHBvcnQgZnVuY3Rpb24gY2xlYW51cENvbGxlY3Rpb25HdWlkS2V5PFRNb2RlbCBleHRlbmRzIE1vZGVsPihcblx0bW9kZWw6IE1vZGVsQ29sbGVjdGlvbjxUTW9kZWw+LFxuXHRjb25maWc6IENvbGxlY3Rpb25NZXRob2RDb25maWd1cmF0aW9uXG4pIHtcblx0Y29uc3QgeyBndWlkLCBtb2RlbE5hbWUsIHBhdGhQYXJhbXMgfSA9IGNvbmZpZ1xuXHRpZiAoaW5jbHVkZXMoT2JqZWN0LmtleXMobW9kZWwpLCBndWlkKSkge1xuXHRcdGNvbnN0IG1vZGVsTmFtZXMgPSBtb2RlbE5hbWUuc3BsaXQoJy4nKVxuXHRcdGNvbnN0IHRlbXBQYXRoUGFyYW1zID0gcGF0aFBhcmFtcy5zbGljZSgpXG5cdFx0Ly8gc2hvdWxkIGluY2x1ZGUgdGhlIGd1aWQgYXQgdGhlIGVuZFxuXHRcdHRlbXBQYXRoUGFyYW1zLnB1c2goZ3VpZClcblx0XHRpZiAobW9kZWxOYW1lcy5sZW5ndGggPT09IHRlbXBQYXRoUGFyYW1zLmxlbmd0aCkge1xuXHRcdFx0bGV0IHBhdGggPSAnJ1xuXHRcdFx0bW9kZWxOYW1lcy5mb3JFYWNoKChtLCBpKSA9PiB7XG5cdFx0XHRcdGlmIChpID09PSAwKSB7XG5cdFx0XHRcdFx0cGF0aCArPSBgJHttfS4ke3RlbXBQYXRoUGFyYW1zW2ldfWBcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRwYXRoICs9IGAuJHttfS4ke3RlbXBQYXRoUGFyYW1zW2ldfWBcblx0XHRcdFx0fVxuXHRcdFx0fSlcblx0XHRcdGRpc3BhdGNoTW9kZWxSZW1vdmVLZXlBY3Rpb24oe1xuXHRcdFx0XHRtb2RlbFBhdGg6IHBhdGhcblx0XHRcdH0pXG5cdFx0fVxu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