@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.
- package/dist/src/auth/credential-provider.d.ts +83 -0
- package/dist/src/auth/credential-provider.js +82 -0
- package/dist/src/auth/index.d.ts +1 -0
- package/dist/src/auth/index.js +18 -0
- package/dist/src/config/logging/default-momento-logger.d.ts +24 -0
- package/dist/src/config/logging/default-momento-logger.js +69 -0
- package/dist/src/config/logging/index.d.ts +3 -0
- package/dist/src/config/logging/index.js +20 -0
- package/dist/src/config/logging/momento-logger.d.ts +10 -0
- package/dist/src/config/logging/momento-logger.js +3 -0
- package/dist/src/config/logging/noop-momento-logger.d.ts +11 -0
- package/dist/src/config/logging/noop-momento-logger.js +34 -0
- package/dist/src/config/transport/grpc-configuration.d.ts +41 -0
- package/dist/src/config/transport/grpc-configuration.js +3 -0
- package/dist/src/config/transport/index.d.ts +2 -0
- package/dist/src/config/transport/index.js +19 -0
- package/dist/src/config/transport/transport-strategy.d.ts +77 -0
- package/dist/src/config/transport/transport-strategy.js +60 -0
- package/dist/src/errors/error-utils.d.ts +2 -0
- package/dist/src/errors/error-utils.js +12 -0
- package/dist/src/errors/errors.d.ts +140 -0
- package/dist/src/errors/errors.js +229 -0
- package/dist/src/errors/index.d.ts +2 -0
- package/dist/src/errors/index.js +19 -0
- package/dist/src/index.d.ts +57 -0
- package/dist/src/index.js +137 -0
- package/dist/src/internal/clients/auth/AbstractAuthClient.d.ts +10 -0
- package/dist/src/internal/clients/auth/AbstractAuthClient.js +13 -0
- package/dist/src/internal/clients/auth/IAuthClient.d.ts +4 -0
- package/dist/src/internal/clients/auth/IAuthClient.js +3 -0
- package/dist/src/internal/clients/auth/index.d.ts +2 -0
- package/dist/src/internal/clients/auth/index.js +19 -0
- package/dist/src/internal/clients/cache/AbstractCacheClient.d.ts +638 -0
- package/dist/src/internal/clients/cache/AbstractCacheClient.js +870 -0
- package/dist/src/internal/clients/cache/ICacheClient.d.ts +45 -0
- package/dist/src/internal/clients/cache/ICacheClient.js +3 -0
- package/dist/src/internal/clients/cache/IControlClient.d.ts +7 -0
- package/dist/src/internal/clients/cache/IControlClient.js +3 -0
- package/dist/src/internal/clients/cache/IDataClient.d.ts +29 -0
- package/dist/src/internal/clients/cache/IDataClient.js +3 -0
- package/dist/src/internal/clients/cache/index.d.ts +4 -0
- package/dist/src/internal/clients/cache/index.js +21 -0
- package/dist/src/internal/clients/index.d.ts +3 -0
- package/dist/src/internal/clients/index.js +20 -0
- package/dist/src/internal/clients/ping/AbstractPingClient.d.ts +25 -0
- package/dist/src/internal/clients/ping/AbstractPingClient.js +29 -0
- package/dist/src/internal/clients/ping/IPingClient.d.ts +3 -0
- package/dist/src/internal/clients/ping/IPingClient.js +3 -0
- package/dist/src/internal/clients/ping/index.d.ts +2 -0
- package/dist/src/internal/clients/ping/index.js +19 -0
- package/dist/src/internal/subscription-state.d.ts +15 -0
- package/dist/src/internal/subscription-state.js +38 -0
- package/dist/src/internal/utils/auth.d.ts +25 -0
- package/dist/src/internal/utils/auth.js +50 -0
- package/dist/src/internal/utils/collections.d.ts +1 -0
- package/dist/src/internal/utils/collections.js +8 -0
- package/dist/src/internal/utils/display.d.ts +2 -0
- package/dist/src/internal/utils/display.js +30 -0
- package/dist/src/internal/utils/index.d.ts +7 -0
- package/dist/src/internal/utils/index.js +24 -0
- package/dist/src/internal/utils/object.d.ts +1 -0
- package/dist/src/internal/utils/object.js +8 -0
- package/dist/src/internal/utils/sleep.d.ts +1 -0
- package/dist/src/internal/utils/sleep.js +6 -0
- package/dist/src/internal/utils/string.d.ts +2 -0
- package/dist/src/internal/utils/string.js +17 -0
- package/dist/src/internal/utils/validators.d.ts +13 -0
- package/dist/src/internal/utils/validators.js +105 -0
- package/dist/src/internal/vendor/printf/README.md +31 -0
- package/dist/src/internal/vendor/printf/printf.d.ts +9 -0
- package/dist/src/internal/vendor/printf/printf.js +478 -0
- package/dist/src/messages/cache-info.d.ts +5 -0
- package/dist/src/messages/cache-info.js +13 -0
- package/dist/src/messages/responses/cache-delete.d.ts +61 -0
- package/dist/src/messages/responses/cache-delete.js +54 -0
- package/dist/src/messages/responses/cache-dictionary-fetch.d.ts +120 -0
- package/dist/src/messages/responses/cache-dictionary-fetch.js +162 -0
- package/dist/src/messages/responses/cache-dictionary-get-field.d.ts +123 -0
- package/dist/src/messages/responses/cache-dictionary-get-field.js +143 -0
- package/dist/src/messages/responses/cache-dictionary-get-fields.d.ts +122 -0
- package/dist/src/messages/responses/cache-dictionary-get-fields.js +173 -0
- package/dist/src/messages/responses/cache-dictionary-increment.d.ts +69 -0
- package/dist/src/messages/responses/cache-dictionary-increment.js +68 -0
- package/dist/src/messages/responses/cache-dictionary-remove-field.d.ts +61 -0
- package/dist/src/messages/responses/cache-dictionary-remove-field.js +54 -0
- package/dist/src/messages/responses/cache-dictionary-remove-fields.d.ts +61 -0
- package/dist/src/messages/responses/cache-dictionary-remove-fields.js +54 -0
- package/dist/src/messages/responses/cache-dictionary-set-field.d.ts +61 -0
- package/dist/src/messages/responses/cache-dictionary-set-field.js +54 -0
- package/dist/src/messages/responses/cache-dictionary-set-fields.d.ts +61 -0
- package/dist/src/messages/responses/cache-dictionary-set-fields.js +54 -0
- package/dist/src/messages/responses/cache-flush.d.ts +61 -0
- package/dist/src/messages/responses/cache-flush.js +54 -0
- package/dist/src/messages/responses/cache-get.d.ts +86 -0
- package/dist/src/messages/responses/cache-get.js +88 -0
- package/dist/src/messages/responses/cache-increment.d.ts +69 -0
- package/dist/src/messages/responses/cache-increment.js +68 -0
- package/dist/src/messages/responses/cache-list-concatenate-back.d.ts +69 -0
- package/dist/src/messages/responses/cache-list-concatenate-back.js +68 -0
- package/dist/src/messages/responses/cache-list-concatenate-front.d.ts +69 -0
- package/dist/src/messages/responses/cache-list-concatenate-front.js +68 -0
- package/dist/src/messages/responses/cache-list-fetch.d.ts +92 -0
- package/dist/src/messages/responses/cache-list-fetch.js +96 -0
- package/dist/src/messages/responses/cache-list-length.d.ts +84 -0
- package/dist/src/messages/responses/cache-list-length.js +78 -0
- package/dist/src/messages/responses/cache-list-pop-back.d.ts +86 -0
- package/dist/src/messages/responses/cache-list-pop-back.js +88 -0
- package/dist/src/messages/responses/cache-list-pop-front.d.ts +86 -0
- package/dist/src/messages/responses/cache-list-pop-front.js +88 -0
- package/dist/src/messages/responses/cache-list-push-back.d.ts +69 -0
- package/dist/src/messages/responses/cache-list-push-back.js +68 -0
- package/dist/src/messages/responses/cache-list-push-front.d.ts +69 -0
- package/dist/src/messages/responses/cache-list-push-front.js +68 -0
- package/dist/src/messages/responses/cache-list-remove-value.d.ts +61 -0
- package/dist/src/messages/responses/cache-list-remove-value.js +54 -0
- package/dist/src/messages/responses/cache-list-retain.d.ts +61 -0
- package/dist/src/messages/responses/cache-list-retain.js +54 -0
- package/dist/src/messages/responses/cache-set-add-element.d.ts +71 -0
- package/dist/src/messages/responses/cache-set-add-element.js +54 -0
- package/dist/src/messages/responses/cache-set-add-elements.d.ts +65 -0
- package/dist/src/messages/responses/cache-set-add-elements.js +61 -0
- package/dist/src/messages/responses/cache-set-fetch.d.ts +111 -0
- package/dist/src/messages/responses/cache-set-fetch.js +121 -0
- package/dist/src/messages/responses/cache-set-if-not-exists.d.ts +74 -0
- package/dist/src/messages/responses/cache-set-if-not-exists.js +63 -0
- package/dist/src/messages/responses/cache-set-remove-element.d.ts +61 -0
- package/dist/src/messages/responses/cache-set-remove-element.js +54 -0
- package/dist/src/messages/responses/cache-set-remove-elements.d.ts +65 -0
- package/dist/src/messages/responses/cache-set-remove-elements.js +61 -0
- package/dist/src/messages/responses/cache-set.d.ts +61 -0
- package/dist/src/messages/responses/cache-set.js +54 -0
- package/dist/src/messages/responses/cache-sorted-set-fetch.d.ts +107 -0
- package/dist/src/messages/responses/cache-sorted-set-fetch.js +124 -0
- package/dist/src/messages/responses/cache-sorted-set-get-rank.d.ts +81 -0
- package/dist/src/messages/responses/cache-sorted-set-get-rank.js +78 -0
- package/dist/src/messages/responses/cache-sorted-set-get-score.d.ts +118 -0
- package/dist/src/messages/responses/cache-sorted-set-get-score.js +131 -0
- package/dist/src/messages/responses/cache-sorted-set-get-scores.d.ts +109 -0
- package/dist/src/messages/responses/cache-sorted-set-get-scores.js +148 -0
- package/dist/src/messages/responses/cache-sorted-set-increment-score.d.ts +69 -0
- package/dist/src/messages/responses/cache-sorted-set-increment-score.js +68 -0
- package/dist/src/messages/responses/cache-sorted-set-put-element.d.ts +61 -0
- package/dist/src/messages/responses/cache-sorted-set-put-element.js +54 -0
- package/dist/src/messages/responses/cache-sorted-set-put-elements.d.ts +61 -0
- package/dist/src/messages/responses/cache-sorted-set-put-elements.js +54 -0
- package/dist/src/messages/responses/cache-sorted-set-remove-element.d.ts +61 -0
- package/dist/src/messages/responses/cache-sorted-set-remove-element.js +54 -0
- package/dist/src/messages/responses/cache-sorted-set-remove-elements.d.ts +61 -0
- package/dist/src/messages/responses/cache-sorted-set-remove-elements.js +54 -0
- package/dist/src/messages/responses/create-cache.d.ts +77 -0
- package/dist/src/messages/responses/create-cache.js +61 -0
- package/dist/src/messages/responses/create-signing-key.d.ts +71 -0
- package/dist/src/messages/responses/create-signing-key.js +76 -0
- package/dist/src/messages/responses/delete-cache.d.ts +61 -0
- package/dist/src/messages/responses/delete-cache.js +54 -0
- package/dist/src/messages/responses/generate-api-token.d.ts +50 -0
- package/dist/src/messages/responses/generate-api-token.js +52 -0
- package/dist/src/messages/responses/grpc-response-types.d.ts +41 -0
- package/dist/src/messages/responses/grpc-response-types.js +53 -0
- package/dist/src/messages/responses/list-caches.d.ts +70 -0
- package/dist/src/messages/responses/list-caches.js +69 -0
- package/dist/src/messages/responses/list-signing-keys.d.ts +68 -0
- package/dist/src/messages/responses/list-signing-keys.js +68 -0
- package/dist/src/messages/responses/response-base.d.ts +43 -0
- package/dist/src/messages/responses/response-base.js +50 -0
- package/dist/src/messages/responses/revoke-signing-key.d.ts +61 -0
- package/dist/src/messages/responses/revoke-signing-key.js +54 -0
- package/dist/src/messages/responses/topic-item.d.ts +27 -0
- package/dist/src/messages/responses/topic-item.js +43 -0
- package/dist/src/messages/responses/topic-publish.d.ts +61 -0
- package/dist/src/messages/responses/topic-publish.js +54 -0
- package/dist/src/messages/responses/topic-subscribe.d.ts +69 -0
- package/dist/src/messages/responses/topic-subscribe.js +72 -0
- package/dist/src/messages/signing-key.d.ts +9 -0
- package/dist/src/messages/signing-key.js +21 -0
- package/dist/src/utils/cache-call-options.d.ts +99 -0
- package/dist/src/utils/cache-call-options.js +9 -0
- package/dist/src/utils/collection-ttl.d.ts +78 -0
- package/dist/src/utils/collection-ttl.js +102 -0
- package/dist/src/utils/index.d.ts +3 -0
- package/dist/src/utils/index.js +20 -0
- package/dist/src/utils/topic-call-options.d.ts +19 -0
- package/dist/src/utils/topic-call-options.js +3 -0
- 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==
|