@ngrx/data 12.5.1 → 13.0.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 (157) hide show
  1. package/{esm2015/index.js → esm2020/index.mjs} +0 -0
  2. package/esm2020/ngrx-data.mjs +5 -0
  3. package/{esm2015/public_api.js → esm2020/public_api.mjs} +0 -0
  4. package/esm2020/src/actions/entity-action-factory.mjs +50 -0
  5. package/{esm2015/src/actions/entity-action-guard.js → esm2020/src/actions/entity-action-guard.mjs} +0 -0
  6. package/{esm2015/src/actions/entity-action-operators.js → esm2020/src/actions/entity-action-operators.mjs} +0 -0
  7. package/{esm2015/src/actions/entity-action.js → esm2020/src/actions/entity-action.mjs} +0 -0
  8. package/esm2020/src/actions/entity-cache-action.mjs +116 -0
  9. package/esm2020/src/actions/entity-cache-change-set.mjs +50 -0
  10. package/{esm2015/src/actions/entity-op.js → esm2020/src/actions/entity-op.mjs} +0 -0
  11. package/{esm2015/src/actions/merge-strategy.js → esm2020/src/actions/merge-strategy.mjs} +0 -0
  12. package/{esm2015/src/actions/update-response-data.js → esm2020/src/actions/update-response-data.mjs} +0 -0
  13. package/{esm2015/src/dataservices/data-service-error.js → esm2020/src/dataservices/data-service-error.mjs} +0 -0
  14. package/{esm2015/src/dataservices/default-data-service-config.js → esm2020/src/dataservices/default-data-service-config.mjs} +0 -0
  15. package/{esm2015/src/dataservices/default-data.service.js → esm2020/src/dataservices/default-data.service.mjs} +13 -20
  16. package/esm2020/src/dataservices/entity-cache-data.service.mjs +146 -0
  17. package/esm2020/src/dataservices/entity-data.service.mjs +63 -0
  18. package/esm2020/src/dataservices/http-url-generator.mjs +86 -0
  19. package/{esm2015/src/dataservices/interfaces.js → esm2020/src/dataservices/interfaces.mjs} +0 -0
  20. package/esm2020/src/dataservices/persistence-result-handler.service.mjs +49 -0
  21. package/esm2020/src/dispatchers/entity-cache-dispatcher.mjs +163 -0
  22. package/{esm2015/src/dispatchers/entity-commands.js → esm2020/src/dispatchers/entity-commands.mjs} +0 -0
  23. package/esm2020/src/dispatchers/entity-dispatcher-base.mjs +405 -0
  24. package/esm2020/src/dispatchers/entity-dispatcher-default-options.mjs +30 -0
  25. package/esm2020/src/dispatchers/entity-dispatcher-factory.mjs +65 -0
  26. package/{esm2015/src/dispatchers/entity-dispatcher.js → esm2020/src/dispatchers/entity-dispatcher.mjs} +0 -0
  27. package/esm2020/src/effects/entity-cache-effects.mjs +115 -0
  28. package/{esm2015/src/effects/entity-effects-scheduler.js → esm2020/src/effects/entity-effects-scheduler.mjs} +0 -0
  29. package/esm2020/src/effects/entity-effects.mjs +148 -0
  30. package/esm2020/src/entity-data-without-effects.module.mjs +160 -0
  31. package/esm2020/src/entity-data.module.mjs +121 -0
  32. package/esm2020/src/entity-metadata/entity-definition.mjs +33 -0
  33. package/esm2020/src/entity-metadata/entity-definition.service.mjs +93 -0
  34. package/{esm2015/src/entity-metadata/entity-filters.js → esm2020/src/entity-metadata/entity-filters.mjs} +0 -0
  35. package/{esm2015/src/entity-metadata/entity-metadata.js → esm2020/src/entity-metadata/entity-metadata.mjs} +0 -0
  36. package/{esm2015/src/entity-services/entity-collection-service-base.js → esm2020/src/entity-services/entity-collection-service-base.mjs} +0 -0
  37. package/esm2020/src/entity-services/entity-collection-service-elements-factory.mjs +38 -0
  38. package/esm2020/src/entity-services/entity-collection-service-factory.mjs +28 -0
  39. package/{esm2015/src/entity-services/entity-collection-service.js → esm2020/src/entity-services/entity-collection-service.mjs} +0 -0
  40. package/esm2020/src/entity-services/entity-services-base.mjs +119 -0
  41. package/esm2020/src/entity-services/entity-services-elements.mjs +33 -0
  42. package/{esm2015/src/entity-services/entity-services.js → esm2020/src/entity-services/entity-services.mjs} +0 -0
  43. package/{esm2015/src/index.js → esm2020/src/index.mjs} +0 -0
  44. package/{esm2015/src/reducers/constants.js → esm2020/src/reducers/constants.mjs} +0 -0
  45. package/esm2020/src/reducers/entity-cache-reducer.mjs +271 -0
  46. package/{esm2015/src/reducers/entity-cache.js → esm2020/src/reducers/entity-cache.mjs} +0 -0
  47. package/esm2020/src/reducers/entity-change-tracker-base.mjs +587 -0
  48. package/{esm2015/src/reducers/entity-change-tracker.js → esm2020/src/reducers/entity-change-tracker.mjs} +0 -0
  49. package/esm2020/src/reducers/entity-collection-creator.mjs +37 -0
  50. package/esm2020/src/reducers/entity-collection-reducer-methods.mjs +807 -0
  51. package/esm2020/src/reducers/entity-collection-reducer-registry.mjs +68 -0
  52. package/esm2020/src/reducers/entity-collection-reducer.mjs +24 -0
  53. package/{esm2015/src/reducers/entity-collection.js → esm2020/src/reducers/entity-collection.mjs} +0 -0
  54. package/{esm2015/src/selectors/entity-cache-selector.js → esm2020/src/selectors/entity-cache-selector.mjs} +0 -0
  55. package/esm2020/src/selectors/entity-selectors$.mjs +52 -0
  56. package/esm2020/src/selectors/entity-selectors.mjs +96 -0
  57. package/esm2020/src/utils/correlation-id-generator.mjs +30 -0
  58. package/esm2020/src/utils/default-logger.mjs +25 -0
  59. package/esm2020/src/utils/default-pluralizer.mjs +71 -0
  60. package/{esm2015/src/utils/guid-fns.js → esm2020/src/utils/guid-fns.mjs} +0 -0
  61. package/{esm2015/src/utils/interfaces.js → esm2020/src/utils/interfaces.mjs} +0 -0
  62. package/{esm2015/src/utils/utilities.js → esm2020/src/utils/utilities.mjs} +0 -0
  63. package/fesm2015/{ngrx-data.js → ngrx-data.mjs} +341 -457
  64. package/fesm2015/ngrx-data.mjs.map +1 -0
  65. package/fesm2020/ngrx-data.mjs +4936 -0
  66. package/fesm2020/ngrx-data.mjs.map +1 -0
  67. package/ngrx-data.d.ts +1 -1
  68. package/package.json +25 -13
  69. package/schematics/ng-add/index.js +29 -25
  70. package/schematics/ng-add/index.js.map +1 -1
  71. package/schematics-core/index.js +1 -3
  72. package/schematics-core/index.js.map +1 -1
  73. package/schematics-core/utility/ast-utils.js +12 -8
  74. package/schematics-core/utility/ast-utils.js.map +1 -1
  75. package/schematics-core/utility/find-component.js +12 -12
  76. package/schematics-core/utility/find-component.js.map +1 -1
  77. package/schematics-core/utility/find-module.js +12 -12
  78. package/schematics-core/utility/find-module.js.map +1 -1
  79. package/schematics-core/utility/json-utilts.js.map +1 -1
  80. package/schematics-core/utility/libs-version.js +1 -1
  81. package/schematics-core/utility/libs-version.js.map +1 -1
  82. package/schematics-core/utility/ngrx-utils.js +16 -12
  83. package/schematics-core/utility/ngrx-utils.js.map +1 -1
  84. package/schematics-core/utility/parse-name.js +3 -3
  85. package/schematics-core/utility/parse-name.js.map +1 -1
  86. package/schematics-core/utility/project.js +1 -1
  87. package/schematics-core/utility/project.js.map +1 -1
  88. package/schematics-core/utility/visitors.js +2 -2
  89. package/schematics-core/utility/visitors.js.map +1 -1
  90. package/src/actions/entity-action-factory.d.ts +3 -0
  91. package/src/dataservices/default-data.service.d.ts +3 -0
  92. package/src/dataservices/entity-cache-data.service.d.ts +3 -0
  93. package/src/dataservices/entity-data.service.d.ts +3 -0
  94. package/src/dataservices/http-url-generator.d.ts +3 -0
  95. package/src/dataservices/persistence-result-handler.service.d.ts +3 -0
  96. package/src/dispatchers/entity-cache-dispatcher.d.ts +3 -0
  97. package/src/dispatchers/entity-dispatcher-default-options.d.ts +3 -0
  98. package/src/dispatchers/entity-dispatcher-factory.d.ts +3 -0
  99. package/src/effects/entity-cache-effects.d.ts +3 -0
  100. package/src/effects/entity-effects.d.ts +3 -0
  101. package/src/entity-data-without-effects.module.d.ts +5 -0
  102. package/src/entity-data.module.d.ts +6 -0
  103. package/src/entity-metadata/entity-definition.service.d.ts +3 -0
  104. package/src/entity-services/entity-collection-service-base.d.ts +1 -1
  105. package/src/entity-services/entity-collection-service-elements-factory.d.ts +3 -0
  106. package/src/entity-services/entity-collection-service-factory.d.ts +3 -0
  107. package/src/entity-services/entity-services-base.d.ts +3 -0
  108. package/src/entity-services/entity-services-elements.d.ts +3 -0
  109. package/src/reducers/entity-cache-reducer.d.ts +3 -0
  110. package/src/reducers/entity-collection-creator.d.ts +3 -0
  111. package/src/reducers/entity-collection-reducer-methods.d.ts +3 -0
  112. package/src/reducers/entity-collection-reducer-registry.d.ts +3 -0
  113. package/src/reducers/entity-collection-reducer.d.ts +3 -0
  114. package/src/selectors/entity-selectors$.d.ts +3 -0
  115. package/src/selectors/entity-selectors.d.ts +3 -0
  116. package/src/utils/correlation-id-generator.d.ts +3 -0
  117. package/src/utils/default-logger.d.ts +3 -0
  118. package/src/utils/default-pluralizer.d.ts +3 -0
  119. package/bundles/ngrx-data.umd.js +0 -5579
  120. package/bundles/ngrx-data.umd.js.map +0 -1
  121. package/esm2015/ngrx-data.js +0 -6
  122. package/esm2015/src/actions/entity-action-factory.js +0 -44
  123. package/esm2015/src/actions/entity-cache-action.js +0 -116
  124. package/esm2015/src/actions/entity-cache-change-set.js +0 -50
  125. package/esm2015/src/dataservices/entity-cache-data.service.js +0 -148
  126. package/esm2015/src/dataservices/entity-data.service.js +0 -71
  127. package/esm2015/src/dataservices/http-url-generator.js +0 -91
  128. package/esm2015/src/dataservices/persistence-result-handler.service.js +0 -58
  129. package/esm2015/src/dispatchers/entity-cache-dispatcher.js +0 -169
  130. package/esm2015/src/dispatchers/entity-dispatcher-base.js +0 -401
  131. package/esm2015/src/dispatchers/entity-dispatcher-default-options.js +0 -28
  132. package/esm2015/src/dispatchers/entity-dispatcher-factory.js +0 -68
  133. package/esm2015/src/effects/entity-cache-effects.js +0 -121
  134. package/esm2015/src/effects/entity-effects.js +0 -154
  135. package/esm2015/src/entity-data-without-effects.module.js +0 -133
  136. package/esm2015/src/entity-data.module.js +0 -110
  137. package/esm2015/src/entity-metadata/entity-definition.js +0 -26
  138. package/esm2015/src/entity-metadata/entity-definition.service.js +0 -96
  139. package/esm2015/src/entity-services/entity-collection-service-elements-factory.js +0 -49
  140. package/esm2015/src/entity-services/entity-collection-service-factory.js +0 -36
  141. package/esm2015/src/entity-services/entity-services-base.js +0 -127
  142. package/esm2015/src/entity-services/entity-services-elements.js +0 -44
  143. package/esm2015/src/reducers/entity-cache-reducer.js +0 -281
  144. package/esm2015/src/reducers/entity-change-tracker-base.js +0 -575
  145. package/esm2015/src/reducers/entity-collection-creator.js +0 -43
  146. package/esm2015/src/reducers/entity-collection-reducer-methods.js +0 -792
  147. package/esm2015/src/reducers/entity-collection-reducer-registry.js +0 -72
  148. package/esm2015/src/reducers/entity-collection-reducer.js +0 -32
  149. package/esm2015/src/selectors/entity-selectors$.js +0 -59
  150. package/esm2015/src/selectors/entity-selectors.js +0 -90
  151. package/esm2015/src/utils/correlation-id-generator.js +0 -28
  152. package/esm2015/src/utils/default-logger.js +0 -23
  153. package/esm2015/src/utils/default-pluralizer.js +0 -74
  154. package/fesm2015/ngrx-data.js.map +0 -1
  155. package/ngrx-data.metadata.json +0 -1
  156. package/schematics-core/utility/angular-utils.js +0 -33
  157. package/schematics-core/utility/angular-utils.js.map +0 -1
@@ -1,792 +0,0 @@
1
- import { Injectable } from '@angular/core';
2
- import { ChangeType, } from './entity-collection';
3
- import { EntityChangeTrackerBase } from './entity-change-tracker-base';
4
- import { toUpdateFactory } from '../utils/utilities';
5
- import { EntityActionGuard } from '../actions/entity-action-guard';
6
- import { EntityDefinitionService } from '../entity-metadata/entity-definition.service';
7
- import { EntityOp } from '../actions/entity-op';
8
- import { MergeStrategy } from '../actions/merge-strategy';
9
- /**
10
- * Base implementation of reducer methods for an entity collection.
11
- */
12
- export class EntityCollectionReducerMethods {
13
- constructor(entityName, definition,
14
- /*
15
- * Track changes to entities since the last query or save
16
- * Can revert some or all of those changes
17
- */
18
- entityChangeTracker) {
19
- this.entityName = entityName;
20
- this.definition = definition;
21
- /**
22
- * Dictionary of the {EntityCollectionReducerMethods} for this entity type,
23
- * keyed by the {EntityOp}
24
- */
25
- this.methods = {
26
- [EntityOp.CANCEL_PERSIST]: this.cancelPersist.bind(this),
27
- [EntityOp.QUERY_ALL]: this.queryAll.bind(this),
28
- [EntityOp.QUERY_ALL_ERROR]: this.queryAllError.bind(this),
29
- [EntityOp.QUERY_ALL_SUCCESS]: this.queryAllSuccess.bind(this),
30
- [EntityOp.QUERY_BY_KEY]: this.queryByKey.bind(this),
31
- [EntityOp.QUERY_BY_KEY_ERROR]: this.queryByKeyError.bind(this),
32
- [EntityOp.QUERY_BY_KEY_SUCCESS]: this.queryByKeySuccess.bind(this),
33
- [EntityOp.QUERY_LOAD]: this.queryLoad.bind(this),
34
- [EntityOp.QUERY_LOAD_ERROR]: this.queryLoadError.bind(this),
35
- [EntityOp.QUERY_LOAD_SUCCESS]: this.queryLoadSuccess.bind(this),
36
- [EntityOp.QUERY_MANY]: this.queryMany.bind(this),
37
- [EntityOp.QUERY_MANY_ERROR]: this.queryManyError.bind(this),
38
- [EntityOp.QUERY_MANY_SUCCESS]: this.queryManySuccess.bind(this),
39
- [EntityOp.SAVE_ADD_MANY]: this.saveAddMany.bind(this),
40
- [EntityOp.SAVE_ADD_MANY_ERROR]: this.saveAddManyError.bind(this),
41
- [EntityOp.SAVE_ADD_MANY_SUCCESS]: this.saveAddManySuccess.bind(this),
42
- [EntityOp.SAVE_ADD_ONE]: this.saveAddOne.bind(this),
43
- [EntityOp.SAVE_ADD_ONE_ERROR]: this.saveAddOneError.bind(this),
44
- [EntityOp.SAVE_ADD_ONE_SUCCESS]: this.saveAddOneSuccess.bind(this),
45
- [EntityOp.SAVE_DELETE_MANY]: this.saveDeleteMany.bind(this),
46
- [EntityOp.SAVE_DELETE_MANY_ERROR]: this.saveDeleteManyError.bind(this),
47
- [EntityOp.SAVE_DELETE_MANY_SUCCESS]: this.saveDeleteManySuccess.bind(this),
48
- [EntityOp.SAVE_DELETE_ONE]: this.saveDeleteOne.bind(this),
49
- [EntityOp.SAVE_DELETE_ONE_ERROR]: this.saveDeleteOneError.bind(this),
50
- [EntityOp.SAVE_DELETE_ONE_SUCCESS]: this.saveDeleteOneSuccess.bind(this),
51
- [EntityOp.SAVE_UPDATE_MANY]: this.saveUpdateMany.bind(this),
52
- [EntityOp.SAVE_UPDATE_MANY_ERROR]: this.saveUpdateManyError.bind(this),
53
- [EntityOp.SAVE_UPDATE_MANY_SUCCESS]: this.saveUpdateManySuccess.bind(this),
54
- [EntityOp.SAVE_UPDATE_ONE]: this.saveUpdateOne.bind(this),
55
- [EntityOp.SAVE_UPDATE_ONE_ERROR]: this.saveUpdateOneError.bind(this),
56
- [EntityOp.SAVE_UPDATE_ONE_SUCCESS]: this.saveUpdateOneSuccess.bind(this),
57
- [EntityOp.SAVE_UPSERT_MANY]: this.saveUpsertMany.bind(this),
58
- [EntityOp.SAVE_UPSERT_MANY_ERROR]: this.saveUpsertManyError.bind(this),
59
- [EntityOp.SAVE_UPSERT_MANY_SUCCESS]: this.saveUpsertManySuccess.bind(this),
60
- [EntityOp.SAVE_UPSERT_ONE]: this.saveUpsertOne.bind(this),
61
- [EntityOp.SAVE_UPSERT_ONE_ERROR]: this.saveUpsertOneError.bind(this),
62
- [EntityOp.SAVE_UPSERT_ONE_SUCCESS]: this.saveUpsertOneSuccess.bind(this),
63
- // Do nothing on save errors except turn the loading flag off.
64
- // See the ChangeTrackerMetaReducers
65
- // Or the app could listen for those errors and do something
66
- /// cache only operations ///
67
- [EntityOp.ADD_ALL]: this.addAll.bind(this),
68
- [EntityOp.ADD_MANY]: this.addMany.bind(this),
69
- [EntityOp.ADD_ONE]: this.addOne.bind(this),
70
- [EntityOp.REMOVE_ALL]: this.removeAll.bind(this),
71
- [EntityOp.REMOVE_MANY]: this.removeMany.bind(this),
72
- [EntityOp.REMOVE_ONE]: this.removeOne.bind(this),
73
- [EntityOp.UPDATE_MANY]: this.updateMany.bind(this),
74
- [EntityOp.UPDATE_ONE]: this.updateOne.bind(this),
75
- [EntityOp.UPSERT_MANY]: this.upsertMany.bind(this),
76
- [EntityOp.UPSERT_ONE]: this.upsertOne.bind(this),
77
- [EntityOp.COMMIT_ALL]: this.commitAll.bind(this),
78
- [EntityOp.COMMIT_MANY]: this.commitMany.bind(this),
79
- [EntityOp.COMMIT_ONE]: this.commitOne.bind(this),
80
- [EntityOp.UNDO_ALL]: this.undoAll.bind(this),
81
- [EntityOp.UNDO_MANY]: this.undoMany.bind(this),
82
- [EntityOp.UNDO_ONE]: this.undoOne.bind(this),
83
- [EntityOp.SET_CHANGE_STATE]: this.setChangeState.bind(this),
84
- [EntityOp.SET_COLLECTION]: this.setCollection.bind(this),
85
- [EntityOp.SET_FILTER]: this.setFilter.bind(this),
86
- [EntityOp.SET_LOADED]: this.setLoaded.bind(this),
87
- [EntityOp.SET_LOADING]: this.setLoading.bind(this),
88
- };
89
- this.adapter = definition.entityAdapter;
90
- this.isChangeTracking = definition.noChangeTracking !== true;
91
- this.selectId = definition.selectId;
92
- this.guard = new EntityActionGuard(entityName, this.selectId);
93
- this.toUpdate = toUpdateFactory(this.selectId);
94
- this.entityChangeTracker =
95
- entityChangeTracker ||
96
- new EntityChangeTrackerBase(this.adapter, this.selectId);
97
- }
98
- /** Cancel a persistence operation */
99
- cancelPersist(collection) {
100
- return this.setLoadingFalse(collection);
101
- }
102
- // #region query operations
103
- queryAll(collection) {
104
- return this.setLoadingTrue(collection);
105
- }
106
- queryAllError(collection, action) {
107
- return this.setLoadingFalse(collection);
108
- }
109
- /**
110
- * Merges query results per the MergeStrategy
111
- * Sets loading flag to false and loaded flag to true.
112
- */
113
- queryAllSuccess(collection, action) {
114
- const data = this.extractData(action);
115
- const mergeStrategy = this.extractMergeStrategy(action);
116
- return Object.assign(Object.assign({}, this.entityChangeTracker.mergeQueryResults(data, collection, mergeStrategy)), { loaded: true, loading: false });
117
- }
118
- queryByKey(collection, action) {
119
- return this.setLoadingTrue(collection);
120
- }
121
- queryByKeyError(collection, action) {
122
- return this.setLoadingFalse(collection);
123
- }
124
- queryByKeySuccess(collection, action) {
125
- const data = this.extractData(action);
126
- const mergeStrategy = this.extractMergeStrategy(action);
127
- collection =
128
- data == null
129
- ? collection
130
- : this.entityChangeTracker.mergeQueryResults([data], collection, mergeStrategy);
131
- return this.setLoadingFalse(collection);
132
- }
133
- queryLoad(collection) {
134
- return this.setLoadingTrue(collection);
135
- }
136
- queryLoadError(collection, action) {
137
- return this.setLoadingFalse(collection);
138
- }
139
- /**
140
- * Replaces all entities in the collection
141
- * Sets loaded flag to true, loading flag to false,
142
- * and clears changeState for the entire collection.
143
- */
144
- queryLoadSuccess(collection, action) {
145
- const data = this.extractData(action);
146
- return Object.assign(Object.assign({}, this.adapter.setAll(data, collection)), { loading: false, loaded: true, changeState: {} });
147
- }
148
- queryMany(collection, action) {
149
- return this.setLoadingTrue(collection);
150
- }
151
- queryManyError(collection, action) {
152
- return this.setLoadingFalse(collection);
153
- }
154
- queryManySuccess(collection, action) {
155
- const data = this.extractData(action);
156
- const mergeStrategy = this.extractMergeStrategy(action);
157
- return Object.assign(Object.assign({}, this.entityChangeTracker.mergeQueryResults(data, collection, mergeStrategy)), { loading: false });
158
- }
159
- // #endregion query operations
160
- // #region save operations
161
- // #region saveAddMany
162
- /**
163
- * Save multiple new entities.
164
- * If saving pessimistically, delay adding to collection until server acknowledges success.
165
- * If saving optimistically; add immediately.
166
- * @param collection The collection to which the entities should be added.
167
- * @param action The action payload holds options, including whether the save is optimistic,
168
- * and the data, which must be an array of entities.
169
- * If saving optimistically, the entities must have their keys.
170
- */
171
- saveAddMany(collection, action) {
172
- if (this.isOptimistic(action)) {
173
- const entities = this.guard.mustBeEntities(action); // ensure the entity has a PK
174
- const mergeStrategy = this.extractMergeStrategy(action);
175
- collection = this.entityChangeTracker.trackAddMany(entities, collection, mergeStrategy);
176
- collection = this.adapter.addMany(entities, collection);
177
- }
178
- return this.setLoadingTrue(collection);
179
- }
180
- /**
181
- * Attempt to save new entities failed or timed-out.
182
- * Action holds the error.
183
- * If saved pessimistically, new entities are not in the collection and
184
- * you may not have to compensate for the error.
185
- * If saved optimistically, the unsaved entities are in the collection and
186
- * you may need to compensate for the error.
187
- */
188
- saveAddManyError(collection, action) {
189
- return this.setLoadingFalse(collection);
190
- }
191
- // #endregion saveAddMany
192
- // #region saveAddOne
193
- /**
194
- * Successfully saved new entities to the server.
195
- * If saved pessimistically, add the entities from the server to the collection.
196
- * If saved optimistically, the added entities are already in the collection.
197
- * However, the server might have set or modified other fields (e.g, concurrency field),
198
- * and may even return additional new entities.
199
- * Therefore, upsert the entities in the collection with the returned values (if any)
200
- * Caution: in a race, this update could overwrite unsaved user changes.
201
- * Use pessimistic add to avoid this risk.
202
- * Note: saveAddManySuccess differs from saveAddOneSuccess when optimistic.
203
- * saveAddOneSuccess updates (not upserts) with the lone entity from the server.
204
- * There is no effect if the entity is not already in cache.
205
- * saveAddManySuccess will add an entity if it is not found in cache.
206
- */
207
- saveAddManySuccess(collection, action) {
208
- // For pessimistic save, ensure the server generated the primary key if the client didn't send one.
209
- const entities = this.guard.mustBeEntities(action);
210
- const mergeStrategy = this.extractMergeStrategy(action);
211
- if (this.isOptimistic(action)) {
212
- collection = this.entityChangeTracker.mergeSaveUpserts(entities, collection, mergeStrategy);
213
- }
214
- else {
215
- collection = this.entityChangeTracker.mergeSaveAdds(entities, collection, mergeStrategy);
216
- }
217
- return this.setLoadingFalse(collection);
218
- }
219
- // #endregion saveAddMany
220
- // #region saveAddOne
221
- /**
222
- * Save a new entity.
223
- * If saving pessimistically, delay adding to collection until server acknowledges success.
224
- * If saving optimistically; add entity immediately.
225
- * @param collection The collection to which the entity should be added.
226
- * @param action The action payload holds options, including whether the save is optimistic,
227
- * and the data, which must be an entity.
228
- * If saving optimistically, the entity must have a key.
229
- */
230
- saveAddOne(collection, action) {
231
- if (this.isOptimistic(action)) {
232
- const entity = this.guard.mustBeEntity(action); // ensure the entity has a PK
233
- const mergeStrategy = this.extractMergeStrategy(action);
234
- collection = this.entityChangeTracker.trackAddOne(entity, collection, mergeStrategy);
235
- collection = this.adapter.addOne(entity, collection);
236
- }
237
- return this.setLoadingTrue(collection);
238
- }
239
- /**
240
- * Attempt to save a new entity failed or timed-out.
241
- * Action holds the error.
242
- * If saved pessimistically, the entity is not in the collection and
243
- * you may not have to compensate for the error.
244
- * If saved optimistically, the unsaved entity is in the collection and
245
- * you may need to compensate for the error.
246
- */
247
- saveAddOneError(collection, action) {
248
- return this.setLoadingFalse(collection);
249
- }
250
- /**
251
- * Successfully saved a new entity to the server.
252
- * If saved pessimistically, add the entity from the server to the collection.
253
- * If saved optimistically, the added entity is already in the collection.
254
- * However, the server might have set or modified other fields (e.g, concurrency field)
255
- * Therefore, update the entity in the collection with the returned value (if any)
256
- * Caution: in a race, this update could overwrite unsaved user changes.
257
- * Use pessimistic add to avoid this risk.
258
- */
259
- saveAddOneSuccess(collection, action) {
260
- // For pessimistic save, ensure the server generated the primary key if the client didn't send one.
261
- const entity = this.guard.mustBeEntity(action);
262
- const mergeStrategy = this.extractMergeStrategy(action);
263
- if (this.isOptimistic(action)) {
264
- const update = this.toUpdate(entity);
265
- // Always update the cache with added entity returned from server
266
- collection = this.entityChangeTracker.mergeSaveUpdates([update], collection, mergeStrategy, false /*never skip*/);
267
- }
268
- else {
269
- collection = this.entityChangeTracker.mergeSaveAdds([entity], collection, mergeStrategy);
270
- }
271
- return this.setLoadingFalse(collection);
272
- }
273
- // #endregion saveAddOne
274
- // #region saveAddMany
275
- // TODO MANY
276
- // #endregion saveAddMany
277
- // #region saveDeleteOne
278
- /**
279
- * Delete an entity from the server by key and remove it from the collection (if present).
280
- * If the entity is an unsaved new entity, remove it from the collection immediately
281
- * and skip the server delete request.
282
- * An optimistic save removes an existing entity from the collection immediately;
283
- * a pessimistic save removes it after the server confirms successful delete.
284
- * @param collection Will remove the entity with this key from the collection.
285
- * @param action The action payload holds options, including whether the save is optimistic,
286
- * and the data, which must be a primary key or an entity with a key;
287
- * this reducer extracts the key from the entity.
288
- */
289
- saveDeleteOne(collection, action) {
290
- const toDelete = this.extractData(action);
291
- const deleteId = typeof toDelete === 'object'
292
- ? this.selectId(toDelete)
293
- : toDelete;
294
- const change = collection.changeState[deleteId];
295
- // If entity is already tracked ...
296
- if (change) {
297
- if (change.changeType === ChangeType.Added) {
298
- // Remove the added entity immediately and forget about its changes (via commit).
299
- collection = this.adapter.removeOne(deleteId, collection);
300
- collection = this.entityChangeTracker.commitOne(deleteId, collection);
301
- // Should not waste effort trying to delete on the server because it can't be there.
302
- action.payload.skip = true;
303
- }
304
- else {
305
- // Re-track it as a delete, even if tracking is turned off for this call.
306
- collection = this.entityChangeTracker.trackDeleteOne(deleteId, collection);
307
- }
308
- }
309
- // If optimistic delete, track current state and remove immediately.
310
- if (this.isOptimistic(action)) {
311
- const mergeStrategy = this.extractMergeStrategy(action);
312
- collection = this.entityChangeTracker.trackDeleteOne(deleteId, collection, mergeStrategy);
313
- collection = this.adapter.removeOne(deleteId, collection);
314
- }
315
- return this.setLoadingTrue(collection);
316
- }
317
- /**
318
- * Attempt to delete the entity on the server failed or timed-out.
319
- * Action holds the error.
320
- * If saved pessimistically, the entity could still be in the collection and
321
- * you may not have to compensate for the error.
322
- * If saved optimistically, the entity is not in the collection and
323
- * you may need to compensate for the error.
324
- */
325
- saveDeleteOneError(collection, action) {
326
- return this.setLoadingFalse(collection);
327
- }
328
- /**
329
- * Successfully deleted entity on the server. The key of the deleted entity is in the action payload data.
330
- * If saved pessimistically, if the entity is still in the collection it will be removed.
331
- * If saved optimistically, the entity has already been removed from the collection.
332
- */
333
- saveDeleteOneSuccess(collection, action) {
334
- const deleteId = this.extractData(action);
335
- if (this.isOptimistic(action)) {
336
- const mergeStrategy = this.extractMergeStrategy(action);
337
- collection = this.entityChangeTracker.mergeSaveDeletes([deleteId], collection, mergeStrategy);
338
- }
339
- else {
340
- // Pessimistic: ignore mergeStrategy. Remove entity from the collection and from change tracking.
341
- collection = this.adapter.removeOne(deleteId, collection);
342
- collection = this.entityChangeTracker.commitOne(deleteId, collection);
343
- }
344
- return this.setLoadingFalse(collection);
345
- }
346
- // #endregion saveDeleteOne
347
- // #region saveDeleteMany
348
- /**
349
- * Delete multiple entities from the server by key and remove them from the collection (if present).
350
- * Removes unsaved new entities from the collection immediately
351
- * but the id is still sent to the server for deletion even though the server will not find that entity.
352
- * Therefore, the server must be willing to ignore a delete request for an entity it cannot find.
353
- * An optimistic save removes existing entities from the collection immediately;
354
- * a pessimistic save removes them after the server confirms successful delete.
355
- * @param collection Removes entities from this collection.
356
- * @param action The action payload holds options, including whether the save is optimistic,
357
- * and the data, which must be an array of primary keys or entities with a key;
358
- * this reducer extracts the key from the entity.
359
- */
360
- saveDeleteMany(collection, action) {
361
- const deleteIds = this.extractData(action).map((d) => typeof d === 'object' ? this.selectId(d) : d);
362
- deleteIds.forEach((deleteId) => {
363
- const change = collection.changeState[deleteId];
364
- // If entity is already tracked ...
365
- if (change) {
366
- if (change.changeType === ChangeType.Added) {
367
- // Remove the added entity immediately and forget about its changes (via commit).
368
- collection = this.adapter.removeOne(deleteId, collection);
369
- collection = this.entityChangeTracker.commitOne(deleteId, collection);
370
- // Should not waste effort trying to delete on the server because it can't be there.
371
- action.payload.skip = true;
372
- }
373
- else {
374
- // Re-track it as a delete, even if tracking is turned off for this call.
375
- collection = this.entityChangeTracker.trackDeleteOne(deleteId, collection);
376
- }
377
- }
378
- });
379
- // If optimistic delete, track current state and remove immediately.
380
- if (this.isOptimistic(action)) {
381
- const mergeStrategy = this.extractMergeStrategy(action);
382
- collection = this.entityChangeTracker.trackDeleteMany(deleteIds, collection, mergeStrategy);
383
- collection = this.adapter.removeMany(deleteIds, collection);
384
- }
385
- return this.setLoadingTrue(collection);
386
- }
387
- /**
388
- * Attempt to delete the entities on the server failed or timed-out.
389
- * Action holds the error.
390
- * If saved pessimistically, the entities could still be in the collection and
391
- * you may not have to compensate for the error.
392
- * If saved optimistically, the entities are not in the collection and
393
- * you may need to compensate for the error.
394
- */
395
- saveDeleteManyError(collection, action) {
396
- return this.setLoadingFalse(collection);
397
- }
398
- /**
399
- * Successfully deleted entities on the server. The keys of the deleted entities are in the action payload data.
400
- * If saved pessimistically, entities that are still in the collection will be removed.
401
- * If saved optimistically, the entities have already been removed from the collection.
402
- */
403
- saveDeleteManySuccess(collection, action) {
404
- const deleteIds = this.extractData(action);
405
- if (this.isOptimistic(action)) {
406
- const mergeStrategy = this.extractMergeStrategy(action);
407
- collection = this.entityChangeTracker.mergeSaveDeletes(deleteIds, collection, mergeStrategy);
408
- }
409
- else {
410
- // Pessimistic: ignore mergeStrategy. Remove entity from the collection and from change tracking.
411
- collection = this.adapter.removeMany(deleteIds, collection);
412
- collection = this.entityChangeTracker.commitMany(deleteIds, collection);
413
- }
414
- return this.setLoadingFalse(collection);
415
- }
416
- // #endregion saveDeleteMany
417
- // #region saveUpdateOne
418
- /**
419
- * Save an update to an existing entity.
420
- * If saving pessimistically, update the entity in the collection after the server confirms success.
421
- * If saving optimistically, update the entity immediately, before the save request.
422
- * @param collection The collection to update
423
- * @param action The action payload holds options, including if the save is optimistic,
424
- * and the data which, must be an {Update<T>}
425
- */
426
- saveUpdateOne(collection, action) {
427
- const update = this.guard.mustBeUpdate(action);
428
- if (this.isOptimistic(action)) {
429
- const mergeStrategy = this.extractMergeStrategy(action);
430
- collection = this.entityChangeTracker.trackUpdateOne(update, collection, mergeStrategy);
431
- collection = this.adapter.updateOne(update, collection);
432
- }
433
- return this.setLoadingTrue(collection);
434
- }
435
- /**
436
- * Attempt to update the entity on the server failed or timed-out.
437
- * Action holds the error.
438
- * If saved pessimistically, the entity in the collection is in the pre-save state
439
- * you may not have to compensate for the error.
440
- * If saved optimistically, the entity in the collection was updated
441
- * and you may need to compensate for the error.
442
- */
443
- saveUpdateOneError(collection, action) {
444
- return this.setLoadingFalse(collection);
445
- }
446
- /**
447
- * Successfully saved the updated entity to the server.
448
- * If saved pessimistically, update the entity in the collection with data from the server.
449
- * If saved optimistically, the entity was already updated in the collection.
450
- * However, the server might have set or modified other fields (e.g, concurrency field)
451
- * Therefore, update the entity in the collection with the returned value (if any)
452
- * Caution: in a race, this update could overwrite unsaved user changes.
453
- * Use pessimistic update to avoid this risk.
454
- * @param collection The collection to update
455
- * @param action The action payload holds options, including if the save is optimistic, and
456
- * the update data which, must be an UpdateResponse<T> that corresponds to the Update sent to the server.
457
- * You must include an UpdateResponse even if the save was optimistic,
458
- * to ensure that the change tracking is properly reset.
459
- */
460
- saveUpdateOneSuccess(collection, action) {
461
- const update = this.guard.mustBeUpdateResponse(action);
462
- const isOptimistic = this.isOptimistic(action);
463
- const mergeStrategy = this.extractMergeStrategy(action);
464
- collection = this.entityChangeTracker.mergeSaveUpdates([update], collection, mergeStrategy, isOptimistic /*skip unchanged if optimistic */);
465
- return this.setLoadingFalse(collection);
466
- }
467
- // #endregion saveUpdateOne
468
- // #region saveUpdateMany
469
- /**
470
- * Save updated entities.
471
- * If saving pessimistically, update the entities in the collection after the server confirms success.
472
- * If saving optimistically, update the entities immediately, before the save request.
473
- * @param collection The collection to update
474
- * @param action The action payload holds options, including if the save is optimistic,
475
- * and the data which, must be an array of {Update<T>}.
476
- */
477
- saveUpdateMany(collection, action) {
478
- const updates = this.guard.mustBeUpdates(action);
479
- if (this.isOptimistic(action)) {
480
- const mergeStrategy = this.extractMergeStrategy(action);
481
- collection = this.entityChangeTracker.trackUpdateMany(updates, collection, mergeStrategy);
482
- collection = this.adapter.updateMany(updates, collection);
483
- }
484
- return this.setLoadingTrue(collection);
485
- }
486
- /**
487
- * Attempt to update entities on the server failed or timed-out.
488
- * Action holds the error.
489
- * If saved pessimistically, the entities in the collection are in the pre-save state
490
- * you may not have to compensate for the error.
491
- * If saved optimistically, the entities in the collection were updated
492
- * and you may need to compensate for the error.
493
- */
494
- saveUpdateManyError(collection, action) {
495
- return this.setLoadingFalse(collection);
496
- }
497
- /**
498
- * Successfully saved the updated entities to the server.
499
- * If saved pessimistically, the entities in the collection will be updated with data from the server.
500
- * If saved optimistically, the entities in the collection were already updated.
501
- * However, the server might have set or modified other fields (e.g, concurrency field)
502
- * Therefore, update the entity in the collection with the returned values (if any)
503
- * Caution: in a race, this update could overwrite unsaved user changes.
504
- * Use pessimistic update to avoid this risk.
505
- * @param collection The collection to update
506
- * @param action The action payload holds options, including if the save is optimistic,
507
- * and the data which, must be an array of UpdateResponse<T>.
508
- * You must include an UpdateResponse for every Update sent to the server,
509
- * even if the save was optimistic, to ensure that the change tracking is properly reset.
510
- */
511
- saveUpdateManySuccess(collection, action) {
512
- const updates = this.guard.mustBeUpdateResponses(action);
513
- const isOptimistic = this.isOptimistic(action);
514
- const mergeStrategy = this.extractMergeStrategy(action);
515
- collection = this.entityChangeTracker.mergeSaveUpdates(updates, collection, mergeStrategy, false /* never skip */);
516
- return this.setLoadingFalse(collection);
517
- }
518
- // #endregion saveUpdateMany
519
- // #region saveUpsertOne
520
- /**
521
- * Save a new or existing entity.
522
- * If saving pessimistically, delay adding to collection until server acknowledges success.
523
- * If saving optimistically; add immediately.
524
- * @param collection The collection to which the entity should be upserted.
525
- * @param action The action payload holds options, including whether the save is optimistic,
526
- * and the data, which must be a whole entity.
527
- * If saving optimistically, the entity must have its key.
528
- */
529
- saveUpsertOne(collection, action) {
530
- if (this.isOptimistic(action)) {
531
- const entity = this.guard.mustBeEntity(action); // ensure the entity has a PK
532
- const mergeStrategy = this.extractMergeStrategy(action);
533
- collection = this.entityChangeTracker.trackUpsertOne(entity, collection, mergeStrategy);
534
- collection = this.adapter.upsertOne(entity, collection);
535
- }
536
- return this.setLoadingTrue(collection);
537
- }
538
- /**
539
- * Attempt to save new or existing entity failed or timed-out.
540
- * Action holds the error.
541
- * If saved pessimistically, new or updated entity is not in the collection and
542
- * you may not have to compensate for the error.
543
- * If saved optimistically, the unsaved entities are in the collection and
544
- * you may need to compensate for the error.
545
- */
546
- saveUpsertOneError(collection, action) {
547
- return this.setLoadingFalse(collection);
548
- }
549
- /**
550
- * Successfully saved new or existing entities to the server.
551
- * If saved pessimistically, add the entities from the server to the collection.
552
- * If saved optimistically, the added entities are already in the collection.
553
- * However, the server might have set or modified other fields (e.g, concurrency field)
554
- * Therefore, update the entities in the collection with the returned values (if any)
555
- * Caution: in a race, this update could overwrite unsaved user changes.
556
- * Use pessimistic add to avoid this risk.
557
- */
558
- saveUpsertOneSuccess(collection, action) {
559
- // For pessimistic save, ensure the server generated the primary key if the client didn't send one.
560
- const entity = this.guard.mustBeEntity(action);
561
- const mergeStrategy = this.extractMergeStrategy(action);
562
- // Always update the cache with upserted entities returned from server
563
- collection = this.entityChangeTracker.mergeSaveUpserts([entity], collection, mergeStrategy);
564
- return this.setLoadingFalse(collection);
565
- }
566
- // #endregion saveUpsertOne
567
- // #region saveUpsertMany
568
- /**
569
- * Save multiple new or existing entities.
570
- * If saving pessimistically, delay adding to collection until server acknowledges success.
571
- * If saving optimistically; add immediately.
572
- * @param collection The collection to which the entities should be upserted.
573
- * @param action The action payload holds options, including whether the save is optimistic,
574
- * and the data, which must be an array of whole entities.
575
- * If saving optimistically, the entities must have their keys.
576
- */
577
- saveUpsertMany(collection, action) {
578
- if (this.isOptimistic(action)) {
579
- const entities = this.guard.mustBeEntities(action); // ensure the entity has a PK
580
- const mergeStrategy = this.extractMergeStrategy(action);
581
- collection = this.entityChangeTracker.trackUpsertMany(entities, collection, mergeStrategy);
582
- collection = this.adapter.upsertMany(entities, collection);
583
- }
584
- return this.setLoadingTrue(collection);
585
- }
586
- /**
587
- * Attempt to save new or existing entities failed or timed-out.
588
- * Action holds the error.
589
- * If saved pessimistically, new entities are not in the collection and
590
- * you may not have to compensate for the error.
591
- * If saved optimistically, the unsaved entities are in the collection and
592
- * you may need to compensate for the error.
593
- */
594
- saveUpsertManyError(collection, action) {
595
- return this.setLoadingFalse(collection);
596
- }
597
- /**
598
- * Successfully saved new or existing entities to the server.
599
- * If saved pessimistically, add the entities from the server to the collection.
600
- * If saved optimistically, the added entities are already in the collection.
601
- * However, the server might have set or modified other fields (e.g, concurrency field)
602
- * Therefore, update the entities in the collection with the returned values (if any)
603
- * Caution: in a race, this update could overwrite unsaved user changes.
604
- * Use pessimistic add to avoid this risk.
605
- */
606
- saveUpsertManySuccess(collection, action) {
607
- // For pessimistic save, ensure the server generated the primary key if the client didn't send one.
608
- const entities = this.guard.mustBeEntities(action);
609
- const mergeStrategy = this.extractMergeStrategy(action);
610
- // Always update the cache with upserted entities returned from server
611
- collection = this.entityChangeTracker.mergeSaveUpserts(entities, collection, mergeStrategy);
612
- return this.setLoadingFalse(collection);
613
- }
614
- // #endregion saveUpsertMany
615
- // #endregion save operations
616
- // #region cache-only operations
617
- /**
618
- * Replaces all entities in the collection
619
- * Sets loaded flag to true.
620
- * Merges query results, preserving unsaved changes
621
- */
622
- addAll(collection, action) {
623
- const entities = this.guard.mustBeEntities(action);
624
- return Object.assign(Object.assign({}, this.adapter.setAll(entities, collection)), { loading: false, loaded: true, changeState: {} });
625
- }
626
- addMany(collection, action) {
627
- const entities = this.guard.mustBeEntities(action);
628
- const mergeStrategy = this.extractMergeStrategy(action);
629
- collection = this.entityChangeTracker.trackAddMany(entities, collection, mergeStrategy);
630
- return this.adapter.addMany(entities, collection);
631
- }
632
- addOne(collection, action) {
633
- const entity = this.guard.mustBeEntity(action);
634
- const mergeStrategy = this.extractMergeStrategy(action);
635
- collection = this.entityChangeTracker.trackAddOne(entity, collection, mergeStrategy);
636
- return this.adapter.addOne(entity, collection);
637
- }
638
- removeMany(collection, action) {
639
- // payload must be entity keys
640
- const keys = this.guard.mustBeKeys(action);
641
- const mergeStrategy = this.extractMergeStrategy(action);
642
- collection = this.entityChangeTracker.trackDeleteMany(keys, collection, mergeStrategy);
643
- return this.adapter.removeMany(keys, collection);
644
- }
645
- removeOne(collection, action) {
646
- // payload must be entity key
647
- const key = this.guard.mustBeKey(action);
648
- const mergeStrategy = this.extractMergeStrategy(action);
649
- collection = this.entityChangeTracker.trackDeleteOne(key, collection, mergeStrategy);
650
- return this.adapter.removeOne(key, collection);
651
- }
652
- removeAll(collection, action) {
653
- return Object.assign(Object.assign({}, this.adapter.removeAll(collection)), { loaded: false, loading: false, changeState: {} });
654
- }
655
- updateMany(collection, action) {
656
- // payload must be an array of `Updates<T>`, not entities
657
- const updates = this.guard.mustBeUpdates(action);
658
- const mergeStrategy = this.extractMergeStrategy(action);
659
- collection = this.entityChangeTracker.trackUpdateMany(updates, collection, mergeStrategy);
660
- return this.adapter.updateMany(updates, collection);
661
- }
662
- updateOne(collection, action) {
663
- // payload must be an `Update<T>`, not an entity
664
- const update = this.guard.mustBeUpdate(action);
665
- const mergeStrategy = this.extractMergeStrategy(action);
666
- collection = this.entityChangeTracker.trackUpdateOne(update, collection, mergeStrategy);
667
- return this.adapter.updateOne(update, collection);
668
- }
669
- upsertMany(collection, action) {
670
- // <v6: payload must be an array of `Updates<T>`, not entities
671
- // v6+: payload must be an array of T
672
- const entities = this.guard.mustBeEntities(action);
673
- const mergeStrategy = this.extractMergeStrategy(action);
674
- collection = this.entityChangeTracker.trackUpsertMany(entities, collection, mergeStrategy);
675
- return this.adapter.upsertMany(entities, collection);
676
- }
677
- upsertOne(collection, action) {
678
- // <v6: payload must be an `Update<T>`, not an entity
679
- // v6+: payload must be a T
680
- const entity = this.guard.mustBeEntity(action);
681
- const mergeStrategy = this.extractMergeStrategy(action);
682
- collection = this.entityChangeTracker.trackUpsertOne(entity, collection, mergeStrategy);
683
- return this.adapter.upsertOne(entity, collection);
684
- }
685
- commitAll(collection) {
686
- return this.entityChangeTracker.commitAll(collection);
687
- }
688
- commitMany(collection, action) {
689
- return this.entityChangeTracker.commitMany(this.extractData(action), collection);
690
- }
691
- commitOne(collection, action) {
692
- return this.entityChangeTracker.commitOne(this.extractData(action), collection);
693
- }
694
- undoAll(collection) {
695
- return this.entityChangeTracker.undoAll(collection);
696
- }
697
- undoMany(collection, action) {
698
- return this.entityChangeTracker.undoMany(this.extractData(action), collection);
699
- }
700
- undoOne(collection, action) {
701
- return this.entityChangeTracker.undoOne(this.extractData(action), collection);
702
- }
703
- /** Dangerous: Completely replace the collection's ChangeState. Use rarely and wisely. */
704
- setChangeState(collection, action) {
705
- const changeState = this.extractData(action);
706
- return collection.changeState === changeState
707
- ? collection
708
- : Object.assign(Object.assign({}, collection), { changeState });
709
- }
710
- /**
711
- * Dangerous: Completely replace the collection.
712
- * Primarily for testing and rehydration from local storage.
713
- * Use rarely and wisely.
714
- */
715
- setCollection(collection, action) {
716
- const newCollection = this.extractData(action);
717
- return collection === newCollection ? collection : newCollection;
718
- }
719
- setFilter(collection, action) {
720
- const filter = this.extractData(action);
721
- return collection.filter === filter
722
- ? collection
723
- : Object.assign(Object.assign({}, collection), { filter });
724
- }
725
- setLoaded(collection, action) {
726
- const loaded = this.extractData(action) === true || false;
727
- return collection.loaded === loaded
728
- ? collection
729
- : Object.assign(Object.assign({}, collection), { loaded });
730
- }
731
- setLoading(collection, action) {
732
- return this.setLoadingFlag(collection, this.extractData(action));
733
- }
734
- setLoadingFalse(collection) {
735
- return this.setLoadingFlag(collection, false);
736
- }
737
- setLoadingTrue(collection) {
738
- return this.setLoadingFlag(collection, true);
739
- }
740
- /** Set the collection's loading flag */
741
- setLoadingFlag(collection, loading) {
742
- loading = loading === true ? true : false;
743
- return collection.loading === loading
744
- ? collection
745
- : Object.assign(Object.assign({}, collection), { loading });
746
- }
747
- // #endregion Cache-only operations
748
- // #region helpers
749
- /** Safely extract data from the EntityAction payload */
750
- extractData(action) {
751
- return (action.payload && action.payload.data);
752
- }
753
- /** Safely extract MergeStrategy from EntityAction. Set to IgnoreChanges if collection itself is not tracked. */
754
- extractMergeStrategy(action) {
755
- // If not tracking this collection, always ignore changes
756
- return this.isChangeTracking
757
- ? action.payload && action.payload.mergeStrategy
758
- : MergeStrategy.IgnoreChanges;
759
- }
760
- isOptimistic(action) {
761
- return action.payload && action.payload.isOptimistic === true;
762
- }
763
- }
764
- /**
765
- * Creates {EntityCollectionReducerMethods} for a given entity type.
766
- */
767
- export class EntityCollectionReducerMethodsFactory {
768
- constructor(entityDefinitionService) {
769
- this.entityDefinitionService = entityDefinitionService;
770
- }
771
- /** Create the {EntityCollectionReducerMethods} for the named entity type */
772
- create(entityName) {
773
- const definition = this.entityDefinitionService.getDefinition(entityName);
774
- const methodsClass = new EntityCollectionReducerMethods(entityName, definition);
775
- return methodsClass.methods;
776
- }
777
- }
778
- /** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */
779
- EntityCollectionReducerMethodsFactory.decorators = [
780
- { type: Injectable }
781
- ];
782
- /**
783
- * @type {function(): !Array<(null|{
784
- * type: ?,
785
- * decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>),
786
- * })>}
787
- * @nocollapse
788
- */
789
- EntityCollectionReducerMethodsFactory.ctorParameters = () => [
790
- { type: EntityDefinitionService }
791
- ];
792
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LWNvbGxlY3Rpb24tcmVkdWNlci1tZXRob2RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbW9kdWxlcy9kYXRhL3NyYy9yZWR1Y2Vycy9lbnRpdHktY29sbGVjdGlvbi1yZWR1Y2VyLW1ldGhvZHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUzQyxPQUFPLEVBRUwsVUFBVSxHQUVYLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDdkUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBR3JELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBR25FLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDhDQUE4QyxDQUFDO0FBQ3ZGLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFjMUQ7O0dBRUc7QUFDSCxNQUFNLE9BQU8sOEJBQThCO0lBK0d6QyxZQUNTLFVBQWtCLEVBQ2xCLFVBQStCO0lBQ3RDOzs7T0FHRztJQUNILG1CQUE0QztRQU5yQyxlQUFVLEdBQVYsVUFBVSxDQUFRO1FBQ2xCLGVBQVUsR0FBVixVQUFVLENBQXFCO1FBM0Z4Qzs7O1dBR0c7UUFDTSxZQUFPLEdBQXdDO1lBQ3RELENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUV4RCxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDOUMsQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLEVBQUUs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QUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQU0sQ0FBQztJQUN0RCxDQUFDO0lBRUQsZ0hBQWdIO0lBQ3RHLG9CQUFvQixDQUFDLE1BQW9CO1FBQ2pELHlEQUF5RDtRQUN6RCxPQUFPLElBQUksQ0FBQyxnQkFBZ0I7WUFDMUIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxhQUFhO1lBQ2hELENBQUMsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDO0lBQ2xDLENBQUM7SUFFUyxZQUFZLENBQUMsTUFBb0I7UUFDekMsT0FBTyxNQUFNLENBQUMsT0FBTyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsWUFBWSxLQUFLLElBQUksQ0FBQztJQUNoRSxDQUFDO0NBR0Y7QUFFRDs7R0FFRztBQUVILE1BQU0sT0FBTyxxQ0FBcUM7SUFDaEQsWUFBb0IsdUJBQWdEO1FBQWhELDRCQUF1QixHQUF2Qix1QkFBdUIsQ0FBeUI7SUFBRyxDQUFDO0lBRXhFLDZFQUE2RTtJQUM3RSxNQUFNLENBQUksVUFBa0I7UUFDMUIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLGFBQWEsQ0FDM0QsVUFBVSxDQUNYLENBQUM7UUFDRixNQUFNLFlBQVksR0FBRyxJQUFJLDhCQUE4QixDQUNyRCxVQUFVLEVBQ1YsVUFBVSxDQUNYLENBQUM7UUFFRixPQUFPLFlBQVksQ0FBQyxPQUFPLENBQUM7SUFDOUIsQ0FBQzs7OztZQWZGLFVBQVU7Ozs7Ozs7Ozs7WUEzckNGLHVCQUF1QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEVudGl0eUFkYXB0ZXIsIElkU2VsZWN0b3IsIFVwZGF0ZSB9IGZyb20gJ0BuZ3J4L2VudGl0eSc7XG5pbXBvcnQge1xuICBDaGFuZ2VTdGF0ZU1hcCxcbiAgQ2hhbmdlVHlwZSxcbiAgRW50aXR5Q29sbGVjdGlvbixcbn0gZnJvbSAnLi9lbnRpdHktY29sbGVjdGlvbic7XG5pbXBvcnQgeyBFbnRpdHlDaGFuZ2VUcmFja2VyQmFzZSB9IGZyb20gJy4vZW50aXR5LWNoYW5nZS10cmFja2VyLWJhc2UnO1xuaW1wb3J0IHsgdG9VcGRhdGVGYWN0b3J5IH0gZnJvbSAnLi4vdXRpbHMvdXRpbGl0aWVzJztcbmltcG9ydCB7IEVudGl0eUFjdGlvbiB9IGZyb20gJy4uL2FjdGlvbnMvZW50aXR5LWFjdGlvbic7XG5pbXBvcnQgeyBFbnRpdHlBY3Rpb25EYXRhU2VydmljZUVycm9yIH0gZnJvbSAnLi4vZGF0YXNlcnZpY2VzL2RhdGEtc2VydmljZS1lcnJvcic7XG5pbXBvcnQgeyBFbnRpdHlBY3Rpb25HdWFyZCB9IGZyb20gJy4uL2FjdGlvbnMvZW50aXR5LWFjdGlvbi1ndWFyZCc7XG5pbXBvcnQgeyBFbnRpdHlDaGFuZ2VUcmFja2VyIH0gZnJvbSAnLi9lbnRpdHktY2hhbmdlLXRyYWNrZXInO1xuaW1wb3J0IHsgRW50aXR5RGVmaW5pdGlvbiB9IGZyb20gJy4uL2VudGl0eS1tZXRhZGF0YS9lbnRpdHktZGVmaW5pdGlvbic7XG5pbXBvcnQgeyBFbnRpdHlEZWZpbml0aW9uU2VydmljZSB9IGZyb20gJy4uL2VudGl0eS1tZXRhZGF0YS9lbnRpdHktZGVmaW5pdGlvbi5zZXJ2aWNlJztcbmltcG9ydCB7IEVudGl0eU9wIH0gZnJvbSAnLi4vYWN0aW9ucy9lbnRpdHktb3AnO1xuaW1wb3J0IHsgTWVyZ2VTdHJhdGVneSB9IGZyb20gJy4uL2FjdGlvbnMvbWVyZ2Utc3RyYXRlZ3knO1xuaW1wb3J0IHsgVXBkYXRlUmVzcG9uc2VEYXRhIH0gZnJvbSAnLi4vYWN0aW9ucy91cGRhdGUtcmVzcG9uc2UtZGF0YSc7XG5cbi8qKlxuICogTWFwIG9mIHtFbnRpdHlPcH0gdG8gcmVkdWNlciBtZXRob2QgZm9yIHRoZSBvcGVyYXRpb24uXG4gKiBJZiBhbiBvcGVyYXRpb24gaXMgbWlzc2luZywgY2FsbGVyIHNob3VsZCByZXR1cm4gdGhlIGNvbGxlY3Rpb24gZm9yIHRoYXQgcmVkdWNlci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFbnRpdHlDb2xsZWN0aW9uUmVkdWNlck1ldGhvZE1hcDxUPiB7XG4gIFttZXRob2Q6IHN0cmluZ106IChcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uXG4gICkgPT4gRW50aXR5Q29sbGVjdGlvbjxUPjtcbn1cblxuLyoqXG4gKiBCYXNlIGltcGxlbWVudGF0aW9uIG9mIHJlZHVjZXIgbWV0aG9kcyBmb3IgYW4gZW50aXR5IGNvbGxlY3Rpb24uXG4gKi9cbmV4cG9ydCBjbGFzcyBFbnRpdHlDb2xsZWN0aW9uUmVkdWNlck1ldGhvZHM8VD4ge1xuICBwcm90ZWN0ZWQgYWRhcHRlcjogRW50aXR5QWRhcHRlcjxUPjtcbiAgcHJvdGVjdGVkIGd1YXJkOiBFbnRpdHlBY3Rpb25HdWFyZDxUPjtcbiAgLyoqIFRydWUgaWYgdGhpcyBjb2xsZWN0aW9uIHRyYWNrcyB1bnNhdmVkIGNoYW5nZXMgKi9cbiAgcHJvdGVjdGVkIGlzQ2hhbmdlVHJhY2tpbmc6IGJvb2xlYW47XG5cbiAgLyoqIEV4dHJhY3QgdGhlIHByaW1hcnkga2V5IChpZCk7IGRlZmF1bHQgdG8gYGlkYCAqL1xuICBzZWxlY3RJZDogSWRTZWxlY3RvcjxUPjtcblxuICAvKipcbiAgICogVHJhY2sgY2hhbmdlcyB0byBlbnRpdGllcyBzaW5jZSB0aGUgbGFzdCBxdWVyeSBvciBzYXZlXG4gICAqIENhbiByZXZlcnQgc29tZSBvciBhbGwgb2YgdGhvc2UgY2hhbmdlc1xuICAgKi9cbiAgZW50aXR5Q2hhbmdlVHJhY2tlcjogRW50aXR5Q2hhbmdlVHJhY2tlcjxUPjtcblxuICAvKipcbiAgICogQ29udmVydCBhbiBlbnRpdHkgKG9yIHBhcnRpYWwgZW50aXR5KSBpbnRvIHRoZSBgVXBkYXRlPFQ+YCBvYmplY3RcbiAgICogYGlkYDogdGhlIHByaW1hcnkga2V5IGFuZFxuICAgKiBgY2hhbmdlc2A6IHRoZSBlbnRpdHkgKG9yIHBhcnRpYWwgZW50aXR5IG9mIGNoYW5nZXMpLlxuICAgKi9cbiAgcHJvdGVjdGVkIHRvVXBkYXRlOiAoZW50aXR5OiBQYXJ0aWFsPFQ+KSA9PiBVcGRhdGU8VD47XG5cbiAgLyoqXG4gICAqIERpY3Rpb25hcnkgb2YgdGhlIHtFbnRpdHlDb2xsZWN0aW9uUmVkdWNlck1ldGhvZHN9IGZvciB0aGlzIGVudGl0eSB0eXBlLFxuICAgKiBrZXllZCBieSB0aGUge0VudGl0eU9wfVxuICAgKi9cbiAgcmVhZG9ubHkgbWV0aG9kczogRW50aXR5Q29sbGVjdGlvblJlZHVjZXJNZXRob2RNYXA8VD4gPSB7XG4gICAgW0VudGl0eU9wLkNBTkNFTF9QRVJTSVNUXTogdGhpcy5jYW5jZWxQZXJzaXN0LmJpbmQodGhpcyksXG5cbiAgICBbRW50aXR5T3AuUVVFUllfQUxMXTogdGhpcy5xdWVyeUFsbC5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5RVUVSWV9BTExfRVJST1JdOiB0aGlzLnF1ZXJ5QWxsRXJyb3IuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuUVVFUllfQUxMX1NVQ0NFU1NdOiB0aGlzLnF1ZXJ5QWxsU3VjY2Vzcy5iaW5kKHRoaXMpLFxuXG4gICAgW0VudGl0eU9wLlFVRVJZX0JZX0tFWV06IHRoaXMucXVlcnlCeUtleS5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5RVUVSWV9CWV9LRVlfRVJST1JdOiB0aGlzLnF1ZXJ5QnlLZXlFcnJvci5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5RVUVSWV9CWV9LRVlfU1VDQ0VTU106IHRoaXMucXVlcnlCeUtleVN1Y2Nlc3MuYmluZCh0aGlzKSxcblxuICAgIFtFbnRpdHlPcC5RVUVSWV9MT0FEXTogdGhpcy5xdWVyeUxvYWQuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuUVVFUllfTE9BRF9FUlJPUl06IHRoaXMucXVlcnlMb2FkRXJyb3IuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuUVVFUllfTE9BRF9TVUNDRVNTXTogdGhpcy5xdWVyeUxvYWRTdWNjZXNzLmJpbmQodGhpcyksXG5cbiAgICBbRW50aXR5T3AuUVVFUllfTUFOWV06IHRoaXMucXVlcnlNYW55LmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlFVRVJZX01BTllfRVJST1JdOiB0aGlzLnF1ZXJ5TWFueUVycm9yLmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlFVRVJZX01BTllfU1VDQ0VTU106IHRoaXMucXVlcnlNYW55U3VjY2Vzcy5iaW5kKHRoaXMpLFxuXG4gICAgW0VudGl0eU9wLlNBVkVfQUREX01BTlldOiB0aGlzLnNhdmVBZGRNYW55LmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlNBVkVfQUREX01BTllfRVJST1JdOiB0aGlzLnNhdmVBZGRNYW55RXJyb3IuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuU0FWRV9BRERfTUFOWV9TVUNDRVNTXTogdGhpcy5zYXZlQWRkTWFueVN1Y2Nlc3MuYmluZCh0aGlzKSxcblxuICAgIFtFbnRpdHlPcC5TQVZFX0FERF9PTkVdOiB0aGlzLnNhdmVBZGRPbmUuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuU0FWRV9BRERfT05FX0VSUk9SXTogdGhpcy5zYXZlQWRkT25lRXJyb3IuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuU0FWRV9BRERfT05FX1NVQ0NFU1NdOiB0aGlzLnNhdmVBZGRPbmVTdWNjZXNzLmJpbmQodGhpcyksXG5cbiAgICBbRW50aXR5T3AuU0FWRV9ERUxFVEVfTUFOWV06IHRoaXMuc2F2ZURlbGV0ZU1hbnkuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuU0FWRV9ERUxFVEVfTUFOWV9FUlJPUl06IHRoaXMuc2F2ZURlbGV0ZU1hbnlFcnJvci5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5TQVZFX0RFTEVURV9NQU5ZX1NVQ0NFU1NdOiB0aGlzLnNhdmVEZWxldGVNYW55U3VjY2Vzcy5iaW5kKHRoaXMpLFxuXG4gICAgW0VudGl0eU9wLlNBVkVfREVMRVRFX09ORV06IHRoaXMuc2F2ZURlbGV0ZU9uZS5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5TQVZFX0RFTEVURV9PTkVfRVJST1JdOiB0aGlzLnNhdmVEZWxldGVPbmVFcnJvci5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5TQVZFX0RFTEVURV9PTkVfU1VDQ0VTU106IHRoaXMuc2F2ZURlbGV0ZU9uZVN1Y2Nlc3MuYmluZCh0aGlzKSxcblxuICAgIFtFbnRpdHlPcC5TQVZFX1VQREFURV9NQU5ZXTogdGhpcy5zYXZlVXBkYXRlTWFueS5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5TQVZFX1VQREFURV9NQU5ZX0VSUk9SXTogdGhpcy5zYXZlVXBkYXRlTWFueUVycm9yLmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlNBVkVfVVBEQVRFX01BTllfU1VDQ0VTU106IHRoaXMuc2F2ZVVwZGF0ZU1hbnlTdWNjZXNzLmJpbmQodGhpcyksXG5cbiAgICBbRW50aXR5T3AuU0FWRV9VUERBVEVfT05FXTogdGhpcy5zYXZlVXBkYXRlT25lLmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlNBVkVfVVBEQVRFX09ORV9FUlJPUl06IHRoaXMuc2F2ZVVwZGF0ZU9uZUVycm9yLmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlNBVkVfVVBEQVRFX09ORV9TVUNDRVNTXTogdGhpcy5zYXZlVXBkYXRlT25lU3VjY2Vzcy5iaW5kKHRoaXMpLFxuXG4gICAgW0VudGl0eU9wLlNBVkVfVVBTRVJUX01BTlldOiB0aGlzLnNhdmVVcHNlcnRNYW55LmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlNBVkVfVVBTRVJUX01BTllfRVJST1JdOiB0aGlzLnNhdmVVcHNlcnRNYW55RXJyb3IuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuU0FWRV9VUFNFUlRfTUFOWV9TVUNDRVNTXTogdGhpcy5zYXZlVXBzZXJ0TWFueVN1Y2Nlc3MuYmluZCh0aGlzKSxcblxuICAgIFtFbnRpdHlPcC5TQVZFX1VQU0VSVF9PTkVdOiB0aGlzLnNhdmVVcHNlcnRPbmUuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuU0FWRV9VUFNFUlRfT05FX0VSUk9SXTogdGhpcy5zYXZlVXBzZXJ0T25lRXJyb3IuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuU0FWRV9VUFNFUlRfT05FX1NVQ0NFU1NdOiB0aGlzLnNhdmVVcHNlcnRPbmVTdWNjZXNzLmJpbmQodGhpcyksXG5cbiAgICAvLyBEbyBub3RoaW5nIG9uIHNhdmUgZXJyb3JzIGV4Y2VwdCB0dXJuIHRoZSBsb2FkaW5nIGZsYWcgb2ZmLlxuICAgIC8vIFNlZSB0aGUgQ2hhbmdlVHJhY2tlck1ldGFSZWR1Y2Vyc1xuICAgIC8vIE9yIHRoZSBhcHAgY291bGQgbGlzdGVuIGZvciB0aG9zZSBlcnJvcnMgYW5kIGRvIHNvbWV0aGluZ1xuXG4gICAgLy8vIGNhY2hlIG9ubHkgb3BlcmF0aW9ucyAvLy9cblxuICAgIFtFbnRpdHlPcC5BRERfQUxMXTogdGhpcy5hZGRBbGwuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuQUREX01BTlldOiB0aGlzLmFkZE1hbnkuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuQUREX09ORV06IHRoaXMuYWRkT25lLmJpbmQodGhpcyksXG5cbiAgICBbRW50aXR5T3AuUkVNT1ZFX0FMTF06IHRoaXMucmVtb3ZlQWxsLmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlJFTU9WRV9NQU5ZXTogdGhpcy5yZW1vdmVNYW55LmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlJFTU9WRV9PTkVdOiB0aGlzLnJlbW92ZU9uZS5iaW5kKHRoaXMpLFxuXG4gICAgW0VudGl0eU9wLlVQREFURV9NQU5ZXTogdGhpcy51cGRhdGVNYW55LmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlVQREFURV9PTkVdOiB0aGlzLnVwZGF0ZU9uZS5iaW5kKHRoaXMpLFxuXG4gICAgW0VudGl0eU9wLlVQU0VSVF9NQU5ZXTogdGhpcy51cHNlcnRNYW55LmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlVQU0VSVF9PTkVdOiB0aGlzLnVwc2VydE9uZS5iaW5kKHRoaXMpLFxuXG4gICAgW0VudGl0eU9wLkNPTU1JVF9BTExdOiB0aGlzLmNvbW1pdEFsbC5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5DT01NSVRfTUFOWV06IHRoaXMuY29tbWl0TWFueS5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5DT01NSVRfT05FXTogdGhpcy5jb21taXRPbmUuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuVU5ET19BTExdOiB0aGlzLnVuZG9BbGwuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuVU5ET19NQU5ZXTogdGhpcy51bmRvTWFueS5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5VTkRPX09ORV06IHRoaXMudW5kb09uZS5iaW5kKHRoaXMpLFxuXG4gICAgW0VudGl0eU9wLlNFVF9DSEFOR0VfU1RBVEVdOiB0aGlzLnNldENoYW5nZVN0YXRlLmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlNFVF9DT0xMRUNUSU9OXTogdGhpcy5zZXRDb2xsZWN0aW9uLmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlNFVF9GSUxURVJdOiB0aGlzLnNldEZpbHRlci5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5TRVRfTE9BREVEXTogdGhpcy5zZXRMb2FkZWQuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuU0VUX0xPQURJTkddOiB0aGlzLnNldExvYWRpbmcuYmluZCh0aGlzKSxcbiAgfTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgZW50aXR5TmFtZTogc3RyaW5nLFxuICAgIHB1YmxpYyBkZWZpbml0aW9uOiBFbnRpdHlEZWZpbml0aW9uPFQ+LFxuICAgIC8qXG4gICAgICogVHJhY2sgY2hhbmdlcyB0byBlbnRpdGllcyBzaW5jZSB0aGUgbGFzdCBxdWVyeSBvciBzYXZlXG4gICAgICogQ2FuIHJldmVydCBzb21lIG9yIGFsbCBvZiB0aG9zZSBjaGFuZ2VzXG4gICAgICovXG4gICAgZW50aXR5Q2hhbmdlVHJhY2tlcj86IEVudGl0eUNoYW5nZVRyYWNrZXI8VD5cbiAgKSB7XG4gICAgdGhpcy5hZGFwdGVyID0gZGVmaW5pdGlvbi5lbnRpdHlBZGFwdGVyO1xuICAgIHRoaXMuaXNDaGFuZ2VUcmFja2luZyA9IGRlZmluaXRpb24ubm9DaGFuZ2VUcmFja2luZyAhPT0gdHJ1ZTtcbiAgICB0aGlzLnNlbGVjdElkID0gZGVmaW5pdGlvbi5zZWxlY3RJZDtcblxuICAgIHRoaXMuZ3VhcmQgPSBuZXcgRW50aXR5QWN0aW9uR3VhcmQoZW50aXR5TmFtZSwgdGhpcy5zZWxlY3RJZCk7XG4gICAgdGhpcy50b1VwZGF0ZSA9IHRvVXBkYXRlRmFjdG9yeSh0aGlzLnNlbGVjdElkKTtcblxuICAgIHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlciA9XG4gICAgICBlbnRpdHlDaGFuZ2VUcmFja2VyIHx8XG4gICAgICBuZXcgRW50aXR5Q2hhbmdlVHJhY2tlckJhc2U8VD4odGhpcy5hZGFwdGVyLCB0aGlzLnNlbGVjdElkKTtcbiAgfVxuXG4gIC8qKiBDYW5jZWwgYSBwZXJzaXN0ZW5jZSBvcGVyYXRpb24gKi9cbiAgcHJvdGVjdGVkIGNhbmNlbFBlcnNpc3QoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cblxuICAvLyAjcmVnaW9uIHF1ZXJ5IG9wZXJhdGlvbnNcblxuICBwcm90ZWN0ZWQgcXVlcnlBbGwoY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPik6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdUcnVlKGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHF1ZXJ5QWxsRXJyb3IoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxFbnRpdHlBY3Rpb25EYXRhU2VydmljZUVycm9yPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogTWVyZ2VzIHF1ZXJ5IHJlc3VsdHMgcGVyIHRoZSBNZXJnZVN0cmF0ZWd5XG4gICAqIFNldHMgbG9hZGluZyBmbGFnIHRvIGZhbHNlIGFuZCBsb2FkZWQgZmxhZyB0byB0cnVlLlxuICAgKi9cbiAgcHJvdGVjdGVkIHF1ZXJ5QWxsU3VjY2VzcyhcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFRbXT5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgY29uc3QgZGF0YSA9IHRoaXMuZXh0cmFjdERhdGEoYWN0aW9uKTtcbiAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgIHJldHVybiB7XG4gICAgICAuLi50aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIubWVyZ2VRdWVyeVJlc3VsdHMoXG4gICAgICAgIGRhdGEsXG4gICAgICAgIGNvbGxlY3Rpb24sXG4gICAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICAgICksXG4gICAgICBsb2FkZWQ6IHRydWUsXG4gICAgICBsb2FkaW5nOiBmYWxzZSxcbiAgICB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIHF1ZXJ5QnlLZXkoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxudW1iZXIgfCBzdHJpbmc+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdUcnVlKGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHF1ZXJ5QnlLZXlFcnJvcihcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPEVudGl0eUFjdGlvbkRhdGFTZXJ2aWNlRXJyb3I+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGYWxzZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBxdWVyeUJ5S2V5U3VjY2VzcyhcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFQ+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLmV4dHJhY3REYXRhKGFjdGlvbik7XG4gICAgY29uc3QgbWVyZ2VTdHJhdGVneSA9IHRoaXMuZXh0cmFjdE1lcmdlU3RyYXRlZ3koYWN0aW9uKTtcbiAgICBjb2xsZWN0aW9uID1cbiAgICAgIGRhdGEgPT0gbnVsbFxuICAgICAgICA/IGNvbGxlY3Rpb25cbiAgICAgICAgOiB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIubWVyZ2VRdWVyeVJlc3VsdHMoXG4gICAgICAgICAgICBbZGF0YV0sXG4gICAgICAgICAgICBjb2xsZWN0aW9uLFxuICAgICAgICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICAgICAgICk7XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ0ZhbHNlKGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHF1ZXJ5TG9hZChjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+KTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ1RydWUoY29sbGVjdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgcXVlcnlMb2FkRXJyb3IoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxFbnRpdHlBY3Rpb25EYXRhU2VydmljZUVycm9yPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogUmVwbGFjZXMgYWxsIGVudGl0aWVzIGluIHRoZSBjb2xsZWN0aW9uXG4gICAqIFNldHMgbG9hZGVkIGZsYWcgdG8gdHJ1ZSwgbG9hZGluZyBmbGFnIHRvIGZhbHNlLFxuICAgKiBhbmQgY2xlYXJzIGNoYW5nZVN0YXRlIGZvciB0aGUgZW50aXJlIGNvbGxlY3Rpb24uXG4gICAqL1xuICBwcm90ZWN0ZWQgcXVlcnlMb2FkU3VjY2VzcyhcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFRbXT5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgY29uc3QgZGF0YSA9IHRoaXMuZXh0cmFjdERhdGEoYWN0aW9uKTtcbiAgICByZXR1cm4ge1xuICAgICAgLi4udGhpcy5hZGFwdGVyLnNldEFsbChkYXRhLCBjb2xsZWN0aW9uKSxcbiAgICAgIGxvYWRpbmc6IGZhbHNlLFxuICAgICAgbG9hZGVkOiB0cnVlLFxuICAgICAgY2hhbmdlU3RhdGU6IHt9LFxuICAgIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgcXVlcnlNYW55KFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb25cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ1RydWUoY29sbGVjdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgcXVlcnlNYW55RXJyb3IoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxFbnRpdHlBY3Rpb25EYXRhU2VydmljZUVycm9yPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgcXVlcnlNYW55U3VjY2VzcyhcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFRbXT5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgY29uc3QgZGF0YSA9IHRoaXMuZXh0cmFjdERhdGEoYWN0aW9uKTtcbiAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgIHJldHVybiB7XG4gICAgICAuLi50aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIubWVyZ2VRdWVyeVJlc3VsdHMoXG4gICAgICAgIGRhdGEsXG4gICAgICAgIGNvbGxlY3Rpb24sXG4gICAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICAgICksXG4gICAgICBsb2FkaW5nOiBmYWxzZSxcbiAgICB9O1xuICB9XG4gIC8vICNlbmRyZWdpb24gcXVlcnkgb3BlcmF0aW9uc1xuXG4gIC8vICNyZWdpb24gc2F2ZSBvcGVyYXRpb25zXG5cbiAgLy8gI3JlZ2lvbiBzYXZlQWRkTWFueVxuICAvKipcbiAgICogU2F2ZSBtdWx0aXBsZSBuZXcgZW50aXRpZXMuXG4gICAqIElmIHNhdmluZyBwZXNzaW1pc3RpY2FsbHksIGRlbGF5IGFkZGluZyB0byBjb2xsZWN0aW9uIHVudGlsIHNlcnZlciBhY2tub3dsZWRnZXMgc3VjY2Vzcy5cbiAgICogSWYgc2F2aW5nIG9wdGltaXN0aWNhbGx5OyBhZGQgaW1tZWRpYXRlbHkuXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHdoaWNoIHRoZSBlbnRpdGllcyBzaG91bGQgYmUgYWRkZWQuXG4gICAqIEBwYXJhbSBhY3Rpb24gVGhlIGFjdGlvbiBwYXlsb2FkIGhvbGRzIG9wdGlvbnMsIGluY2x1ZGluZyB3aGV0aGVyIHRoZSBzYXZlIGlzIG9wdGltaXN0aWMsXG4gICAqIGFuZCB0aGUgZGF0YSwgd2hpY2ggbXVzdCBiZSBhbiBhcnJheSBvZiBlbnRpdGllcy5cbiAgICogSWYgc2F2aW5nIG9wdGltaXN0aWNhbGx5LCB0aGUgZW50aXRpZXMgbXVzdCBoYXZlIHRoZWlyIGtleXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZUFkZE1hbnkoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxUW10+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIGlmICh0aGlzLmlzT3B0aW1pc3RpYyhhY3Rpb24pKSB7XG4gICAgICBjb25zdCBlbnRpdGllcyA9IHRoaXMuZ3VhcmQubXVzdEJlRW50aXRpZXMoYWN0aW9uKTsgLy8gZW5zdXJlIHRoZSBlbnRpdHkgaGFzIGEgUEtcbiAgICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLnRyYWNrQWRkTWFueShcbiAgICAgICAgZW50aXRpZXMsXG4gICAgICAgIGNvbGxlY3Rpb24sXG4gICAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICAgICk7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5hZGFwdGVyLmFkZE1hbnkoZW50aXRpZXMsIGNvbGxlY3Rpb24pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nVHJ1ZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBdHRlbXB0IHRvIHNhdmUgbmV3IGVudGl0aWVzIGZhaWxlZCBvciB0aW1lZC1vdXQuXG4gICAqIEFjdGlvbiBob2xkcyB0aGUgZXJyb3IuXG4gICAqIElmIHNhdmVkIHBlc3NpbWlzdGljYWxseSwgbmV3IGVudGl0aWVzIGFyZSBub3QgaW4gdGhlIGNvbGxlY3Rpb24gYW5kXG4gICAqIHlvdSBtYXkgbm90IGhhdmUgdG8gY29tcGVuc2F0ZSBmb3IgdGhlIGVycm9yLlxuICAgKiBJZiBzYXZlZCBvcHRpbWlzdGljYWxseSwgdGhlIHVuc2F2ZWQgZW50aXRpZXMgYXJlIGluIHRoZSBjb2xsZWN0aW9uIGFuZFxuICAgKiB5b3UgbWF5IG5lZWQgdG8gY29tcGVuc2F0ZSBmb3IgdGhlIGVycm9yLlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVBZGRNYW55RXJyb3IoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxFbnRpdHlBY3Rpb25EYXRhU2VydmljZUVycm9yPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cbiAgLy8gI2VuZHJlZ2lvbiBzYXZlQWRkTWFueVxuXG4gIC8vICNyZWdpb24gc2F2ZUFkZE9uZVxuICAvKipcbiAgICogU3VjY2Vzc2Z1bGx5IHNhdmVkIG5ldyBlbnRpdGllcyB0byB0aGUgc2VydmVyLlxuICAgKiBJZiBzYXZlZCBwZXNzaW1pc3RpY2FsbHksIGFkZCB0aGUgZW50aXRpZXMgZnJvbSB0aGUgc2VydmVyIHRvIHRoZSBjb2xsZWN0aW9uLlxuICAgKiBJZiBzYXZlZCBvcHRpbWlzdGljYWxseSwgdGhlIGFkZGVkIGVudGl0aWVzIGFyZSBhbHJlYWR5IGluIHRoZSBjb2xsZWN0aW9uLlxuICAgKiBIb3dldmVyLCB0aGUgc2VydmVyIG1pZ2h0IGhhdmUgc2V0IG9yIG1vZGlmaWVkIG90aGVyIGZpZWxkcyAoZS5nLCBjb25jdXJyZW5jeSBmaWVsZCksXG4gICAqIGFuZCBtYXkgZXZlbiByZXR1cm4gYWRkaXRpb25hbCBuZXcgZW50aXRpZXMuXG4gICAqIFRoZXJlZm9yZSwgdXBzZXJ0IHRoZSBlbnRpdGllcyBpbiB0aGUgY29sbGVjdGlvbiB3aXRoIHRoZSByZXR1cm5lZCB2YWx1ZXMgKGlmIGFueSlcbiAgICogQ2F1dGlvbjogaW4gYSByYWNlLCB0aGlzIHVwZGF0ZSBjb3VsZCBvdmVyd3JpdGUgdW5zYXZlZCB1c2VyIGNoYW5nZXMuXG4gICAqIFVzZSBwZXNzaW1pc3RpYyBhZGQgdG8gYXZvaWQgdGhpcyByaXNrLlxuICAgKiBOb3RlOiBzYXZlQWRkTWFueVN1Y2Nlc3MgZGlmZmVycyBmcm9tIHNhdmVBZGRPbmVTdWNjZXNzIHdoZW4gb3B0aW1pc3RpYy5cbiAgICogc2F2ZUFkZE9uZVN1Y2Nlc3MgdXBkYXRlcyAobm90IHVwc2VydHMpIHdpdGggdGhlIGxvbmUgZW50aXR5IGZyb20gdGhlIHNlcnZlci5cbiAgICogVGhlcmUgaXMgbm8gZWZmZWN0IGlmIHRoZSBlbnRpdHkgaXMgbm90IGFscmVhZHkgaW4gY2FjaGUuXG4gICAqIHNhdmVBZGRNYW55U3VjY2VzcyB3aWxsIGFkZCBhbiBlbnRpdHkgaWYgaXQgaXMgbm90IGZvdW5kIGluIGNhY2hlLlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVBZGRNYW55U3VjY2VzcyhcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFRbXT5cbiAgKSB7XG4gICAgLy8gRm9yIHBlc3NpbWlzdGljIHNhdmUsIGVuc3VyZSB0aGUgc2VydmVyIGdlbmVyYXRlZCB0aGUgcHJpbWFyeSBrZXkgaWYgdGhlIGNsaWVudCBkaWRuJ3Qgc2VuZCBvbmUuXG4gICAgY29uc3QgZW50aXRpZXMgPSB0aGlzLmd1YXJkLm11c3RCZUVudGl0aWVzKGFjdGlvbik7XG4gICAgY29uc3QgbWVyZ2VTdHJhdGVneSA9IHRoaXMuZXh0cmFjdE1lcmdlU3RyYXRlZ3koYWN0aW9uKTtcbiAgICBpZiAodGhpcy5pc09wdGltaXN0aWMoYWN0aW9uKSkge1xuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5tZXJnZVNhdmVVcHNlcnRzKFxuICAgICAgICBlbnRpdGllcyxcbiAgICAgICAgY29sbGVjdGlvbixcbiAgICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5tZXJnZVNhdmVBZGRzKFxuICAgICAgICBlbnRpdGllcyxcbiAgICAgICAgY29sbGVjdGlvbixcbiAgICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ0ZhbHNlKGNvbGxlY3Rpb24pO1xuICB9XG4gIC8vICNlbmRyZWdpb24gc2F2ZUFkZE1hbnlcblxuICAvLyAjcmVnaW9uIHNhdmVBZGRPbmVcbiAgLyoqXG4gICAqIFNhdmUgYSBuZXcgZW50aXR5LlxuICAgKiBJZiBzYXZpbmcgcGVzc2ltaXN0aWNhbGx5LCBkZWxheSBhZGRpbmcgdG8gY29sbGVjdGlvbiB1bnRpbCBzZXJ2ZXIgYWNrbm93bGVkZ2VzIHN1Y2Nlc3MuXG4gICAqIElmIHNhdmluZyBvcHRpbWlzdGljYWxseTsgYWRkIGVudGl0eSBpbW1lZGlhdGVseS5cbiAgICogQHBhcmFtIGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gd2hpY2ggdGhlIGVudGl0eSBzaG91bGQgYmUgYWRkZWQuXG4gICAqIEBwYXJhbSBhY3Rpb24gVGhlIGFjdGlvbiBwYXlsb2FkIGhvbGRzIG9wdGlvbnMsIGluY2x1ZGluZyB3aGV0aGVyIHRoZSBzYXZlIGlzIG9wdGltaXN0aWMsXG4gICAqIGFuZCB0aGUgZGF0YSwgd2hpY2ggbXVzdCBiZSBhbiBlbnRpdHkuXG4gICAqIElmIHNhdmluZyBvcHRpbWlzdGljYWxseSwgdGhlIGVudGl0eSBtdXN0IGhhdmUgYSBrZXkuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZUFkZE9uZShcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFQ+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIGlmICh0aGlzLmlzT3B0aW1pc3RpYyhhY3Rpb24pKSB7XG4gICAgICBjb25zdCBlbnRpdHkgPSB0aGlzLmd1YXJkLm11c3RCZUVudGl0eShhY3Rpb24pOyAvLyBlbnN1cmUgdGhlIGVudGl0eSBoYXMgYSBQS1xuICAgICAgY29uc3QgbWVyZ2VTdHJhdGVneSA9IHRoaXMuZXh0cmFjdE1lcmdlU3RyYXRlZ3koYWN0aW9uKTtcbiAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIudHJhY2tBZGRPbmUoXG4gICAgICAgIGVudGl0eSxcbiAgICAgICAgY29sbGVjdGlvbixcbiAgICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICAgKTtcbiAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmFkYXB0ZXIuYWRkT25lKGVudGl0eSwgY29sbGVjdGlvbik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdUcnVlKGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dGVtcHQgdG8gc2F2ZSBhIG5ldyBlbnRpdHkgZmFpbGVkIG9yIHRpbWVkLW91dC5cbiAgICogQWN0aW9uIGhvbGRzIHRoZSBlcnJvci5cbiAgICogSWYgc2F2ZWQgcGVzc2ltaXN0aWNhbGx5LCB0aGUgZW50aXR5IGlzIG5vdCBpbiB0aGUgY29sbGVjdGlvbiBhbmRcbiAgICogeW91IG1heSBub3QgaGF2ZSB0byBjb21wZW5zYXRlIGZvciB0aGUgZXJyb3IuXG4gICAqIElmIHNhdmVkIG9wdGltaXN0aWNhbGx5LCB0aGUgdW5zYXZlZCBlbnRpdHkgaXMgaW4gdGhlIGNvbGxlY3Rpb24gYW5kXG4gICAqIHlvdSBtYXkgbmVlZCB0byBjb21wZW5zYXRlIGZvciB0aGUgZXJyb3IuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZUFkZE9uZUVycm9yKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248RW50aXR5QWN0aW9uRGF0YVNlcnZpY2VFcnJvcj5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ0ZhbHNlKGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIFN1Y2Nlc3NmdWxseSBzYXZlZCBhIG5ldyBlbnRpdHkgdG8gdGhlIHNlcnZlci5cbiAgICogSWYgc2F2ZWQgcGVzc2ltaXN0aWNhbGx5LCBhZGQgdGhlIGVudGl0eSBmcm9tIHRoZSBzZXJ2ZXIgdG8gdGhlIGNvbGxlY3Rpb24uXG4gICAqIElmIHNhdmVkIG9wdGltaXN0aWNhbGx5LCB0aGUgYWRkZWQgZW50aXR5IGlzIGFscmVhZHkgaW4gdGhlIGNvbGxlY3Rpb24uXG4gICAqIEhvd2V2ZXIsIHRoZSBzZXJ2ZXIgbWlnaHQgaGF2ZSBzZXQgb3IgbW9kaWZpZWQgb3RoZXIgZmllbGRzIChlLmcsIGNvbmN1cnJlbmN5IGZpZWxkKVxuICAgKiBUaGVyZWZvcmUsIHVwZGF0ZSB0aGUgZW50aXR5IGluIHRoZSBjb2xsZWN0aW9uIHdpdGggdGhlIHJldHVybmVkIHZhbHVlIChpZiBhbnkpXG4gICAqIENhdXRpb246IGluIGEgcmFjZSwgdGhpcyB1cGRhdGUgY291bGQgb3ZlcndyaXRlIHVuc2F2ZWQgdXNlciBjaGFuZ2VzLlxuICAgKiBVc2UgcGVzc2ltaXN0aWMgYWRkIHRvIGF2b2lkIHRoaXMgcmlzay5cbiAgICovXG4gIHByb3RlY3RlZCBzYXZlQWRkT25lU3VjY2VzcyhcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFQ+XG4gICkge1xuICAgIC8vIEZvciBwZXNzaW1pc3RpYyBzYXZlLCBlbnN1cmUgdGhlIHNlcnZlciBnZW5lcmF0ZWQgdGhlIHByaW1hcnkga2V5IGlmIHRoZSBjbGllbnQgZGlkbid0IHNlbmQgb25lLlxuICAgIGNvbnN0IGVudGl0eSA9IHRoaXMuZ3VhcmQubXVzdEJlRW50aXR5KGFjdGlvbik7XG4gICAgY29uc3QgbWVyZ2VTdHJhdGVneSA9IHRoaXMuZXh0cmFjdE1lcmdlU3RyYXRlZ3koYWN0aW9uKTtcbiAgICBpZiAodGhpcy5pc09wdGltaXN0aWMoYWN0aW9uKSkge1xuICAgICAgY29uc3QgdXBkYXRlOiBVcGRhdGVSZXNwb25zZURhdGE8VD4gPSB0aGlzLnRvVXBkYXRlKGVudGl0eSk7XG4gICAgICAvLyBBbHdheXMgdXBkYXRlIHRoZSBjYWNoZSB3aXRoIGFkZGVkIGVudGl0eSByZXR1cm5lZCBmcm9tIHNlcnZlclxuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5tZXJnZVNhdmVVcGRhdGVzKFxuICAgICAgICBbdXBkYXRlXSxcbiAgICAgICAgY29sbGVjdGlvbixcbiAgICAgICAgbWVyZ2VTdHJhdGVneSxcbiAgICAgICAgZmFsc2UgLypuZXZlciBza2lwKi9cbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIubWVyZ2VTYXZlQWRkcyhcbiAgICAgICAgW2VudGl0eV0sXG4gICAgICAgIGNvbGxlY3Rpb24sXG4gICAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGYWxzZShjb2xsZWN0aW9uKTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uIHNhdmVBZGRPbmVcblxuICAvLyAjcmVnaW9uIHNhdmVBZGRNYW55XG4gIC8vIFRPRE8gTUFOWVxuICAvLyAjZW5kcmVnaW9uIHNhdmVBZGRNYW55XG5cbiAgLy8gI3JlZ2lvbiBzYXZlRGVsZXRlT25lXG4gIC8qKlxuICAgKiBEZWxldGUgYW4gZW50aXR5IGZyb20gdGhlIHNlcnZlciBieSBrZXkgYW5kIHJlbW92ZSBpdCBmcm9tIHRoZSBjb2xsZWN0aW9uIChpZiBwcmVzZW50KS5cbiAgICogSWYgdGhlIGVudGl0eSBpcyBhbiB1bnNhdmVkIG5ldyBlbnRpdHksIHJlbW92ZSBpdCBmcm9tIHRoZSBjb2xsZWN0aW9uIGltbWVkaWF0ZWx5XG4gICAqIGFuZCBza2lwIHRoZSBzZXJ2ZXIgZGVsZXRlIHJlcXVlc3QuXG4gICAqIEFuIG9wdGltaXN0aWMgc2F2ZSByZW1vdmVzIGFuIGV4aXN0aW5nIGVudGl0eSBmcm9tIHRoZSBjb2xsZWN0aW9uIGltbWVkaWF0ZWx5O1xuICAgKiBhIHBlc3NpbWlzdGljIHNhdmUgcmVtb3ZlcyBpdCBhZnRlciB0aGUgc2VydmVyIGNvbmZpcm1zIHN1Y2Nlc3NmdWwgZGVsZXRlLlxuICAgKiBAcGFyYW0gY29sbGVjdGlvbiBXaWxsIHJlbW92ZSB0aGUgZW50aXR5IHdpdGggdGhpcyBrZXkgZnJvbSB0aGUgY29sbGVjdGlvbi5cbiAgICogQHBhcmFtIGFjdGlvbiBUaGUgYWN0aW9uIHBheWxvYWQgaG9sZHMgb3B0aW9ucywgaW5jbHVkaW5nIHdoZXRoZXIgdGhlIHNhdmUgaXMgb3B0aW1pc3RpYyxcbiAgICogYW5kIHRoZSBkYXRhLCB3aGljaCBtdXN0IGJlIGEgcHJpbWFyeSBrZXkgb3IgYW4gZW50aXR5IHdpdGggYSBrZXk7XG4gICAqIHRoaXMgcmVkdWNlciBleHRyYWN0cyB0aGUga2V5IGZyb20gdGhlIGVudGl0eS5cbiAgICovXG4gIHByb3RlY3RlZCBzYXZlRGVsZXRlT25lKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248bnVtYmVyIHwgc3RyaW5nIHwgVD5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgY29uc3QgdG9EZWxldGUgPSB0aGlzLmV4dHJhY3REYXRhKGFjdGlvbik7XG4gICAgY29uc3QgZGVsZXRlSWQgPVxuICAgICAgdHlwZW9mIHRvRGVsZXRlID09PSAnb2JqZWN0J1xuICAgICAgICA/IHRoaXMuc2VsZWN0SWQodG9EZWxldGUpXG4gICAgICAgIDogKHRvRGVsZXRlIGFzIHN0cmluZyB8IG51bWJlcik7XG4gICAgY29uc3QgY2hhbmdlID0gY29sbGVjdGlvbi5jaGFuZ2VTdGF0ZVtkZWxldGVJZF07XG4gICAgLy8gSWYgZW50aXR5IGlzIGFscmVhZHkgdHJhY2tlZCAuLi5cbiAgICBpZiAoY2hhbmdlKSB7XG4gICAgICBpZiAoY2hhbmdlLmNoYW5nZVR5cGUgPT09IENoYW5nZVR5cGUuQWRkZWQpIHtcbiAgICAgICAgLy8gUmVtb3ZlIHRoZSBhZGRlZCBlbnRpdHkgaW1tZWRpYXRlbHkgYW5kIGZvcmdldCBhYm91dCBpdHMgY2hhbmdlcyAodmlhIGNvbW1pdCkuXG4gICAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmFkYXB0ZXIucmVtb3ZlT25lKGRlbGV0ZUlkIGFzIHN0cmluZywgY29sbGVjdGlvbik7XG4gICAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIuY29tbWl0T25lKGRlbGV0ZUlkLCBjb2xsZWN0aW9uKTtcbiAgICAgICAgLy8gU2hvdWxkIG5vdCB3YXN0ZSBlZmZvcnQgdHJ5aW5nIHRvIGRlbGV0ZSBvbiB0aGUgc2VydmVyIGJlY2F1c2UgaXQgY2FuJ3QgYmUgdGhlcmUuXG4gICAgICAgIGFjdGlvbi5wYXlsb2FkLnNraXAgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gUmUtdHJhY2sgaXQgYXMgYSBkZWxldGUsIGV2ZW4gaWYgdHJhY2tpbmcgaXMgdHVybmVkIG9mZiBmb3IgdGhpcyBjYWxsLlxuICAgICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLnRyYWNrRGVsZXRlT25lKFxuICAgICAgICAgIGRlbGV0ZUlkLFxuICAgICAgICAgIGNvbGxlY3Rpb25cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBJZiBvcHRpbWlzdGljIGRlbGV0ZSwgdHJhY2sgY3VycmVudCBzdGF0ZSBhbmQgcmVtb3ZlIGltbWVkaWF0ZWx5LlxuICAgIGlmICh0aGlzLmlzT3B0aW1pc3RpYyhhY3Rpb24pKSB7XG4gICAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci50cmFja0RlbGV0ZU9uZShcbiAgICAgICAgZGVsZXRlSWQsXG4gICAgICAgIGNvbGxlY3Rpb24sXG4gICAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICAgICk7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5hZGFwdGVyLnJlbW92ZU9uZShkZWxldGVJZCBhcyBzdHJpbmcsIGNvbGxlY3Rpb24pO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdUcnVlKGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dGVtcHQgdG8gZGVsZXRlIHRoZSBlbnRpdHkgb24gdGhlIHNlcnZlciBmYWlsZWQgb3IgdGltZWQtb3V0LlxuICAgKiBBY3Rpb24gaG9sZHMgdGhlIGVycm9yLlxuICAgKiBJZiBzYXZlZCBwZXNzaW1pc3RpY2FsbHksIHRoZSBlbnRpdHkgY291bGQgc3RpbGwgYmUgaW4gdGhlIGNvbGxlY3Rpb24gYW5kXG4gICAqIHlvdSBtYXkgbm90IGhhdmUgdG8gY29tcGVuc2F0ZSBmb3IgdGhlIGVycm9yLlxuICAgKiBJZiBzYXZlZCBvcHRpbWlzdGljYWxseSwgdGhlIGVudGl0eSBpcyBub3QgaW4gdGhlIGNvbGxlY3Rpb24gYW5kXG4gICAqIHlvdSBtYXkgbmVlZCB0byBjb21wZW5zYXRlIGZvciB0aGUgZXJyb3IuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZURlbGV0ZU9uZUVycm9yKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248RW50aXR5QWN0aW9uRGF0YVNlcnZpY2VFcnJvcj5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ0ZhbHNlKGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIFN1Y2Nlc3NmdWxseSBkZWxldGVkIGVudGl0eSBvbiB0aGUgc2VydmVyLiBUaGUga2V5IG9mIHRoZSBkZWxldGVkIGVudGl0eSBpcyBpbiB0aGUgYWN0aW9uIHBheWxvYWQgZGF0YS5cbiAgICogSWYgc2F2ZWQgcGVzc2ltaXN0aWNhbGx5LCBpZiB0aGUgZW50aXR5IGlzIHN0aWxsIGluIHRoZSBjb2xsZWN0aW9uIGl0IHdpbGwgYmUgcmVtb3ZlZC5cbiAgICogSWYgc2F2ZWQgb3B0aW1pc3RpY2FsbHksIHRoZSBlbnRpdHkgaGFzIGFscmVhZHkgYmVlbiByZW1vdmVkIGZyb20gdGhlIGNvbGxlY3Rpb24uXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZURlbGV0ZU9uZVN1Y2Nlc3MoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxudW1iZXIgfCBzdHJpbmc+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIGNvbnN0IGRlbGV0ZUlkID0gdGhpcy5leHRyYWN0RGF0YShhY3Rpb24pO1xuICAgIGlmICh0aGlzLmlzT3B0aW1pc3RpYyhhY3Rpb24pKSB7XG4gICAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5tZXJnZVNhdmVEZWxldGVzKFxuICAgICAgICBbZGVsZXRlSWRdLFxuICAgICAgICBjb2xsZWN0aW9uLFxuICAgICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBQZXNzaW1pc3RpYzogaWdub3JlIG1lcmdlU3RyYXRlZ3kuIFJlbW92ZSBlbnRpdHkgZnJvbSB0aGUgY29sbGVjdGlvbiBhbmQgZnJvbSBjaGFuZ2UgdHJhY2tpbmcuXG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5hZGFwdGVyLnJlbW92ZU9uZShkZWxldGVJZCBhcyBzdHJpbmcsIGNvbGxlY3Rpb24pO1xuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5jb21taXRPbmUoZGVsZXRlSWQsIGNvbGxlY3Rpb24pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cbiAgLy8gI2VuZHJlZ2lvbiBzYXZlRGVsZXRlT25lXG5cbiAgLy8gI3JlZ2lvbiBzYXZlRGVsZXRlTWFueVxuICAvKipcbiAgICogRGVsZXRlIG11bHRpcGxlIGVudGl0aWVzIGZyb20gdGhlIHNlcnZlciBieSBrZXkgYW5kIHJlbW92ZSB0aGVtIGZyb20gdGhlIGNvbGxlY3Rpb24gKGlmIHByZXNlbnQpLlxuICAgKiBSZW1vdmVzIHVuc2F2ZWQgbmV3IGVudGl0aWVzIGZyb20gdGhlIGNvbGxlY3Rpb24gaW1tZWRpYXRlbHlcbiAgICogYnV0IHRoZSBpZCBpcyBzdGlsbCBzZW50IHRvIHRoZSBzZXJ2ZXIgZm9yIGRlbGV0aW9uIGV2ZW4gdGhvdWdoIHRoZSBzZXJ2ZXIgd2lsbCBub3QgZmluZCB0aGF0IGVudGl0eS5cbiAgICogVGhlcmVmb3JlLCB0aGUgc2VydmVyIG11c3QgYmUgd2lsbGluZyB0byBpZ25vcmUgYSBkZWxldGUgcmVxdWVzdCBmb3IgYW4gZW50aXR5IGl0IGNhbm5vdCBmaW5kLlxuICAgKiBBbiBvcHRpbWlzdGljIHNhdmUgcmVtb3ZlcyBleGlzdGluZyBlbnRpdGllcyBmcm9tIHRoZSBjb2xsZWN0aW9uIGltbWVkaWF0ZWx5O1xuICAgKiBhIHBlc3NpbWlzdGljIHNhdmUgcmVtb3ZlcyB0aGVtIGFmdGVyIHRoZSBzZXJ2ZXIgY29uZmlybXMgc3VjY2Vzc2Z1bCBkZWxldGUuXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFJlbW92ZXMgZW50aXRpZXMgZnJvbSB0aGlzIGNvbGxlY3Rpb24uXG4gICAqIEBwYXJhbSBhY3Rpb24gVGhlIGFjdGlvbiBwYXlsb2FkIGhvbGRzIG9wdGlvbnMsIGluY2x1ZGluZyB3aGV0aGVyIHRoZSBzYXZlIGlzIG9wdGltaXN0aWMsXG4gICAqIGFuZCB0aGUgZGF0YSwgd2hpY2ggbXVzdCBiZSBhbiBhcnJheSBvZiBwcmltYXJ5IGtleXMgb3IgZW50aXRpZXMgd2l0aCBhIGtleTtcbiAgICogdGhpcyByZWR1Y2VyIGV4dHJhY3RzIHRoZSBrZXkgZnJvbSB0aGUgZW50aXR5LlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVEZWxldGVNYW55KFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248KG51bWJlciB8IHN0cmluZyB8IFQpW10+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIGNvbnN0IGRlbGV0ZUlkcyA9IHRoaXMuZXh0cmFjdERhdGEoYWN0aW9uKS5tYXAoKGQpID0+XG4gICAgICB0eXBlb2YgZCA9PT0gJ29iamVjdCcgPyB0aGlzLnNlbGVjdElkKGQpIDogKGQgYXMgc3RyaW5nIHwgbnVtYmVyKVxuICAgICk7XG4gICAgZGVsZXRlSWRzLmZvckVhY2goKGRlbGV0ZUlkKSA9PiB7XG4gICAgICBjb25zdCBjaGFuZ2UgPSBjb2xsZWN0aW9uLmNoYW5nZVN0YXRlW2RlbGV0ZUlkXTtcbiAgICAgIC8vIElmIGVudGl0eSBpcyBhbHJlYWR5IHRyYWNrZWQgLi4uXG4gICAgICBpZiAoY2hhbmdlKSB7XG4gICAgICAgIGlmIChjaGFuZ2UuY2hhbmdlVHlwZSA9PT0gQ2hhbmdlVHlwZS5BZGRlZCkge1xuICAgICAgICAgIC8vIFJlbW92ZSB0aGUgYWRkZWQgZW50aXR5IGltbWVkaWF0ZWx5IGFuZCBmb3JnZXQgYWJvdXQgaXRzIGNoYW5nZXMgKHZpYSBjb21taXQpLlxuICAgICAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmFkYXB0ZXIucmVtb3ZlT25lKGRlbGV0ZUlkIGFzIHN0cmluZywgY29sbGVjdGlvbik7XG4gICAgICAgICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5jb21taXRPbmUoZGVsZXRlSWQsIGNvbGxlY3Rpb24pO1xuICAgICAgICAgIC8vIFNob3VsZCBub3Qgd2FzdGUgZWZmb3J0IHRyeWluZyB0byBkZWxldGUgb24gdGhlIHNlcnZlciBiZWNhdXNlIGl0IGNhbid0IGJlIHRoZXJlLlxuICAgICAgICAgIGFjdGlvbi5wYXlsb2FkLnNraXAgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFJlLXRyYWNrIGl0IGFzIGEgZGVsZXRlLCBldmVuIGlmIHRyYWNraW5nIGlzIHR1cm5lZCBvZmYgZm9yIHRoaXMgY2FsbC5cbiAgICAgICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLnRyYWNrRGVsZXRlT25lKFxuICAgICAgICAgICAgZGVsZXRlSWQsXG4gICAgICAgICAgICBjb2xsZWN0aW9uXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIC8vIElmIG9wdGltaXN0aWMgZGVsZXRlLCB0cmFjayBjdXJyZW50IHN0YXRlIGFuZCByZW1vdmUgaW1tZWRpYXRlbHkuXG4gICAgaWYgKHRoaXMuaXNPcHRpbWlzdGljKGFjdGlvbikpIHtcbiAgICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLnRyYWNrRGVsZXRlTWFueShcbiAgICAgICAgZGVsZXRlSWRzLFxuICAgICAgICBjb2xsZWN0aW9uLFxuICAgICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgICApO1xuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuYWRhcHRlci5yZW1vdmVNYW55KGRlbGV0ZUlkcyBhcyBzdHJpbmdbXSwgY29sbGVjdGlvbik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdUcnVlKGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dGVtcHQgdG8gZGVsZXRlIHRoZSBlbnRpdGllcyBvbiB0aGUgc2VydmVyIGZhaWxlZCBvciB0aW1lZC1vdXQuXG4gICAqIEFjdGlvbiBob2xkcyB0aGUgZXJyb3IuXG4gICAqIElmIHNhdmVkIHBlc3NpbWlzdGljYWxseSwgdGhlIGVudGl0aWVzIGNvdWxkIHN0aWxsIGJlIGluIHRoZSBjb2xsZWN0aW9uIGFuZFxuICAgKiB5b3UgbWF5IG5vdCBoYXZlIHRvIGNvbXBlbnNhdGUgZm9yIHRoZSBlcnJvci5cbiAgICogSWYgc2F2ZWQgb3B0aW1pc3RpY2FsbHksIHRoZSBlbnRpdGllcyBhcmUgbm90IGluIHRoZSBjb2xsZWN0aW9uIGFuZFxuICAgKiB5b3UgbWF5IG5lZWQgdG8gY29tcGVuc2F0ZSBmb3IgdGhlIGVycm9yLlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVEZWxldGVNYW55RXJyb3IoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxFbnRpdHlBY3Rpb25EYXRhU2VydmljZUVycm9yPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogU3VjY2Vzc2Z1bGx5IGRlbGV0ZWQgZW50aXRpZXMgb24gdGhlIHNlcnZlci4gVGhlIGtleXMgb2YgdGhlIGRlbGV0ZWQgZW50aXRpZXMgYXJlIGluIHRoZSBhY3Rpb24gcGF5bG9hZCBkYXRhLlxuICAgKiBJZiBzYXZlZCBwZXNzaW1pc3RpY2FsbHksIGVudGl0aWVzIHRoYXQgYXJlIHN0aWxsIGluIHRoZSBjb2xsZWN0aW9uIHdpbGwgYmUgcmVtb3ZlZC5cbiAgICogSWYgc2F2ZWQgb3B0aW1pc3RpY2FsbHksIHRoZSBlbnRpdGllcyBoYXZlIGFscmVhZHkgYmVlbiByZW1vdmVkIGZyb20gdGhlIGNvbGxlY3Rpb24uXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZURlbGV0ZU1hbnlTdWNjZXNzKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248KG51bWJlciB8IHN0cmluZylbXT5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgY29uc3QgZGVsZXRlSWRzID0gdGhpcy5leHRyYWN0RGF0YShhY3Rpb24pO1xuICAgIGlmICh0aGlzLmlzT3B0aW1pc3RpYyhhY3Rpb24pKSB7XG4gICAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5tZXJnZVNhdmVEZWxldGVzKFxuICAgICAgICBkZWxldGVJZHMsXG4gICAgICAgIGNvbGxlY3Rpb24sXG4gICAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFBlc3NpbWlzdGljOiBpZ25vcmUgbWVyZ2VTdHJhdGVneS4gUmVtb3ZlIGVudGl0eSBmcm9tIHRoZSBjb2xsZWN0aW9uIGFuZCBmcm9tIGNoYW5nZSB0cmFja2luZy5cbiAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmFkYXB0ZXIucmVtb3ZlTWFueShkZWxldGVJZHMgYXMgc3RyaW5nW10sIGNvbGxlY3Rpb24pO1xuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5jb21taXRNYW55KGRlbGV0ZUlkcywgY29sbGVjdGlvbik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGYWxzZShjb2xsZWN0aW9uKTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uIHNhdmVEZWxldGVNYW55XG5cbiAgLy8gI3JlZ2lvbiBzYXZlVXBkYXRlT25lXG4gIC8qKlxuICAgKiBTYXZlIGFuIHVwZGF0ZSB0byBhbiBleGlzdGluZyBlbnRpdHkuXG4gICAqIElmIHNhdmluZyBwZXNzaW1pc3RpY2FsbHksIHVwZGF0ZSB0aGUgZW50aXR5IGluIHRoZSBjb2xsZWN0aW9uIGFmdGVyIHRoZSBzZXJ2ZXIgY29uZmlybXMgc3VjY2Vzcy5cbiAgICogSWYgc2F2aW5nIG9wdGltaXN0aWNhbGx5LCB1cGRhdGUgdGhlIGVudGl0eSBpbW1lZGlhdGVseSwgYmVmb3JlIHRoZSBzYXZlIHJlcXVlc3QuXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHVwZGF0ZVxuICAgKiBAcGFyYW0gYWN0aW9uIFRoZSBhY3Rpb24gcGF5bG9hZCBob2xkcyBvcHRpb25zLCBpbmNsdWRpbmcgaWYgdGhlIHNhdmUgaXMgb3B0aW1pc3RpYyxcbiAgICogYW5kIHRoZSBkYXRhIHdoaWNoLCBtdXN0IGJlIGFuIHtVcGRhdGU8VD59XG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZVVwZGF0ZU9uZShcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFVwZGF0ZTxUPj5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgY29uc3QgdXBkYXRlID0gdGhpcy5ndWFyZC5tdXN0QmVVcGRhdGUoYWN0aW9uKTtcbiAgICBpZiAodGhpcy5pc09wdGltaXN0aWMoYWN0aW9uKSkge1xuICAgICAgY29uc3QgbWVyZ2VTdHJhdGVneSA9IHRoaXMuZXh0cmFjdE1lcmdlU3RyYXRlZ3koYWN0aW9uKTtcbiAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIudHJhY2tVcGRhdGVPbmUoXG4gICAgICAgIHVwZGF0ZSxcbiAgICAgICAgY29sbGVjdGlvbixcbiAgICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICAgKTtcbiAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmFkYXB0ZXIudXBkYXRlT25lKHVwZGF0ZSwgY29sbGVjdGlvbik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdUcnVlKGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dGVtcHQgdG8gdXBkYXRlIHRoZSBlbnRpdHkgb24gdGhlIHNlcnZlciBmYWlsZWQgb3IgdGltZWQtb3V0LlxuICAgKiBBY3Rpb24gaG9sZHMgdGhlIGVycm9yLlxuICAgKiBJZiBzYXZlZCBwZXNzaW1pc3RpY2FsbHksIHRoZSBlbnRpdHkgaW4gdGhlIGNvbGxlY3Rpb24gaXMgaW4gdGhlIHByZS1zYXZlIHN0YXRlXG4gICAqIHlvdSBtYXkgbm90IGhhdmUgdG8gY29tcGVuc2F0ZSBmb3IgdGhlIGVycm9yLlxuICAgKiBJZiBzYXZlZCBvcHRpbWlzdGljYWxseSwgdGhlIGVudGl0eSBpbiB0aGUgY29sbGVjdGlvbiB3YXMgdXBkYXRlZFxuICAgKiBhbmQgeW91IG1heSBuZWVkIHRvIGNvbXBlbnNhdGUgZm9yIHRoZSBlcnJvci5cbiAgICovXG4gIHByb3RlY3RlZCBzYXZlVXBkYXRlT25lRXJyb3IoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxFbnRpdHlBY3Rpb25EYXRhU2VydmljZUVycm9yPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogU3VjY2Vzc2Z1bGx5IHNhdmVkIHRoZSB1cGRhdGVkIGVudGl0eSB0byB0aGUgc2VydmVyLlxuICAgKiBJZiBzYXZlZCBwZXNzaW1pc3RpY2FsbHksIHVwZGF0ZSB0aGUgZW50aXR5IGluIHRoZSBjb2xsZWN0aW9uIHdpdGggZGF0YSBmcm9tIHRoZSBzZXJ2ZXIuXG4gICAqIElmIHNhdmVkIG9wdGltaXN0aWNhbGx5LCB0aGUgZW50aXR5IHdhcyBhbHJlYWR5IHVwZGF0ZWQgaW4gdGhlIGNvbGxlY3Rpb24uXG4gICAqIEhvd2V2ZXIsIHRoZSBzZXJ2ZXIgbWlnaHQgaGF2ZSBzZXQgb3IgbW9kaWZpZWQgb3RoZXIgZmllbGRzIChlLmcsIGNvbmN1cnJlbmN5IGZpZWxkKVxuICAgKiBUaGVyZWZvcmUsIHVwZGF0ZSB0aGUgZW50aXR5IGluIHRoZSBjb2xsZWN0aW9uIHdpdGggdGhlIHJldHVybmVkIHZhbHVlIChpZiBhbnkpXG4gICAqIENhdXRpb246IGluIGEgcmFjZSwgdGhpcyB1cGRhdGUgY291bGQgb3ZlcndyaXRlIHVuc2F2ZWQgdXNlciBjaGFuZ2VzLlxuICAgKiBVc2UgcGVzc2ltaXN0aWMgdXBkYXRlIHRvIGF2b2lkIHRoaXMgcmlzay5cbiAgICogQHBhcmFtIGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gdXBkYXRlXG4gICAqIEBwYXJhbSBhY3Rpb24gVGhlIGFjdGlvbiBwYXlsb2FkIGhvbGRzIG9wdGlvbnMsIGluY2x1ZGluZyBpZiB0aGUgc2F2ZSBpcyBvcHRpbWlzdGljLCBhbmRcbiAgICogdGhlIHVwZGF0ZSBkYXRhIHdoaWNoLCBtdXN0IGJlIGFuIFVwZGF0ZVJlc3BvbnNlPFQ+IHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIFVwZGF0ZSBzZW50IHRvIHRoZSBzZXJ2ZXIuXG4gICAqIFlvdSBtdXN0IGluY2x1ZGUgYW4gVXBkYXRlUmVzcG9uc2UgZXZlbiBpZiB0aGUgc2F2ZSB3YXMgb3B0aW1pc3RpYyxcbiAgICogdG8gZW5zdXJlIHRoYXQgdGhlIGNoYW5nZSB0cmFja2luZyBpcyBwcm9wZXJseSByZXNldC5cbiAgICovXG4gIHByb3RlY3RlZCBzYXZlVXBkYXRlT25lU3VjY2VzcyhcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFVwZGF0ZVJlc3BvbnNlRGF0YTxUPj5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgY29uc3QgdXBkYXRlID0gdGhpcy5ndWFyZC5tdXN0QmVVcGRhdGVSZXNwb25zZShhY3Rpb24pO1xuICAgIGNvbnN0IGlzT3B0aW1pc3RpYyA9IHRoaXMuaXNPcHRpbWlzdGljKGFjdGlvbik7XG4gICAgY29uc3QgbWVyZ2VTdHJhdGVneSA9IHRoaXMuZXh0cmFjdE1lcmdlU3RyYXRlZ3koYWN0aW9uKTtcbiAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLm1lcmdlU2F2ZVVwZGF0ZXMoXG4gICAgICBbdXBkYXRlXSxcbiAgICAgIGNvbGxlY3Rpb24sXG4gICAgICBtZXJnZVN0cmF0ZWd5LFxuICAgICAgaXNPcHRpbWlzdGljIC8qc2tpcCB1bmNoYW5nZWQgaWYgb3B0aW1pc3RpYyAqL1xuICAgICk7XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ0ZhbHNlKGNvbGxlY3Rpb24pO1xuICB9XG4gIC8vICNlbmRyZWdpb24gc2F2ZVVwZGF0ZU9uZVxuXG4gIC8vICNyZWdpb24gc2F2ZVVwZGF0ZU1hbnlcbiAgLyoqXG4gICAqIFNhdmUgdXBkYXRlZCBlbnRpdGllcy5cbiAgICogSWYgc2F2aW5nIHBlc3NpbWlzdGljYWxseSwgdXBkYXRlIHRoZSBlbnRpdGllcyBpbiB0aGUgY29sbGVjdGlvbiBhZnRlciB0aGUgc2VydmVyIGNvbmZpcm1zIHN1Y2Nlc3MuXG4gICAqIElmIHNhdmluZyBvcHRpbWlzdGljYWxseSwgdXBkYXRlIHRoZSBlbnRpdGllcyBpbW1lZGlhdGVseSwgYmVmb3JlIHRoZSBzYXZlIHJlcXVlc3QuXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHVwZGF0ZVxuICAgKiBAcGFyYW0gYWN0aW9uIFRoZSBhY3Rpb24gcGF5bG9hZCBob2xkcyBvcHRpb25zLCBpbmNsdWRpbmcgaWYgdGhlIHNhdmUgaXMgb3B0aW1pc3RpYyxcbiAgICogYW5kIHRoZSBkYXRhIHdoaWNoLCBtdXN0IGJlIGFuIGFycmF5IG9mIHtVcGRhdGU8VD59LlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVVcGRhdGVNYW55KFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VXBkYXRlPFQ+W10+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIGNvbnN0IHVwZGF0ZXMgPSB0aGlzLmd1YXJkLm11c3RCZVVwZGF0ZXMoYWN0aW9uKTtcbiAgICBpZiAodGhpcy5pc09wdGltaXN0aWMoYWN0aW9uKSkge1xuICAgICAgY29uc3QgbWVyZ2VTdHJhdGVneSA9IHRoaXMuZXh0cmFjdE1lcmdlU3RyYXRlZ3koYWN0aW9uKTtcbiAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIudHJhY2tVcGRhdGVNYW55KFxuICAgICAgICB1cGRhdGVzLFxuICAgICAgICBjb2xsZWN0aW9uLFxuICAgICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgICApO1xuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuYWRhcHRlci51cGRhdGVNYW55KHVwZGF0ZXMsIGNvbGxlY3Rpb24pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nVHJ1ZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBdHRlbXB0IHRvIHVwZGF0ZSBlbnRpdGllcyBvbiB0aGUgc2VydmVyIGZhaWxlZCBvciB0aW1lZC1vdXQuXG4gICAqIEFjdGlvbiBob2xkcyB0aGUgZXJyb3IuXG4gICAqIElmIHNhdmVkIHBlc3NpbWlzdGljYWxseSwgdGhlIGVudGl0aWVzIGluIHRoZSBjb2xsZWN0aW9uIGFyZSBpbiB0aGUgcHJlLXNhdmUgc3RhdGVcbiAgICogeW91IG1heSBub3QgaGF2ZSB0byBjb21wZW5zYXRlIGZvciB0aGUgZXJyb3IuXG4gICAqIElmIHNhdmVkIG9wdGltaXN0aWNhbGx5LCB0aGUgZW50aXRpZXMgaW4gdGhlIGNvbGxlY3Rpb24gd2VyZSB1cGRhdGVkXG4gICAqIGFuZCB5b3UgbWF5IG5lZWQgdG8gY29tcGVuc2F0ZSBmb3IgdGhlIGVycm9yLlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVVcGRhdGVNYW55RXJyb3IoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxFbnRpdHlBY3Rpb25EYXRhU2VydmljZUVycm9yPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogU3VjY2Vzc2Z1bGx5IHNhdmVkIHRoZSB1cGRhdGVkIGVudGl0aWVzIHRvIHRoZSBzZXJ2ZXIuXG4gICAqIElmIHNhdmVkIHBlc3NpbWlzdGljYWxseSwgdGhlIGVudGl0aWVzIGluIHRoZSBjb2xsZWN0aW9uIHdpbGwgYmUgdXBkYXRlZCB3aXRoIGRhdGEgZnJvbSB0aGUgc2VydmVyLlxuICAgKiBJZiBzYXZlZCBvcHRpbWlzdGljYWxseSwgdGhlIGVudGl0aWVzIGluIHRoZSBjb2xsZWN0aW9uIHdlcmUgYWxyZWFkeSB1cGRhdGVkLlxuICAgKiBIb3dldmVyLCB0aGUgc2VydmVyIG1pZ2h0IGhhdmUgc2V0IG9yIG1vZGlmaWVkIG90aGVyIGZpZWxkcyAoZS5nLCBjb25jdXJyZW5jeSBmaWVsZClcbiAgICogVGhlcmVmb3JlLCB1cGRhdGUgdGhlIGVudGl0eSBpbiB0aGUgY29sbGVjdGlvbiB3aXRoIHRoZSByZXR1cm5lZCB2YWx1ZXMgKGlmIGFueSlcbiAgICogQ2F1dGlvbjogaW4gYSByYWNlLCB0aGlzIHVwZGF0ZSBjb3VsZCBvdmVyd3JpdGUgdW5zYXZlZCB1c2VyIGNoYW5nZXMuXG4gICAqIFVzZSBwZXNzaW1pc3RpYyB1cGRhdGUgdG8gYXZvaWQgdGhpcyByaXNrLlxuICAgKiBAcGFyYW0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byB1cGRhdGVcbiAgICogQHBhcmFtIGFjdGlvbiBUaGUgYWN0aW9uIHBheWxvYWQgaG9sZHMgb3B0aW9ucywgaW5jbHVkaW5nIGlmIHRoZSBzYXZlIGlzIG9wdGltaXN0aWMsXG4gICAqIGFuZCB0aGUgZGF0YSB3aGljaCwgbXVzdCBiZSBhbiBhcnJheSBvZiBVcGRhdGVSZXNwb25zZTxUPi5cbiAgICogWW91IG11c3QgaW5jbHVkZSBhbiBVcGRhdGVSZXNwb25zZSBmb3IgZXZlcnkgVXBkYXRlIHNlbnQgdG8gdGhlIHNlcnZlcixcbiAgICogZXZlbiBpZiB0aGUgc2F2ZSB3YXMgb3B0aW1pc3RpYywgdG8gZW5zdXJlIHRoYXQgdGhlIGNoYW5nZSB0cmFja2luZyBpcyBwcm9wZXJseSByZXNldC5cbiAgICovXG4gIHByb3RlY3RlZCBzYXZlVXBkYXRlTWFueVN1Y2Nlc3MoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxVcGRhdGVSZXNwb25zZURhdGE8VD5bXT5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgY29uc3QgdXBkYXRlcyA9IHRoaXMuZ3VhcmQubXVzdEJlVXBkYXRlUmVzcG9uc2VzKGFjdGlvbik7XG4gICAgY29uc3QgaXNPcHRpbWlzdGljID0gdGhpcy5pc09wdGltaXN0aWMoYWN0aW9uKTtcbiAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIubWVyZ2VTYXZlVXBkYXRlcyhcbiAgICAgIHVwZGF0ZXMsXG4gICAgICBjb2xsZWN0aW9uLFxuICAgICAgbWVyZ2VTdHJhdGVneSxcbiAgICAgIGZhbHNlIC8qIG5ldmVyIHNraXAgKi9cbiAgICApO1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGYWxzZShjb2xsZWN0aW9uKTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uIHNhdmVVcGRhdGVNYW55XG5cbiAgLy8gI3JlZ2lvbiBzYXZlVXBzZXJ0T25lXG4gIC8qKlxuICAgKiBTYXZlIGEgbmV3IG9yIGV4aXN0aW5nIGVudGl0eS5cbiAgICogSWYgc2F2aW5nIHBlc3NpbWlzdGljYWxseSwgZGVsYXkgYWRkaW5nIHRvIGNvbGxlY3Rpb24gdW50aWwgc2VydmVyIGFja25vd2xlZGdlcyBzdWNjZXNzLlxuICAgKiBJZiBzYXZpbmcgb3B0aW1pc3RpY2FsbHk7IGFkZCBpbW1lZGlhdGVseS5cbiAgICogQHBhcmFtIGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gd2hpY2ggdGhlIGVudGl0eSBzaG91bGQgYmUgdXBzZXJ0ZWQuXG4gICAqIEBwYXJhbSBhY3Rpb24gVGhlIGFjdGlvbiBwYXlsb2FkIGhvbGRzIG9wdGlvbnMsIGluY2x1ZGluZyB3aGV0aGVyIHRoZSBzYXZlIGlzIG9wdGltaXN0aWMsXG4gICAqIGFuZCB0aGUgZGF0YSwgd2hpY2ggbXVzdCBiZSBhIHdob2xlIGVudGl0eS5cbiAgICogSWYgc2F2aW5nIG9wdGltaXN0aWNhbGx5LCB0aGUgZW50aXR5IG11c3QgaGF2ZSBpdHMga2V5LlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVVcHNlcnRPbmUoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxUPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBpZiAodGhpcy5pc09wdGltaXN0aWMoYWN0aW9uKSkge1xuICAgICAgY29uc3QgZW50aXR5ID0gdGhpcy5ndWFyZC5tdXN0QmVFbnRpdHkoYWN0aW9uKTsgLy8gZW5zdXJlIHRoZSBlbnRpdHkgaGFzIGEgUEtcbiAgICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLnRyYWNrVXBzZXJ0T25lKFxuICAgICAgICBlbnRpdHksXG4gICAgICAgIGNvbGxlY3Rpb24sXG4gICAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICAgICk7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5hZGFwdGVyLnVwc2VydE9uZShlbnRpdHksIGNvbGxlY3Rpb24pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nVHJ1ZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBdHRlbXB0IHRvIHNhdmUgbmV3IG9yIGV4aXN0aW5nIGVudGl0eSBmYWlsZWQgb3IgdGltZWQtb3V0LlxuICAgKiBBY3Rpb24gaG9sZHMgdGhlIGVycm9yLlxuICAgKiBJZiBzYXZlZCBwZXNzaW1pc3RpY2FsbHksIG5ldyBvciB1cGRhdGVkIGVudGl0eSBpcyBub3QgaW4gdGhlIGNvbGxlY3Rpb24gYW5kXG4gICAqIHlvdSBtYXkgbm90IGhhdmUgdG8gY29tcGVuc2F0ZSBmb3IgdGhlIGVycm9yLlxuICAgKiBJZiBzYXZlZCBvcHRpbWlzdGljYWxseSwgdGhlIHVuc2F2ZWQgZW50aXRpZXMgYXJlIGluIHRoZSBjb2xsZWN0aW9uIGFuZFxuICAgKiB5b3UgbWF5IG5lZWQgdG8gY29tcGVuc2F0ZSBmb3IgdGhlIGVycm9yLlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVVcHNlcnRPbmVFcnJvcihcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPEVudGl0eUFjdGlvbkRhdGFTZXJ2aWNlRXJyb3I+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGYWxzZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdWNjZXNzZnVsbHkgc2F2ZWQgbmV3IG9yIGV4aXN0aW5nIGVudGl0aWVzIHRvIHRoZSBzZXJ2ZXIuXG4gICAqIElmIHNhdmVkIHBlc3NpbWlzdGljYWxseSwgYWRkIHRoZSBlbnRpdGllcyBmcm9tIHRoZSBzZXJ2ZXIgdG8gdGhlIGNvbGxlY3Rpb24uXG4gICAqIElmIHNhdmVkIG9wdGltaXN0aWNhbGx5LCB0aGUgYWRkZWQgZW50aXRpZXMgYXJlIGFscmVhZHkgaW4gdGhlIGNvbGxlY3Rpb24uXG4gICAqIEhvd2V2ZXIsIHRoZSBzZXJ2ZXIgbWlnaHQgaGF2ZSBzZXQgb3IgbW9kaWZpZWQgb3RoZXIgZmllbGRzIChlLmcsIGNvbmN1cnJlbmN5IGZpZWxkKVxuICAgKiBUaGVyZWZvcmUsIHVwZGF0ZSB0aGUgZW50aXRpZXMgaW4gdGhlIGNvbGxlY3Rpb24gd2l0aCB0aGUgcmV0dXJuZWQgdmFsdWVzIChpZiBhbnkpXG4gICAqIENhdXRpb246IGluIGEgcmFjZSwgdGhpcyB1cGRhdGUgY291bGQgb3ZlcndyaXRlIHVuc2F2ZWQgdXNlciBjaGFuZ2VzLlxuICAgKiBVc2UgcGVzc2ltaXN0aWMgYWRkIHRvIGF2b2lkIHRoaXMgcmlzay5cbiAgICovXG4gIHByb3RlY3RlZCBzYXZlVXBzZXJ0T25lU3VjY2VzcyhcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFQ+XG4gICkge1xuICAgIC8vIEZvciBwZXNzaW1pc3RpYyBzYXZlLCBlbnN1cmUgdGhlIHNlcnZlciBnZW5lcmF0ZWQgdGhlIHByaW1hcnkga2V5IGlmIHRoZSBjbGllbnQgZGlkbid0IHNlbmQgb25lLlxuICAgIGNvbnN0IGVudGl0eSA9IHRoaXMuZ3VhcmQubXVzdEJlRW50aXR5KGFjdGlvbik7XG4gICAgY29uc3QgbWVyZ2VTdHJhdGVneSA9IHRoaXMuZXh0cmFjdE1lcmdlU3RyYXRlZ3koYWN0aW9uKTtcbiAgICAvLyBBbHdheXMgdXBkYXRlIHRoZSBjYWNoZSB3aXRoIHVwc2VydGVkIGVudGl0aWVzIHJldHVybmVkIGZyb20gc2VydmVyXG4gICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5tZXJnZVNhdmVVcHNlcnRzKFxuICAgICAgW2VudGl0eV0sXG4gICAgICBjb2xsZWN0aW9uLFxuICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICk7XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ0ZhbHNlKGNvbGxlY3Rpb24pO1xuICB9XG4gIC8vICNlbmRyZWdpb24gc2F2ZVVwc2VydE9uZVxuXG4gIC8vICNyZWdpb24gc2F2ZVVwc2VydE1hbnlcbiAgLyoqXG4gICAqIFNhdmUgbXVsdGlwbGUgbmV3IG9yIGV4aXN0aW5nIGVudGl0aWVzLlxuICAgKiBJZiBzYXZpbmcgcGVzc2ltaXN0aWNhbGx5LCBkZWxheSBhZGRpbmcgdG8gY29sbGVjdGlvbiB1bnRpbCBzZXJ2ZXIgYWNrbm93bGVkZ2VzIHN1Y2Nlc3MuXG4gICAqIElmIHNhdmluZyBvcHRpbWlzdGljYWxseTsgYWRkIGltbWVkaWF0ZWx5LlxuICAgKiBAcGFyYW0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byB3aGljaCB0aGUgZW50aXRpZXMgc2hvdWxkIGJlIHVwc2VydGVkLlxuICAgKiBAcGFyYW0gYWN0aW9uIFRoZSBhY3Rpb24gcGF5bG9hZCBob2xkcyBvcHRpb25zLCBpbmNsdWRpbmcgd2hldGhlciB0aGUgc2F2ZSBpcyBvcHRpbWlzdGljLFxuICAgKiBhbmQgdGhlIGRhdGEsIHdoaWNoIG11c3QgYmUgYW4gYXJyYXkgb2Ygd2hvbGUgZW50aXRpZXMuXG4gICAqIElmIHNhdmluZyBvcHRpbWlzdGljYWxseSwgdGhlIGVudGl0aWVzIG11c3QgaGF2ZSB0aGVpciBrZXlzLlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVVcHNlcnRNYW55KFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VFtdPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBpZiAodGhpcy5pc09wdGltaXN0aWMoYWN0aW9uKSkge1xuICAgICAgY29uc3QgZW50aXRpZXMgPSB0aGlzLmd1YXJkLm11c3RCZUVudGl0aWVzKGFjdGlvbik7IC8vIGVuc3VyZSB0aGUgZW50aXR5IGhhcyBhIFBLXG4gICAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci50cmFja1Vwc2VydE1hbnkoXG4gICAgICAgIGVudGl0aWVzLFxuICAgICAgICBjb2xsZWN0aW9uLFxuICAgICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgICApO1xuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuYWRhcHRlci51cHNlcnRNYW55KGVudGl0aWVzLCBjb2xsZWN0aW9uKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ1RydWUoY29sbGVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogQXR0ZW1wdCB0byBzYXZlIG5ldyBvciBleGlzdGluZyBlbnRpdGllcyBmYWlsZWQgb3IgdGltZWQtb3V0LlxuICAgKiBBY3Rpb24gaG9sZHMgdGhlIGVycm9yLlxuICAgKiBJZiBzYXZlZCBwZXNzaW1pc3RpY2FsbHksIG5ldyBlbnRpdGllcyBhcmUgbm90IGluIHRoZSBjb2xsZWN0aW9uIGFuZFxuICAgKiB5b3UgbWF5IG5vdCBoYXZlIHRvIGNvbXBlbnNhdGUgZm9yIHRoZSBlcnJvci5cbiAgICogSWYgc2F2ZWQgb3B0aW1pc3RpY2FsbHksIHRoZSB1bnNhdmVkIGVudGl0aWVzIGFyZSBpbiB0aGUgY29sbGVjdGlvbiBhbmRcbiAgICogeW91IG1heSBuZWVkIHRvIGNvbXBlbnNhdGUgZm9yIHRoZSBlcnJvci5cbiAgICovXG4gIHByb3RlY3RlZCBzYXZlVXBzZXJ0TWFueUVycm9yKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248RW50aXR5QWN0aW9uRGF0YVNlcnZpY2VFcnJvcj5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ0ZhbHNlKGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIFN1Y2Nlc3NmdWxseSBzYXZlZCBuZXcgb3IgZXhpc3RpbmcgZW50aXRpZXMgdG8gdGhlIHNlcnZlci5cbiAgICogSWYgc2F2ZWQgcGVzc2ltaXN0aWNhbGx5LCBhZGQgdGhlIGVudGl0aWVzIGZyb20gdGhlIHNlcnZlciB0byB0aGUgY29sbGVjdGlvbi5cbiAgICogSWYgc2F2ZWQgb3B0aW1pc3RpY2FsbHksIHRoZSBhZGRlZCBlbnRpdGllcyBhcmUgYWxyZWFkeSBpbiB0aGUgY29sbGVjdGlvbi5cbiAgICogSG93ZXZlciwgdGhlIHNlcnZlciBtaWdodCBoYXZlIHNldCBvciBtb2RpZmllZCBvdGhlciBmaWVsZHMgKGUuZywgY29uY3VycmVuY3kgZmllbGQpXG4gICAqIFRoZXJlZm9yZSwgdXBkYXRlIHRoZSBlbnRpdGllcyBpbiB0aGUgY29sbGVjdGlvbiB3aXRoIHRoZSByZXR1cm5lZCB2YWx1ZXMgKGlmIGFueSlcbiAgICogQ2F1dGlvbjogaW4gYSByYWNlLCB0aGlzIHVwZGF0ZSBjb3VsZCBvdmVyd3JpdGUgdW5zYXZlZCB1c2VyIGNoYW5nZXMuXG4gICAqIFVzZSBwZXNzaW1pc3RpYyBhZGQgdG8gYXZvaWQgdGhpcyByaXNrLlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVVcHNlcnRNYW55U3VjY2VzcyhcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFRbXT5cbiAgKSB7XG4gICAgLy8gRm9yIHBlc3NpbWlzdGljIHNhdmUsIGVuc3VyZSB0aGUgc2VydmVyIGdlbmVyYXRlZCB0aGUgcHJpbWFyeSBrZXkgaWYgdGhlIGNsaWVudCBkaWRuJ3Qgc2VuZCBvbmUuXG4gICAgY29uc3QgZW50aXRpZXMgPSB0aGlzLmd1YXJkLm11c3RCZUVudGl0aWVzKGFjdGlvbik7XG4gICAgY29uc3QgbWVyZ2VTdHJhdGVneSA9IHRoaXMuZXh0cmFjdE1lcmdlU3RyYXRlZ3koYWN0aW9uKTtcbiAgICAvLyBBbHdheXMgdXBkYXRlIHRoZSBjYWNoZSB3aXRoIHVwc2VydGVkIGVudGl0aWVzIHJldHVybmVkIGZyb20gc2VydmVyXG4gICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5tZXJnZVNhdmVVcHNlcnRzKFxuICAgICAgZW50aXRpZXMsXG4gICAgICBjb2xsZWN0aW9uLFxuICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICk7XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ0ZhbHNlKGNvbGxlY3Rpb24pO1xuICB9XG4gIC8vICNlbmRyZWdpb24gc2F2ZVVwc2VydE1hbnlcblxuICAvLyAjZW5kcmVnaW9uIHNhdmUgb3BlcmF0aW9uc1xuXG4gIC8vICNyZWdpb24gY2FjaGUtb25seSBvcGVyYXRpb25zXG5cbiAgLyoqXG4gICAqIFJlcGxhY2VzIGFsbCBlbnRpdGllcyBpbiB0aGUgY29sbGVjdGlvblxuICAgKiBTZXRzIGxvYWRlZCBmbGFnIHRvIHRydWUuXG4gICAqIE1lcmdlcyBxdWVyeSByZXN1bHRzLCBwcmVzZXJ2aW5nIHVuc2F2ZWQgY2hhbmdlc1xuICAgKi9cbiAgcHJvdGVjdGVkIGFkZEFsbChcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFRbXT5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgY29uc3QgZW50aXRpZXMgPSB0aGlzLmd1YXJkLm11c3RCZUVudGl0aWVzKGFjdGlvbik7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnRoaXMuYWRhcHRlci5zZXRBbGwoZW50aXRpZXMsIGNvbGxlY3Rpb24pLFxuICAgICAgbG9hZGluZzogZmFsc2UsXG4gICAgICBsb2FkZWQ6IHRydWUsXG4gICAgICBjaGFuZ2VTdGF0ZToge30sXG4gICAgfTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhZGRNYW55KFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VFtdPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBjb25zdCBlbnRpdGllcyA9IHRoaXMuZ3VhcmQubXVzdEJlRW50aXRpZXMoYWN0aW9uKTtcbiAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIudHJhY2tBZGRNYW55KFxuICAgICAgZW50aXRpZXMsXG4gICAgICBjb2xsZWN0aW9uLFxuICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICk7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5hZGRNYW55KGVudGl0aWVzLCBjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhZGRPbmUoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxUPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBjb25zdCBlbnRpdHkgPSB0aGlzLmd1YXJkLm11c3RCZUVudGl0eShhY3Rpb24pO1xuICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci50cmFja0FkZE9uZShcbiAgICAgIGVudGl0eSxcbiAgICAgIGNvbGxlY3Rpb24sXG4gICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmFkZE9uZShlbnRpdHksIGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHJlbW92ZU1hbnkoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxudW1iZXJbXSB8IHN0cmluZ1tdPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICAvLyBwYXlsb2FkIG11c3QgYmUgZW50aXR5IGtleXNcbiAgICBjb25zdCBrZXlzID0gdGhpcy5ndWFyZC5tdXN0QmVLZXlzKGFjdGlvbikgYXMgc3RyaW5nW107XG4gICAgY29uc3QgbWVyZ2VTdHJhdGVneSA9IHRoaXMuZXh0cmFjdE1lcmdlU3RyYXRlZ3koYWN0aW9uKTtcbiAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLnRyYWNrRGVsZXRlTWFueShcbiAgICAgIGtleXMsXG4gICAgICBjb2xsZWN0aW9uLFxuICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICk7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5yZW1vdmVNYW55KGtleXMsIGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHJlbW92ZU9uZShcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPG51bWJlciB8IHN0cmluZz5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgLy8gcGF5bG9hZCBtdXN0IGJlIGVudGl0eSBrZXlcbiAgICBjb25zdCBrZXkgPSB0aGlzLmd1YXJkLm11c3RCZUtleShhY3Rpb24pIGFzIHN0cmluZztcbiAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIudHJhY2tEZWxldGVPbmUoXG4gICAgICBrZXksXG4gICAgICBjb2xsZWN0aW9uLFxuICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICk7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5yZW1vdmVPbmUoa2V5LCBjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIHByb3RlY3RlZCByZW1vdmVBbGwoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxUPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4udGhpcy5hZGFwdGVyLnJlbW92ZUFsbChjb2xsZWN0aW9uKSxcbiAgICAgIGxvYWRlZDogZmFsc2UsIC8vIE9ubHkgUkVNT1ZFX0FMTCBzZXRzIGxvYWRlZCB0byBmYWxzZVxuICAgICAgbG9hZGluZzogZmFsc2UsXG4gICAgICBjaGFuZ2VTdGF0ZToge30sIC8vIEFzc3VtZSBjbGVhcmluZyB0aGUgY29sbGVjdGlvbiBhbmQgbm90IHRyeWluZyB0byBkZWxldGUgYWxsIGVudGl0aWVzXG4gICAgfTtcbiAgfVxuXG4gIHByb3RlY3RlZCB1cGRhdGVNYW55KFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VXBkYXRlPFQ+W10+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIC8vIHBheWxvYWQgbXVzdCBiZSBhbiBhcnJheSBvZiBgVXBkYXRlczxUPmAsIG5vdCBlbnRpdGllc1xuICAgIGNvbnN0IHVwZGF0ZXMgPSB0aGlzLmd1YXJkLm11c3RCZVVwZGF0ZXMoYWN0aW9uKTtcbiAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIudHJhY2tVcGRhdGVNYW55KFxuICAgICAgdXBkYXRlcyxcbiAgICAgIGNvbGxlY3Rpb24sXG4gICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnVwZGF0ZU1hbnkodXBkYXRlcywgY29sbGVjdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgdXBkYXRlT25lKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VXBkYXRlPFQ+PlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICAvLyBwYXlsb2FkIG11c3QgYmUgYW4gYFVwZGF0ZTxUPmAsIG5vdCBhbiBlbnRpdHlcbiAgICBjb25zdCB1cGRhdGUgPSB0aGlzLmd1YXJkLm11c3RCZVVwZGF0ZShhY3Rpb24pO1xuICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci50cmFja1VwZGF0ZU9uZShcbiAgICAgIHVwZGF0ZSxcbiAgICAgIGNvbGxlY3Rpb24sXG4gICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnVwZGF0ZU9uZSh1cGRhdGUsIGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHVwc2VydE1hbnkoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxUW10+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIC8vIDx2NjogcGF5bG9hZCBtdXN0IGJlIGFuIGFycmF5IG9mIGBVcGRhdGVzPFQ+YCwgbm90IGVudGl0aWVzXG4gICAgLy8gdjYrOiBwYXlsb2FkIG11c3QgYmUgYW4gYXJyYXkgb2YgVFxuICAgIGNvbnN0IGVudGl0aWVzID0gdGhpcy5ndWFyZC5tdXN0QmVFbnRpdGllcyhhY3Rpb24pO1xuICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci50cmFja1Vwc2VydE1hbnkoXG4gICAgICBlbnRpdGllcyxcbiAgICAgIGNvbGxlY3Rpb24sXG4gICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnVwc2VydE1hbnkoZW50aXRpZXMsIGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHVwc2VydE9uZShcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFQ+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIC8vIDx2NjogcGF5bG9hZCBtdXN0IGJlIGFuIGBVcGRhdGU8VD5gLCBub3QgYW4gZW50aXR5XG4gICAgLy8gdjYrOiBwYXlsb2FkIG11c3QgYmUgYSBUXG4gICAgY29uc3QgZW50aXR5ID0gdGhpcy5ndWFyZC5tdXN0QmVFbnRpdHkoYWN0aW9uKTtcbiAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIudHJhY2tVcHNlcnRPbmUoXG4gICAgICBlbnRpdHksXG4gICAgICBjb2xsZWN0aW9uLFxuICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICk7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci51cHNlcnRPbmUoZW50aXR5LCBjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjb21taXRBbGwoY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPikge1xuICAgIHJldHVybiB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIuY29tbWl0QWxsKGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNvbW1pdE1hbnkoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxUW10+XG4gICkge1xuICAgIHJldHVybiB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIuY29tbWl0TWFueShcbiAgICAgIHRoaXMuZXh0cmFjdERhdGEoYWN0aW9uKSxcbiAgICAgIGNvbGxlY3Rpb25cbiAgICApO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNvbW1pdE9uZShcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFQ+XG4gICkge1xuICAgIHJldHVybiB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIuY29tbWl0T25lKFxuICAgICAgdGhpcy5leHRyYWN0RGF0YShhY3Rpb24pLFxuICAgICAgY29sbGVjdGlvblxuICAgICk7XG4gIH1cblxuICBwcm90ZWN0ZWQgdW5kb0FsbChjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+KSB7XG4gICAgcmV0dXJuIHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci51bmRvQWxsKGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHVuZG9NYW55KFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VFtdPlxuICApIHtcbiAgICByZXR1cm4gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLnVuZG9NYW55KFxuICAgICAgdGhpcy5leHRyYWN0RGF0YShhY3Rpb24pLFxuICAgICAgY29sbGVjdGlvblxuICAgICk7XG4gIH1cblxuICBwcm90ZWN0ZWQgdW5kb09uZShjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LCBhY3Rpb246IEVudGl0eUFjdGlvbjxUPikge1xuICAgIHJldHVybiB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIudW5kb09uZShcbiAgICAgIHRoaXMuZXh0cmFjdERhdGEoYWN0aW9uKSxcbiAgICAgIGNvbGxlY3Rpb25cbiAgICApO1xuICB9XG5cbiAgLyoqIERhbmdlcm91czogQ29tcGxldGVseSByZXBsYWNlIHRoZSBjb2xsZWN0aW9uJ3MgQ2hhbmdlU3RhdGUuIFVzZSByYXJlbHkgYW5kIHdpc2VseS4gKi9cbiAgcHJvdGVjdGVkIHNldENoYW5nZVN0YXRlKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248Q2hhbmdlU3RhdGVNYXA8VD4+XG4gICkge1xuICAgIGNvbnN0IGNoYW5nZVN0YXRlID0gdGhpcy5leHRyYWN0RGF0YShhY3Rpb24pO1xuICAgIHJldHVybiBjb2xsZWN0aW9uLmNoYW5nZVN0YXRlID09PSBjaGFuZ2VTdGF0ZVxuICAgICAgPyBjb2xsZWN0aW9uXG4gICAgICA6IHsgLi4uY29sbGVjdGlvbiwgY2hhbmdlU3RhdGUgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEYW5nZXJvdXM6IENvbXBsZXRlbHkgcmVwbGFjZSB0aGUgY29sbGVjdGlvbi5cbiAgICogUHJpbWFyaWx5IGZvciB0ZXN0aW5nIGFuZCByZWh5ZHJhdGlvbiBmcm9tIGxvY2FsIHN0b3JhZ2UuXG4gICAqIFVzZSByYXJlbHkgYW5kIHdpc2VseS5cbiAgICovXG4gIHByb3RlY3RlZCBzZXRDb2xsZWN0aW9uKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248RW50aXR5Q29sbGVjdGlvbjxUPj5cbiAgKSB7XG4gICAgY29uc3QgbmV3Q29sbGVjdGlvbiA9IHRoaXMuZXh0cmFjdERhdGEoYWN0aW9uKTtcbiAgICByZXR1cm4gY29sbGVjdGlvbiA9PT0gbmV3Q29sbGVjdGlvbiA/IGNvbGxlY3Rpb24gOiBuZXdDb2xsZWN0aW9uO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNldEZpbHRlcihcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPGFueT5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgY29uc3QgZmlsdGVyID0gdGhpcy5leHRyYWN0RGF0YShhY3Rpb24pO1xuICAgIHJldHVybiBjb2xsZWN0aW9uLmZpbHRlciA9PT0gZmlsdGVyXG4gICAgICA/IGNvbGxlY3Rpb25cbiAgICAgIDogeyAuLi5jb2xsZWN0aW9uLCBmaWx0ZXIgfTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzZXRMb2FkZWQoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxib29sZWFuPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBjb25zdCBsb2FkZWQgPSB0aGlzLmV4dHJhY3REYXRhKGFjdGlvbikgPT09IHRydWUgfHwgZmFsc2U7XG4gICAgcmV0dXJuIGNvbGxlY3Rpb24ubG9hZGVkID09PSBsb2FkZWRcbiAgICAgID8gY29sbGVjdGlvblxuICAgICAgOiB7IC4uLmNvbGxlY3Rpb24sIGxvYWRlZCB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIHNldExvYWRpbmcoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxib29sZWFuPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmxhZyhjb2xsZWN0aW9uLCB0aGlzLmV4dHJhY3REYXRhKGFjdGlvbikpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNldExvYWRpbmdGYWxzZShcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGbGFnKGNvbGxlY3Rpb24sIGZhbHNlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzZXRMb2FkaW5nVHJ1ZShcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGbGFnKGNvbGxlY3Rpb24sIHRydWUpO1xuICB9XG5cbiAgLyoqIFNldCB0aGUgY29sbGVjdGlvbidzIGxvYWRpbmcgZmxhZyAqL1xuICBwcm90ZWN0ZWQgc2V0TG9hZGluZ0ZsYWcoY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPiwgbG9hZGluZzogYm9vbGVhbikge1xuICAgIGxvYWRpbmcgPSBsb2FkaW5nID09PSB0cnVlID8gdHJ1ZSA6IGZhbHNlO1xuICAgIHJldHVybiBjb2xsZWN0aW9uLmxvYWRpbmcgPT09IGxvYWRpbmdcbiAgICAgID8gY29sbGVjdGlvblxuICAgICAgOiB7IC4uLmNvbGxlY3Rpb24sIGxvYWRpbmcgfTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uIENhY2hlLW9ubHkgb3BlcmF0aW9uc1xuXG4gIC8vICNyZWdpb24gaGVscGVyc1xuICAvKiogU2FmZWx5IGV4dHJhY3QgZGF0YSBmcm9tIHRoZSBFbnRpdHlBY3Rpb24gcGF5bG9hZCAqL1xuICBwcm90ZWN0ZWQgZXh0cmFjdERhdGE8RCA9IGFueT4oYWN0aW9uOiBFbnRpdHlBY3Rpb248RD4pOiBEIHtcbiAgICByZXR1cm4gKGFjdGlvbi5wYXlsb2FkICYmIGFjdGlvbi5wYXlsb2FkLmRhdGEpIGFzIEQ7XG4gIH1cblxuICAvKiogU2FmZWx5IGV4dHJhY3QgTWVyZ2VTdHJhdGVneSBmcm9tIEVudGl0eUFjdGlvbi4gU2V0IHRvIElnbm9yZUNoYW5nZXMgaWYgY29sbGVjdGlvbiBpdHNlbGYgaXMgbm90IHRyYWNrZWQuICovXG4gIHByb3RlY3RlZCBleHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb246IEVudGl0eUFjdGlvbikge1xuICAgIC8vIElmIG5vdCB0cmFja2luZyB0aGlzIGNvbGxlY3Rpb24sIGFsd2F5cyBpZ25vcmUgY2hhbmdlc1xuICAgIHJldHVybiB0aGlzLmlzQ2hhbmdlVHJhY2tpbmdcbiAgICAgID8gYWN0aW9uLnBheWxvYWQgJiYgYWN0aW9uLnBheWxvYWQubWVyZ2VTdHJhdGVneVxuICAgICAgOiBNZXJnZVN0cmF0ZWd5Lklnbm9yZUNoYW5nZXM7XG4gIH1cblxuICBwcm90ZWN0ZWQgaXNPcHRpbWlzdGljKGFjdGlvbjogRW50aXR5QWN0aW9uKSB7XG4gICAgcmV0dXJuIGFjdGlvbi5wYXlsb2FkICYmIGFjdGlvbi5wYXlsb2FkLmlzT3B0aW1pc3RpYyA9PT0gdHJ1ZTtcbiAgfVxuXG4gIC8vICNlbmRyZWdpb24gaGVscGVyc1xufVxuXG4vKipcbiAqIENyZWF0ZXMge0VudGl0eUNvbGxlY3Rpb25SZWR1Y2VyTWV0aG9kc30gZm9yIGEgZ2l2ZW4gZW50aXR5IHR5cGUuXG4gKi9cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBFbnRpdHlDb2xsZWN0aW9uUmVkdWNlck1ldGhvZHNGYWN0b3J5IHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBlbnRpdHlEZWZpbml0aW9uU2VydmljZTogRW50aXR5RGVmaW5pdGlvblNlcnZpY2UpIHt9XG5cbiAgLyoqIENyZWF0ZSB0aGUgIHtFbnRpdHlDb2xsZWN0aW9uUmVkdWNlck1ldGhvZHN9IGZvciB0aGUgbmFtZWQgZW50aXR5IHR5cGUgKi9cbiAgY3JlYXRlPFQ+KGVudGl0eU5hbWU6IHN0cmluZyk6IEVudGl0eUNvbGxlY3Rpb25SZWR1Y2VyTWV0aG9kTWFwPFQ+IHtcbiAgICBjb25zdCBkZWZpbml0aW9uID0gdGhpcy5lbnRpdHlEZWZpbml0aW9uU2VydmljZS5nZXREZWZpbml0aW9uPFQ+KFxuICAgICAgZW50aXR5TmFtZVxuICAgICk7XG4gICAgY29uc3QgbWV0aG9kc0NsYXNzID0gbmV3IEVudGl0eUNvbGxlY3Rpb25SZWR1Y2VyTWV0aG9kcyhcbiAgICAgIGVudGl0eU5hbWUsXG4gICAgICBkZWZpbml0aW9uXG4gICAgKTtcblxuICAgIHJldHVybiBtZXRob2RzQ2xhc3MubWV0aG9kcztcbiAgfVxufVxuIl19