@gomomento/sdk-core 1.12.8

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 (184) hide show
  1. package/dist/src/auth/credential-provider.d.ts +83 -0
  2. package/dist/src/auth/credential-provider.js +82 -0
  3. package/dist/src/auth/index.d.ts +1 -0
  4. package/dist/src/auth/index.js +18 -0
  5. package/dist/src/config/logging/default-momento-logger.d.ts +24 -0
  6. package/dist/src/config/logging/default-momento-logger.js +69 -0
  7. package/dist/src/config/logging/index.d.ts +3 -0
  8. package/dist/src/config/logging/index.js +20 -0
  9. package/dist/src/config/logging/momento-logger.d.ts +10 -0
  10. package/dist/src/config/logging/momento-logger.js +3 -0
  11. package/dist/src/config/logging/noop-momento-logger.d.ts +11 -0
  12. package/dist/src/config/logging/noop-momento-logger.js +34 -0
  13. package/dist/src/config/transport/grpc-configuration.d.ts +41 -0
  14. package/dist/src/config/transport/grpc-configuration.js +3 -0
  15. package/dist/src/config/transport/index.d.ts +2 -0
  16. package/dist/src/config/transport/index.js +19 -0
  17. package/dist/src/config/transport/transport-strategy.d.ts +77 -0
  18. package/dist/src/config/transport/transport-strategy.js +60 -0
  19. package/dist/src/errors/error-utils.d.ts +2 -0
  20. package/dist/src/errors/error-utils.js +12 -0
  21. package/dist/src/errors/errors.d.ts +140 -0
  22. package/dist/src/errors/errors.js +229 -0
  23. package/dist/src/errors/index.d.ts +2 -0
  24. package/dist/src/errors/index.js +19 -0
  25. package/dist/src/index.d.ts +57 -0
  26. package/dist/src/index.js +137 -0
  27. package/dist/src/internal/clients/auth/AbstractAuthClient.d.ts +10 -0
  28. package/dist/src/internal/clients/auth/AbstractAuthClient.js +13 -0
  29. package/dist/src/internal/clients/auth/IAuthClient.d.ts +4 -0
  30. package/dist/src/internal/clients/auth/IAuthClient.js +3 -0
  31. package/dist/src/internal/clients/auth/index.d.ts +2 -0
  32. package/dist/src/internal/clients/auth/index.js +19 -0
  33. package/dist/src/internal/clients/cache/AbstractCacheClient.d.ts +638 -0
  34. package/dist/src/internal/clients/cache/AbstractCacheClient.js +870 -0
  35. package/dist/src/internal/clients/cache/ICacheClient.d.ts +45 -0
  36. package/dist/src/internal/clients/cache/ICacheClient.js +3 -0
  37. package/dist/src/internal/clients/cache/IControlClient.d.ts +7 -0
  38. package/dist/src/internal/clients/cache/IControlClient.js +3 -0
  39. package/dist/src/internal/clients/cache/IDataClient.d.ts +29 -0
  40. package/dist/src/internal/clients/cache/IDataClient.js +3 -0
  41. package/dist/src/internal/clients/cache/index.d.ts +4 -0
  42. package/dist/src/internal/clients/cache/index.js +21 -0
  43. package/dist/src/internal/clients/index.d.ts +3 -0
  44. package/dist/src/internal/clients/index.js +20 -0
  45. package/dist/src/internal/clients/ping/AbstractPingClient.d.ts +25 -0
  46. package/dist/src/internal/clients/ping/AbstractPingClient.js +29 -0
  47. package/dist/src/internal/clients/ping/IPingClient.d.ts +3 -0
  48. package/dist/src/internal/clients/ping/IPingClient.js +3 -0
  49. package/dist/src/internal/clients/ping/index.d.ts +2 -0
  50. package/dist/src/internal/clients/ping/index.js +19 -0
  51. package/dist/src/internal/subscription-state.d.ts +15 -0
  52. package/dist/src/internal/subscription-state.js +38 -0
  53. package/dist/src/internal/utils/auth.d.ts +25 -0
  54. package/dist/src/internal/utils/auth.js +50 -0
  55. package/dist/src/internal/utils/collections.d.ts +1 -0
  56. package/dist/src/internal/utils/collections.js +8 -0
  57. package/dist/src/internal/utils/display.d.ts +2 -0
  58. package/dist/src/internal/utils/display.js +30 -0
  59. package/dist/src/internal/utils/index.d.ts +7 -0
  60. package/dist/src/internal/utils/index.js +24 -0
  61. package/dist/src/internal/utils/object.d.ts +1 -0
  62. package/dist/src/internal/utils/object.js +8 -0
  63. package/dist/src/internal/utils/sleep.d.ts +1 -0
  64. package/dist/src/internal/utils/sleep.js +6 -0
  65. package/dist/src/internal/utils/string.d.ts +2 -0
  66. package/dist/src/internal/utils/string.js +17 -0
  67. package/dist/src/internal/utils/validators.d.ts +13 -0
  68. package/dist/src/internal/utils/validators.js +105 -0
  69. package/dist/src/internal/vendor/printf/README.md +31 -0
  70. package/dist/src/internal/vendor/printf/printf.d.ts +9 -0
  71. package/dist/src/internal/vendor/printf/printf.js +478 -0
  72. package/dist/src/messages/cache-info.d.ts +5 -0
  73. package/dist/src/messages/cache-info.js +13 -0
  74. package/dist/src/messages/responses/cache-delete.d.ts +61 -0
  75. package/dist/src/messages/responses/cache-delete.js +54 -0
  76. package/dist/src/messages/responses/cache-dictionary-fetch.d.ts +120 -0
  77. package/dist/src/messages/responses/cache-dictionary-fetch.js +162 -0
  78. package/dist/src/messages/responses/cache-dictionary-get-field.d.ts +123 -0
  79. package/dist/src/messages/responses/cache-dictionary-get-field.js +143 -0
  80. package/dist/src/messages/responses/cache-dictionary-get-fields.d.ts +122 -0
  81. package/dist/src/messages/responses/cache-dictionary-get-fields.js +173 -0
  82. package/dist/src/messages/responses/cache-dictionary-increment.d.ts +69 -0
  83. package/dist/src/messages/responses/cache-dictionary-increment.js +68 -0
  84. package/dist/src/messages/responses/cache-dictionary-remove-field.d.ts +61 -0
  85. package/dist/src/messages/responses/cache-dictionary-remove-field.js +54 -0
  86. package/dist/src/messages/responses/cache-dictionary-remove-fields.d.ts +61 -0
  87. package/dist/src/messages/responses/cache-dictionary-remove-fields.js +54 -0
  88. package/dist/src/messages/responses/cache-dictionary-set-field.d.ts +61 -0
  89. package/dist/src/messages/responses/cache-dictionary-set-field.js +54 -0
  90. package/dist/src/messages/responses/cache-dictionary-set-fields.d.ts +61 -0
  91. package/dist/src/messages/responses/cache-dictionary-set-fields.js +54 -0
  92. package/dist/src/messages/responses/cache-flush.d.ts +61 -0
  93. package/dist/src/messages/responses/cache-flush.js +54 -0
  94. package/dist/src/messages/responses/cache-get.d.ts +86 -0
  95. package/dist/src/messages/responses/cache-get.js +88 -0
  96. package/dist/src/messages/responses/cache-increment.d.ts +69 -0
  97. package/dist/src/messages/responses/cache-increment.js +68 -0
  98. package/dist/src/messages/responses/cache-list-concatenate-back.d.ts +69 -0
  99. package/dist/src/messages/responses/cache-list-concatenate-back.js +68 -0
  100. package/dist/src/messages/responses/cache-list-concatenate-front.d.ts +69 -0
  101. package/dist/src/messages/responses/cache-list-concatenate-front.js +68 -0
  102. package/dist/src/messages/responses/cache-list-fetch.d.ts +92 -0
  103. package/dist/src/messages/responses/cache-list-fetch.js +96 -0
  104. package/dist/src/messages/responses/cache-list-length.d.ts +84 -0
  105. package/dist/src/messages/responses/cache-list-length.js +78 -0
  106. package/dist/src/messages/responses/cache-list-pop-back.d.ts +86 -0
  107. package/dist/src/messages/responses/cache-list-pop-back.js +88 -0
  108. package/dist/src/messages/responses/cache-list-pop-front.d.ts +86 -0
  109. package/dist/src/messages/responses/cache-list-pop-front.js +88 -0
  110. package/dist/src/messages/responses/cache-list-push-back.d.ts +69 -0
  111. package/dist/src/messages/responses/cache-list-push-back.js +68 -0
  112. package/dist/src/messages/responses/cache-list-push-front.d.ts +69 -0
  113. package/dist/src/messages/responses/cache-list-push-front.js +68 -0
  114. package/dist/src/messages/responses/cache-list-remove-value.d.ts +61 -0
  115. package/dist/src/messages/responses/cache-list-remove-value.js +54 -0
  116. package/dist/src/messages/responses/cache-list-retain.d.ts +61 -0
  117. package/dist/src/messages/responses/cache-list-retain.js +54 -0
  118. package/dist/src/messages/responses/cache-set-add-element.d.ts +71 -0
  119. package/dist/src/messages/responses/cache-set-add-element.js +54 -0
  120. package/dist/src/messages/responses/cache-set-add-elements.d.ts +65 -0
  121. package/dist/src/messages/responses/cache-set-add-elements.js +61 -0
  122. package/dist/src/messages/responses/cache-set-fetch.d.ts +111 -0
  123. package/dist/src/messages/responses/cache-set-fetch.js +121 -0
  124. package/dist/src/messages/responses/cache-set-if-not-exists.d.ts +74 -0
  125. package/dist/src/messages/responses/cache-set-if-not-exists.js +63 -0
  126. package/dist/src/messages/responses/cache-set-remove-element.d.ts +61 -0
  127. package/dist/src/messages/responses/cache-set-remove-element.js +54 -0
  128. package/dist/src/messages/responses/cache-set-remove-elements.d.ts +65 -0
  129. package/dist/src/messages/responses/cache-set-remove-elements.js +61 -0
  130. package/dist/src/messages/responses/cache-set.d.ts +61 -0
  131. package/dist/src/messages/responses/cache-set.js +54 -0
  132. package/dist/src/messages/responses/cache-sorted-set-fetch.d.ts +107 -0
  133. package/dist/src/messages/responses/cache-sorted-set-fetch.js +124 -0
  134. package/dist/src/messages/responses/cache-sorted-set-get-rank.d.ts +81 -0
  135. package/dist/src/messages/responses/cache-sorted-set-get-rank.js +78 -0
  136. package/dist/src/messages/responses/cache-sorted-set-get-score.d.ts +118 -0
  137. package/dist/src/messages/responses/cache-sorted-set-get-score.js +131 -0
  138. package/dist/src/messages/responses/cache-sorted-set-get-scores.d.ts +109 -0
  139. package/dist/src/messages/responses/cache-sorted-set-get-scores.js +148 -0
  140. package/dist/src/messages/responses/cache-sorted-set-increment-score.d.ts +69 -0
  141. package/dist/src/messages/responses/cache-sorted-set-increment-score.js +68 -0
  142. package/dist/src/messages/responses/cache-sorted-set-put-element.d.ts +61 -0
  143. package/dist/src/messages/responses/cache-sorted-set-put-element.js +54 -0
  144. package/dist/src/messages/responses/cache-sorted-set-put-elements.d.ts +61 -0
  145. package/dist/src/messages/responses/cache-sorted-set-put-elements.js +54 -0
  146. package/dist/src/messages/responses/cache-sorted-set-remove-element.d.ts +61 -0
  147. package/dist/src/messages/responses/cache-sorted-set-remove-element.js +54 -0
  148. package/dist/src/messages/responses/cache-sorted-set-remove-elements.d.ts +61 -0
  149. package/dist/src/messages/responses/cache-sorted-set-remove-elements.js +54 -0
  150. package/dist/src/messages/responses/create-cache.d.ts +77 -0
  151. package/dist/src/messages/responses/create-cache.js +61 -0
  152. package/dist/src/messages/responses/create-signing-key.d.ts +71 -0
  153. package/dist/src/messages/responses/create-signing-key.js +76 -0
  154. package/dist/src/messages/responses/delete-cache.d.ts +61 -0
  155. package/dist/src/messages/responses/delete-cache.js +54 -0
  156. package/dist/src/messages/responses/generate-api-token.d.ts +50 -0
  157. package/dist/src/messages/responses/generate-api-token.js +52 -0
  158. package/dist/src/messages/responses/grpc-response-types.d.ts +41 -0
  159. package/dist/src/messages/responses/grpc-response-types.js +53 -0
  160. package/dist/src/messages/responses/list-caches.d.ts +70 -0
  161. package/dist/src/messages/responses/list-caches.js +69 -0
  162. package/dist/src/messages/responses/list-signing-keys.d.ts +68 -0
  163. package/dist/src/messages/responses/list-signing-keys.js +68 -0
  164. package/dist/src/messages/responses/response-base.d.ts +43 -0
  165. package/dist/src/messages/responses/response-base.js +50 -0
  166. package/dist/src/messages/responses/revoke-signing-key.d.ts +61 -0
  167. package/dist/src/messages/responses/revoke-signing-key.js +54 -0
  168. package/dist/src/messages/responses/topic-item.d.ts +27 -0
  169. package/dist/src/messages/responses/topic-item.js +43 -0
  170. package/dist/src/messages/responses/topic-publish.d.ts +61 -0
  171. package/dist/src/messages/responses/topic-publish.js +54 -0
  172. package/dist/src/messages/responses/topic-subscribe.d.ts +69 -0
  173. package/dist/src/messages/responses/topic-subscribe.js +72 -0
  174. package/dist/src/messages/signing-key.d.ts +9 -0
  175. package/dist/src/messages/signing-key.js +21 -0
  176. package/dist/src/utils/cache-call-options.d.ts +99 -0
  177. package/dist/src/utils/cache-call-options.js +9 -0
  178. package/dist/src/utils/collection-ttl.d.ts +78 -0
  179. package/dist/src/utils/collection-ttl.js +102 -0
  180. package/dist/src/utils/index.d.ts +3 -0
  181. package/dist/src/utils/index.js +20 -0
  182. package/dist/src/utils/topic-call-options.d.ts +19 -0
  183. package/dist/src/utils/topic-call-options.js +3 -0
  184. package/package.json +53 -0
@@ -0,0 +1,870 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AbstractCacheClient = void 0;
4
+ class AbstractCacheClient {
5
+ constructor(controlClient, dataClients) {
6
+ this.controlClient = controlClient;
7
+ this.dataClients = dataClients;
8
+ // We round-robin the requests through all of our clients. Since javascript
9
+ // is single-threaded, we don't have to worry about thread safety on this
10
+ // index variable.
11
+ this.nextDataClientIndex = 0;
12
+ }
13
+ /**
14
+ * Creates a cache if it does not exist.
15
+ *
16
+ * @param {string} cacheName - The cache to be created.
17
+ * @returns {Promise<CreateCache.Response>} -
18
+ * {@link CreateCache.Success} on success.
19
+ * {@link CreateCache.AlreadyExists} if the cache already exists.
20
+ * {@link CreateCache.Error} on failure.
21
+ */
22
+ async createCache(cacheName) {
23
+ return await this.controlClient.createCache(cacheName);
24
+ }
25
+ /**
26
+ * Deletes a cache and all items stored in it.
27
+ *
28
+ * @param {string} cacheName - The cache to delete.
29
+ * @returns {Promise<DeleteCache.Response>} -
30
+ * {@link DeleteCache.Success} on success.
31
+ * {@link DeleteCache.Error} on failure.
32
+ */
33
+ async deleteCache(cacheName) {
34
+ return await this.controlClient.deleteCache(cacheName);
35
+ }
36
+ /**
37
+ * Lists all caches.
38
+ *
39
+ * @returns {Promise<ListCaches.Response>} -
40
+ * {@link ListCaches.Success} containing the list on success.
41
+ * {@link ListCaches.Error} on failure.
42
+ */
43
+ async listCaches() {
44
+ return await this.controlClient.listCaches();
45
+ }
46
+ /**
47
+ * Gets the value stored for the given key.
48
+ *
49
+ * @param {string} cacheName - The cache to perform the lookup in.
50
+ * @param {string | Uint8Array} key - The key to look up.
51
+ * @returns {Promise<CacheGet.Response>} -
52
+ * {@link CacheGet.Hit} containing the value if one is found.
53
+ * {@link CacheGet.Miss} if the key does not exist.
54
+ * {@link CacheGet.Error} on failure.
55
+ */
56
+ async get(cacheName, key) {
57
+ return await this.getNextDataClient().get(cacheName, key);
58
+ }
59
+ /**
60
+ * Associates the given key with the given value. If a value for the key is
61
+ * already present it is replaced with the new value.
62
+ *
63
+ * @param {string} cacheName - The cache to store the value in.
64
+ * @param {string | Uint8Array} key - The key to set.
65
+ * @param {string | Uint8Array} value - The value to be stored.
66
+ * @param {SetOptions} [options]
67
+ * @param {number} [options.ttl] - The time to live for the item in the cache.
68
+ * Uses the client's default TTL if this is not supplied.
69
+ * @returns {Promise<CacheSet.Response>} -
70
+ * {@link CacheSet.Success} on success.
71
+ * {@link CacheSet.Error} on failure.
72
+ */
73
+ async set(cacheName, key, value, options) {
74
+ const client = this.getNextDataClient();
75
+ return await client.set(cacheName, key, value, options === null || options === void 0 ? void 0 : options.ttl);
76
+ }
77
+ /**
78
+ * Removes the given key from the cache. The key can represent a single value
79
+ * or a collection.
80
+ *
81
+ * @param {string} cacheName - The cache to delete from.
82
+ * @param {string | Uint8Array} key - The key to delete.
83
+ * @returns {Promise<CacheDelete.Response>} -
84
+ * {@link CacheDelete.Success} on success.
85
+ * {@link CacheDelete.Error} on failure.
86
+ */
87
+ async delete(cacheName, key) {
88
+ const client = this.getNextDataClient();
89
+ return await client.delete(cacheName, key);
90
+ }
91
+ /**
92
+ * Adds multiple elements to the back of the given list. Creates the list if
93
+ * it does not already exist.
94
+ *
95
+ * @param {string} cacheName - The cache to store the list in.
96
+ * @param {string} listName - The list to add to.
97
+ * @param {string[] | Uint8Array[]} values - The elements to add to the list.
98
+ * @param {ListConcatenateBackOptions} [options]
99
+ * @param {number} [options.truncateFrontToSize] - If the list exceeds this
100
+ * length, remove excess from the front of the list. Must be positive.
101
+ * @param {CollectionTtl} [options.ttl] - How the TTL should be managed.
102
+ * Refreshes the list's TTL using the client's default if this is not
103
+ * supplied.
104
+ * @returns {Promise<CacheListConcatenateBack.Response>} -
105
+ * {@link CacheListConcatenateBack.Success} on success.
106
+ * {@link CacheListConcatenateBack.Error} on failure.
107
+ */
108
+ async listConcatenateBack(cacheName, listName, values, options) {
109
+ const client = this.getNextDataClient();
110
+ return await client.listConcatenateBack(cacheName, listName, values, options === null || options === void 0 ? void 0 : options.truncateFrontToSize, options === null || options === void 0 ? void 0 : options.ttl);
111
+ }
112
+ /**
113
+ * Adds multiple elements to the front of the given list. Creates the list if
114
+ * it does not already exist.
115
+ *
116
+ * @param {string} cacheName - The cache to store the list in.
117
+ * @param {string} listName - The list to add to.
118
+ * @param {string[] | Uint8Array[]} values - The elements to add to the list.
119
+ * @param {ListConcatenateFrontOptions} [options]
120
+ * @param {number} [options.truncateBackToSize] - If the list exceeds this
121
+ * length, remove excess from the back of the list. Must be positive.
122
+ * @param {CollectionTtl} [options.ttl] - How the TTL should be managed.
123
+ * Refreshes the list's TTL using the client's default if this is not
124
+ * supplied.
125
+ * @returns {Promise<CacheListConcatenateFront.Response>} -
126
+ * {@link CacheListConcatenateFront.Success} on success.
127
+ * {@link CacheListConcatenateFront.Error} on failure.
128
+ */
129
+ async listConcatenateFront(cacheName, listName, values, options) {
130
+ const client = this.getNextDataClient();
131
+ return await client.listConcatenateFront(cacheName, listName, values, options === null || options === void 0 ? void 0 : options.truncateBackToSize, options === null || options === void 0 ? void 0 : options.ttl);
132
+ }
133
+ /**
134
+ * Fetches all elements of the given list.
135
+ *
136
+ * @param {string} cacheName - The cache containing the list.
137
+ * @param {string} listName - The list to fetch.
138
+ * @param {ListFetchCallOptions} [options]
139
+ * @param {number} [options.startIndex] - Start inclusive index for fetch operation.
140
+ * @param {number} [options.endIndex] - End exclusive index for fetch operation.
141
+ * @returns {Promise<CacheListFetch.Response>} -
142
+ * {@link CacheListFetch.Hit} containing the list elements if the list exists.
143
+ * {@link CacheListFetch.Miss} if the list does not exist.
144
+ * {@link CacheListFetch.Error} on failure.
145
+ */
146
+ async listFetch(cacheName, listName, options) {
147
+ const client = this.getNextDataClient();
148
+ return await client.listFetch(cacheName, listName, options === null || options === void 0 ? void 0 : options.startIndex, options === null || options === void 0 ? void 0 : options.endIndex);
149
+ }
150
+ /**
151
+ * Gets the number of elements in the given list.
152
+ *
153
+ * @param {string} cacheName - The cache containing the list.
154
+ * @param {string} listName - The list to get the length of.
155
+ * @returns {Promise<CacheListLength.Response>} -
156
+ * {@link CacheListLength.Hit} containing the length if the list exists.
157
+ * {@link CacheListLength.Miss} if the list does not exist.
158
+ * {@link CacheListLength.Error} on failure.
159
+ */
160
+ async listLength(cacheName, listName) {
161
+ const client = this.getNextDataClient();
162
+ return await client.listLength(cacheName, listName);
163
+ }
164
+ /**
165
+ * Gets and removes the last value from the given list.
166
+ *
167
+ * @param {string} cacheName - The cache containing the list.
168
+ * @param {string} listName - The list to pop.
169
+ * @returns {Promise<CacheListPopBack.Response>} -
170
+ * {@link CacheListPopBack.Hit} containing the element if the list exists.
171
+ * {@link CacheListPopBack.Miss} if the list does not exist.
172
+ * {@link CacheListPopBack.Error} on failure.
173
+ */
174
+ async listPopBack(cacheName, listName) {
175
+ const client = this.getNextDataClient();
176
+ return await client.listPopBack(cacheName, listName);
177
+ }
178
+ /**
179
+ * Gets and removes the first value from the given list.
180
+ *
181
+ * @param {string} cacheName - The cache containing the list.
182
+ * @param {string} listName - The list to pop.
183
+ * @returns {Promise<CacheListPopFront.Response>} -
184
+ * {@link CacheListPopFront.Hit} containing the element if the list exists.
185
+ * {@link CacheListPopFront.Miss} if the list does not exist.
186
+ * {@link CacheListPopFront.Error} on failure.
187
+ */
188
+ async listPopFront(cacheName, listName) {
189
+ const client = this.getNextDataClient();
190
+ return await client.listPopFront(cacheName, listName);
191
+ }
192
+ /**
193
+ * Adds an element to the back of the given list. Creates the list if
194
+ * it does not already exist.
195
+ *
196
+ * @param {string} cacheName - The cache to store the list in.
197
+ * @param {string} listName - The list to push to.
198
+ * @param {string | Uint8Array} value - The value to push.
199
+ * @param {ListPushBackOptions} [options]
200
+ * @param {number} [options.truncateFrontToSize] - If the list exceeds this
201
+ * length, remove excess from the front of the list. Must be positive.
202
+ * @param {CollectionTtl} [options.ttl] - How the TTL should be managed.
203
+ * Refreshes the list's TTL using the client's default if this is not
204
+ * supplied.
205
+ * @returns {Promise<CacheListPushBack.Response>} -
206
+ * {@link CacheListPushBack.Success} containing the list's new length on
207
+ * success.
208
+ * {@link CacheListPushBack.Error} on failure.
209
+ */
210
+ async listPushBack(cacheName, listName, value, options) {
211
+ const client = this.getNextDataClient();
212
+ return await client.listPushBack(cacheName, listName, value, options === null || options === void 0 ? void 0 : options.truncateFrontToSize, options === null || options === void 0 ? void 0 : options.ttl);
213
+ }
214
+ /**
215
+ * Adds an element to the front of the given list. Creates the list if
216
+ * it does not already exist.
217
+ *
218
+ * @param {string} cacheName - The cache to store the list in.
219
+ * @param {string} listName - The list to push to.
220
+ * @param {string | Uint8Array} value - The value to push.
221
+ * @param {ListPushFrontOptions} [options]
222
+ * @param {number} [options.truncateBackToSize] - If the list exceeds this
223
+ * length, remove excess from the end of the list. Must be positive.
224
+ * @param {CollectionTtl} [options.ttl] - How the TTL should be managed.
225
+ * Refreshes the list's TTL using the client's default if this is not
226
+ * supplied.
227
+ * @returns {Promise<CacheListPushFront.Response>} -
228
+ * {@link CacheListPushFront.Success} containing the list's new length on
229
+ * success.
230
+ * {@link CacheListPushFront.Error} on failure.
231
+ */
232
+ async listPushFront(cacheName, listName, value, options) {
233
+ const client = this.getNextDataClient();
234
+ return await client.listPushFront(cacheName, listName, value, options === null || options === void 0 ? void 0 : options.truncateBackToSize, options === null || options === void 0 ? void 0 : options.ttl);
235
+ }
236
+ /**
237
+ * Removes all elements from the given list equal to the given value.
238
+ *
239
+ * @param {string} cacheName - The cache containing the list.
240
+ * @param {string} listName - The list to remove from.
241
+ * @param {string | Uint8Array} value - The value to remove.
242
+ * @returns {Promise<CacheListRemoveValue.Response>} -
243
+ * {@link CacheListRemoveValue.Success} on success. Removing an element that
244
+ * does not occur in the list or removing from a non-existent list counts as a
245
+ * success.
246
+ * {@link CacheListRemoveValue.Error} on failure.
247
+ */
248
+ async listRemoveValue(cacheName, listName, value) {
249
+ const client = this.getNextDataClient();
250
+ return await client.listRemoveValue(cacheName, listName, value);
251
+ }
252
+ /**
253
+ * Retains slice of elements of a given list, deletes the rest of the list
254
+ * that isn't being retained. Returns a Success or Error.
255
+ *
256
+ * @param {string} cacheName - The cache containing the list.
257
+ * @param {string} listName - The list to retain a slice of.
258
+ * @param {ListRetainCallOptions} [options]
259
+ * @param {number} [options.startIndex] - Start inclusive index for fetch
260
+ * operation. Defaults to start of array if not given, 0.
261
+ * @param {number} [options.endIndex] - End exclusive index for fetch
262
+ * operation. Defaults to end of array if not given.
263
+ * @param {CollectionTtl} [options.ttl] - How the TTL should be managed.
264
+ * Refreshes the list's TTL using the client's default if this is not
265
+ * supplied.
266
+ * @returns {Promise<CacheListRetain.Response>} -
267
+ * {@link CacheListRetain.Success} on success.
268
+ * {@link CacheListRetain.Error} on failure.
269
+ */
270
+ async listRetain(cacheName, listName, options) {
271
+ const client = this.getNextDataClient();
272
+ return await client.listRetain(cacheName, listName, options === null || options === void 0 ? void 0 : options.startIndex, options === null || options === void 0 ? void 0 : options.endIndex, options === null || options === void 0 ? void 0 : options.ttl);
273
+ }
274
+ /**
275
+ * Fetches all elements of the given set
276
+ *
277
+ * @param {string} cacheName - The cache containing the set.
278
+ * @param {string} setName - The set to fetch.
279
+ * @returns {Promise<CacheSetFetch.Response>} -
280
+ * {@link CacheSetFetch.Hit} containing the set elements if the set exists.
281
+ * {@link CacheSetFetch.Miss} if the set does not exist.
282
+ * {@link CacheSetFetch.Error} on failure.
283
+ */
284
+ async setFetch(cacheName, setName) {
285
+ const client = this.getNextDataClient();
286
+ return await client.setFetch(cacheName, setName);
287
+ }
288
+ /**
289
+ * Adds an element to the given set. Creates the set if it does not already
290
+ * exist.
291
+ *
292
+ * @remarks
293
+ * After this operation the set will contain the union of the element passed
294
+ * in and the original elements of the set.
295
+ *
296
+ * @param {string} cacheName - The cache to store the set in.
297
+ * @param {string} setName - The set to add to.
298
+ * @param {string | Uint8Array} element - The element to add.
299
+ * @param {SetAddElementOptions} options
300
+ * @param {CollectionTtl} [options.ttl] - How the TTL should be managed.
301
+ * Refreshes the set's TTL using the client's default if this is not supplied.
302
+ * @returns {Promise<CacheSetAddElement.Response>} -
303
+ * {@link CacheSetAddElement.Success} on success.
304
+ * {@link CacheSetAddElement.Error} on failure.
305
+ */
306
+ async setAddElement(cacheName, setName, element, options) {
307
+ return (await this.setAddElements(cacheName, setName, [element], options)).toSingularResponse();
308
+ }
309
+ /**
310
+ * Adds multiple elements to the given set. Creates the set if it does not
311
+ * already exist.
312
+ *
313
+ * @remarks
314
+ * After this operation, the set will contain the union of the elements passed
315
+ * in and the original elements of the set.
316
+ *
317
+ * @param {string} cacheName - The cache to store the set in.
318
+ * @param {string} setName - The set to add to.
319
+ * @param {string[] | Uint8Array[]} elements - The elements to add.
320
+ * @param {SetAddElementsOptions} options
321
+ * @param {CollectionTtl} [options.ttl] - How the TTL should be managed.
322
+ * Refreshes the set's TTL using the client's default if this is not supplied.
323
+ * @returns {Promise<CacheSetAddElements.Response>} -
324
+ * {@link CacheSetAddElements.Success} on success.
325
+ * {@link CacheSetAddElements.Error} on failure.
326
+ */
327
+ async setAddElements(cacheName, setName, elements, options) {
328
+ const client = this.getNextDataClient();
329
+ return await client.setAddElements(cacheName, setName, elements, options === null || options === void 0 ? void 0 : options.ttl);
330
+ }
331
+ /**
332
+ * Removes an element from the given set.
333
+ *
334
+ * @param {string} cacheName - The cache containing the set.
335
+ * @param {string} setName - The set to remove from.
336
+ * @param {string | Uint8Array} element - The element to remove.
337
+ * @returns {Promise<CacheSetRemoveElement.Response>} -
338
+ * {@link CacheSetRemoveElement.Success} on success. Removing an element that
339
+ * does not occur in the set or removing from a non-existent set counts as a
340
+ * success.
341
+ * {@link CacheSetRemoveElement.Error} on failure.
342
+ */
343
+ async setRemoveElement(cacheName, setName, element) {
344
+ return (await this.setRemoveElements(cacheName, setName, [element])).toSingularResponse();
345
+ }
346
+ /**
347
+ * Removes multiple elements from the given set.
348
+ *
349
+ * @param {string} cacheName - The cache containing the set.
350
+ * @param {string} setName - The set to remove from.
351
+ * @param {string[] | Uint8Array[]} elements - The elements to remove.
352
+ * @returns {Promise<CacheSetRemoveElements.Response>} -
353
+ * {@link CacheSetRemoveElements.Success} on success. Removing elements that
354
+ * do not occur in the set or removing from a non-existent set counts as a
355
+ * success.
356
+ * {@link CacheSetRemoveElements.Error} on failure.
357
+ */
358
+ async setRemoveElements(cacheName, setName, elements) {
359
+ const client = this.getNextDataClient();
360
+ return await client.setRemoveElements(cacheName, setName, elements);
361
+ }
362
+ /**
363
+ * Associates the given key with the given value. If a value for the key is
364
+ * already present it is not replaced with the new value.
365
+ *
366
+ * @param {string} cacheName - The cache to store the value in.
367
+ * @param {string | Uint8Array} key - The key to set.
368
+ * @param {string | Uint8Array} field - The value to be stored.
369
+ * @param {SetIfNotExistsOptions} [options]
370
+ * @param {number} [options.ttl] - The time to live for the item in the cache.
371
+ * Uses the client's default TTL if this is not supplied.
372
+ * @returns {Promise<CacheSetIfNotExists.Response>} -
373
+ * {@link CacheSetIfNotExists.Stored} on storing the new value.
374
+ * {@link CacheSetIfNotExists.NotStored} on not storing the new value.
375
+ * {@link CacheSetIfNotExists.Error} on failure.
376
+ */
377
+ async setIfNotExists(cacheName, key, field, options) {
378
+ const client = this.getNextDataClient();
379
+ return await client.setIfNotExists(cacheName, key, field, options === null || options === void 0 ? void 0 : options.ttl);
380
+ }
381
+ /**
382
+ * Flushes / clears all the items of the given cache
383
+ *
384
+ * @param {string} cacheName - The cache to be flushed.
385
+ * @returns {Promise<CacheFlush.Response>} -
386
+ * {@link CacheFlush.Success} on success.
387
+ * {@link CacheFlush.Error} on failure.
388
+ */
389
+ async flushCache(cacheName) {
390
+ return await this.controlClient.flushCache(cacheName);
391
+ }
392
+ /**
393
+ * Fetches all elements of the given dictionary.
394
+ *
395
+ * @param {string} cacheName - The cache to perform the lookup in.
396
+ * @param {string} dictionaryName - The dictionary to fetch.
397
+ * @returns {Promise<CacheDictionaryFetch.Response>} -
398
+ * {@link CacheDictionaryFetch.Hit} containing the dictionary elements if the
399
+ * dictionary exists.
400
+ * {@link CacheDictionaryFetch.Miss} if the dictionary does not exist.
401
+ * {@link CacheDictionaryFetch.Error} on failure.
402
+ */
403
+ async dictionaryFetch(cacheName, dictionaryName) {
404
+ const client = this.getNextDataClient();
405
+ return await client.dictionaryFetch(cacheName, dictionaryName);
406
+ }
407
+ /**
408
+ * Adds an integer quantity to a field value.
409
+ *
410
+ * @remarks
411
+ * Incrementing the value of a missing field sets the value to amount.
412
+ *
413
+ * @param {string} cacheName - The cache containing the field.
414
+ * @param {string | Uint8Array} field - The field to increment.
415
+ * @param {number} amount - The quantity to add to the value. May be positive,
416
+ * negative, or zero. Defaults to 1.
417
+ * @param {IncrementOptions} options
418
+ * @param {CollectionTtl} [options.ttl] - How the TTL should be managed.
419
+ * @returns {Promise<CacheIncrement>} -
420
+ * {@link CacheIncrement.Success} containing the incremented value
421
+ * on success.
422
+ * {@link CacheIncrement.Error} on failure. Incrementing a value
423
+ * that was not set using this method or is not the string representation of
424
+ * an integer results in a failure with a FailedPreconditionException error.
425
+ */
426
+ async increment(cacheName, field, amount = 1, options) {
427
+ const client = this.getNextDataClient();
428
+ return await client.increment(cacheName, field, amount, options === null || options === void 0 ? void 0 : options.ttl);
429
+ }
430
+ /**
431
+ * Adds an element to the given dictionary. Creates the dictionary if it does
432
+ * not already exist.
433
+ *
434
+ * @param {string} cacheName - The cache to store the dictionary in.
435
+ * @param {string} dictionaryName - The dictionary to add to.
436
+ * @param {string | Uint8Array} field - The field to set.
437
+ * @param {string | Uint8Array} value - The value to store.
438
+ * @param {DictionarySetFieldOptions} options
439
+ * @param {CollectionTtl} [options.ttl] - How the TTL should be managed.
440
+ * Refreshes the dictionary's TTL using the client's default if this is not
441
+ * supplied.
442
+ * @returns {Promise<CacheDictionarySetField.Response>} -
443
+ * {@link CacheDictionarySetField.Success} on success.
444
+ * {@link CacheDictionarySetField.Error} on failure.
445
+ */
446
+ async dictionarySetField(cacheName, dictionaryName, field, value, options) {
447
+ const client = this.getNextDataClient();
448
+ return await client.dictionarySetField(cacheName, dictionaryName, field, value, options === null || options === void 0 ? void 0 : options.ttl);
449
+ }
450
+ /**
451
+ * Adds multiple elements to the given dictionary. Creates the dictionary if
452
+ * it does not already exist.
453
+ *
454
+ * @param {string} cacheName - The cache to store the dictionary in.
455
+ * @param {string} dictionaryName - The dictionary to add to.
456
+ * @param {Map<string | Uint8Array, string | Uint8Array>} elements - The
457
+ * elements to set.
458
+ * @param {DictionarySetFieldsOptions} options
459
+ * @param {CollectionTtl} [options.ttl] - How the TTL should be managed.
460
+ * Refreshes the dictionary's TTL using the client's default if this is not
461
+ * supplied.
462
+ * @returns {Promise<CacheDictionarySetFields.Response>} -
463
+ * {@link CacheDictionarySetFields.Success} on success.
464
+ * {@link CacheDictionarySetFields.Error} on failure.
465
+ */
466
+ async dictionarySetFields(cacheName, dictionaryName, elements, options) {
467
+ const client = this.getNextDataClient();
468
+ return await client.dictionarySetFields(cacheName, dictionaryName, elements, options === null || options === void 0 ? void 0 : options.ttl);
469
+ }
470
+ /**
471
+ * Gets the value stored for the given dictionary and field.
472
+ *
473
+ * @param {string} cacheName - The cache containing the dictionary.
474
+ * @param {string} dictionaryName - The dictionary to look up.
475
+ * @param {string | Uint8Array} field - The field to look up.
476
+ * @returns {Promise<CacheDictionaryGetField.Response>} -
477
+ * {@link CacheDictionaryGetField.Hit} containing the dictionary element if
478
+ * one is found.
479
+ * {@link CacheDictionaryGetField.Miss} if the dictionary does not exist.
480
+ * {@link CacheDictionaryGetField.Error} on failure.
481
+ */
482
+ async dictionaryGetField(cacheName, dictionaryName, field) {
483
+ const client = this.getNextDataClient();
484
+ return await client.dictionaryGetField(cacheName, dictionaryName, field);
485
+ }
486
+ /**
487
+ * Gets multiple values from the given dictionary.
488
+ *
489
+ * @param {string} cacheName - The cache containing the dictionary.
490
+ * @param {string} dictionaryName - The dictionary to look up.
491
+ * @param {string[] | Uint8Array[]} fields - The fields to look up.
492
+ * @returns {Promise<CacheDictionaryGetFields.Response>} -
493
+ * {@link CacheDictionaryGetFields.Hit} containing the dictionary elements if
494
+ * the dictionary exists.
495
+ * {@link CacheDictionaryGetFields.Miss} if the dictionary does not exist.
496
+ * {@link CacheDictionaryGetFields.Error} on failure.
497
+ */
498
+ async dictionaryGetFields(cacheName, dictionaryName, fields) {
499
+ const client = this.getNextDataClient();
500
+ return await client.dictionaryGetFields(cacheName, dictionaryName, fields);
501
+ }
502
+ /**
503
+ * Removes an element from the given dictionary.
504
+ *
505
+ * @remarks
506
+ * Performs a no-op if the dictionary or field does not exist.
507
+ *
508
+ * @param {string} cacheName - The cache containing the dictionary.
509
+ * @param {string} dictionaryName - The dictionary to remove from.
510
+ * @param {string | Uint8Array} field - The field to remove.
511
+ * @returns {Promise<CacheDictionaryRemoveField.Response>} -
512
+ * {@link CacheDictionaryRemoveField.Success} on success.
513
+ * {@link CacheDictionaryRemoveField.Error} on failure.
514
+ */
515
+ async dictionaryRemoveField(cacheName, dictionaryName, field) {
516
+ const client = this.getNextDataClient();
517
+ return await client.dictionaryRemoveField(cacheName, dictionaryName, field);
518
+ }
519
+ /**
520
+ * Removes multiple fields from the given dictionary.
521
+ *
522
+ * @remarks
523
+ * Performs a no-op if the dictionary or fields do not exist.
524
+ *
525
+ * @param {string} cacheName - The cache containing the dictionary.
526
+ * @param {string} dictionaryName - The dictionary to remove from.
527
+ * @param {string[] | Uint8Array[]} fields - The fields to remove.
528
+ * @returns {Promise<CacheDictionaryRemoveFields.Response>} -
529
+ * {@link CacheDictionaryRemoveFields.Success} on success.
530
+ * {@link CacheDictionaryRemoveFields.Error} on failure.
531
+ */
532
+ async dictionaryRemoveFields(cacheName, dictionaryName, fields) {
533
+ const client = this.getNextDataClient();
534
+ return await client.dictionaryRemoveFields(cacheName, dictionaryName, fields);
535
+ }
536
+ /**
537
+ * Adds an integer quantity to a dictionary value.
538
+ *
539
+ * @remarks
540
+ * Incrementing the value of a missing field sets the value to amount.
541
+ *
542
+ * @param {string} cacheName - The cache containing the dictionary.
543
+ * @param {string} dictionaryName - The dictionary to set.
544
+ * @param {string | Uint8Array} field - The field to increment.
545
+ * @param {number} amount - The quantity to add to the value. May be positive,
546
+ * negative, or zero. Defaults to 1.
547
+ * @param {DictionaryIncrementOptions} options
548
+ * @param {CollectionTtl} [options.ttl] - How the TTL should be managed.
549
+ * Refreshes the dictionary's TTL using the client's default if this is not
550
+ * supplied.
551
+ * @returns {Promise<CacheDictionaryIncrement.Response>} -
552
+ * {@link CacheDictionaryIncrement.Success} containing the incremented value
553
+ * on success.
554
+ * {@link CacheDictionaryIncrement.Error} on failure. Incrementing a value
555
+ * that was not set using this method or is not the string representation of
556
+ * an integer results in a failure with a FailedPreconditionException error.
557
+ */
558
+ async dictionaryIncrement(cacheName, dictionaryName, field, amount = 1, options) {
559
+ const client = this.getNextDataClient();
560
+ return await client.dictionaryIncrement(cacheName, dictionaryName, field, amount, options === null || options === void 0 ? void 0 : options.ttl);
561
+ }
562
+ /**
563
+ * Adds an element to the given sorted set. If the element already exists, its
564
+ * score is updated. Creates the sorted set if it does not exist.
565
+ *
566
+ * @param {string} cacheName - The cache containing the sorted set.
567
+ * @param {string} sortedSetName - The sorted set to add to.
568
+ * @param {string | Uint8Array} value - The value to add.
569
+ * @param {number} score - The score to assign to the value.
570
+ * @param {SortedSetPutElementOptions} options
571
+ * @param {CollectionTtl} [options.ttl] - How the TTL should be managed.
572
+ * Refreshes the sorted set's TTL using the client's default if this is not
573
+ * supplied.
574
+ * @returns {Promise<CacheSortedSetPutElement.Response>} -
575
+ * {@link CacheSortedSetPutElement.Success} on success.
576
+ * {@link CacheSortedSetPutElement.Error} on failure.
577
+ * @returns
578
+ */
579
+ // public async sortedSetPutElement(
580
+ // cacheName: string,
581
+ // sortedSetName: string,
582
+ // value: string | Uint8Array,
583
+ // score: number,
584
+ // options?: SortedSetPutElementOptions
585
+ // ): Promise<CacheSortedSetPutElement.Response> {
586
+ // const client = this.getNextDataClient();
587
+ // return await client.sortedSetPutElement(
588
+ // cacheName,
589
+ // sortedSetName,
590
+ // value,
591
+ // score,
592
+ // options?.ttl
593
+ // );
594
+ // }
595
+ /**
596
+ * Adds elements to the given sorted set. For any values that already exist, it
597
+ * the score is updated. Creates the sorted set if it does not exist.
598
+ *
599
+ * @param {string} cacheName - The cache containing the sorted set.
600
+ * @param {string} sortedSetName - The sorted set to add to.
601
+ * @param {Map<string | Uint8Array, number>| Record<string, number>} elements - The value->score pairs to add to the sorted set.
602
+ * @param {SortedSetPutElementOptions} options
603
+ * @param {CollectionTtl} [options.ttl] - How the TTL should be managed.
604
+ * Refreshes the sorted set's TTL using the client's default if this is not
605
+ * supplied.
606
+ * @returns {Promise<CacheSortedSetPutElements.Response>} -
607
+ * {@link CacheSortedSetPutElements.Success} on success.
608
+ * {@link CacheSortedSetPutElements.Error} on failure.
609
+ * @returns
610
+ */
611
+ // public async sortedSetPutElements(
612
+ // cacheName: string,
613
+ // sortedSetName: string,
614
+ // elements: Map<string | Uint8Array, number> | Record<string, number>,
615
+ // options?: SortedSetPutElementsOptions
616
+ // ): Promise<CacheSortedSetPutElements.Response> {
617
+ // const client = this.getNextDataClient();
618
+ // return await client.sortedSetPutElements(
619
+ // cacheName,
620
+ // sortedSetName,
621
+ // elements,
622
+ // options?.ttl
623
+ // );
624
+ // }
625
+ // sorted set put values
626
+ /**
627
+ * Fetch the elements in the given sorted set by index (rank).
628
+ *
629
+ * @param {string} cacheName - The cache containing the sorted set.
630
+ * @param {string} sortedSetName - The sorted set to fetch from.
631
+ * @param {SortedSetFetchByRankOptions} options
632
+ * @param {number} [options.startRank] - The rank of the first element to
633
+ * fetch. Defaults to 0. This rank is inclusive, ie the element at this rank
634
+ * will be fetched.
635
+ * @param {number} [options.endRank] - The rank of the last element to fetch.
636
+ * This rank is exclusive, ie the element at this rank will not be fetched.
637
+ * Defaults to null, which fetches up until and including the last element.
638
+ * @param {SortedSetOrder} [options.order] - The order to fetch the elements in.
639
+ * Defaults to ascending.
640
+ * @returns {Promise<CacheSortedSetFetch.Response>}
641
+ * {@link CacheSortedSetFetch.Hit} containing the requested elements when found.
642
+ * {@link CacheSortedSetFetch.Miss} when the sorted set does not exist.
643
+ * {@link CacheSortedSetFetch.Error} on failure.
644
+ */
645
+ // public async sortedSetFetchByRank(
646
+ // cacheName: string,
647
+ // sortedSetName: string,
648
+ // options?: SortedSetFetchByRankOptions
649
+ // ): Promise<CacheSortedSetFetch.Response> {
650
+ // const client = this.getNextDataClient();
651
+ // return await client.sortedSetFetchByRank(
652
+ // cacheName,
653
+ // sortedSetName,
654
+ // options?.order ?? SortedSetOrder.Ascending,
655
+ // options?.startRank ?? 0,
656
+ // options?.endRank
657
+ // );
658
+ // }
659
+ /**
660
+ * Fetch the elements in the given sorted set by score.
661
+ *
662
+ * @param {string} cacheName - The cache containing the sorted set.
663
+ * @param {string} sortedSetName - The sorted set to fetch from.
664
+ * @param {SortedSetFetchByScoreOptions} options
665
+ * @param {number} [options.minScore] - The minimum score (inclusive) of the
666
+ * elements to fetch. Defaults to negative infinity.
667
+ * @param {number} [options.maxScore] - The maximum score (inclusive) of the
668
+ * elements to fetch. Defaults to positive infinity.
669
+ * @param {SortedSetOrder} [options.order] - The order to fetch the elements in.
670
+ * Defaults to ascending.
671
+ * @param {number} [options.offset] - The number of elements to skip before
672
+ * returning the first element. Defaults to 0. Note: this is not the rank of
673
+ * the first element to return, but the number of elements of the result set
674
+ * to skip before returning the first element.
675
+ * @param {number} [options.count] - The maximum number of elements to return.
676
+ * Defaults to undefined, which returns all elements.
677
+ * @returns {Promise<CacheSortedSetFetch.Response>} -
678
+ * {@link CacheSortedSetFetch.Hit} containing the requested elements when found.
679
+ * {@link CacheSortedSetFetch.Miss} when the sorted set does not exist.
680
+ * {@link CacheSortedSetFetch.Error} on failure.
681
+ */
682
+ // public async sortedSetFetchByScore(
683
+ // cacheName: string,
684
+ // sortedSetName: string,
685
+ // options?: SortedSetFetchByScoreOptions
686
+ // ): Promise<CacheSortedSetFetch.Response> {
687
+ // const client = this.getNextDataClient();
688
+ // return await client.sortedSetFetchByScore(
689
+ // cacheName,
690
+ // sortedSetName,
691
+ // options?.order ?? SortedSetOrder.Ascending,
692
+ // options?.minScore,
693
+ // options?.maxScore,
694
+ // options?.offset,
695
+ // options?.count
696
+ // );
697
+ // }
698
+ /**
699
+ * Look up the rank of an element in the sorted set, by the value of the element.
700
+ *
701
+ * @param {string} cacheName - The cache containing the sorted set.
702
+ * @param {string} sortedSetName - The sorted set to fetch from.
703
+ * @param {string | Uint8Array} value - The value of the element whose rank we are retrieving.
704
+ * @returns {Promise<CacheSortedSetGetRank.Response>}
705
+ * {@link CacheSortedGetRank.Hit} containing the rank of the requested elements when found.
706
+ * {@link CacheSortedGetRank.Miss} when the element does not exist.
707
+ * {@link CacheSortedGetRank.Error} on failure.
708
+ */
709
+ // public async sortedSetGetRank(
710
+ // cacheName: string,
711
+ // sortedSetName: string,
712
+ // value: string | Uint8Array
713
+ // ): Promise<CacheSortedSetGetRank.Response> {
714
+ // const client = this.getNextDataClient();
715
+ // return await client.sortedSetGetRank(cacheName, sortedSetName, value);
716
+ // }
717
+ /**
718
+ * Look up the score of an element in the sorted set, by the value of the element.
719
+ *
720
+ * @param {string} cacheName - The cache containing the sorted set.
721
+ * @param {string} sortedSetName - The sorted set to fetch from.
722
+ * @param {string | Uint8Array} value - The value of the element whose score we are retrieving.
723
+ * @returns {Promise<CacheSortedSetGetScore.Response>}
724
+ * {@link CacheSortedGetScore.Hit} containing the score of the requested element when found.
725
+ * {@link CacheSortedGetScore.Miss} when the element or collection does not exist.
726
+ * {@link CacheSortedGetScore.Error} on failure.
727
+ */
728
+ // public async sortedSetGetScore(
729
+ // cacheName: string,
730
+ // sortedSetName: string,
731
+ // value: string | Uint8Array
732
+ // ): Promise<CacheSortedSetGetScore.Response> {
733
+ // const client = this.getNextDataClient();
734
+ // return await client.sortedSetGetScore(cacheName, sortedSetName, value);
735
+ // }
736
+ /**
737
+ * Look up the scores of multiple elements in the sorted set, by the value of the elements.
738
+ *
739
+ * @param {string} cacheName - The cache containing the sorted set.
740
+ * @param {string} sortedSetName - The sorted set to fetch from.
741
+ * @param {string[] | Uint8Array[]} values - The values of the elements whose scores we are retrieving.
742
+ * @returns {Promise<CacheSortedSetGetScores.Response>}
743
+ * {@link CacheSortedGetScores.Hit} containing the scores of the requested elements when found.
744
+ * {@link CacheSortedGetScores.Miss} when the element or collection does not exist.
745
+ * {@link CacheSortedGetScores.Error} on failure.
746
+ */
747
+ // public async sortedSetGetScores(
748
+ // cacheName: string,
749
+ // sortedSetName: string,
750
+ // values: string[] | Uint8Array[]
751
+ // ): Promise<CacheSortedSetGetScores.Response> {
752
+ // const client = this.getNextDataClient();
753
+ // return await client.sortedSetGetScores(cacheName, sortedSetName, values);
754
+ // }
755
+ /**
756
+ * Increment the score of an element in the sorted set.
757
+ *
758
+ * @param {string} cacheName - The cache containing the sorted set.
759
+ * @param {string} sortedSetName - The sorted set to fetch from.
760
+ * @param {string | Uint8Array} value - The value of the element whose score we are incrementing.
761
+ * @param {number} amount - The quantity to add to the score. May be positive,
762
+ * negative, or zero. Defaults to 1.
763
+ * @param {SortedSetIncrementOptions} options
764
+ * @param {CollectionTtl} [options.ttl] - How the TTL should be managed.
765
+ * Refreshes the sorted set's TTL using the client's default if this is not
766
+ * supplied.
767
+ * @returns {Promise<CacheSortedSetIncrementScore.Response>} -
768
+ * {@link CacheSortedSetIncrementScore.Success} containing the incremented score
769
+ * on success.
770
+ * {@link CacheSortedSetIncrementScore.Error} on failure. Incrementing a score
771
+ * that was not set using this method or is not the string representation of
772
+ * an integer results in a failure with a FailedPreconditionException error.
773
+ */
774
+ // public async sortedSetIncrementScore(
775
+ // cacheName: string,
776
+ // sortedSetName: string,
777
+ // value: string | Uint8Array,
778
+ // amount = 1,
779
+ // options?: SortedSetIncrementOptions
780
+ // ): Promise<CacheSortedSetIncrementScore.Response> {
781
+ // const client = this.getNextDataClient();
782
+ // return await client.sortedSetIncrementScore(
783
+ // cacheName,
784
+ // sortedSetName,
785
+ // value,
786
+ // amount,
787
+ // options?.ttl
788
+ // );
789
+ // }
790
+ /**
791
+ * Remove an element from the sorted set
792
+ * @param {string} cacheName - The cache containing the sorted set.
793
+ * @param {string} sortedSetName - The sorted set to remove from.
794
+ * @param {string | Uint8Array} value - The value of the element to remove from the set.
795
+ * @returns {Promise<CacheSortedSetRemoveElement.Response>}
796
+ * {@link CacheSortedSetRemoveElement.Success} if the element was successfully removed
797
+ * {@link CacheSortedSetIncrementScore.Error} on failure
798
+ */
799
+ // public async sortedSetRemoveElement(
800
+ // cacheName: string,
801
+ // sortedSetName: string,
802
+ // value: string | Uint8Array
803
+ // ): Promise<CacheSortedSetRemoveElement.Response> {
804
+ // const client = this.getNextDataClient();
805
+ // return await client.sortedSetRemoveElement(cacheName, sortedSetName, value);
806
+ // }
807
+ /**
808
+ * Remove multiple elements from the sorted set
809
+ * @param {string} cacheName - The cache containing the sorted set.
810
+ * @param {string} sortedSetName - The sorted set to remove from.
811
+ * @param {string | Uint8Array} values - The values of the elements to remove from the set.
812
+ * @returns {Promise<CacheSortedSetRemoveElement.Response>}
813
+ * {@link CacheSortedSetRemoveElement.Success} if the elements were successfully removed
814
+ * {@link CacheSortedSetIncrementScore.Error} on failure
815
+ */
816
+ // public async sortedSetRemoveElements(
817
+ // cacheName: string,
818
+ // sortedSetName: string,
819
+ // values: string[] | Uint8Array[]
820
+ // ): Promise<CacheSortedSetRemoveElements.Response> {
821
+ // const client = this.getNextDataClient();
822
+ // return await client.sortedSetRemoveElements(
823
+ // cacheName,
824
+ // sortedSetName,
825
+ // values
826
+ // );
827
+ // }
828
+ /**
829
+ * Creates a Momento signing key.
830
+ *
831
+ * @param {number} ttlMinutes - The time to live in minutes until the Momento
832
+ * signing key expires.
833
+ * @returns {Promise<CreateSigningKey.Response>} -
834
+ * {@link CreateSigningKey.Success} containing the key, key ID, endpoint, and
835
+ * expiration date on success.
836
+ * {@link CreateSigningKey.Error} on failure.
837
+ */
838
+ // public async createSigningKey(
839
+ // ttlMinutes: number
840
+ // ): Promise<CreateSigningKey.Response> {
841
+ // return await this.controlClient.createSigningKey(
842
+ // ttlMinutes,
843
+ // this.dataClient.getEndpoint()
844
+ // );
845
+ // }
846
+ /**
847
+ * Revokes a Momento signing key.
848
+ *
849
+ * @remarks
850
+ * All tokens signed by this key will be invalid.
851
+ *
852
+ * @param {string} keyId - The ID of the key to revoke.
853
+ * @returns {Promise<RevokeSigningKey.Response>} -
854
+ * {@link RevokeSigningKey.Success} on success.
855
+ * {@link RevokeSigningKey.Error} on failure.
856
+ */
857
+ // public async revokeSigningKey(
858
+ // keyId: string
859
+ // ): Promise<RevokeSigningKey.Response> {
860
+ // return await this.controlClient.revokeSigningKey(keyId);
861
+ // }
862
+ getNextDataClient() {
863
+ const client = this.dataClients[this.nextDataClientIndex];
864
+ this.nextDataClientIndex =
865
+ (this.nextDataClientIndex + 1) % this.dataClients.length;
866
+ return client;
867
+ }
868
+ }
869
+ exports.AbstractCacheClient = AbstractCacheClient;
870
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQWJzdHJhY3RDYWNoZUNsaWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9pbnRlcm5hbC9jbGllbnRzL2NhY2hlL0Fic3RyYWN0Q2FjaGVDbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBb0RBLE1BQXNCLG1CQUFtQjtJQU12QyxZQUFZLGFBQTZCLEVBQUUsV0FBMEI7UUFDbkUsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUM7UUFDbkMsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7UUFFL0IsNEVBQTRFO1FBQzVFLHlFQUF5RTtRQUN6RSxrQkFBa0I7UUFDbEIsSUFBSSxDQUFDLG1CQUFtQixHQUFHLENBQUMsQ0FBQztJQUMvQixDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSSxLQUFLLENBQUMsV0FBVyxDQUFDLFNBQWlCO1FBQ3hDLE9BQU8sTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN6RCxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNJLEtBQUssQ0FBQyxXQUFXLENBQUMsU0FBaUI7UUFDeEMsT0FBTyxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxLQUFLLENBQUMsVUFBVTtRQUNyQixPQUFPLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUMvQyxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0ksS0FBSyxDQUFDLEdBQUcsQ0FDZCxTQUFpQixFQUNqQixHQUF3QjtRQUV4QixPQUFPLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7T0FhRztJQUNJLEtBQUssQ0FBQyxHQUFH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QUNILHVDQUF1QztJQUN2Qyx1QkFBdUI7SUFDdkIsMkJBQTJCO0lBQzNCLCtCQUErQjtJQUMvQixxREFBcUQ7SUFDckQsNkNBQTZDO0lBQzdDLGlGQUFpRjtJQUNqRixJQUFJO0lBRUo7Ozs7Ozs7O09BUUc7SUFDSCx3Q0FBd0M7SUFDeEMsdUJBQXVCO0lBQ3ZCLDJCQUEyQjtJQUMzQixvQ0FBb0M7SUFDcEMsc0RBQXNEO0lBQ3RELDZDQUE2QztJQUM3QyxpREFBaUQ7SUFDakQsaUJBQWlCO0lBQ2pCLHFCQUFxQjtJQUNyQixhQUFhO0lBQ2IsT0FBTztJQUNQLElBQUk7SUFFSjs7Ozs7Ozs7O09BU0c7SUFDSCxpQ0FBaUM7SUFDakMsdUJBQXVCO0lBQ3ZCLDBDQUEwQztJQUMxQyxzREFBc0Q7SUFDdEQsa0JBQWtCO0lBQ2xCLG9DQUFvQztJQUNwQyxPQUFPO0lBQ1AsSUFBSTtJQUVKOzs7Ozs7Ozs7O09BVUc7SUFDSCxpQ0FBaUM7SUFDakMsa0JBQWtCO0lBQ2xCLDBDQUEwQztJQUMxQyw2REFBNkQ7SUFDN0QsSUFBSTtJQUVNLGlCQUFpQjtRQUN6QixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQzFELElBQUksQ0FBQyxtQkFBbUI7WUFDdEIsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUM7UUFDM0QsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztDQUNGO0FBcmxDRCxrREFxbENDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ3JlYXRlQ2FjaGUsXG4gIERlbGV0ZUNhY2hlLFxuICBMaXN0Q2FjaGVzLFxuICBDYWNoZUZsdXNoLFxuICBDYWNoZUdldCxcbiAgQ2FjaGVTZXQsXG4gIENhY2hlRGVsZXRlLFxuICBDYWNoZUluY3JlbWVudCxcbiAgSW5jcmVtZW50T3B0aW9ucyxcbiAgQ2FjaGVTZXRJZk5vdEV4aXN0cyxcbiAgU2V0SWZOb3RFeGlzdHNPcHRpb25zLFxuICBDYWNoZVNldEZldGNoLFxuICBDYWNoZVNldEFkZEVsZW1lbnQsXG4gIENhY2hlU2V0QWRkRWxlbWVudHMsXG4gIENhY2hlU2V0UmVtb3ZlRWxlbWVudCxcbiAgQ2FjaGVTZXRSZW1vdmVFbGVtZW50cyxcbiAgQ2FjaGVMaXN0RmV0Y2gsXG4gIENhY2hlTGlzdExlbmd0aCxcbiAgQ2FjaGVMaXN0UHVzaEZyb250LFxuICBDYWNoZUxpc3RQdXNoQmFjayxcbiAgQ2FjaGVMaXN0Q29uY2F0ZW5hdGVCYWNrLFxuICBDYWNoZUxpc3RDb25jYXRlbmF0ZUZyb250LFxuICBDYWNoZUxpc3RQb3BCYWNrLFxuICBDYWNoZUxpc3RQb3BGcm9udCxcbiAgQ2FjaGVMaXN0UmVtb3ZlVmFsdWUsXG4gIENhY2hlTGlzdFJldGFpbixcbiAgQ2FjaGVEaWN0aW9uYXJ5U2V0RmllbGQsXG4gIENhY2hlRGljdGlvbmFyeVNldEZpZWxkcyxcbiAgQ2FjaGVEaWN0aW9uYXJ5R2V0RmllbGQsXG4gIENhY2hlRGljdGlvbmFyeUdldEZpZWxkcyxcbiAgQ2FjaGVEaWN0aW9uYXJ5SW5jcmVtZW50LFxuICBDYWNoZURpY3Rpb25hcnlGZXRjaCxcbiAgQ2FjaGVEaWN0aW9uYXJ5UmVtb3ZlRmllbGQsXG4gIENhY2hlRGljdGlvbmFyeVJlbW92ZUZpZWxkcyxcbn0gZnJvbSAnLi4vLi4vLi4vaW5kZXgnO1xuaW1wb3J0IHtMaXN0RmV0Y2hDYWxsT3B0aW9ucywgTGlzdFJldGFpbkNhbGxPcHRpb25zfSBmcm9tICcuLi8uLi8uLi91dGlscyc7XG5pbXBvcnQge1xuICBJQ2FjaGVDbGllbnQsXG4gIFNldE9wdGlvbnMsXG4gIFNldEFkZEVsZW1lbnRPcHRpb25zLFxuICBTZXRBZGRFbGVtZW50c09wdGlvbnMsXG4gIExpc3RQdXNoRnJvbnRPcHRpb25zLFxuICBMaXN0UHVzaEJhY2tPcHRpb25zLFxuICBMaXN0Q29uY2F0ZW5hdGVCYWNrT3B0aW9ucyxcbiAgTGlzdENvbmNhdGVuYXRlRnJvbnRPcHRpb25zLFxuICBEaWN0aW9uYXJ5U2V0RmllbGRPcHRpb25zLFxuICBEaWN0aW9uYXJ5SW5jcmVtZW50T3B0aW9ucyxcbn0gZnJvbSAnLi9JQ2FjaGVDbGllbnQnO1xuaW1wb3J0IHtJQ29udHJvbENsaWVudH0gZnJvbSAnLi9JQ29udHJvbENsaWVudCc7XG5pbXBvcnQge0lEYXRhQ2xpZW50fSBmcm9tICcuL0lEYXRhQ2xpZW50JztcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEFic3RyYWN0Q2FjaGVDbGllbnQgaW1wbGVtZW50cyBJQ2FjaGVDbGllbnQge1xuICAvLyBtYWtpbmcgdGhlc2UgcHJvdGVjdGVkIHVudGlsIHdlIGZ1bGx5IGFic3RyYWN0IGF3YXkgdGhlIG5vZGVqcyBjbGllbnRcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGNvbnRyb2xDbGllbnQ6IElDb250cm9sQ2xpZW50O1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZGF0YUNsaWVudHM6IElEYXRhQ2xpZW50W107XG4gIHByb3RlY3RlZCBuZXh0RGF0YUNsaWVudEluZGV4OiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3IoY29udHJvbENsaWVudDogSUNvbnRyb2xDbGllbnQsIGRhdGFDbGllbnRzOiBJRGF0YUNsaWVudFtdKSB7XG4gICAgdGhpcy5jb250cm9sQ2xpZW50ID0gY29udHJvbENsaWVudDtcbiAgICB0aGlzLmRhdGFDbGllbnRzID0gZGF0YUNsaWVudHM7XG5cbiAgICAvLyBXZSByb3VuZC1yb2JpbiB0aGUgcmVxdWVzdHMgdGhyb3VnaCBhbGwgb2Ygb3VyIGNsaWVudHMuICBTaW5jZSBqYXZhc2NyaXB0XG4gICAgLy8gaXMgc2luZ2xlLXRocmVhZGVkLCB3ZSBkb24ndCBoYXZlIHRvIHdvcnJ5IGFib3V0IHRocmVhZCBzYWZldHkgb24gdGhpc1xuICAgIC8vIGluZGV4IHZhcmlhYmxlLlxuICAgIHRoaXMubmV4dERhdGFDbGllbnRJbmRleCA9IDA7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIGNhY2hlIGlmIGl0IGRvZXMgbm90IGV4aXN0LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY2FjaGVOYW1lIC0gVGhlIGNhY2hlIHRvIGJlIGNyZWF0ZWQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPENyZWF0ZUNhY2hlLlJlc3BvbnNlPn0gLVxuICAgKiB7QGxpbmsgQ3JlYXRlQ2FjaGUuU3VjY2Vzc30gb24gc3VjY2Vzcy5cbiAgICoge0BsaW5rIENyZWF0ZUNhY2hlLkFscmVhZHlFeGlzdHN9IGlmIHRoZSBjYWNoZSBhbHJlYWR5IGV4aXN0cy5cbiAgICoge0BsaW5rIENyZWF0ZUNhY2hlLkVycm9yfSBvbiBmYWlsdXJlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGNyZWF0ZUNhY2hlKGNhY2hlTmFtZTogc3RyaW5nKTogUHJvbWlzZTxDcmVhdGVDYWNoZS5SZXNwb25zZT4ge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLmNvbnRyb2xDbGllbnQuY3JlYXRlQ2FjaGUoY2FjaGVOYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIGEgY2FjaGUgYW5kIGFsbCBpdGVtcyBzdG9yZWQgaW4gaXQuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjYWNoZU5hbWUgLSBUaGUgY2FjaGUgdG8gZGVsZXRlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxEZWxldGVDYWNoZS5SZXNwb25zZT59IC1cbiAgICoge0BsaW5rIERlbGV0ZUNhY2hlLlN1Y2Nlc3N9IG9uIHN1Y2Nlc3MuXG4gICAqIHtAbGluayBEZWxldGVDYWNoZS5FcnJvcn0gb24gZmFpbHVyZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBkZWxldGVDYWNoZShjYWNoZU5hbWU6IHN0cmluZyk6IFByb21pc2U8RGVsZXRlQ2FjaGUuUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5jb250cm9sQ2xpZW50LmRlbGV0ZUNhY2hlKGNhY2hlTmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogTGlzdHMgYWxsIGNhY2hlcy5cbiAgICpcbiAgICogQHJldHVybnMge1Byb21pc2U8TGlzdENhY2hlcy5SZXNwb25zZT59IC1cbiAgICoge0BsaW5rIExpc3RDYWNoZXMuU3VjY2Vzc30gY29udGFpbmluZyB0aGUgbGlzdCBvbiBzdWNjZXNzLlxuICAgKiB7QGxpbmsgTGlzdENhY2hlcy5FcnJvcn0gb24gZmFpbHVyZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBsaXN0Q2FjaGVzKCk6IFByb21pc2U8TGlzdENhY2hlcy5SZXNwb25zZT4ge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLmNvbnRyb2xDbGllbnQubGlzdENhY2hlcygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIHZhbHVlIHN0b3JlZCBmb3IgdGhlIGdpdmVuIGtleS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNhY2hlTmFtZSAtIFRoZSBjYWNoZSB0byBwZXJmb3JtIHRoZSBsb29rdXAgaW4uXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgVWludDhBcnJheX0ga2V5IC0gVGhlIGtleSB0byBsb29rIHVwLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxDYWNoZUdldC5SZXNwb25zZT59IC1cbiAgICoge0BsaW5rIENhY2hlR2V0LkhpdH0gY29udGFpbmluZyB0aGUgdmFsdWUgaWYgb25lIGlzIGZvdW5kLlxuICAgKiB7QGxpbmsgQ2FjaGVHZXQuTWlzc30gaWYgdGhlIGtleSBkb2VzIG5vdCBleGlzdC5cbiAgICoge0BsaW5rIENhY2hlR2V0LkVycm9yfSBvbiBmYWlsdXJlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGdldChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBrZXk6IHN0cmluZyB8IFVpbnQ4QXJyYXlcbiAgKTogUHJvbWlzZTxDYWNoZUdldC5SZXNwb25zZT4ge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLmdldE5leHREYXRhQ2xpZW50KCkuZ2V0KGNhY2hlTmFtZSwga2V5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBc3NvY2lhdGVzIHRoZSBnaXZlbiBrZXkgd2l0aCB0aGUgZ2l2ZW4gdmFsdWUuIElmIGEgdmFsdWUgZm9yIHRoZSBrZXkgaXNcbiAgICogYWxyZWFkeSBwcmVzZW50IGl0IGlzIHJlcGxhY2VkIHdpdGggdGhlIG5ldyB2YWx1ZS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNhY2hlTmFtZSAtIFRoZSBjYWNoZSB0byBzdG9yZSB0aGUgdmFsdWUgaW4uXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgVWludDhBcnJheX0ga2V5IC0gVGhlIGtleSB0byBzZXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgVWludDhBcnJheX0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gYmUgc3RvcmVkLlxuICAgKiBAcGFyYW0ge1NldE9wdGlvbnN9IFtvcHRpb25zXVxuICAgKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMudHRsXSAtIFRoZSB0aW1lIHRvIGxpdmUgZm9yIHRoZSBpdGVtIGluIHRoZSBjYWNoZS5cbiAgICogVXNlcyB0aGUgY2xpZW50J3MgZGVmYXVsdCBUVEwgaWYgdGhpcyBpcyBub3Qgc3VwcGxpZWQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPENhY2hlU2V0LlJlc3BvbnNlPn0gLVxuICAgKiB7QGxpbmsgQ2FjaGVTZXQuU3VjY2Vzc30gb24gc3VjY2Vzcy5cbiAgICoge0BsaW5rIENhY2hlU2V0LkVycm9yfSBvbiBmYWlsdXJlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHNldChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBrZXk6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgdmFsdWU6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgb3B0aW9ucz86IFNldE9wdGlvbnNcbiAgKTogUHJvbWlzZTxDYWNoZVNldC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IGNsaWVudCA9IHRoaXMuZ2V0TmV4dERhdGFDbGllbnQoKTtcbiAgICByZXR1cm4gYXdhaXQgY2xpZW50LnNldChjYWNoZU5hbWUsIGtleSwgdmFsdWUsIG9wdGlvbnM/LnR0bCk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyB0aGUgZ2l2ZW4ga2V5IGZyb20gdGhlIGNhY2hlLiBUaGUga2V5IGNhbiByZXByZXNlbnQgYSBzaW5nbGUgdmFsdWVcbiAgICogb3IgYSBjb2xsZWN0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY2FjaGVOYW1lIC0gVGhlIGNhY2hlIHRvIGRlbGV0ZSBmcm9tLlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IFVpbnQ4QXJyYXl9IGtleSAtIFRoZSBrZXkgdG8gZGVsZXRlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxDYWNoZURlbGV0ZS5SZXNwb25zZT59IC1cbiAgICoge0BsaW5rIENhY2hlRGVsZXRlLlN1Y2Nlc3N9IG9uIHN1Y2Nlc3MuXG4gICAqIHtAbGluayBDYWNoZURlbGV0ZS5FcnJvcn0gb24gZmFpbHVyZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBkZWxldGUoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBzdHJpbmcgfCBVaW50OEFycmF5XG4gICk6IFByb21pc2U8Q2FjaGVEZWxldGUuUmVzcG9uc2U+IHtcbiAgICBjb25zdCBjbGllbnQgPSB0aGlzLmdldE5leHREYXRhQ2xpZW50KCk7XG4gICAgcmV0dXJuIGF3YWl0IGNsaWVudC5kZWxldGUoY2FjaGVOYW1lLCBrZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgbXVsdGlwbGUgZWxlbWVudHMgdG8gdGhlIGJhY2sgb2YgdGhlIGdpdmVuIGxpc3QuIENyZWF0ZXMgdGhlIGxpc3QgaWZcbiAgICogaXQgZG9lcyBub3QgYWxyZWFkeSBleGlzdC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNhY2hlTmFtZSAtIFRoZSBjYWNoZSB0byBzdG9yZSB0aGUgbGlzdCBpbi5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGxpc3ROYW1lIC0gVGhlIGxpc3QgdG8gYWRkIHRvLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdIHwgVWludDhBcnJheVtdfSB2YWx1ZXMgLSBUaGUgZWxlbWVudHMgdG8gYWRkIHRvIHRoZSBsaXN0LlxuICAgKiBAcGFyYW0ge0xpc3RDb25jYXRlbmF0ZUJhY2tPcHRpb25zfSBbb3B0aW9uc11cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLnRydW5jYXRlRnJvbnRUb1NpemVdIC0gSWYgdGhlIGxpc3QgZXhjZWVkcyB0aGlzXG4gICAqIGxlbmd0aCwgcmVtb3ZlIGV4Y2VzcyBmcm9tIHRoZSBmcm9udCBvZiB0aGUgbGlzdC4gTXVzdCBiZSBwb3NpdGl2ZS5cbiAgICogQHBhcmFtIHtDb2xsZWN0aW9uVHRsfSBbb3B0aW9ucy50dGxdIC0gSG93IHRoZSBUVEwgc2hvdWxkIGJlIG1hbmFnZWQuXG4gICAqIFJlZnJlc2hlcyB0aGUgbGlzdCdzIFRUTCB1c2luZyB0aGUgY2xpZW50J3MgZGVmYXVsdCBpZiB0aGlzIGlzIG5vdFxuICAgKiBzdXBwbGllZC5cbiAgICogQHJldHVybnMge1Byb21pc2U8Q2FjaGVMaXN0Q29uY2F0ZW5hdGVCYWNrLlJlc3BvbnNlPn0gLVxuICAgKiB7QGxpbmsgQ2FjaGVMaXN0Q29uY2F0ZW5hdGVCYWNrLlN1Y2Nlc3N9IG9uIHN1Y2Nlc3MuXG4gICAqIHtAbGluayBDYWNoZUxpc3RDb25jYXRlbmF0ZUJhY2suRXJyb3J9IG9uIGZhaWx1cmUuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgbGlzdENvbmNhdGVuYXRlQmFjayhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBsaXN0TmFtZTogc3RyaW5nLFxuICAgIHZhbHVlczogc3RyaW5nW10gfCBVaW50OEFycmF5W10sXG4gICAgb3B0aW9ucz86IExpc3RDb25jYXRlbmF0ZUJhY2tPcHRpb25zXG4gICk6IFByb21pc2U8Q2FjaGVMaXN0Q29uY2F0ZW5hdGVCYWNrLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgY2xpZW50ID0gdGhpcy5nZXROZXh0RGF0YUNsaWVudCgpO1xuICAgIHJldHVybiBhd2FpdCBjbGllbnQubGlzdENvbmNhdGVuYXRlQmFjayhcbiAgICAgIGNhY2hlTmFtZSxcbiAgICAgIGxpc3ROYW1lLFxuICAgICAgdmFsdWVzLFxuICAgICAgb3B0aW9ucz8udHJ1bmNhdGVGcm9udFRvU2l6ZSxcbiAgICAgIG9wdGlvbnM/LnR0bFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBtdWx0aXBsZSBlbGVtZW50cyB0byB0aGUgZnJvbnQgb2YgdGhlIGdpdmVuIGxpc3QuIENyZWF0ZXMgdGhlIGxpc3QgaWZcbiAgICogaXQgZG9lcyBub3QgYWxyZWFkeSBleGlzdC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNhY2hlTmFtZSAtIFRoZSBjYWNoZSB0byBzdG9yZSB0aGUgbGlzdCBpbi5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGxpc3ROYW1lIC0gVGhlIGxpc3QgdG8gYWRkIHRvLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdIHwgVWludDhBcnJheVtdfSB2YWx1ZXMgLSBUaGUgZWxlbWVudHMgdG8gYWRkIHRvIHRoZSBsaXN0LlxuICAgKiBAcGFyYW0ge0xpc3RDb25jYXRlbmF0ZUZyb250T3B0aW9uc30gW29wdGlvbnNdXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy50cnVuY2F0ZUJhY2tUb1NpemVdIC0gSWYgdGhlIGxpc3QgZXhjZWVkcyB0aGlzXG4gICAqIGxlbmd0aCwgcmVtb3ZlIGV4Y2VzcyBmcm9tIHRoZSBiYWNrIG9mIHRoZSBsaXN0LiBNdXN0IGJlIHBvc2l0aXZlLlxuICAgKiBAcGFyYW0ge0NvbGxlY3Rpb25UdGx9IFtvcHRpb25zLnR0bF0gLSBIb3cgdGhlIFRUTCBzaG91bGQgYmUgbWFuYWdlZC5cbiAgICogUmVmcmVzaGVzIHRoZSBsaXN0J3MgVFRMIHVzaW5nIHRoZSBjbGllbnQncyBkZWZhdWx0IGlmIHRoaXMgaXMgbm90XG4gICAqIHN1cHBsaWVkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxDYWNoZUxpc3RDb25jYXRlbmF0ZUZyb250LlJlc3BvbnNlPn0gLVxuICAgKiB7QGxpbmsgQ2FjaGVMaXN0Q29uY2F0ZW5hdGVGcm9udC5TdWNjZXNzfSBvbiBzdWNjZXNzLlxuICAgKiB7QGxpbmsgQ2FjaGVMaXN0Q29uY2F0ZW5hdGVGcm9udC5FcnJvcn0gb24gZmFpbHVyZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBsaXN0Q29uY2F0ZW5hdGVGcm9udChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBsaXN0TmFtZTogc3RyaW5nLFxuICAgIHZhbHVlczogc3RyaW5nW10gfCBVaW50OEFycmF5W10sXG4gICAgb3B0aW9ucz86IExpc3RDb25jYXRlbmF0ZUZyb250T3B0aW9uc1xuICApOiBQcm9taXNlPENhY2hlTGlzdENvbmNhdGVuYXRlRnJvbnQuUmVzcG9uc2U+IHtcbiAgICBjb25zdCBjbGllbnQgPSB0aGlzLmdldE5leHREYXRhQ2xpZW50KCk7XG4gICAgcmV0dXJuIGF3YWl0IGNsaWVudC5saXN0Q29uY2F0ZW5hdGVGcm9udChcbiAgICAgIGNhY2hlTmFtZSxcbiAgICAgIGxpc3ROYW1lLFxuICAgICAgdmFsdWVzLFxuICAgICAgb3B0aW9ucz8udHJ1bmNhdGVCYWNrVG9TaXplLFxuICAgICAgb3B0aW9ucz8udHRsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGZXRjaGVzIGFsbCBlbGVtZW50cyBvZiB0aGUgZ2l2ZW4gbGlzdC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNhY2hlTmFtZSAtIFRoZSBjYWNoZSBjb250YWluaW5nIHRoZSBsaXN0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbGlzdE5hbWUgLSBUaGUgbGlzdCB0byBmZXRjaC5cbiAgICogQHBhcmFtIHtMaXN0RmV0Y2hDYWxsT3B0aW9uc30gW29wdGlvbnNdXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5zdGFydEluZGV4XSAtIFN0YXJ0IGluY2x1c2l2ZSBpbmRleCBmb3IgZmV0Y2ggb3BlcmF0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMuZW5kSW5kZXhdIC0gRW5kIGV4Y2x1c2l2ZSBpbmRleCBmb3IgZmV0Y2ggb3BlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxDYWNoZUxpc3RGZXRjaC5SZXNwb25zZT59IC1cbiAgICoge0BsaW5rIENhY2hlTGlzdEZldGNoLkhpdH0gY29udGFpbmluZyB0aGUgbGlzdCBlbGVtZW50cyBpZiB0aGUgbGlzdCBleGlzdHMuXG4gICAqIHtAbGluayBDYWNoZUxpc3RGZXRjaC5NaXNzfSBpZiB0aGUgbGlzdCBkb2VzIG5vdCBleGlzdC5cbiAgICoge0BsaW5rIENhY2hlTGlzdEZldGNoLkVycm9yfSBvbiBmYWlsdXJlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGxpc3RGZXRjaChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBsaXN0TmFtZTogc3RyaW5nLFxuICAgIG9wdGlvbnM/OiBMaXN0RmV0Y2hDYWxsT3B0aW9uc1xuICApOiBQcm9taXNlPENhY2hlTGlzdEZldGNoLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgY2xpZW50ID0gdGhpcy5nZXROZXh0RGF0YUNsaWVudCgpO1xuICAgIHJldHVybiBhd2FpdCBjbGllbnQubGlzdEZldGNoKFxuICAgICAgY2FjaGVOYW1lLFxuICAgICAgbGlzdE5hbWUsXG4gICAgICBvcHRpb25zPy5zdGFydEluZGV4LFxuICAgICAgb3B0aW9ucz8uZW5kSW5kZXhcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgZ2l2ZW4gbGlzdC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNhY2hlTmFtZSAtIFRoZSBjYWNoZSBjb250YWluaW5nIHRoZSBsaXN0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbGlzdE5hbWUgLSBUaGUgbGlzdCB0byBnZXQgdGhlIGxlbmd0aCBvZi5cbiAgICogQHJldHVybnMge1Byb21pc2U8Q2FjaGVMaXN0TGVuZ3RoLlJlc3BvbnNlPn0gLVxuICAgKiB7QGxpbmsgQ2FjaGVMaXN0TGVuZ3RoLkhpdH0gY29udGFpbmluZyB0aGUgbGVuZ3RoIGlmIHRoZSBsaXN0IGV4aXN0cy5cbiAgICoge0BsaW5rIENhY2hlTGlzdExlbmd0aC5NaXNzfSBpZiB0aGUgbGlzdCBkb2VzIG5vdCBleGlzdC5cbiAgICoge0BsaW5rIENhY2hlTGlzdExlbmd0aC5FcnJvcn0gb24gZmFpbHVyZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBsaXN0TGVuZ3RoKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGxpc3ROYW1lOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxDYWNoZUxpc3RMZW5ndGguUmVzcG9uc2U+IHtcbiAgICBjb25zdCBjbGllbnQgPSB0aGlzLmdldE5leHREYXRhQ2xpZW50KCk7XG4gICAgcmV0dXJuIGF3YWl0IGNsaWVudC5saXN0TGVuZ3RoKGNhY2hlTmFtZSwgbGlzdE5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgYW5kIHJlbW92ZXMgdGhlIGxhc3QgdmFsdWUgZnJvbSB0aGUgZ2l2ZW4gbGlzdC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNhY2hlTmFtZSAtIFRoZSBjYWNoZSBjb250YWluaW5nIHRoZSBsaXN0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbGlzdE5hbWUgLSBUaGUgbGlzdCB0byBwb3AuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPENhY2hlTGlzdFBvcEJhY2suUmVzcG9uc2U+fSAtXG4gICAqIHtAbGluayBDYWNoZUxpc3RQb3BCYWNrLkhpdH0gY29udGFpbmluZyB0aGUgZWxlbWVudCBpZiB0aGUgbGlzdCBleGlzdHMuXG4gICAqIHtAbGluayBDYWNoZUxpc3RQb3BCYWNrLk1pc3N9IGlmIHRoZSBsaXN0IGRvZXMgbm90IGV4aXN0LlxuICAgKiB7QGxpbmsgQ2FjaGVMaXN0UG9wQmFjay5FcnJvcn0gb24gZmFpbHVyZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBsaXN0UG9wQmFjayhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBsaXN0TmFtZTogc3RyaW5nXG4gICk6IFByb21pc2U8Q2FjaGVMaXN0UG9wQmFjay5SZXNwb25zZT4ge1xuICAgIGNvbnN0IGNsaWVudCA9IHRoaXMuZ2V0TmV4dERhdGFDbGllbnQoKTtcbiAgICByZXR1cm4gYXdhaXQgY2xpZW50Lmxpc3RQb3BCYWNrKGNhY2hlTmFtZSwgbGlzdE5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgYW5kIHJlbW92ZXMgdGhlIGZpcnN0IHZhbHVlIGZyb20gdGhlIGdpdmVuIGxpc3QuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjYWNoZU5hbWUgLSBUaGUgY2FjaGUgY29udGFpbmluZyB0aGUgbGlzdC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGxpc3ROYW1lIC0gVGhlIGxpc3QgdG8gcG9wLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxDYWNoZUxpc3RQb3BGcm9udC5SZXNwb25zZT59IC1cbiAgICoge0BsaW5rIENhY2hlTGlzdFBvcEZyb250LkhpdH0gY29udGFpbmluZyB0aGUgZWxlbWVudCBpZiB0aGUgbGlzdCBleGlzdHMuXG4gICAqIHtAbGluayBDYWNoZUxpc3RQb3BGcm9udC5NaXNzfSBpZiB0aGUgbGlzdCBkb2VzIG5vdCBleGlzdC5cbiAgICoge0BsaW5rIENhY2hlTGlzdFBvcEZyb250LkVycm9yfSBvbiBmYWlsdXJlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGxpc3RQb3BGcm9udChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBsaXN0TmFtZTogc3RyaW5nXG4gICk6IFByb21pc2U8Q2FjaGVMaXN0UG9wRnJvbnQuUmVzcG9uc2U+IHtcbiAgICBjb25zdCBjbGllbnQgPSB0aGlzLmdldE5leHREYXRhQ2xpZW50KCk7XG4gICAgcmV0dXJuIGF3YWl0IGNsaWVudC5saXN0UG9wRnJvbnQoY2FjaGVOYW1lLCBsaXN0TmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhbiBlbGVtZW50IHRvIHRoZSBiYWNrIG9mIHRoZSBnaXZlbiBsaXN0LiBDcmVhdGVzIHRoZSBsaXN0IGlmXG4gICAqIGl0IGRvZXMgbm90IGFscmVhZHkgZXhpc3QuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjYWNoZU5hbWUgLSBUaGUgY2FjaGUgdG8gc3RvcmUgdGhlIGxpc3QgaW4uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBsaXN0TmFtZSAtIFRoZSBsaXN0IHRvIHB1c2ggdG8uXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgVWludDhBcnJheX0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gcHVzaC5cbiAgICogQHBhcmFtIHtMaXN0UHVzaEJhY2tPcHRpb25zfSBbb3B0aW9uc11cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLnRydW5jYXRlRnJvbnRUb1NpemVdIC0gSWYgdGhlIGxpc3QgZXhjZWVkcyB0aGlzXG4gICAqIGxlbmd0aCwgcmVtb3ZlIGV4Y2VzcyBmcm9tIHRoZSBmcm9udCBvZiB0aGUgbGlzdC4gTXVzdCBiZSBwb3NpdGl2ZS5cbiAgICogQHBhcmFtIHtDb2xsZWN0aW9uVHRsfSBbb3B0aW9ucy50dGxdIC0gSG93IHRoZSBUVEwgc2hvdWxkIGJlIG1hbmFnZWQuXG4gICAqIFJlZnJlc2hlcyB0aGUgbGlzdCdzIFRUTCB1c2luZyB0aGUgY2xpZW50J3MgZGVmYXVsdCBpZiB0aGlzIGlzIG5vdFxuICAgKiBzdXBwbGllZC5cbiAgICogQHJldHVybnMge1Byb21pc2U8Q2FjaGVMaXN0UHVzaEJhY2suUmVzcG9uc2U+fSAtXG4gICAqIHtAbGluayBDYWNoZUxpc3RQdXNoQmFjay5TdWNjZXNzfSBjb250YWluaW5nIHRoZSBsaXN0J3MgbmV3IGxlbmd0aCBvblxuICAgKiBzdWNjZXNzLlxuICAgKiB7QGxpbmsgQ2FjaGVMaXN0UHVzaEJhY2suRXJyb3J9IG9uIGZhaWx1cmUuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgbGlzdFB1c2hCYWNrKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGxpc3ROYW1lOiBzdHJpbmcsXG4gICAgdmFsdWU6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgb3B0aW9ucz86IExpc3RQdXNoQmFja09wdGlvbnNcbiAgKTogUHJvbWlzZTxDYWNoZUxpc3RQdXNoQmFjay5SZXNwb25zZT4ge1xuICAgIGNvbnN0IGNsaWVudCA9IHRoaXMuZ2V0TmV4dERhdGFDbGllbnQoKTtcbiAgICByZXR1cm4gYXdhaXQgY2xpZW50Lmxpc3RQdXNoQmFjayhcbiAgICAgIGNhY2hlTmFtZSxcbiAgICAgIGxpc3ROYW1lLFxuICAgICAgdmFsdWUsXG4gICAgICBvcHRpb25zPy50cnVuY2F0ZUZyb250VG9TaXplLFxuICAgICAgb3B0aW9ucz8udHRsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGFuIGVsZW1lbnQgdG8gdGhlIGZyb250IG9mIHRoZSBnaXZlbiBsaXN0LiBDcmVhdGVzIHRoZSBsaXN0IGlmXG4gICAqIGl0IGRvZXMgbm90IGFscmVhZHkgZXhpc3QuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjYWNoZU5hbWUgLSBUaGUgY2FjaGUgdG8gc3RvcmUgdGhlIGxpc3QgaW4uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBsaXN0TmFtZSAtIFRoZSBsaXN0IHRvIHB1c2ggdG8uXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgVWludDhBcnJheX0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gcHVzaC5cbiAgICogQHBhcmFtIHtMaXN0UHVzaEZyb250T3B0aW9uc30gW29wdGlvbnNdXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy50cnVuY2F0ZUJhY2tUb1NpemVdIC0gSWYgdGhlIGxpc3QgZXhjZWVkcyB0aGlzXG4gICAqIGxlbmd0aCwgcmVtb3ZlIGV4Y2VzcyBmcm9tIHRoZSBlbmQgb2YgdGhlIGxpc3QuIE11c3QgYmUgcG9zaXRpdmUuXG4gICAqIEBwYXJhbSB7Q29sbGVjdGlvblR0bH0gW29wdGlvbnMudHRsXSAtIEhvdyB0aGUgVFRMIHNob3VsZCBiZSBtYW5hZ2VkLlxuICAgKiBSZWZyZXNoZXMgdGhlIGxpc3QncyBUVEwgdXNpbmcgdGhlIGNsaWVudCdzIGRlZmF1bHQgaWYgdGhpcyBpcyBub3RcbiAgICogc3VwcGxpZWQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPENhY2hlTGlzdFB1c2hGcm9udC5SZXNwb25zZT59IC1cbiAgICoge0BsaW5rIENhY2hlTGlzdFB1c2hGcm9udC5TdWNjZXNzfSBjb250YWluaW5nIHRoZSBsaXN0J3MgbmV3IGxlbmd0aCBvblxuICAgKiBzdWNjZXNzLlxuICAgKiB7QGxpbmsgQ2FjaGVMaXN0UHVzaEZyb250LkVycm9yfSBvbiBmYWlsdXJlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGxpc3RQdXNoRnJvbnQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgbGlzdE5hbWU6IHN0cmluZyxcbiAgICB2YWx1ZTogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICBvcHRpb25zPzogTGlzdFB1c2hGcm9udE9wdGlvbnNcbiAgKTogUHJvbWlzZTxDYWNoZUxpc3RQdXNoRnJvbnQuUmVzcG9uc2U+IHtcbiAgICBjb25zdCBjbGllbnQgPSB0aGlzLmdldE5leHREYXRhQ2xpZW50KCk7XG4gICAgcmV0dXJuIGF3YWl0IGNsaWVudC5saXN0UHVzaEZyb250KFxuICAgICAgY2FjaGVOYW1lLFxuICAgICAgbGlzdE5hbWUsXG4gICAgICB2YWx1ZSxcbiAgICAgIG9wdGlvbnM/LnRydW5jYXRlQmFja1RvU2l6ZSxcbiAgICAgIG9wdGlvbnM/LnR0bFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhbGwgZWxlbWVudHMgZnJvbSB0aGUgZ2l2ZW4gbGlzdCBlcXVhbCB0byB0aGUgZ2l2ZW4gdmFsdWUuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjYWNoZU5hbWUgLSBUaGUgY2FjaGUgY29udGFpbmluZyB0aGUgbGlzdC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGxpc3ROYW1lIC0gVGhlIGxpc3QgdG8gcmVtb3ZlIGZyb20uXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgVWludDhBcnJheX0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gcmVtb3ZlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxDYWNoZUxpc3RSZW1vdmVWYWx1ZS5SZXNwb25zZT59IC1cbiAgICoge0BsaW5rIENhY2hlTGlzdFJlbW92ZVZhbHVlLlN1Y2Nlc3N9IG9uIHN1Y2Nlc3MuIFJlbW92aW5nIGFuIGVsZW1lbnQgdGhhdFxuICAgKiBkb2VzIG5vdCBvY2N1ciBpbiB0aGUgbGlzdCBvciByZW1vdmluZyBmcm9tIGEgbm9uLWV4aXN0ZW50IGxpc3QgY291bnRzIGFzIGFcbiAgICogc3VjY2Vzcy5cbiAgICoge0BsaW5rIENhY2hlTGlzdFJlbW92ZVZhbHVlLkVycm9yfSBvbiBmYWlsdXJlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGxpc3RSZW1vdmVWYWx1ZShcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBsaXN0TmFtZTogc3RyaW5nLFxuICAgIHZhbHVlOiBzdHJpbmcgfCBVaW50OEFycmF5XG4gICk6IFByb21pc2U8Q2FjaGVMaXN0UmVtb3ZlVmFsdWUuUmVzcG9uc2U+IHtcbiAgICBjb25zdCBjbGllbnQgPSB0aGlzLmdldE5leHREYXRhQ2xpZW50KCk7XG4gICAgcmV0dXJuIGF3YWl0IGNsaWVudC5saXN0UmVtb3ZlVmFsdWUoY2FjaGVOYW1lLCBsaXN0TmFtZSwgdmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldGFpbnMgc2xpY2Ugb2YgZWxlbWVudHMgb2YgYSBnaXZlbiBsaXN0LCBkZWxldGVzIHRoZSByZXN0IG9mIHRoZSBsaXN0XG4gICAqIHRoYXQgaXNuJ3QgYmVpbmcgcmV0YWluZWQuIFJldHVybnMgYSBTdWNjZXNzIG9yIEVycm9yLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY2FjaGVOYW1lIC0gVGhlIGNhY2hlIGNvbnRhaW5pbmcgdGhlIGxpc3QuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBsaXN0TmFtZSAtIFRoZSBsaXN0IHRvIHJldGFpbiBhIHNsaWNlIG9mLlxuICAgKiBAcGFyYW0ge0xpc3RSZXRhaW5DYWxsT3B0aW9uc30gW29wdGlvbnNdXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5zdGFydEluZGV4XSAtIFN0YXJ0IGluY2x1c2l2ZSBpbmRleCBmb3IgZmV0Y2hcbiAgICogb3BlcmF0aW9uLiBEZWZhdWx0cyB0byBzdGFydCBvZiBhcnJheSBpZiBub3QgZ2l2ZW4sIDAuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5lbmRJbmRleF0gLSBFbmQgZXhjbHVzaXZlIGluZGV4IGZvciBmZXRjaFxuICAgKiBvcGVyYXRpb24uIERlZmF1bHRzIHRvIGVuZCBvZiBhcnJheSBpZiBub3QgZ2l2ZW4uXG4gICAqIEBwYXJhbSB7Q29sbGVjdGlvblR0bH0gW29wdGlvbnMudHRsXSAtIEhvdyB0aGUgVFRMIHNob3VsZCBiZSBtYW5hZ2VkLlxuICAgKiBSZWZyZXNoZXMgdGhlIGxpc3QncyBUVEwgdXNpbmcgdGhlIGNsaWVudCdzIGRlZmF1bHQgaWYgdGhpcyBpcyBub3RcbiAgICogc3VwcGxpZWQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPENhY2hlTGlzdFJldGFpbi5SZXNwb25zZT59IC1cbiAgICoge0BsaW5rIENhY2hlTGlzdFJldGFpbi5TdWNjZXNzfSBvbiBzdWNjZXNzLlxuICAgKiB7QGxpbmsgQ2FjaGVMaXN0UmV0YWluLkVycm9yfSBvbiBmYWlsdXJlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGxpc3RSZXRhaW4oXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgbGlzdE5hbWU6IHN0cmluZyxcbiAgICBvcHRpb25zPzogTGlzdFJldGFpbkNhbGxPcHRpb25zXG4gICk6IFByb21pc2U8Q2FjaGVMaXN0UmV0YWluLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgY2xpZW50ID0gdGhpcy5nZXROZXh0RGF0YUNsaWVudCgpO1xuICAgIHJldHVybiBhd2FpdCBjbGllbnQubGlzdFJldGFpbihcbiAgICAgIGNhY2hlTmFtZSxcbiAgICAgIGxpc3ROYW1lLFxuICAgICAgb3B0aW9ucz8uc3RhcnRJbmRleCxcbiAgICAgIG9wdGlvbnM/LmVuZEluZGV4LFxuICAgICAgb3B0aW9ucz8udHRsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGZXRjaGVzIGFsbCBlbGVtZW50cyBvZiB0aGUgZ2l2ZW4gc2V0XG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjYWNoZU5hbWUgLSBUaGUgY2FjaGUgY29udGFpbmluZyB0aGUgc2V0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc2V0TmFtZSAtIFRoZSBzZXQgdG8gZmV0Y2guXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPENhY2hlU2V0RmV0Y2guUmVzcG9uc2U+fSAtXG4gICAqIHtAbGluayBDYWNoZVNldEZldGNoLkhpdH0gY29udGFpbmluZyB0aGUgc2V0IGVsZW1lbnRzIGlmIHRoZSBzZXQgZXhpc3RzLlxuICAgKiB7QGxpbmsgQ2FjaGVTZXRGZXRjaC5NaXNzfSBpZiB0aGUgc2V0IGRvZXMgbm90IGV4aXN0LlxuICAgKiB7QGxpbmsgQ2FjaGVTZXRGZXRjaC5FcnJvcn0gb24gZmFpbHVyZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBzZXRGZXRjaChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzZXROYW1lOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxDYWNoZVNldEZldGNoLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgY2xpZW50ID0gdGhpcy5nZXROZXh0RGF0YUNsaWVudCgpO1xuICAgIHJldHVybiBhd2FpdCBjbGllbnQuc2V0RmV0Y2goY2FjaGVOYW1lLCBzZXROYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGFuIGVsZW1lbnQgdG8gdGhlIGdpdmVuIHNldC4gQ3JlYXRlcyB0aGUgc2V0IGlmIGl0IGRvZXMgbm90IGFscmVhZHlcbiAgICogZXhpc3QuXG4gICAqXG4gICAqIEByZW1hcmtzXG4gICAqIEFmdGVyIHRoaXMgb3BlcmF0aW9uIHRoZSBzZXQgd2lsbCBjb250YWluIHRoZSB1bmlvbiBvZiB0aGUgZWxlbWVudCBwYXNzZWRcbiAgICogaW4gYW5kIHRoZSBvcmlnaW5hbCBlbGVtZW50cyBvZiB0aGUgc2V0LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY2FjaGVOYW1lIC0gVGhlIGNhY2hlIHRvIHN0b3JlIHRoZSBzZXQgaW4uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzZXROYW1lIC0gVGhlIHNldCB0byBhZGQgdG8uXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgVWludDhBcnJheX0gZWxlbWVudCAtIFRoZSBlbGVtZW50IHRvIGFkZC5cbiAgICogQHBhcmFtIHtTZXRBZGRFbGVtZW50T3B0aW9uc30gb3B0aW9uc1xuICAgKiBAcGFyYW0ge0NvbGxlY3Rpb25UdGx9IFtvcHRpb25zLnR0bF0gLSBIb3cgdGhlIFRUTCBzaG91bGQgYmUgbWFuYWdlZC5cbiAgICogUmVmcmVzaGVzIHRoZSBzZXQncyBUVEwgdXNpbmcgdGhlIGNsaWVudCdzIGRlZmF1bHQgaWYgdGhpcyBpcyBub3Qgc3VwcGxpZWQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPENhY2hlU2V0QWRkRWxlbWVudC5SZXNwb25zZT59IC1cbiAgICoge0BsaW5rIENhY2hlU2V0QWRkRWxlbWVudC5TdWNjZXNzfSBvbiBzdWNjZXNzLlxuICAgKiB7QGxpbmsgQ2FjaGVTZXRBZGRFbGVtZW50LkVycm9yfSBvbiBmYWlsdXJlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHNldEFkZEVsZW1lbnQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc2V0TmFtZTogc3RyaW5nLFxuICAgIGVsZW1lbnQ6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgb3B0aW9ucz86IFNldEFkZEVsZW1lbnRPcHRpb25zXG4gICk6IFByb21pc2U8Q2FjaGVTZXRBZGRFbGVtZW50LlJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIChcbiAgICAgIGF3YWl0IHRoaXMuc2V0QWRkRWxlbWVudHMoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgc2V0TmFtZSxcbiAgICAgICAgW2VsZW1lbnRdIGFzIHN0cmluZ1tdIHwgVWludDhBcnJheVtdLFxuICAgICAgICBvcHRpb25zXG4gICAgICApXG4gICAgKS50b1Npbmd1bGFyUmVzcG9uc2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIG11bHRpcGxlIGVsZW1lbnRzIHRvIHRoZSBnaXZlbiBzZXQuIENyZWF0ZXMgdGhlIHNldCBpZiBpdCBkb2VzIG5vdFxuICAgKiBhbHJlYWR5IGV4aXN0LlxuICAgKlxuICAgKiBAcmVtYXJrc1xuICAgKiBBZnRlciB0aGlzIG9wZXJhdGlvbiwgdGhlIHNldCB3aWxsIGNvbnRhaW4gdGhlIHVuaW9uIG9mIHRoZSBlbGVtZW50cyBwYXNzZWRcbiAgICogaW4gYW5kIHRoZSBvcmlnaW5hbCBlbGVtZW50cyBvZiB0aGUgc2V0LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY2FjaGVOYW1lIC0gVGhlIGNhY2hlIHRvIHN0b3JlIHRoZSBzZXQgaW4uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzZXROYW1lIC0gVGhlIHNldCB0byBhZGQgdG8uXG4gICAqIEBwYXJhbSB7c3RyaW5nW10gfCBVaW50OEFycmF5W119IGVsZW1lbnRzIC0gVGhlIGVsZW1lbnRzIHRvIGFkZC5cbiAgICogQHBhcmFtIHtTZXRBZGRFbGVtZW50c09wdGlvbnN9IG9wdGlvbnNcbiAgICogQHBhcmFtIHtDb2xsZWN0aW9uVHRsfSBbb3B0aW9ucy50dGxdIC0gSG93IHRoZSBUVEwgc2hvdWxkIGJlIG1hbmFnZWQuXG4gICAqIFJlZnJlc2hlcyB0aGUgc2V0J3MgVFRMIHVzaW5nIHRoZSBjbGllbnQncyBkZWZhdWx0IGlmIHRoaXMgaXMgbm90IHN1cHBsaWVkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxDYWNoZVNldEFkZEVsZW1lbnRzLlJlc3BvbnNlPn0gLVxuICAgKiB7QGxpbmsgQ2FjaGVTZXRBZGRFbGVtZW50cy5TdWNjZXNzfSBvbiBzdWNjZXNzLlxuICAgKiB7QGxpbmsgQ2FjaGVTZXRBZGRFbGVtZW50cy5FcnJvcn0gb24gZmFpbHVyZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBzZXRBZGRFbGVtZW50cyhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzZXROYW1lOiBzdHJpbmcsXG4gICAgZWxlbWVudHM6IHN0cmluZ1tdIHwgVWludDhBcnJheVtdLFxuICAgIG9wdGlvbnM/OiBTZXRBZGRFbGVtZW50c09wdGlvbnNcbiAgKTogUHJvbWlzZTxDYWNoZVNldEFkZEVsZW1lbnRzLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgY2xpZW50ID0gdGhpcy5nZXROZXh0RGF0YUNsaWVudCgpO1xuICAgIHJldHVybiBhd2FpdCBjbGllbnQuc2V0QWRkRWxlbWVudHMoXG4gICAgICBjYWNoZU5hbWUsXG4gICAgICBzZXROYW1lLFxuICAgICAgZWxlbWVudHMsXG4gICAgICBvcHRpb25zPy50dGxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYW4gZWxlbWVudCBmcm9tIHRoZSBnaXZlbiBzZXQuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjYWNoZU5hbWUgLSBUaGUgY2FjaGUgY29udGFpbmluZyB0aGUgc2V0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc2V0TmFtZSAtIFRoZSBzZXQgdG8gcmVtb3ZlIGZyb20uXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgVWludDhBcnJheX0gZWxlbWVudCAtIFRoZSBlbGVtZW50IHRvIHJlbW92ZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8Q2FjaGVTZXRSZW1vdmVFbGVtZW50LlJlc3BvbnNlPn0gLVxuICAgKiB7QGxpbmsgQ2FjaGVTZXRSZW1vdmVFbGVtZW50LlN1Y2Nlc3N9IG9uIHN1Y2Nlc3MuIFJlbW92aW5nIGFuIGVsZW1lbnQgdGhhdFxuICAgKiBkb2VzIG5vdCBvY2N1ciBpbiB0aGUgc2V0IG9yIHJlbW92aW5nIGZyb20gYSBub24tZXhpc3RlbnQgc2V0IGNvdW50cyBhcyBhXG4gICAqIHN1Y2Nlc3MuXG4gICAqIHtAbGluayBDYWNoZVNldFJlbW92ZUVsZW1lbnQuRXJyb3J9IG9uIGZhaWx1cmUuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgc2V0UmVtb3ZlRWxlbWVudChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzZXROYW1lOiBzdHJpbmcsXG4gICAgZWxlbWVudDogc3RyaW5nIHwgVWludDhBcnJheVxuICApOiBQcm9taXNlPENhY2hlU2V0UmVtb3ZlRWxlbWVudC5SZXNwb25zZT4ge1xuICAgIHJldHVybiAoXG4gICAgICBhd2FpdCB0aGlzLnNldFJlbW92ZUVsZW1lbnRzKGNhY2hlTmFtZSwgc2V0TmFtZSwgW2VsZW1lbnRdIGFzXG4gICAgICAgIHwgc3RyaW5nW11cbiAgICAgICAgfCBVaW50OEFycmF5W10pXG4gICAgKS50b1Npbmd1bGFyUmVzcG9uc2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIG11bHRpcGxlIGVsZW1lbnRzIGZyb20gdGhlIGdpdmVuIHNldC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNhY2hlTmFtZSAtIFRoZSBjYWNoZSBjb250YWluaW5nIHRoZSBzZXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzZXROYW1lIC0gVGhlIHNldCB0byByZW1vdmUgZnJvbS5cbiAgICogQHBhcmFtIHtzdHJpbmdbXSB8IFVpbnQ4QXJyYXlbXX0gZWxlbWVudHMgLSBUaGUgZWxlbWVudHMgdG8gcmVtb3ZlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxDYWNoZVNldFJlbW92ZUVsZW1lbnRzLlJlc3BvbnNlPn0gLVxuICAgKiB7QGxpbmsgQ2FjaGVTZXRSZW1vdmVFbGVtZW50cy5TdWNjZXNzfSBvbiBzdWNjZXNzLiBSZW1vdmluZyBlbGVtZW50cyB0aGF0XG4gICAqIGRvIG5vdCBvY2N1ciBpbiB0aGUgc2V0IG9yIHJlbW92aW5nIGZyb20gYSBub24tZXhpc3RlbnQgc2V0IGNvdW50cyBhcyBhXG4gICAqIHN1Y2Nlc3MuXG4gICAqIHtAbGluayBDYWNoZVNldFJlbW92ZUVsZW1lbnRzLkVycm9yfSBvbiBmYWlsdXJlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHNldFJlbW92ZUVsZW1lbnRzKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNldE5hbWU6IHN0cmluZyxcbiAgICBlbGVtZW50czogc3RyaW5nW10gfCBVaW50OEFycmF5W11cbiAgKTogUHJvbWlzZTxDYWNoZVNldFJlbW92ZUVsZW1lbnRzLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgY2xpZW50ID0gdGhpcy5nZXROZXh0RGF0YUNsaWVudCgpO1xuICAgIHJldHVybiBhd2FpdCBjbGllbnQuc2V0UmVtb3ZlRWxlbWVudHMoY2FjaGVOYW1lLCBzZXROYW1lLCBlbGVtZW50cyk7XG4gIH1cblxuICAvKipcbiAgICogQXNzb2NpYXRlcyB0aGUgZ2l2ZW4ga2V5IHdpdGggdGhlIGdpdmVuIHZhbHVlLiBJZiBhIHZhbHVlIGZvciB0aGUga2V5IGlzXG4gICAqIGFscmVhZHkgcHJlc2VudCBpdCBpcyBub3QgcmVwbGFjZWQgd2l0aCB0aGUgbmV3IHZhbHVlLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY2FjaGVOYW1lIC0gVGhlIGNhY2hlIHRvIHN0b3JlIHRoZSB2YWx1ZSBpbi5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCBVaW50OEFycmF5fSBrZXkgLSBUaGUga2V5IHRvIHNldC5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCBVaW50OEFycmF5fSBmaWVsZCAtIFRoZSB2YWx1ZSB0byBiZSBzdG9yZWQuXG4gICAqIEBwYXJhbSB7U2V0SWZOb3RFeGlzdHNPcHRpb25zfSBbb3B0aW9uc11cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLnR0bF0gLSBUaGUgdGltZSB0byBsaXZlIGZvciB0aGUgaXRlbSBpbiB0aGUgY2FjaGUuXG4gICAqIFVzZXMgdGhlIGNsaWVudCdzIGRlZmF1bHQgVFRMIGlmIHRoaXMgaXMgbm90IHN1cHBsaWVkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxDYWNoZVNldElmTm90RXhpc3RzLlJlc3BvbnNlPn0gLVxuICAgKiB7QGxpbmsgQ2FjaGVTZXRJZk5vdEV4aXN0cy5TdG9yZWR9IG9uIHN0b3JpbmcgdGhlIG5ldyB2YWx1ZS5cbiAgICoge0BsaW5rIENhY2hlU2V0SWZOb3RFeGlzdHMuTm90U3RvcmVkfSBvbiBub3Qgc3RvcmluZyB0aGUgbmV3IHZhbHVlLlxuICAgKiB7QGxpbmsgQ2FjaGVTZXRJZk5vdEV4aXN0cy5FcnJvcn0gb24gZmFpbHVyZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBzZXRJZk5vdEV4aXN0cyhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBrZXk6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgZmllbGQ6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgb3B0aW9ucz86IFNldElmTm90RXhpc3RzT3B0aW9uc1xuICApOiBQcm9taXNlPENhY2hlU2V0SWZOb3RFeGlzdHMuUmVzcG9uc2U+IHtcbiAgICBjb25zdCBjbGllbnQgPSB0aGlzLmdldE5leHREYXRhQ2xpZW50KCk7XG4gICAgcmV0dXJuIGF3YWl0IGNsaWVudC5zZXRJZk5vdEV4aXN0cyhjYWNoZU5hbWUsIGtleSwgZmllbGQsIG9wdGlvbnM/LnR0bCk7XG4gIH1cblxuICAvKipcbiAgICogRmx1c2hlcyAvIGNsZWFycyBhbGwgdGhlIGl0ZW1zIG9mIHRoZSBnaXZlbiBjYWNoZVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY2FjaGVOYW1lIC0gVGhlIGNhY2hlIHRvIGJlIGZsdXNoZWQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPENhY2hlRmx1c2guUmVzcG9uc2U+fSAtXG4gICAqIHtAbGluayBDYWNoZUZsdXNoLlN1Y2Nlc3N9IG9uIHN1Y2Nlc3MuXG4gICAqIHtAbGluayBDYWNoZUZsdXNoLkVycm9yfSBvbiBmYWlsdXJlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGZsdXNoQ2FjaGUoY2FjaGVOYW1lOiBzdHJpbmcpOiBQcm9taXNlPENhY2hlRmx1c2guUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5jb250cm9sQ2xpZW50LmZsdXNoQ2FjaGUoY2FjaGVOYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGZXRjaGVzIGFsbCBlbGVtZW50cyBvZiB0aGUgZ2l2ZW4gZGljdGlvbmFyeS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNhY2hlTmFtZSAtIFRoZSBjYWNoZSB0byBwZXJmb3JtIHRoZSBsb29rdXAgaW4uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBkaWN0aW9uYXJ5TmFtZSAtIFRoZSBkaWN0aW9uYXJ5IHRvIGZldGNoLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxDYWNoZURpY3Rpb25hcnlGZXRjaC5SZXNwb25zZT59IC1cbiAgICoge0BsaW5rIENhY2hlRGljdGlvbmFyeUZldGNoLkhpdH0gY29udGFpbmluZyB0aGUgZGljdGlvbmFyeSBlbGVtZW50cyBpZiB0aGVcbiAgICogZGljdGlvbmFyeSBleGlzdHMuXG4gICAqIHtAbGluayBDYWNoZURpY3Rpb25hcnlGZXRjaC5NaXNzfSBpZiB0aGUgZGljdGlvbmFyeSBkb2VzIG5vdCBleGlzdC5cbiAgICoge0BsaW5rIENhY2hlRGljdGlvbmFyeUZldGNoLkVycm9yfSBvbiBmYWlsdXJlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGRpY3Rpb25hcnlGZXRjaChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBkaWN0aW9uYXJ5TmFtZTogc3RyaW5nXG4gICk6IFByb21pc2U8Q2FjaGVEaWN0aW9uYXJ5RmV0Y2guUmVzcG9uc2U+IHtcbiAgICBjb25zdCBjbGllbnQgPSB0aGlzLmdldE5leHREYXRhQ2xpZW50KCk7XG4gICAgcmV0dXJuIGF3YWl0IGNsaWVudC5kaWN0aW9uYXJ5RmV0Y2goY2FjaGVOYW1lLCBkaWN0aW9uYXJ5TmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhbiBpbnRlZ2VyIHF1YW50aXR5IHRvIGEgZmllbGQgdmFsdWUuXG4gICAqXG4gICAqIEByZW1hcmtzXG4gICAqIEluY3JlbWVudGluZyB0aGUgdmFsdWUgb2YgYSBtaXNzaW5nIGZpZWxkIHNldHMgdGhlIHZhbHVlIHRvIGFtb3VudC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNhY2hlTmFtZSAtIFRoZSBjYWNoZSBjb250YWluaW5nIHRoZSBmaWVsZC5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCBVaW50OEFycmF5fSBmaWVsZCAtIFRoZSBmaWVsZCB0byBpbmNyZW1lbnQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBhbW91bnQgLSBUaGUgcXVhbnRpdHkgdG8gYWRkIHRvIHRoZSB2YWx1ZS4gTWF5IGJlIHBvc2l0aXZlLFxuICAgKiBuZWdhdGl2ZSwgb3IgemVyby4gRGVmYXVsdHMgdG8gMS5cbiAgICogQHBhcmFtIHtJbmNyZW1lbnRPcHRpb25zfSBvcHRpb25zXG4gICAqIEBwYXJhbSB7Q29sbGVjdGlvblR0bH0gW29wdGlvbnMudHRsXSAtIEhvdyB0aGUgVFRMIHNob3VsZCBiZSBtYW5hZ2VkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxDYWNoZUluY3JlbWVudD59IC1cbiAgICoge0BsaW5rIENhY2hlSW5jcmVtZW50LlN1Y2Nlc3N9IGNvbnRhaW5pbmcgdGhlIGluY3JlbWVudGVkIHZhbHVlXG4gICAqIG9uIHN1Y2Nlc3MuXG4gICAqIHtAbGluayBDYWNoZUluY3JlbWVudC5FcnJvcn0gb24gZmFpbHVyZS4gSW5jcmVtZW50aW5nIGEgdmFsdWVcbiAgICogdGhhdCB3YXMgbm90IHNldCB1c2luZyB0aGlzIG1ldGhvZCBvciBpcyBub3QgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZlxuICAgKiBhbiBpbnRlZ2VyIHJlc3VsdHMgaW4gYSBmYWlsdXJlIHdpdGggYSBGYWlsZWRQcmVjb25kaXRpb25FeGNlcHRpb24gZXJyb3IuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgaW5jcmVtZW50KFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGZpZWxkOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIGFtb3VudCA9IDEsXG4gICAgb3B0aW9ucz86IEluY3JlbWVudE9wdGlvbnNcbiAgKTogUHJvbWlzZTxDYWNoZUluY3JlbWVudC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IGNsaWVudCA9IHRoaXMuZ2V0TmV4dERhdGFDbGllbnQoKTtcbiAgICByZXR1cm4gYXdhaXQgY2xpZW50LmluY3JlbWVudChjYWNoZU5hbWUsIGZpZWxkLCBhbW91bnQsIG9wdGlvbnM/LnR0bCk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhbiBlbGVtZW50IHRvIHRoZSBnaXZlbiBkaWN0aW9uYXJ5LiBDcmVhdGVzIHRoZSBkaWN0aW9uYXJ5IGlmIGl0IGRvZXNcbiAgICogbm90IGFscmVhZHkgZXhpc3QuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjYWNoZU5hbWUgLSBUaGUgY2FjaGUgdG8gc3RvcmUgdGhlIGRpY3Rpb25hcnkgaW4uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBkaWN0aW9uYXJ5TmFtZSAtIFRoZSBkaWN0aW9uYXJ5IHRvIGFkZCB0by5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCBVaW50OEFycmF5fSBmaWVsZCAtIFRoZSBmaWVsZCB0byBzZXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgVWludDhBcnJheX0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gc3RvcmUuXG4gICAqIEBwYXJhbSB7RGljdGlvbmFyeVNldEZpZWxkT3B0aW9uc30gb3B0aW9uc1xuICAgKiBAcGFyYW0ge0NvbGxlY3Rpb25UdGx9IFtvcHRpb25zLnR0bF0gLSBIb3cgdGhlIFRUTCBzaG91bGQgYmUgbWFuYWdlZC5cbiAgICogUmVmcmVzaGVzIHRoZSBkaWN0aW9uYXJ5J3MgVFRMIHVzaW5nIHRoZSBjbGllbnQncyBkZWZhdWx0IGlmIHRoaXMgaXMgbm90XG4gICAqIHN1cHBsaWVkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxDYWNoZURpY3Rpb25hcnlTZXRGaWVsZC5SZXNwb25zZT59IC1cbiAgICoge0BsaW5rIENhY2hlRGljdGlvbmFyeVNldEZpZWxkLlN1Y2Nlc3N9IG9uIHN1Y2Nlc3MuXG4gICAqIHtAbGluayBDYWNoZURpY3Rpb25hcnlTZXRGaWVsZC5FcnJvcn0gb24gZmFpbHVyZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBkaWN0aW9uYXJ5U2V0RmllbGQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgZGljdGlvbmFyeU5hbWU6IHN0cmluZyxcbiAgICBmaWVsZDogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICB2YWx1ZTogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICBvcHRpb25zPzogRGljdGlvbmFyeVNldEZpZWxkT3B0aW9uc1xuICApOiBQcm9taXNlPENhY2hlRGljdGlvbmFyeVNldEZpZWxkLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgY2xpZW50ID0gdGhpcy5nZXROZXh0RGF0YUNsaWVudCgpO1xuICAgIHJldHVybiBhd2FpdCBjbGllbnQuZGljdGlvbmFyeVNldEZpZWxkKFxuICAgICAgY2FjaGVOYW1lLFxuICAgICAgZGljdGlvbmFyeU5hbWUsXG4gICAgICBmaWVsZCxcbiAgICAgIHZhbHVlLFxuICAgICAgb3B0aW9ucz8udHRsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIG11bHRpcGxlIGVsZW1lbnRzIHRvIHRoZSBnaXZlbiBkaWN0aW9uYXJ5LiBDcmVhdGVzIHRoZSBkaWN0aW9uYXJ5IGlmXG4gICAqIGl0IGRvZXMgbm90IGFscmVhZHkgZXhpc3QuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjYWNoZU5hbWUgLSBUaGUgY2FjaGUgdG8gc3RvcmUgdGhlIGRpY3Rpb25hcnkgaW4uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBkaWN0aW9uYXJ5TmFtZSAtIFRoZSBkaWN0aW9uYXJ5IHRvIGFkZCB0by5cbiAgICogQHBhcmFtIHtNYXA8c3RyaW5nIHwgVWludDhBcnJheSwgc3RyaW5nIHwgVWludDhBcnJheT59IGVsZW1lbnRzIC0gVGhlXG4gICAqIGVsZW1lbnRzIHRvIHNldC5cbiAgICogQHBhcmFtIHtEaWN0aW9uYXJ5U2V0RmllbGRzT3B0aW9uc30gb3B0aW9uc1xuICAgKiBAcGFyYW0ge0NvbGxlY3Rpb25UdGx9IFtvcHRpb25zLnR0bF0gLSBIb3cgdGhlIFRUTCBzaG91bGQgYmUgbWFuYWdlZC5cbiAgICogUmVmcmVzaGVzIHRoZSBkaWN0aW9uYXJ5J3MgVFRMIHVzaW5nIHRoZSBjbGllbnQncyBkZWZhdWx0IGlmIHRoaXMgaXMgbm90XG4gICAqIHN1cHBsaWVkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxDYWNoZURpY3Rpb25hcnlTZXRGaWVsZHMuUmVzcG9uc2U+fSAtXG4gICAqIHtAbGluayBDYWNoZURpY3Rpb25hcnlTZXRGaWVsZHMuU3VjY2Vzc30gb24gc3VjY2Vzcy5cbiAgICoge0BsaW5rIENhY2hlRGljdGlvbmFyeVNldEZpZWxkcy5FcnJvcn0gb24gZmFpbHVyZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBkaWN0aW9uYXJ5U2V0RmllbGRzKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGRpY3Rpb25hcnlOYW1lOiBzdHJpbmcsXG4gICAgZWxlbWVudHM6XG4gICAgICB8IE1hcDxzdHJpbmcgfCBVaW50OEFycmF5LCBzdHJpbmcgfCBVaW50OEFycmF5PlxuICAgICAgfCBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBVaW50OEFycmF5PixcbiAgICBvcHRpb25zPzogRGljdGlvbmFyeVNldEZpZWxkT3B0aW9uc1xuICApOiBQcm9taXNlPENhY2hlRGljdGlvbmFyeVNldEZpZWxkcy5SZXNwb25zZT4ge1xuICAgIGNvbnN0IGNsaWVudCA9IHRoaXMuZ2V0TmV4dERhdGFDbGllbnQoKTtcbiAgICByZXR1cm4gYXdhaXQgY2xpZW50LmRpY3Rpb25hcnlTZXRGaWVsZHMoXG4gICAgICBjYWNoZU5hbWUsXG4gICAgICBkaWN0aW9uYXJ5TmFtZSxcbiAgICAgIGVsZW1lbnRzLFxuICAgICAgb3B0aW9ucz8udHRsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSB2YWx1ZSBzdG9yZWQgZm9yIHRoZSBnaXZlbiBkaWN0aW9uYXJ5IGFuZCBmaWVsZC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNhY2hlTmFtZSAtIFRoZSBjYWNoZSBjb250YWluaW5nIHRoZSBkaWN0aW9uYXJ5LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZGljdGlvbmFyeU5hbWUgLSBUaGUgZGljdGlvbmFyeSB0byBsb29rIHVwLlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IFVpbnQ4QXJyYXl9IGZpZWxkIC0gVGhlIGZpZWxkIHRvIGxvb2sgdXAuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPENhY2hlRGljdGlvbmFyeUdldEZpZWxkLlJlc3BvbnNlPn0gLVxuICAgKiB7QGxpbmsgQ2FjaGVEaWN0aW9uYXJ5R2V0RmllbGQuSGl0fSBjb250YWluaW5nIHRoZSBkaWN0aW9uYXJ5IGVsZW1lbnQgaWZcbiAgICogb25lIGlzIGZvdW5kLlxuICAgKiB7QGxpbmsgQ2FjaGVEaWN0aW9uYXJ5R2V0RmllbGQuTWlzc30gaWYgdGhlIGRpY3Rpb25hcnkgZG9lcyBub3QgZXhpc3QuXG4gICAqIHtAbGluayBDYWNoZURpY3Rpb25hcnlHZXRGaWVsZC5FcnJvcn0gb24gZmFpbHVyZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBkaWN0aW9uYXJ5R2V0RmllbGQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgZGljdGlvbmFyeU5hbWU6IHN0cmluZyxcbiAgICBmaWVsZDogc3RyaW5nIHwgVWludDhBcnJheVxuICApOiBQcm9taXNlPENhY2hlRGljdGlvbmFyeUdldEZpZWxkLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgY2xpZW50ID0gdGhpcy5nZXROZXh0RGF0YUNsaWVudCgpO1xuICAgIHJldHVybiBhd2FpdCBjbGllbnQuZGljdGlvbmFyeUdldEZpZWxkKGNhY2hlTmFtZSwgZGljdGlvbmFyeU5hbWUsIGZpZWxkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIG11bHRpcGxlIHZhbHVlcyBmcm9tIHRoZSBnaXZlbiBkaWN0aW9uYXJ5LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY2FjaGVOYW1lIC0gVGhlIGNhY2hlIGNvbnRhaW5pbmcgdGhlIGRpY3Rpb25hcnkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBkaWN0aW9uYXJ5TmFtZSAtIFRoZSBkaWN0aW9uYXJ5IHRvIGxvb2sgdXAuXG4gICAqIEBwYXJhbSB7c3RyaW5nW10gfCBVaW50OEFycmF5W119IGZpZWxkcyAtIFRoZSBmaWVsZHMgdG8gbG9vayB1cC5cbiAgICogQHJldHVybnMge1Byb21pc2U8Q2FjaGVEaWN0aW9uYXJ5R2V0RmllbGRzLlJlc3BvbnNlPn0gLVxuICAgKiB7QGxpbmsgQ2FjaGVEaWN0aW9uYXJ5R2V0RmllbGRzLkhpdH0gY29udGFpbmluZyB0aGUgZGljdGlvbmFyeSBlbGVtZW50cyBpZlxuICAgKiB0aGUgZGljdGlvbmFyeSBleGlzdHMuXG4gICAqIHtAbGluayBDYWNoZURpY3Rpb25hcnlHZXRGaWVsZHMuTWlzc30gaWYgdGhlIGRpY3Rpb25hcnkgZG9lcyBub3QgZXhpc3QuXG4gICAqIHtAbGluayBDYWNoZURpY3Rpb25hcnlHZXRGaWVsZHMuRXJyb3J9IG9uIGZhaWx1cmUuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZGljdGlvbmFyeUdldEZpZWxkcyhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBkaWN0aW9uYXJ5TmFtZTogc3RyaW5nLFxuICAgIGZpZWxkczogc3RyaW5nW10gfCBVaW50OEFycmF5W11cbiAgKTogUHJvbWlzZTxDYWNoZURpY3Rpb25hcnlHZXRGaWVsZHMuUmVzcG9uc2U+IHtcbiAgICBjb25zdCBjbGllbnQgPSB0aGlzLmdldE5leHREYXRhQ2xpZW50KCk7XG4gICAgcmV0dXJuIGF3YWl0IGNsaWVudC5kaWN0aW9uYXJ5R2V0RmllbGRzKGNhY2hlTmFtZSwgZGljdGlvbmFyeU5hbWUsIGZpZWxkcyk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhbiBlbGVtZW50IGZyb20gdGhlIGdpdmVuIGRpY3Rpb25hcnkuXG4gICAqXG4gICAqIEByZW1hcmtzXG4gICAqIFBlcmZvcm1zIGEgbm8tb3AgaWYgdGhlIGRpY3Rpb25hcnkgb3IgZmllbGQgZG9lcyBub3QgZXhpc3QuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjYWNoZU5hbWUgLSBUaGUgY2FjaGUgY29udGFpbmluZyB0aGUgZGljdGlvbmFyeS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGRpY3Rpb25hcnlOYW1lIC0gVGhlIGRpY3Rpb25hcnkgdG8gcmVtb3ZlIGZyb20uXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgVWludDhBcnJheX0gZmllbGQgLSBUaGUgZmllbGQgdG8gcmVtb3ZlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxDYWNoZURpY3Rpb25hcnlSZW1vdmVGaWVsZC5SZXNwb25zZT59IC1cbiAgICoge0BsaW5rIENhY2hlRGljdGlvbmFyeVJlbW92ZUZpZWxkLlN1Y2Nlc3N9IG9uIHN1Y2Nlc3MuXG4gICAqIHtAbGluayBDYWNoZURpY3Rpb25hcnlSZW1vdmVGaWVsZC5FcnJvcn0gb24gZmFpbHVyZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBkaWN0aW9uYXJ5UmVtb3ZlRmllbGQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgZGljdGlvbmFyeU5hbWU6IHN0cmluZyxcbiAgICBmaWVsZDogc3RyaW5nIHwgVWludDhBcnJheVxuICApOiBQcm9taXNlPENhY2hlRGljdGlvbmFyeVJlbW92ZUZpZWxkLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgY2xpZW50ID0gdGhpcy5nZXROZXh0RGF0YUNsaWVudCgpO1xuICAgIHJldHVybiBhd2FpdCBjbGllbnQuZGljdGlvbmFyeVJlbW92ZUZpZWxkKGNhY2hlTmFtZSwgZGljdGlvbmFyeU5hbWUsIGZpZWxkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIG11bHRpcGxlIGZpZWxkcyBmcm9tIHRoZSBnaXZlbiBkaWN0aW9uYXJ5LlxuICAgKlxuICAgKiBAcmVtYXJrc1xuICAgKiBQZXJmb3JtcyBhIG5vLW9wIGlmIHRoZSBkaWN0aW9uYXJ5IG9yIGZpZWxkcyBkbyBub3QgZXhpc3QuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjYWNoZU5hbWUgLSBUaGUgY2FjaGUgY29udGFpbmluZyB0aGUgZGljdGlvbmFyeS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGRpY3Rpb25hcnlOYW1lIC0gVGhlIGRpY3Rpb25hcnkgdG8gcmVtb3ZlIGZyb20uXG4gICAqIEBwYXJhbSB7c3RyaW5nW10gfCBVaW50OEFycmF5W119IGZpZWxkcyAtIFRoZSBmaWVsZHMgdG8gcmVtb3ZlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxDYWNoZURpY3Rpb25hcnlSZW1vdmVGaWVsZHMuUmVzcG9uc2U+fSAtXG4gICAqIHtAbGluayBDYWNoZURpY3Rpb25hcnlSZW1vdmVGaWVsZHMuU3VjY2Vzc30gb24gc3VjY2Vzcy5cbiAgICoge0BsaW5rIENhY2hlRGljdGlvbmFyeVJlbW92ZUZpZWxkcy5FcnJvcn0gb24gZmFpbHVyZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBkaWN0aW9uYXJ5UmVtb3ZlRmllbGRzKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGRpY3Rpb25hcnlOYW1lOiBzdHJpbmcsXG4gICAgZmllbGRzOiBzdHJpbmdbXSB8IFVpbnQ4QXJyYXlbXVxuICApOiBQcm9taXNlPENhY2hlRGljdGlvbmFyeVJlbW92ZUZpZWxkcy5SZXNwb25zZT4ge1xuICAgIGNvbnN0IGNsaWVudCA9IHRoaXMuZ2V0TmV4dERhdGFDbGllbnQoKTtcbiAgICByZXR1cm4gYXdhaXQgY2xpZW50LmRpY3Rpb25hcnlSZW1vdmVGaWVsZHMoXG4gICAgICBjYWNoZU5hbWUsXG4gICAgICBkaWN0aW9uYXJ5TmFtZSxcbiAgICAgIGZpZWxkc1xuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhbiBpbnRlZ2VyIHF1YW50aXR5IHRvIGEgZGljdGlvbmFyeSB2YWx1ZS5cbiAgICpcbiAgICogQHJlbWFya3NcbiAgICogSW5jcmVtZW50aW5nIHRoZSB2YWx1ZSBvZiBhIG1pc3NpbmcgZmllbGQgc2V0cyB0aGUgdmFsdWUgdG8gYW1vdW50LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY2FjaGVOYW1lIC0gVGhlIGNhY2hlIGNvbnRhaW5pbmcgdGhlIGRpY3Rpb25hcnkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBkaWN0aW9uYXJ5TmFtZSAtIFRoZSBkaWN0aW9uYXJ5IHRvIHNldC5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCBVaW50OEFycmF5fSBmaWVsZCAtIFRoZSBmaWVsZCB0byBpbmNyZW1lbnQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBhbW91bnQgLSBUaGUgcXVhbnRpdHkgdG8gYWRkIHRvIHRoZSB2YWx1ZS4gTWF5IGJlIHBvc2l0aXZlLFxuICAgKiBuZWdhdGl2ZSwgb3IgemVyby4gRGVmYXVsdHMgdG8gMS5cbiAgICogQHBhcmFtIHtEaWN0aW9uYXJ5SW5jcmVtZW50T3B0aW9uc30gb3B0aW9uc1xuICAgKiBAcGFyYW0ge0NvbGxlY3Rpb25UdGx9IFtvcHRpb25zLnR0bF0gLSBIb3cgdGhlIFRUTCBzaG91bGQgYmUgbWFuYWdlZC5cbiAgICogUmVmcmVzaGVzIHRoZSBkaWN0aW9uYXJ5J3MgVFRMIHVzaW5nIHRoZSBjbGllbnQncyBkZWZhdWx0IGlmIHRoaXMgaXMgbm90XG4gICAqIHN1cHBsaWVkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxDYWNoZURpY3Rpb25hcnlJbmNyZW1lbnQuUmVzcG9uc2U+fSAtXG4gICAqIHtAbGluayBDYWNoZURpY3Rpb25hcnlJbmNyZW1lbnQuU3VjY2Vzc30gY29udGFpbmluZyB0aGUgaW5jcmVtZW50ZWQgdmFsdWVcbiAgICogb24gc3VjY2Vzcy5cbiAgICoge0BsaW5rIENhY2hlRGljdGlvbmFyeUluY3JlbWVudC5FcnJvcn0gb24gZmFpbHVyZS4gSW5jcmVtZW50aW5nIGEgdmFsdWVcbiAgICogdGhhdCB3YXMgbm90IHNldCB1c2luZyB0aGlzIG1ldGhvZCBvciBpcyBub3QgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZlxuICAgKiBhbiBpbnRlZ2VyIHJlc3VsdHMgaW4gYSBmYWlsdXJlIHdpdGggYSBGYWlsZWRQcmVjb25kaXRpb25FeGNlcHRpb24gZXJyb3IuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZGljdGlvbmFyeUluY3JlbWVudChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBkaWN0aW9uYXJ5TmFtZTogc3RyaW5nLFxuICAgIGZpZWxkOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIGFtb3VudCA9IDEsXG4gICAgb3B0aW9ucz86IERpY3Rpb25hcnlJbmNyZW1lbnRPcHRpb25zXG4gICk6IFByb21pc2U8Q2FjaGVEaWN0aW9uYXJ5SW5jcmVtZW50LlJlc3BvbnNlPiB7XG4gICAgY29uc3QgY2xpZW50ID0gdGhpcy5nZXROZXh0RGF0YUNsaWVudCgpO1xuICAgIHJldHVybiBhd2FpdCBjbGllbnQuZGljdGlvbmFyeUluY3JlbWVudChcbiAgICAgIGNhY2hlTmFtZSxcbiAgICAgIGRpY3Rpb25hcnlOYW1lLFxuICAgICAgZmllbGQsXG4gICAgICBhbW91bnQsXG4gICAgICBvcHRpb25zPy50dGxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYW4gZWxlbWVudCB0byB0aGUgZ2l2ZW4gc29ydGVkIHNldC4gSWYgdGhlIGVsZW1lbnQgYWxyZWFkeSBleGlzdHMsIGl0c1xuICAgKiBzY29yZSBpcyB1cGRhdGVkLiBDcmVhdGVzIHRoZSBzb3J0ZWQgc2V0IGlmIGl0IGRvZXMgbm90IGV4aXN0LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY2FjaGVOYW1lIC0gVGhlIGNhY2hlIGNvbnRhaW5pbmcgdGhlIHNvcnRlZCBzZXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzb3J0ZWRTZXROYW1lIC0gVGhlIHNvcnRlZCBzZXQgdG8gYWRkIHRvLlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IFVpbnQ4QXJyYXl9IHZhbHVlIC0gVGhlIHZhbHVlIHRvIGFkZC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHNjb3JlIC0gVGhlIHNjb3JlIHRvIGFzc2lnbiB0byB0aGUgdmFsdWUuXG4gICAqIEBwYXJhbSB7U29ydGVkU2V0UHV0RWxlbWVudE9wdGlvbnN9IG9wdGlvbnNcbiAgICogQHBhcmFtIHtDb2xsZWN0aW9uVHRsfSBbb3B0aW9ucy50dGxdIC0gSG93IHRoZSBUVEwgc2hvdWxkIGJlIG1hbmFnZWQuXG4gICAqIFJlZnJlc2hlcyB0aGUgc29ydGVkIHNldCdzIFRUTCB1c2luZyB0aGUgY2xpZW50J3MgZGVmYXVsdCBpZiB0aGlzIGlzIG5vdFxuICAgKiBzdXBwbGllZC5cbiAgICogQHJldHVybnMge1Byb21pc2U8Q2FjaGVTb3J0ZWRTZXRQdXRFbGVtZW50LlJlc3BvbnNlPn0gLVxuICAgKiB7QGxpbmsgQ2FjaGVTb3J0ZWRTZXRQdXRFbGVtZW50LlN1Y2Nlc3N9IG9uIHN1Y2Nlc3MuXG4gICAqIHtAbGluayBDYWNoZVNvcnRlZFNldFB1dEVsZW1lbnQuRXJyb3J9IG9uIGZhaWx1cmUuXG4gICAqIEByZXR1cm5zXG4gICAqL1xuICAvLyBwdWJsaWMgYXN5bmMgc29ydGVkU2V0UHV0RWxlbWVudChcbiAgLy8gICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgLy8gICBzb3J0ZWRTZXROYW1lOiBzdHJpbmcsXG4gIC8vICAgdmFsdWU6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gIC8vICAgc2NvcmU6IG51bWJlcixcbiAgLy8gICBvcHRpb25zPzogU29ydGVkU2V0UHV0RWxlbWVudE9wdGlvbnNcbiAgLy8gKTogUHJvbWlzZTxDYWNoZVNvcnRlZFNldFB1dEVsZW1lbnQuUmVzcG9uc2U+IHtcbiAgLy8gICBjb25zdCBjbGllbnQgPSB0aGlzLmdldE5leHREYXRhQ2xpZW50KCk7XG4gIC8vICAgcmV0dXJuIGF3YWl0IGNsaWVudC5zb3J0ZWRTZXRQdXRFbGVtZW50KFxuICAvLyAgICAgY2FjaGVOYW1lLFxuICAvLyAgICAgc29ydGVkU2V0TmFtZSxcbiAgLy8gICAgIHZhbHVlLFxuICAvLyAgICAgc2NvcmUsXG4gIC8vICAgICBvcHRpb25zPy50dGxcbiAgLy8gICApO1xuICAvLyB9XG5cbiAgLyoqXG4gICAqIEFkZHMgZWxlbWVudHMgdG8gdGhlIGdpdmVuIHNvcnRlZCBzZXQuIEZvciBhbnkgdmFsdWVzIHRoYXQgYWxyZWFkeSBleGlzdCwgaXRcbiAgICogdGhlIHNjb3JlIGlzIHVwZGF0ZWQuIENyZWF0ZXMgdGhlIHNvcnRlZCBzZXQgaWYgaXQgZG9lcyBub3QgZXhpc3QuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjYWNoZU5hbWUgLSBUaGUgY2FjaGUgY29udGFpbmluZyB0aGUgc29ydGVkIHNldC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHNvcnRlZFNldE5hbWUgLSBUaGUgc29ydGVkIHNldCB0byBhZGQgdG8uXG4gICAqIEBwYXJhbSB7TWFwPHN0cmluZyB8IFVpbnQ4QXJyYXksIG51bWJlcj58IFJlY29yZDxzdHJpbmcsIG51bWJlcj59IGVsZW1lbnRzIC0gVGhlIHZhbHVlLT5zY29yZSBwYWlycyB0byBhZGQgdG8gdGhlIHNvcnRlZCBzZXQuXG4gICAqIEBwYXJhbSB7U29ydGVkU2V0UHV0RWxlbWVudE9wdGlvbnN9IG9wdGlvbnNcbiAgICogQHBhcmFtIHtDb2xsZWN0aW9uVHRsfSBbb3B0aW9ucy50dGxdIC0gSG93IHRoZSBUVEwgc2hvdWxkIGJlIG1hbmFnZWQuXG4gICAqIFJlZnJlc2hlcyB0aGUgc29ydGVkIHNldCdzIFRUTCB1c2luZyB0aGUgY2xpZW50J3MgZGVmYXVsdCBpZiB0aGlzIGlzIG5vdFxuICAgKiBzdXBwbGllZC5cbiAgICogQHJldHVybnMge1Byb21pc2U8Q2FjaGVTb3J0ZWRTZXRQdXRFbGVtZW50cy5SZXNwb25zZT59IC1cbiAgICoge0BsaW5rIENhY2hlU29ydGVkU2V0UHV0RWxlbWVudHMuU3VjY2Vzc30gb24gc3VjY2Vzcy5cbiAgICoge0BsaW5rIENhY2hlU29ydGVkU2V0UHV0RWxlbWVudHMuRXJyb3J9IG9uIGZhaWx1cmUuXG4gICAqIEByZXR1cm5zXG4gICAqL1xuICAvLyBwdWJsaWMgYXN5bmMgc29ydGVkU2V0UHV0RWxlbWVudHMoXG4gIC8vICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gIC8vICAgc29ydGVkU2V0TmFtZTogc3RyaW5nLFxuICAvLyAgIGVsZW1lbnRzOiBNYXA8c3RyaW5nIHwgVWludDhBcnJheSwgbnVtYmVyPiB8IFJlY29yZDxzdHJpbmcsIG51bWJlcj4sXG4gIC8vICAgb3B0aW9ucz86IFNvcnRlZFNldFB1dEVsZW1lbnRzT3B0aW9uc1xuICAvLyApOiBQcm9taXNlPENhY2hlU29ydGVkU2V0UHV0RWxlbWVudHMuUmVzcG9uc2U+IHtcbiAgLy8gICBjb25zdCBjbGllbnQgPSB0aGlzLmdldE5leHREYXRhQ2xpZW50KCk7XG4gIC8vICAgcmV0dXJuIGF3YWl0IGNsaWVudC5zb3J0ZWRTZXRQdXRFbGVtZW50cyhcbiAgLy8gICAgIGNhY2hlTmFtZSxcbiAgLy8gICAgIHNvcnRlZFNldE5hbWUsXG4gIC8vICAgICBlbGVtZW50cyxcbiAgLy8gICAgIG9wdGlvbnM/LnR0bFxuICAvLyAgICk7XG4gIC8vIH1cblxuICAvLyBzb3J0ZWQgc2V0IHB1dCB2YWx1ZXNcblxuICAvKipcbiAgICogRmV0Y2ggdGhlIGVsZW1lbnRzIGluIHRoZSBnaXZlbiBzb3J0ZWQgc2V0IGJ5IGluZGV4IChyYW5rKS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNhY2hlTmFtZSAtIFRoZSBjYWNoZSBjb250YWluaW5nIHRoZSBzb3J0ZWQgc2V0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc29ydGVkU2V0TmFtZSAtIFRoZSBzb3J0ZWQgc2V0IHRvIGZldGNoIGZyb20uXG4gICAqIEBwYXJhbSB7U29ydGVkU2V0RmV0Y2hCeVJhbmtPcHRpb25zfSBvcHRpb25zXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5zdGFydFJhbmtdIC0gVGhlIHJhbmsgb2YgdGhlIGZpcnN0IGVsZW1lbnQgdG9cbiAgICogZmV0Y2guIERlZmF1bHRzIHRvIDAuIFRoaXMgcmFuayBpcyBpbmNsdXNpdmUsIGllIHRoZSBlbGVtZW50IGF0IHRoaXMgcmFua1xuICAgKiB3aWxsIGJlIGZldGNoZWQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5lbmRSYW5rXSAtIFRoZSByYW5rIG9mIHRoZSBsYXN0IGVsZW1lbnQgdG8gZmV0Y2guXG4gICAqIFRoaXMgcmFuayBpcyBleGNsdXNpdmUsIGllIHRoZSBlbGVtZW50IGF0IHRoaXMgcmFuayB3aWxsIG5vdCBiZSBmZXRjaGVkLlxuICAgKiBEZWZhdWx0cyB0byBudWxsLCB3aGljaCBmZXRjaGVzIHVwIHVudGlsIGFuZCBpbmNsdWRpbmcgdGhlIGxhc3QgZWxlbWVudC5cbiAgICogQHBhcmFtIHtTb3J0ZWRTZXRPcmRlcn0gW29wdGlvbnMub3JkZXJdIC0gVGhlIG9yZGVyIHRvIGZldGNoIHRoZSBlbGVtZW50cyBpbi5cbiAgICogRGVmYXVsdHMgdG8gYXNjZW5kaW5nLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxDYWNoZVNvcnRlZFNldEZldGNoLlJlc3BvbnNlPn1cbiAgICoge0BsaW5rIENhY2hlU29ydGVkU2V0RmV0Y2guSGl0fSBjb250YWluaW5nIHRoZSByZXF1ZXN0ZWQgZWxlbWVudHMgd2hlbiBmb3VuZC5cbiAgICoge0BsaW5rIENhY2hlU29ydGVkU2V0RmV0Y2guTWlzc30gd2hlbiB0aGUgc29ydGVkIHNldCBkb2VzIG5vdCBleGlzdC5cbiAgICoge0BsaW5rIENhY2hlU29ydGVkU2V0RmV0Y2guRXJyb3J9IG9uIGZhaWx1cmUuXG4gICAqL1xuICAvLyBwdWJsaWMgYXN5bmMgc29ydGVkU2V0RmV0Y2hCeVJhbmsoXG4gIC8vICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gIC8vICAgc29ydGVkU2V0TmFtZTogc3RyaW5nLFxuICAvLyAgIG9wdGlvbnM/OiBTb3J0ZWRTZXRGZXRjaEJ5UmFua09wdGlvbnNcbiAgLy8gKTogUHJvbWlzZTxDYWNoZVNvcnRlZFNldEZldGNoLlJlc3BvbnNlPiB7XG4gIC8vICAgY29uc3QgY2xpZW50ID0gdGhpcy5nZXROZXh0RGF0YUNsaWVudCgpO1xuICAvLyAgIHJldHVybiBhd2FpdCBjbGllbnQuc29ydGVkU2V0RmV0Y2hCeVJhbmsoXG4gIC8vICAgICBjYWNoZU5hbWUsXG4gIC8vICAgICBzb3J0ZWRTZXROYW1lLFxuICAvLyAgICAgb3B0aW9ucz8ub3JkZXIgPz8gU29ydGVkU2V0T3JkZXIuQXNjZW5kaW5nLFxuICAvLyAgICAgb3B0aW9ucz8uc3RhcnRSYW5rID8/IDAsXG4gIC8vICAgICBvcHRpb25zPy5lbmRSYW5rXG4gIC8vICAgKTtcbiAgLy8gfVxuXG4gIC8qKlxuICAgKiBGZXRjaCB0aGUgZWxlbWVudHMgaW4gdGhlIGdpdmVuIHNvcnRlZCBzZXQgYnkgc2NvcmUuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjYWNoZU5hbWUgLSBUaGUgY2FjaGUgY29udGFpbmluZyB0aGUgc29ydGVkIHNldC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHNvcnRlZFNldE5hbWUgLSBUaGUgc29ydGVkIHNldCB0byBmZXRjaCBmcm9tLlxuICAgKiBAcGFyYW0ge1NvcnRlZFNldEZldGNoQnlTY29yZU9wdGlvbnN9IG9wdGlvbnNcbiAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLm1pblNjb3JlXSAtIFRoZSBtaW5pbXVtIHNjb3JlIChpbmNsdXNpdmUpIG9mIHRoZVxuICAgKiBlbGVtZW50cyB0byBmZXRjaC4gRGVmYXVsdHMgdG8gbmVnYXRpdmUgaW5maW5pdHkuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5tYXhTY29yZV0gLSBUaGUgbWF4aW11bSBzY29yZSAoaW5jbHVzaXZlKSBvZiB0aGVcbiAgICogZWxlbWVudHMgdG8gZmV0Y2guIERlZmF1bHRzIHRvIHBvc2l0aXZlIGluZmluaXR5LlxuICAgKiBAcGFyYW0ge1NvcnRlZFNldE9yZGVyfSBbb3B0aW9ucy5vcmRlcl0gLSBUaGUgb3JkZXIgdG8gZmV0Y2ggdGhlIGVsZW1lbnRzIGluLlxuICAgKiBEZWZhdWx0cyB0byBhc2NlbmRpbmcuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5vZmZzZXRdIC0gVGhlIG51bWJlciBvZiBlbGVtZW50cyB0byBza2lwIGJlZm9yZVxuICAgKiByZXR1cm5pbmcgdGhlIGZpcnN0IGVsZW1lbnQuIERlZmF1bHRzIHRvIDAuIE5vdGU6IHRoaXMgaXMgbm90IHRoZSByYW5rIG9mXG4gICAqIHRoZSBmaXJzdCBlbGVtZW50IHRvIHJldHVybiwgYnV0IHRoZSBudW1iZXIgb2YgZWxlbWVudHMgb2YgdGhlIHJlc3VsdCBzZXRcbiAgICogdG8gc2tpcCBiZWZvcmUgcmV0dXJuaW5nIHRoZSBmaXJzdCBlbGVtZW50LlxuICAgKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMuY291bnRdIC0gVGhlIG1heGltdW0gbnVtYmVyIG9mIGVsZW1lbnRzIHRvIHJldHVybi5cbiAgICogRGVmYXVsdHMgdG8gdW5kZWZpbmVkLCB3aGljaCByZXR1cm5zIGFsbCBlbGVtZW50cy5cbiAgICogQHJldHVybnMge1Byb21pc2U8Q2FjaGVTb3J0ZWRTZXRGZXRjaC5SZXNwb25zZT59IC1cbiAgICoge0BsaW5rIENhY2hlU29ydGVkU2V0RmV0Y2guSGl0fSBjb250YWluaW5nIHRoZSByZXF1ZXN0ZWQgZWxlbWVudHMgd2hlbiBmb3VuZC5cbiAgICoge0BsaW5rIENhY2hlU29ydGVkU2V0RmV0Y2guTWlzc30gd2hlbiB0aGUgc29ydGVkIHNldCBkb2VzIG5vdCBleGlzdC5cbiAgICoge0BsaW5rIENhY2hlU29ydGVkU2V0RmV0Y2guRXJyb3J9IG9uIGZhaWx1cmUuXG4gICAqL1xuICAvLyBwdWJsaWMgYXN5bmMgc29ydGVkU2V0RmV0Y2hCeVNjb3JlKFxuICAvLyAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAvLyAgIHNvcnRlZFNldE5hbWU6IHN0cmluZyxcbiAgLy8gICBvcHRpb25zPzogU29ydGVkU2V0RmV0Y2hCeVNjb3JlT3B0aW9uc1xuICAvLyApOiBQcm9taXNlPENhY2hlU29ydGVkU2V0RmV0Y2guUmVzcG9uc2U+IHtcbiAgLy8gICBjb25zdCBjbGllbnQgPSB0aGlzLmdldE5leHREYXRhQ2xpZW50KCk7XG4gIC8vICAgcmV0dXJuIGF3YWl0IGNsaWVudC5zb3J0ZWRTZXRGZXRjaEJ5U2NvcmUoXG4gIC8vICAgICBjYWNoZU5hbWUsXG4gIC8vICAgICBzb3J0ZWRTZXROYW1lLFxuICAvLyAgICAgb3B0aW9ucz8ub3JkZXIgPz8gU29ydGVkU2V0T3JkZXIuQXNjZW5kaW5nLFxuICAvLyAgICAgb3B0aW9ucz8ubWluU2NvcmUsXG4gIC8vICAgICBvcHRpb25zPy5tYXhTY29yZSxcbiAgLy8gICAgIG9wdGlvbnM/Lm9mZnNldCxcbiAgLy8gICAgIG9wdGlvbnM/LmNvdW50XG4gIC8vICAgKTtcbiAgLy8gfVxuXG4gIC8qKlxuICAgKiBMb29rIHVwIHRoZSByYW5rIG9mIGFuIGVsZW1lbnQgaW4gdGhlIHNvcnRlZCBzZXQsIGJ5IHRoZSB2YWx1ZSBvZiB0aGUgZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNhY2hlTmFtZSAtIFRoZSBjYWNoZSBjb250YWluaW5nIHRoZSBzb3J0ZWQgc2V0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc29ydGVkU2V0TmFtZSAtIFRoZSBzb3J0ZWQgc2V0IHRvIGZldGNoIGZyb20uXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgVWludDhBcnJheX0gdmFsdWUgLSBUaGUgdmFsdWUgb2YgdGhlIGVsZW1lbnQgd2hvc2UgcmFuayB3ZSBhcmUgcmV0cmlldmluZy5cbiAgICogQHJldHVybnMge1Byb21pc2U8Q2FjaGVTb3J0ZWRTZXRHZXRSYW5rLlJlc3BvbnNlPn1cbiAgICoge0BsaW5rIENhY2hlU29ydGVkR2V0UmFuay5IaXR9IGNvbnRhaW5pbmcgdGhlIHJhbmsgb2YgdGhlIHJlcXVlc3RlZCBlbGVtZW50cyB3aGVuIGZvdW5kLlxuICAgKiB7QGxpbmsgQ2FjaGVTb3J0ZWRHZXRSYW5rLk1pc3N9IHdoZW4gdGhlIGVsZW1lbnQgZG9lcyBub3QgZXhpc3QuXG4gICAqIHtAbGluayBDYWNoZVNvcnRlZEdldFJhbmsuRXJyb3J9IG9uIGZhaWx1cmUuXG4gICAqL1xuICAvLyBwdWJsaWMgYXN5bmMgc29ydGVkU2V0R2V0UmFuayhcbiAgLy8gICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgLy8gICBzb3J0ZWRTZXROYW1lOiBzdHJpbmcsXG4gIC8vICAgdmFsdWU6IHN0cmluZyB8IFVpbnQ4QXJyYXlcbiAgLy8gKTogUHJvbWlzZTxDYWNoZVNvcnRlZFNldEdldFJhbmsuUmVzcG9uc2U+IHtcbiAgLy8gICBjb25zdCBjbGllbnQgPSB0aGlzLmdldE5leHREYXRhQ2xpZW50KCk7XG4gIC8vICAgcmV0dXJuIGF3YWl0IGNsaWVudC5zb3J0ZWRTZXRHZXRSYW5rKGNhY2hlTmFtZSwgc29ydGVkU2V0TmFtZSwgdmFsdWUpO1xuICAvLyB9XG5cbiAgLyoqXG4gICAqIExvb2sgdXAgdGhlIHNjb3JlIG9mIGFuIGVsZW1lbnQgaW4gdGhlIHNvcnRlZCBzZXQsIGJ5IHRoZSB2YWx1ZSBvZiB0aGUgZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNhY2hlTmFtZSAtIFRoZSBjYWNoZSBjb250YWluaW5nIHRoZSBzb3J0ZWQgc2V0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc29ydGVkU2V0TmFtZSAtIFRoZSBzb3J0ZWQgc2V0IHRvIGZldGNoIGZyb20uXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgVWludDhBcnJheX0gdmFsdWUgLSBUaGUgdmFsdWUgb2YgdGhlIGVsZW1lbnQgd2hvc2Ugc2NvcmUgd2UgYXJlIHJldHJpZXZpbmcuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPENhY2hlU29ydGVkU2V0R2V0U2NvcmUuUmVzcG9uc2U+fVxuICAgKiB7QGxpbmsgQ2FjaGVTb3J0ZWRHZXRTY29yZS5IaXR9IGNvbnRhaW5pbmcgdGhlIHNjb3JlIG9mIHRoZSByZXF1ZXN0ZWQgZWxlbWVudCB3aGVuIGZvdW5kLlxuICAgKiB7QGxpbmsgQ2FjaGVTb3J0ZWRHZXRTY29yZS5NaXNzfSB3aGVuIHRoZSBlbGVtZW50IG9yIGNvbGxlY3Rpb24gZG9lcyBub3QgZXhpc3QuXG4gICAqIHtAbGluayBDYWNoZVNvcnRlZEdldFNjb3JlLkVycm9yfSBvbiBmYWlsdXJlLlxuICAgKi9cbiAgLy8gcHVibGljIGFzeW5jIHNvcnRlZFNldEdldFNjb3JlKFxuICAvLyAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAvLyAgIHNvcnRlZFNldE5hbWU6IHN0cmluZyxcbiAgLy8gICB2YWx1ZTogc3RyaW5nIHwgVWludDhBcnJheVxuICAvLyApOiBQcm9taXNlPENhY2hlU29ydGVkU2V0R2V0U2NvcmUuUmVzcG9uc2U+IHtcbiAgLy8gICBjb25zdCBjbGllbnQgPSB0aGlzLmdldE5leHREYXRhQ2xpZW50KCk7XG4gIC8vICAgcmV0dXJuIGF3YWl0IGNsaWVudC5zb3J0ZWRTZXRHZXRTY29yZShjYWNoZU5hbWUsIHNvcnRlZFNldE5hbWUsIHZhbHVlKTtcbiAgLy8gfVxuXG4gIC8qKlxuICAgKiBMb29rIHVwIHRoZSBzY29yZXMgb2YgbXVsdGlwbGUgZWxlbWVudHMgaW4gdGhlIHNvcnRlZCBzZXQsIGJ5IHRoZSB2YWx1ZSBvZiB0aGUgZWxlbWVudHMuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjYWNoZU5hbWUgLSBUaGUgY2FjaGUgY29udGFpbmluZyB0aGUgc29ydGVkIHNldC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHNvcnRlZFNldE5hbWUgLSBUaGUgc29ydGVkIHNldCB0byBmZXRjaCBmcm9tLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdIHwgVWludDhBcnJheVtdfSB2YWx1ZXMgLSBUaGUgdmFsdWVzIG9mIHRoZSBlbGVtZW50cyB3aG9zZSBzY29yZXMgd2UgYXJlIHJldHJpZXZpbmcuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPENhY2hlU29ydGVkU2V0R2V0U2NvcmVzLlJlc3BvbnNlPn1cbiAgICoge0BsaW5rIENhY2hlU29ydGVkR2V0U2NvcmVzLkhpdH0gY29udGFpbmluZyB0aGUgc2NvcmVzIG9mIHRoZSByZXF1ZXN0ZWQgZWxlbWVudHMgd2hlbiBmb3VuZC5cbiAgICoge0BsaW5rIENhY2hlU29ydGVkR2V0U2NvcmVzLk1pc3N9IHdoZW4gdGhlIGVsZW1lbnQgb3IgY29sbGVjdGlvbiBkb2VzIG5vdCBleGlzdC5cbiAgICoge0BsaW5rIENhY2hlU29ydGVkR2V0U2NvcmVzLkVycm9yfSBvbiBmYWlsdXJlLlxuICAgKi9cbiAgLy8gcHVibGljIGFzeW5jIHNvcnRlZFNldEdldFNjb3JlcyhcbiAgLy8gICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgLy8gICBzb3J0ZWRTZXROYW1lOiBzdHJpbmcsXG4gIC8vICAgdmFsdWVzOiBzdHJpbmdbXSB8IFVpbnQ4QXJyYXlbXVxuICAvLyApOiBQcm9taXNlPENhY2hlU29ydGVkU2V0R2V0U2NvcmVzLlJlc3BvbnNlPiB7XG4gIC8vICAgY29uc3QgY2xpZW50ID0gdGhpcy5nZXROZXh0RGF0YUNsaWVudCgpO1xuICAvLyAgIHJldHVybiBhd2FpdCBjbGllbnQuc29ydGVkU2V0R2V0U2NvcmVzKGNhY2hlTmFtZSwgc29ydGVkU2V0TmFtZSwgdmFsdWVzKTtcbiAgLy8gfVxuXG4gIC8qKlxuICAgKiBJbmNyZW1lbnQgdGhlIHNjb3JlIG9mIGFuIGVsZW1lbnQgaW4gdGhlIHNvcnRlZCBzZXQuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjYWNoZU5hbWUgLSBUaGUgY2FjaGUgY29udGFpbmluZyB0aGUgc29ydGVkIHNldC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHNvcnRlZFNldE5hbWUgLSBUaGUgc29ydGVkIHNldCB0byBmZXRjaCBmcm9tLlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IFVpbnQ4QXJyYXl9IHZhbHVlIC0gVGhlIHZhbHVlIG9mIHRoZSBlbGVtZW50IHdob3NlIHNjb3JlIHdlIGFyZSBpbmNyZW1lbnRpbmcuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBhbW91bnQgLSBUaGUgcXVhbnRpdHkgdG8gYWRkIHRvIHRoZSBzY29yZS4gTWF5IGJlIHBvc2l0aXZlLFxuICAgKiBuZWdhdGl2ZSwgb3IgemVyby4gRGVmYXVsdHMgdG8gMS5cbiAgICogQHBhcmFtIHtTb3J0ZWRTZXRJbmNyZW1lbnRPcHRpb25zfSBvcHRpb25zXG4gICAqIEBwYXJhbSB7Q29sbGVjdGlvblR0bH0gW29wdGlvbnMudHRsXSAtIEhvdyB0aGUgVFRMIHNob3VsZCBiZSBtYW5hZ2VkLlxuICAgKiBSZWZyZXNoZXMgdGhlIHNvcnRlZCBzZXQncyBUVEwgdXNpbmcgdGhlIGNsaWVudCdzIGRlZmF1bHQgaWYgdGhpcyBpcyBub3RcbiAgICogc3VwcGxpZWQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPENhY2hlU29ydGVkU2V0SW5jcmVtZW50U2NvcmUuUmVzcG9uc2U+fSAtXG4gICAqIHtAbGluayBDYWNoZVNvcnRlZFNldEluY3JlbWVudFNjb3JlLlN1Y2Nlc3N9IGNvbnRhaW5pbmcgdGhlIGluY3JlbWVudGVkIHNjb3JlXG4gICAqIG9uIHN1Y2Nlc3MuXG4gICAqIHtAbGluayBDYWNoZVNvcnRlZFNldEluY3JlbWVudFNjb3JlLkVycm9yfSBvbiBmYWlsdXJlLiBJbmNyZW1lbnRpbmcgYSBzY29yZVxuICAgKiB0aGF0IHdhcyBub3Qgc2V0IHVzaW5nIHRoaXMgbWV0aG9kIG9yIGlzIG5vdCB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mXG4gICAqIGFuIGludGVnZXIgcmVzdWx0cyBpbiBhIGZhaWx1cmUgd2l0aCBhIEZhaWxlZFByZWNvbmRpdGlvbkV4Y2VwdGlvbiBlcnJvci5cbiAgICovXG4gIC8vIHB1YmxpYyBhc3luYyBzb3J0ZWRTZXRJbmNyZW1lbnRTY29yZShcbiAgLy8gICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgLy8gICBzb3J0ZWRTZXROYW1lOiBzdHJpbmcsXG4gIC8vICAgdmFsdWU6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gIC8vICAgYW1vdW50ID0gMSxcbiAgLy8gICBvcHRpb25zPzogU29ydGVkU2V0SW5jcmVtZW50T3B0aW9uc1xuICAvLyApOiBQcm9taXNlPENhY2hlU29ydGVkU2V0SW5jcmVtZW50U2NvcmUuUmVzcG9uc2U+IHtcbiAgLy8gICBjb25zdCBjbGllbnQgPSB0aGlzLmdldE5leHREYXRhQ2xpZW50KCk7XG4gIC8vICAgcmV0dXJuIGF3YWl0IGNsaWVudC5zb3J0ZWRTZXRJbmNyZW1lbnRTY29yZShcbiAgLy8gICAgIGNhY2hlTmFtZSxcbiAgLy8gICAgIHNvcnRlZFNldE5hbWUsXG4gIC8vICAgICB2YWx1ZSxcbiAgLy8gICAgIGFtb3VudCxcbiAgLy8gICAgIG9wdGlvbnM/LnR0bFxuICAvLyAgICk7XG4gIC8vIH1cblxuICAvKipcbiAgICogUmVtb3ZlIGFuIGVsZW1lbnQgZnJvbSB0aGUgc29ydGVkIHNldFxuICAgKiBAcGFyYW0ge3N0cmluZ30gY2FjaGVOYW1lIC0gVGhlIGNhY2hlIGNvbnRhaW5pbmcgdGhlIHNvcnRlZCBzZXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzb3J0ZWRTZXROYW1lIC0gVGhlIHNvcnRlZCBzZXQgdG8gcmVtb3ZlIGZyb20uXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgVWludDhBcnJheX0gdmFsdWUgLSBUaGUgdmFsdWUgb2YgdGhlIGVsZW1lbnQgdG8gcmVtb3ZlIGZyb20gdGhlIHNldC5cbiAgICogQHJldHVybnMge1Byb21pc2U8Q2FjaGVTb3J0ZWRTZXRSZW1vdmVFbGVtZW50LlJlc3BvbnNlPn1cbiAgICoge0BsaW5rIENhY2hlU29ydGVkU2V0UmVtb3ZlRWxlbWVudC5TdWNjZXNzfSBpZiB0aGUgZWxlbWVudCB3YXMgc3VjY2Vzc2Z1bGx5IHJlbW92ZWRcbiAgICoge0BsaW5rIENhY2hlU29ydGVkU2V0SW5jcmVtZW50U2NvcmUuRXJyb3J9IG9uIGZhaWx1cmVcbiAgICovXG4gIC8vIHB1YmxpYyBhc3luYyBzb3J0ZWRTZXRSZW1vdmVFbGVtZW50KFxuICAvLyAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAvLyAgIHNvcnRlZFNldE5hbWU6IHN0cmluZyxcbiAgLy8gICB2YWx1ZTogc3RyaW5nIHwgVWludDhBcnJheVxuICAvLyApOiBQcm9taXNlPENhY2hlU29ydGVkU2V0UmVtb3ZlRWxlbWVudC5SZXNwb25zZT4ge1xuICAvLyAgIGNvbnN0IGNsaWVudCA9IHRoaXMuZ2V0TmV4dERhdGFDbGllbnQoKTtcbiAgLy8gICByZXR1cm4gYXdhaXQgY2xpZW50LnNvcnRlZFNldFJlbW92ZUVsZW1lbnQoY2FjaGVOYW1lLCBzb3J0ZWRTZXROYW1lLCB2YWx1ZSk7XG4gIC8vIH1cblxuICAvKipcbiAgICogUmVtb3ZlIG11bHRpcGxlIGVsZW1lbnRzIGZyb20gdGhlIHNvcnRlZCBzZXRcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNhY2hlTmFtZSAtIFRoZSBjYWNoZSBjb250YWluaW5nIHRoZSBzb3J0ZWQgc2V0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc29ydGVkU2V0TmFtZSAtIFRoZSBzb3J0ZWQgc2V0IHRvIHJlbW92ZSBmcm9tLlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IFVpbnQ4QXJyYXl9IHZhbHVlcyAtIFRoZSB2YWx1ZXMgb2YgdGhlIGVsZW1lbnRzIHRvIHJlbW92ZSBmcm9tIHRoZSBzZXQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPENhY2hlU29ydGVkU2V0UmVtb3ZlRWxlbWVudC5SZXNwb25zZT59XG4gICAqIHtAbGluayBDYWNoZVNvcnRlZFNldFJlbW92ZUVsZW1lbnQuU3VjY2Vzc30gaWYgdGhlIGVsZW1lbnRzIHdlcmUgc3VjY2Vzc2Z1bGx5IHJlbW92ZWRcbiAgICoge0BsaW5rIENhY2hlU29ydGVkU2V0SW5jcmVtZW50U2NvcmUuRXJyb3J9IG9uIGZhaWx1cmVcbiAgICovXG4gIC8vIHB1YmxpYyBhc3luYyBzb3J0ZWRTZXRSZW1vdmVFbGVtZW50cyhcbiAgLy8gICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgLy8gICBzb3J0ZWRTZXROYW1lOiBzdHJpbmcsXG4gIC8vICAgdmFsdWVzOiBzdHJpbmdbXSB8IFVpbnQ4QXJyYXlbXVxuICAvLyApOiBQcm9taXNlPENhY2hlU29ydGVkU2V0UmVtb3ZlRWxlbWVudHMuUmVzcG9uc2U+IHtcbiAgLy8gICBjb25zdCBjbGllbnQgPSB0aGlzLmdldE5leHREYXRhQ2xpZW50KCk7XG4gIC8vICAgcmV0dXJuIGF3YWl0IGNsaWVudC5zb3J0ZWRTZXRSZW1vdmVFbGVtZW50cyhcbiAgLy8gICAgIGNhY2hlTmFtZSxcbiAgLy8gICAgIHNvcnRlZFNldE5hbWUsXG4gIC8vICAgICB2YWx1ZXNcbiAgLy8gICApO1xuICAvLyB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBNb21lbnRvIHNpZ25pbmcga2V5LlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gdHRsTWludXRlcyAtIFRoZSB0aW1lIHRvIGxpdmUgaW4gbWludXRlcyB1bnRpbCB0aGUgTW9tZW50b1xuICAgKiBzaWduaW5nIGtleSBleHBpcmVzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxDcmVhdGVTaWduaW5nS2V5LlJlc3BvbnNlPn0gLVxuICAgKiB7QGxpbmsgQ3JlYXRlU2lnbmluZ0tleS5TdWNjZXNzfSBjb250YWluaW5nIHRoZSBrZXksIGtleSBJRCwgZW5kcG9pbnQsIGFuZFxuICAgKiBleHBpcmF0aW9uIGRhdGUgb24gc3VjY2Vzcy5cbiAgICoge0BsaW5rIENyZWF0ZVNpZ25pbmdLZXkuRXJyb3J9IG9uIGZhaWx1cmUuXG4gICAqL1xuICAvLyBwdWJsaWMgYXN5bmMgY3JlYXRlU2lnbmluZ0tleShcbiAgLy8gICB0dGxNaW51dGVzOiBudW1iZXJcbiAgLy8gKTogUHJvbWlzZTxDcmVhdGVTaWduaW5nS2V5LlJlc3BvbnNlPiB7XG4gIC8vICAgcmV0dXJuIGF3YWl0IHRoaXMuY29udHJvbENsaWVudC5jcmVhdGVTaWduaW5nS2V5KFxuICAvLyAgICAgdHRsTWludXRlcyxcbiAgLy8gICAgIHRoaXMuZGF0YUNsaWVudC5nZXRFbmRwb2ludCgpXG4gIC8vICAgKTtcbiAgLy8gfVxuXG4gIC8qKlxuICAgKiBSZXZva2VzIGEgTW9tZW50byBzaWduaW5nIGtleS5cbiAgICpcbiAgICogQHJlbWFya3NcbiAgICogQWxsIHRva2VucyBzaWduZWQgYnkgdGhpcyBrZXkgd2lsbCBiZSBpbnZhbGlkLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5SWQgLSBUaGUgSUQgb2YgdGhlIGtleSB0byByZXZva2UuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFJldm9rZVNpZ25pbmdLZXkuUmVzcG9uc2U+fSAtXG4gICAqIHtAbGluayBSZXZva2VTaWduaW5nS2V5LlN1Y2Nlc3N9IG9uIHN1Y2Nlc3MuXG4gICAqIHtAbGluayBSZXZva2VTaWduaW5nS2V5LkVycm9yfSBvbiBmYWlsdXJlLlxuICAgKi9cbiAgLy8gcHVibGljIGFzeW5jIHJldm9rZVNpZ25pbmdLZXkoXG4gIC8vICAga2V5SWQ6IHN0cmluZ1xuICAvLyApOiBQcm9taXNlPFJldm9rZVNpZ25pbmdLZXkuUmVzcG9uc2U+IHtcbiAgLy8gICByZXR1cm4gYXdhaXQgdGhpcy5jb250cm9sQ2xpZW50LnJldm9rZVNpZ25pbmdLZXkoa2V5SWQpO1xuICAvLyB9XG5cbiAgcHJvdGVjdGVkIGdldE5leHREYXRhQ2xpZW50KCk6IElEYXRhQ2xpZW50IHtcbiAgICBjb25zdCBjbGllbnQgPSB0aGlzLmRhdGFDbGllbnRzW3RoaXMubmV4dERhdGFDbGllbnRJbmRleF07XG4gICAgdGhpcy5uZXh0RGF0YUNsaWVudEluZGV4ID1cbiAgICAgICh0aGlzLm5leHREYXRhQ2xpZW50SW5kZXggKyAxKSAlIHRoaXMuZGF0YUNsaWVudHMubGVuZ3RoO1xuICAgIHJldHVybiBjbGllbnQ7XG4gIH1cbn1cbiJdfQ==