@myrmidon/paged-data-browsers 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,419 @@
1
+ import { BehaviorSubject, forkJoin, of, switchMap, tap, } from 'rxjs';
2
+ import { LRUCache } from './lru-cache';
3
+ import { DEFAULT_PAGED_LIST_STORE_OPTIONS } from './paged-list.store';
4
+ /**
5
+ * A store for the node browser component. This store is used to keep a
6
+ * list of nodes, and to load them from the API. It also keeps the root
7
+ * node. Every tree node in the list is extended with page number,
8
+ * page count and total items, plus expansion-related metadata.
9
+ * The store keeps a flat list of these tree nodes, allowing users to
10
+ * expand and collapse them.
11
+ * F is the type of the filter object, E is the type of the paged tree nodes.
12
+ */
13
+ export class PagedTreeStore {
14
+ /**
15
+ * The size of nodes pages in this store. If you change it, the store
16
+ * is reset. The default value is 20.
17
+ */
18
+ get pageSize() {
19
+ return this._pageSize;
20
+ }
21
+ set pageSize(value) {
22
+ if (this._pageSize === value) {
23
+ return;
24
+ }
25
+ this._pageSize = value;
26
+ this.reset(this._radix?.label || this._radixLabel);
27
+ }
28
+ /**
29
+ * Create an instance of the store.
30
+ * @param _service The service used to load nodes.
31
+ * @param options The options to configure this store.
32
+ */
33
+ constructor(_service, options = DEFAULT_PAGED_LIST_STORE_OPTIONS) {
34
+ this._service = _service;
35
+ this._pageSize = options.pageSize;
36
+ this._cache = new LRUCache(options.cacheSize);
37
+ this._customCacheKeyBuilder = options.buildCacheKey;
38
+ this._radixLabel = '(root)';
39
+ this._roots = [];
40
+ this._nodes$ = new BehaviorSubject([]);
41
+ this.nodes$ = this._nodes$.asObservable();
42
+ this._tags$ = new BehaviorSubject([]);
43
+ this.tags$ = this._tags$.asObservable();
44
+ this._filter$ = new BehaviorSubject({});
45
+ this.filter$ = this._filter$.asObservable();
46
+ this._dirty = true;
47
+ this.updateTags();
48
+ }
49
+ updateTags() {
50
+ this._service.getTags().subscribe((tags) => {
51
+ this._tags$.next(tags);
52
+ });
53
+ }
54
+ /**
55
+ * Gets the global filter eventually overridden with values
56
+ * from the specified node's filter.
57
+ * @param node The optional node.
58
+ * @returns The filter.
59
+ */
60
+ getFilter(node) {
61
+ return node?.filter
62
+ ? {
63
+ ...this._filter$.value,
64
+ ...node.filter,
65
+ }
66
+ : this._filter$.value;
67
+ }
68
+ /**
69
+ * Gets all the nodes in the store.
70
+ * @returns The nodes.
71
+ */
72
+ getNodes() {
73
+ return this._nodes$.value;
74
+ }
75
+ /**
76
+ * Gets the list of nodes tags.
77
+ * @returns The tags.
78
+ */
79
+ getTags() {
80
+ return this._tags$.value;
81
+ }
82
+ /**
83
+ * Build the cache key for the given page number and filter.
84
+ * The default implementation just returns a stringified object
85
+ * containing the page number and the filter. You may override
86
+ * this method to provide a custom cache key.
87
+ * @param pageNumber The page number.
88
+ * @param filter The filter.
89
+ * @returns A string to be used as cache key.
90
+ */
91
+ buildCacheKey(pageNumber, filter) {
92
+ if (this._customCacheKeyBuilder) {
93
+ return this._customCacheKeyBuilder(pageNumber, filter);
94
+ }
95
+ return JSON.stringify({ pageNumber, ...filter });
96
+ }
97
+ getPageFromCacheOrServer(filter, pageNumber) {
98
+ const key = this.buildCacheKey(pageNumber, filter);
99
+ const pageInCache = this._cache.get(key);
100
+ if (pageInCache) {
101
+ return of(pageInCache);
102
+ }
103
+ else {
104
+ return this._service.getNodes(filter, pageNumber, this._pageSize).pipe(tap((page) => {
105
+ this._cache.put(key, page, 0);
106
+ }));
107
+ }
108
+ }
109
+ createPageNodes(page) {
110
+ return page.items.map((n) => {
111
+ return {
112
+ ...n,
113
+ hasChildren: n.hasChildren,
114
+ paging: {
115
+ pageNumber: page.pageNumber,
116
+ pageCount: page.pageCount,
117
+ total: page.total,
118
+ },
119
+ };
120
+ });
121
+ }
122
+ /**
123
+ * Applies the filter for this store. Whenever the filter is set,
124
+ * the store is reset.
125
+ * @param filter The filter.
126
+ * @param radixLabel The label of the radix node, if this needs to be set.
127
+ * @returns true if tree was changed, false otherwise.
128
+ */
129
+ applyFilter(filter, radixLabel) {
130
+ if (this._filter$.value === filter) {
131
+ return Promise.resolve(false);
132
+ }
133
+ this._filter$.next(filter);
134
+ this._dirty = true;
135
+ return this.reset(this._radix?.label || radixLabel || this._radixLabel);
136
+ }
137
+ /**
138
+ * Reset the store, loading the root nodes and their children.
139
+ * @param label The label of the radix node.
140
+ * @returns true if tree was changed, false otherwise.
141
+ */
142
+ reset(label) {
143
+ if (!this._dirty) {
144
+ return Promise.resolve(false);
145
+ }
146
+ this._cache.clear();
147
+ const filter = this._filter$.value;
148
+ this._radix = {
149
+ id: 0,
150
+ y: 0,
151
+ x: 1,
152
+ label: label,
153
+ paging: {
154
+ pageNumber: 0,
155
+ pageCount: 0,
156
+ total: 0,
157
+ },
158
+ };
159
+ return new Promise((resolve, reject) => {
160
+ this._service
161
+ .getRootNodes(filter.tags)
162
+ .pipe(switchMap((nodes) => {
163
+ // no roots, clear and return empty set
164
+ if (!nodes || nodes.length === 0) {
165
+ this._roots = [];
166
+ return of([]);
167
+ }
168
+ else {
169
+ // got roots, set them and get their children
170
+ this._roots = nodes.map((node) => ({
171
+ ...node,
172
+ paging: {
173
+ pageNumber: 1,
174
+ pageCount: 1,
175
+ total: 1,
176
+ },
177
+ }));
178
+ // fetch children for each root node
179
+ return forkJoin(this._roots.map((root) => this.getPageFromCacheOrServer({ ...filter, parentId: root.id }, 1)));
180
+ }
181
+ }))
182
+ .subscribe({
183
+ next: (pages) => {
184
+ this._dirty = false;
185
+ if (pages.some((page) => page.total)) {
186
+ // radix
187
+ this._radix.hasChildren = true;
188
+ this._radix.expanded = true;
189
+ this._radix.paging = {
190
+ pageNumber: 1,
191
+ pageCount: 1,
192
+ total: pages.length,
193
+ };
194
+ // roots
195
+ this._roots.forEach((root, i) => {
196
+ root.hasChildren = !!pages[i].total;
197
+ root.expanded = !!pages[i].total;
198
+ });
199
+ const nodes = this._roots.flatMap((root, i) => [
200
+ root,
201
+ ...this.createPageNodes(pages[i]),
202
+ ]);
203
+ this._nodes$.next([this._radix, ...nodes]);
204
+ resolve(true);
205
+ }
206
+ else {
207
+ this._roots.forEach((root) => {
208
+ root.hasChildren = false;
209
+ root.expanded = false;
210
+ });
211
+ this._nodes$.next([this._radix, ...this._roots]);
212
+ resolve(true);
213
+ }
214
+ },
215
+ error: (error) => {
216
+ reject(error);
217
+ },
218
+ });
219
+ });
220
+ }
221
+ /**
222
+ * Set the node filter for the node with the specified ID.
223
+ * @param id The node ID.
224
+ * @param filter The filter to set.
225
+ * @returns Promise with true if filter was set, false otherwise.
226
+ */
227
+ setNodeFilter(id, filter) {
228
+ if (!id) {
229
+ return Promise.resolve(false);
230
+ }
231
+ return new Promise((resolve, reject) => {
232
+ const node = this._nodes$.value.find((n) => n.id === id);
233
+ if (!node) {
234
+ reject(`Node ID ${id} not found in store`);
235
+ }
236
+ node.filter = filter || undefined;
237
+ return this.changePage(id, 1);
238
+ });
239
+ }
240
+ /**
241
+ * Expand the node with the specified ID. If the node is not expandable,
242
+ * or it is already expanded, this method does nothing.
243
+ * @param node The ID of the node to expand.
244
+ * @returns Promise with true if the node was expanded, false otherwise.
245
+ */
246
+ expand(id) {
247
+ if (!id) {
248
+ return Promise.resolve(false);
249
+ }
250
+ return new Promise((resolve, reject) => {
251
+ const node = this._nodes$.value.find((n) => n.id === id);
252
+ if (!node || node.hasChildren === false || node.expanded) {
253
+ resolve(false);
254
+ }
255
+ this.getPageFromCacheOrServer({ ...this.getFilter(node), parentId: id }, 1).subscribe((page) => {
256
+ // no children, set hasChildren to false
257
+ if (!page.total) {
258
+ node.hasChildren = false;
259
+ resolve(false);
260
+ }
261
+ else {
262
+ this._dirty = true;
263
+ // insert page nodes after the current node
264
+ const nodes = this._nodes$.value;
265
+ const index = nodes.indexOf(node);
266
+ if (index === -1) {
267
+ reject(`Node ID ${id} not found in store`);
268
+ }
269
+ else {
270
+ const pageNodes = this.createPageNodes(page);
271
+ nodes.splice(index + 1, 0, ...pageNodes);
272
+ this._nodes$.next(nodes);
273
+ node.hasChildren = true;
274
+ node.expanded = true;
275
+ resolve(true);
276
+ }
277
+ }
278
+ });
279
+ });
280
+ }
281
+ expandAll(id) {
282
+ if (!id) {
283
+ return Promise.resolve(false);
284
+ }
285
+ // get the parent node to start from
286
+ const nodes = this._nodes$.value;
287
+ const nodeIndex = nodes.findIndex((n) => n.id === id);
288
+ if (nodeIndex === -1) {
289
+ return Promise.resolve(false);
290
+ }
291
+ // collect all the descendant nodes IDs
292
+ let i = nodeIndex + 1;
293
+ while (i < nodes.length && nodes[i].y > nodes[nodeIndex].y) {
294
+ i++;
295
+ }
296
+ const nodesToExpand = nodes.slice(nodeIndex, i).map((n) => n.id);
297
+ // expand all the descendant nodes
298
+ return new Promise((resolve, reject) => {
299
+ nodesToExpand.forEach((id) => {
300
+ this.expand(id);
301
+ this.expandAll(id);
302
+ });
303
+ resolve(true);
304
+ });
305
+ }
306
+ getChildren(id) {
307
+ const node = this._nodes$.value.find((n) => n.id === id);
308
+ if (!node || node.hasChildren === false) {
309
+ return [];
310
+ }
311
+ const nodes = this._nodes$.value;
312
+ const index = nodes.indexOf(node);
313
+ if (index === -1) {
314
+ return [];
315
+ }
316
+ const children = [];
317
+ let i = index + 1;
318
+ while (i < nodes.length && nodes[i].y > node.y) {
319
+ children.push(nodes[i]);
320
+ i++;
321
+ }
322
+ return children;
323
+ }
324
+ removeDescendants(nodes, nodeIndex) {
325
+ let i = nodeIndex + 1;
326
+ while (i < nodes.length && nodes[i].y > nodes[nodeIndex].y) {
327
+ i++;
328
+ }
329
+ nodes.splice(nodeIndex + 1, i - nodeIndex - 1);
330
+ }
331
+ /**
332
+ * Collapse the node with the specified ID. If the node is not expandable,
333
+ * or it is already collapsed, this method does nothing.
334
+ * @param node The node to collapse.
335
+ * @returns Promise with true if the node was collapsed, false otherwise.
336
+ */
337
+ collapse(id) {
338
+ if (!id) {
339
+ return Promise.resolve(false);
340
+ }
341
+ return new Promise((resolve, reject) => {
342
+ const node = this._nodes$.value.find((n) => n.id === id);
343
+ if (!node || node.hasChildren === false || !node.expanded) {
344
+ resolve(false);
345
+ }
346
+ // remove all the descendant nodes after the current node
347
+ const nodes = this._nodes$.value;
348
+ const nodeIndex = nodes.indexOf(node);
349
+ if (nodeIndex === -1) {
350
+ reject(`Node ID ${id} not found in store`);
351
+ }
352
+ else {
353
+ this._dirty = true;
354
+ this.removeDescendants(nodes, nodeIndex);
355
+ this._nodes$.next(nodes);
356
+ node.expanded = false;
357
+ resolve(true);
358
+ }
359
+ });
360
+ }
361
+ /**
362
+ * Change the page including the node with the specified ID.
363
+ * @param node The parent node whose children are inside the page you want to change.
364
+ * @param pageNumber The new page number.
365
+ * @returns Promise with true if the page was changed, false otherwise.
366
+ */
367
+ changePage(parentId, pageNumber) {
368
+ return new Promise((resolve, reject) => {
369
+ const parentNode = this._nodes$.value.find((n) => n.id === parentId);
370
+ if (!parentNode) {
371
+ resolve(false);
372
+ }
373
+ this.getPageFromCacheOrServer({ ...this.getFilter(parentNode), parentId }, pageNumber).subscribe((page) => {
374
+ // if page is empty do nothing
375
+ if (!page.total) {
376
+ resolve(false);
377
+ }
378
+ else {
379
+ this._dirty = true;
380
+ // remove all the nodes in the same page of node
381
+ // with all their descendants
382
+ const nodes = this._nodes$.value;
383
+ const nodeIndex = nodes.indexOf(parentNode) + 1;
384
+ const pageNodes = this.createPageNodes(page);
385
+ // find the first node of the node's page
386
+ let start = nodeIndex;
387
+ const oldPageNr = nodes[start].paging.pageNumber;
388
+ while (start > 0 &&
389
+ nodes[start - 1].parentId === parentId &&
390
+ nodes[start - 1].paging.pageNumber === oldPageNr) {
391
+ start--;
392
+ }
393
+ // find the last node of the node's page,
394
+ // including all their descendants
395
+ let end = nodeIndex + 1;
396
+ while (end < nodes.length &&
397
+ nodes[end].parentId === parentId &&
398
+ nodes[end].paging.pageNumber === oldPageNr) {
399
+ end++;
400
+ }
401
+ // replace all these nodes with the new ones
402
+ nodes.splice(start, end - start);
403
+ nodes.splice(start, 0, ...pageNodes);
404
+ // update the parent node paging info
405
+ parentNode.paging.pageNumber = page.pageNumber;
406
+ this._nodes$.next(nodes);
407
+ resolve(true);
408
+ }
409
+ });
410
+ });
411
+ }
412
+ /**
413
+ * Collapse all the nodes in the store.
414
+ */
415
+ collapseAll() {
416
+ this._nodes$.next([this._radix, ...this._roots]);
417
+ }
418
+ }
419
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFnZWQtdHJlZS5zdG9yZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL215cm1pZG9uL3BhZ2VkLWRhdGEtYnJvd3NlcnMvc3JjL2xpYi9zZXJ2aWNlcy9wYWdlZC10cmVlLnN0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxlQUFlLEVBRWYsUUFBUSxFQUNSLEVBQUUsRUFDRixTQUFTLEVBQ1QsR0FBRyxHQUNKLE1BQU0sTUFBTSxDQUFDO0FBSWQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN2QyxPQUFPLEVBQUUsZ0NBQWdDLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQWdHdEU7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLE9BQU8sY0FBYztJQW9DekI7OztPQUdHO0lBQ0gsSUFBVyxRQUFRO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQztJQUN4QixDQUFDO0lBQ0QsSUFBVyxRQUFRLENBQUMsS0FBYTtRQUMvQixJQUFJLElBQUksQ0FBQyxTQUFTLEtBQUssS0FBSyxFQUFFO1lBQzVCLE9BQU87U0FDUjtRQUNELElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxLQUFLLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3JELENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsWUFDVSxRQUFrQyxFQUMxQyxVQUFpQyxnQ0FBZ0M7UUFEekQsYUFBUSxHQUFSLFFBQVEsQ0FBMEI7UUFHMUMsSUFBSSxDQUFDLFNBQVMsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxRQUFRLENBQXFCLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNsRSxJQUFJLENBQUMsc0JBQXNCLEdBQUcsT0FBTyxDQUFDLGFB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QUcsR0FBRyxLQUFLLENBQUMsQ0FBQztvQkFDakMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLEdBQUksU0FBaUIsQ0FBQyxDQUFDO29CQUM5QyxxQ0FBcUM7b0JBQ3JDLFVBQVcsQ0FBQyxNQUFNLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7b0JBQ2hELElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUN6QixPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7aUJBQ2Y7WUFDSCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOztPQUVHO0lBQ0ksV0FBVztRQUNoQixJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFPLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUNwRCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIEJlaGF2aW9yU3ViamVjdCxcclxuICBPYnNlcnZhYmxlLFxyXG4gIGZvcmtKb2luLFxyXG4gIG9mLFxyXG4gIHN3aXRjaE1hcCxcclxuICB0YXAsXHJcbn0gZnJvbSAncnhqcyc7XHJcblxyXG5pbXBvcnQgeyBEYXRhUGFnZSB9IGZyb20gJ0BteXJtaWRvbi9uZy10b29scyc7XHJcblxyXG5pbXBvcnQgeyBMUlVDYWNoZSB9IGZyb20gJy4vbHJ1LWNhY2hlJztcclxuaW1wb3J0IHsgREVGQVVMVF9QQUdFRF9MSVNUX1NUT1JFX09QVElPTlMgfSBmcm9tICcuL3BhZ2VkLWxpc3Quc3RvcmUnO1xyXG5cclxuLyoqXHJcbiAqIEEgdHJlZSBub2RlLiBZb3VyIGRhdGEgc2VydmljZSBzaG91bGQgcmV0dXJuIGEgbGlzdCBvZiB0aGVzZSBub2Rlc1xyXG4gKiBvciBvZiBhbnkgdHlwZSBleHRlbmRpbmcgdGhpcyBpbnRlcmZhY2UuXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIFRyZWVOb2RlIHtcclxuICBpZDogbnVtYmVyO1xyXG4gIHBhcmVudElkPzogbnVtYmVyO1xyXG4gIHk6IG51bWJlcjtcclxuICB4OiBudW1iZXI7XHJcbiAgbGFiZWw6IHN0cmluZztcclxuICB0YWc/OiBzdHJpbmc7XHJcbiAgaGFzQ2hpbGRyZW4/OiBib29sZWFuO1xyXG59XHJcblxyXG4vKipcclxuICogQSBmaWx0ZXIgZm9yIHRyZWUgbm9kZXMuXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIFRyZWVOb2RlRmlsdGVyIHtcclxuICB0YWdzPzogc3RyaW5nW107XHJcbiAgcGFyZW50SWQ/OiBudW1iZXI7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBQYWdpbmcgaW5mb3JtYXRpb24gZm9yIGEgcGFnZWQgdHJlZSBub2RlLlxyXG4gKi9cclxuZXhwb3J0IGludGVyZmFjZSBQYWdpbmdJbmZvIHtcclxuICBwYWdlTnVtYmVyOiBudW1iZXI7XHJcbiAgcGFnZUNvdW50OiBudW1iZXI7XHJcbiAgdG90YWw6IG51bWJlcjtcclxufVxyXG5cclxuLyoqXHJcbiAqIEEgdHJlZSBub2RlIHdpdGggcGFnaW5nIGluZm9ybWF0aW9uLCB1c2VkIGluIE5vZGVCcm93c2VyU3RvcmUuXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIFBhZ2VkVHJlZU5vZGU8RiBleHRlbmRzIFRyZWVOb2RlRmlsdGVyPiBleHRlbmRzIFRyZWVOb2RlIHtcclxuICBwYWdpbmc6IFBhZ2luZ0luZm87XHJcbiAgZXhwYW5kZWQ/OiBib29sZWFuO1xyXG4gIGZpbHRlcj86IEY7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBUaGUgaW50ZXJmYWNlIHRvIGJlIGltcGxlbWVudGVkIGJ5IHRoZSBzZXJ2aWNlIHVzZWQgYnkgTm9kZUJyb3dzZXJTdG9yZVxyXG4gKiB0byBsb2FkIG5vZGVzLlxyXG4gKi9cclxuZXhwb3J0IGludGVyZmFjZSBQYWdlZFRyZWVTdG9yZVNlcnZpY2U8RiBleHRlbmRzIFRyZWVOb2RlRmlsdGVyPiB7XHJcbiAgLyoqXHJcbiAgICogR2V0IGFsbCB0aGUgcm9vdCBub2Rlcywgb3IganVzdCB0aGUgb25lcyBoYXZpbmcgb25lIG9mIHRoZSBzcGVjaWZpZWRcclxuICAgKiB0YWdzLlxyXG4gICAqIEBwYXJhbSB0YWdzIFRoZSBvcHRpb25hbCB0YWdzIHRvIGZpbHRlciB0aGUgcm9vdCBub2Rlcy5cclxuICAgKi9cclxuICBnZXRSb290Tm9kZXModGFncz86IHN0cmluZ1tdKTogT2JzZXJ2YWJsZTxUcmVlTm9kZVtdPjtcclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IHRoZSBzcGVjaWZpZWQgcGFnZSBvZiBub2Rlcy5cclxuICAgKiBAcGFyYW0gZmlsdGVyIFRoZSBmaWx0ZXIuXHJcbiAgICogQHBhcmFtIHBhZ2VOdW1iZXIgVGhlIHBhZ2UgbnVtYmVyLlxyXG4gICAqIEBwYXJhbSBwYWdlU2l6ZSBUaGUgcGFnZSBzaXplLlxyXG4gICAqL1xyXG4gIGdldE5vZGVzKFxyXG4gICAgZmlsdGVyOiBGLFxyXG4gICAgcGFnZU51bWJlcjogbnVtYmVyLFxyXG4gICAgcGFnZVNpemU6IG51bWJlclxyXG4gICk6IE9ic2VydmFibGU8RGF0YVBhZ2U8VHJlZU5vZGU+PjtcclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IHRoZSBsaXN0IG9mIHVuaXF1ZSBub2RlIHRhZ3MuIEVhY2ggdGFnIGNvcnJlc3BvbmRzIHRvIGEgdHJlZSxcclxuICAgKiBhcyBub2RlcyBhcmUgdmlydHVhbGx5IGdyb3VwZWQgYnkgdGhlaXIgdGFnLlxyXG4gICAqL1xyXG4gIGdldFRhZ3MoKTogT2JzZXJ2YWJsZTxzdHJpbmdbXT47XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBPcHRpb25zIGZvciB0aGUgTm9kZUJyb3dzZXJTdG9yZS5cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgUGFnZWRUcmVlU3RvcmVPcHRpb25zIHtcclxuICAvKipcclxuICAgKiBUaGUgc2l6ZSBvZiBwYWdlcyBpbiB0aGUgc3RvcmUuXHJcbiAgICovXHJcbiAgcGFnZVNpemU6IG51bWJlcjtcclxuICAvKipcclxuICAgKiBUaGUgc2l6ZSBvZiB0aGUgY2FjaGUgZm9yIHBhZ2VzIGluIHRoZSBzdG9yZS5cclxuICAgKi9cclxuICBjYWNoZVNpemU6IG51bWJlcjtcclxuXHJcbiAgLyoqXHJcbiAgICogQSBjdXN0b20gZnVuY3Rpb24gZm9yIGJ1aWxkaW5nIHRoZSBjYWNoZSBrZXkgZm9yIHRoZSBnaXZlbiBwYWdlIG51bWJlclxyXG4gICAqIGFuZCBmaWx0ZXIuXHJcbiAgICogQHBhcmFtIHBhZ2VOdW1iZXIgVGhlIHBhZ2UgbnVtYmVyLlxyXG4gICAqIEBwYXJhbSBmaWx0ZXIgVGhlIGZpbHRlci5cclxuICAgKiBAcmV0dXJucyBBIHN0cmluZyB0byBiZSB1c2VkIGFzIGNhY2hlIGtleS5cclxuICAgKi9cclxuICBidWlsZENhY2hlS2V5PzogKHBhZ2VOdW1iZXI6IG51bWJlciwgZmlsdGVyOiBhbnkpID0+IHN0cmluZztcclxufVxyXG5cclxuLyoqXHJcbiAqIEEgc3RvcmUgZm9yIHRoZSBub2RlIGJyb3dzZXIgY29tcG9uZW50LiBUaGlzIHN0b3JlIGlzIHVzZWQgdG8ga2VlcCBhXHJcbiAqIGxpc3Qgb2Ygbm9kZXMsIGFuZCB0byBsb2FkIHRoZW0gZnJvbSB0aGUgQVBJLiBJdCBhbHNvIGtlZXBzIHRoZSByb290XHJcbiAqIG5vZGUuIEV2ZXJ5IHRyZWUgbm9kZSBpbiB0aGUgbGlzdCBpcyBleHRlbmRlZCB3aXRoIHBhZ2UgbnVtYmVyLFxyXG4gKiBwYWdlIGNvdW50IGFuZCB0b3RhbCBpdGVtcywgcGx1cyBleHBhbnNpb24tcmVsYXRlZCBtZXRhZGF0YS5cclxuICogVGhlIHN0b3JlIGtlZXBzIGEgZmxhdCBsaXN0IG9mIHRoZXNlIHRyZWUgbm9kZXMsIGFsbG93aW5nIHVzZXJzIHRvXHJcbiAqIGV4cGFuZCBhbmQgY29sbGFwc2UgdGhlbS5cclxuICogRiBpcyB0aGUgdHlwZSBvZiB0aGUgZmlsdGVyIG9iamVjdCwgRSBpcyB0aGUgdHlwZSBvZiB0aGUgcGFnZWQgdHJlZSBub2Rlcy5cclxuICovXHJcbmV4cG9ydCBjbGFzcyBQYWdlZFRyZWVTdG9yZTxcclxuICBFIGV4dGVuZHMgUGFnZWRUcmVlTm9kZTxGPixcclxuICBGIGV4dGVuZHMgVHJlZU5vZGVGaWx0ZXJcclxuPiB7XHJcbiAgcHJpdmF0ZSBfcmFkaXg/OiBFO1xyXG4gIHByaXZhdGUgX3JhZGl4TGFiZWw6IHN0cmluZztcclxuICBwcml2YXRlIF9yb290czogRVtdO1xyXG4gIHByaXZhdGUgX25vZGVzJDogQmVoYXZpb3JTdWJqZWN0PEVbXT47XHJcbiAgcHJpdmF0ZSBfdGFncyQ6IEJlaGF2aW9yU3ViamVjdDxzdHJpbmdbXT47XHJcbiAgcHJpdmF0ZSBfZmlsdGVyJDogQmVoYXZpb3JTdWJqZWN0PEY+O1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgX2N1c3RvbUNhY2hlS2V5QnVpbGRlcj86IChcclxuICAgIHBhZ2VOdW1iZXI6IG51bWJlcixcclxuICAgIGZpbHRlcjogYW55XHJcbiAgKSA9PiBzdHJpbmc7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBfY2FjaGU6IExSVUNhY2hlPERhdGFQYWdlPFRyZWVOb2RlPj47XHJcblxyXG4gIHByaXZhdGUgX3BhZ2VTaXplOiBudW1iZXI7XHJcbiAgLy8gZGlydHkgc3RhdGU6IHRoaXMgaXMgcmVzZXQgd2hlbiB0aGUgc3RvcmUgaXMgcmVzZXQsIGFuZCBzZXQgdG8gdHJ1ZVxyXG4gIC8vIHdoZW4gdGhlIHN0b3JlIGlzIGNoYW5nZWRcclxuICBwcml2YXRlIF9kaXJ0eT86IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoZSBmbGF0IGxpc3Qgb2YgcGFnZWQgbm9kZXMgaW4gdGhpcyBzdG9yZS5cclxuICAgKi9cclxuICBwdWJsaWMgbm9kZXMkOiBPYnNlcnZhYmxlPFJlYWRvbmx5PEVbXT4+O1xyXG5cclxuICAvKipcclxuICAgKiBUaGUgbGlzdCBvZiB0cmVlIHRhZ3MgaW4gdGhpcyBzdG9yZS5cclxuICAgKi9cclxuICBwdWJsaWMgdGFncyQ6IE9ic2VydmFibGU8UmVhZG9ubHk8c3RyaW5nW10+PjtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIGdsb2JhbCBub2RlcyBmaWx0ZXIuXHJcbiAgICovXHJcbiAgcHVibGljIGZpbHRlciQ6IE9ic2VydmFibGU8UmVhZG9ubHk8Rj4+O1xyXG5cclxuICAvKipcclxuICAgKiBUaGUgc2l6ZSBvZiBub2RlcyBwYWdlcyBpbiB0aGlzIHN0b3JlLiBJZiB5b3UgY2hhbmdlIGl0LCB0aGUgc3RvcmVcclxuICAgKiBpcyByZXNldC4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgMjAuXHJcbiAgICovXHJcbiAgcHVibGljIGdldCBwYWdlU2l6ZSgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMuX3BhZ2VTaXplO1xyXG4gIH1cclxuICBwdWJsaWMgc2V0IHBhZ2VTaXplKHZhbHVlOiBudW1iZXIpIHtcclxuICAgIGlmICh0aGlzLl9wYWdlU2l6ZSA9PT0gdmFsdWUpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgdGhpcy5fcGFnZVNpemUgPSB2YWx1ZTtcclxuICAgIHRoaXMucmVzZXQodGhpcy5fcmFkaXg/LmxhYmVsIHx8IHRoaXMuX3JhZGl4TGFiZWwpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIHRoZSBzdG9yZS5cclxuICAgKiBAcGFyYW0gX3NlcnZpY2UgVGhlIHNlcnZpY2UgdXNlZCB0byBsb2FkIG5vZGVzLlxyXG4gICAqIEBwYXJhbSBvcHRpb25zIFRoZSBvcHRpb25zIHRvIGNvbmZpZ3VyZSB0aGlzIHN0b3JlLlxyXG4gICAqL1xyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSBfc2VydmljZTogUGFnZWRUcmVlU3RvcmVTZXJ2aWNlPEY+LFxyXG4gICAgb3B0aW9uczogUGFnZWRUcmVlU3RvcmVPcHRpb25zID0gREVGQVVMVF9QQUdFRF9MSVNUX1NUT1JFX09QVElPTlNcclxuICApIHtcclxuICAgIHRoaXMuX3BhZ2VTaXplID0gb3B0aW9ucy5wYWdlU2l6ZTtcclxuICAgIHRoaXMuX2NhY2hlID0gbmV3IExSVUNhY2hlPERhdGFQYWdlPFRyZWVOb2RlPj4ob3B0aW9ucy5jYWNoZVNpemUpO1xyXG4gICAgdGhpcy5fY3VzdG9tQ2FjaGVLZXlCdWlsZGVyID0gb3B0aW9ucy5idWlsZENhY2hlS2V5O1xyXG4gICAgdGhpcy5fcmFkaXhMYWJlbCA9ICcocm9vdCknO1xyXG4gICAgdGhpcy5fcm9vdHMgPSBbXTtcclxuICAgIHRoaXMuX25vZGVzJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8RVtdPihbXSk7XHJcbiAgICB0aGlzLm5vZGVzJCA9IHRoaXMuX25vZGVzJC5hc09ic2VydmFibGUoKTtcclxuICAgIHRoaXMuX3RhZ3MkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmdbXT4oW10pO1xyXG4gICAgdGhpcy50YWdzJCA9IHRoaXMuX3RhZ3MkLmFzT2JzZXJ2YWJsZSgpO1xyXG4gICAgdGhpcy5fZmlsdGVyJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Rj4oe30gYXMgRik7XHJcbiAgICB0aGlzLmZpbHRlciQgPSB0aGlzLl9maWx0ZXIkLmFzT2JzZXJ2YWJsZSgpO1xyXG4gICAgdGhpcy5fZGlydHkgPSB0cnVlO1xyXG4gICAgdGhpcy51cGRhdGVUYWdzKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHVwZGF0ZVRhZ3MoKTogdm9pZCB7XHJcbiAgICB0aGlzLl9zZXJ2aWNlLmdldFRhZ3MoKS5zdWJzY3JpYmUoKHRhZ3MpID0+IHtcclxuICAgICAgdGhpcy5fdGFncyQubmV4dCh0YWdzKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0cyB0aGUgZ2xvYmFsIGZpbHRlciBldmVudHVhbGx5IG92ZXJyaWRkZW4gd2l0aCB2YWx1ZXNcclxuICAgKiBmcm9tIHRoZSBzcGVjaWZpZWQgbm9kZSdzIGZpbHRlci5cclxuICAgKiBAcGFyYW0gbm9kZSBUaGUgb3B0aW9uYWwgbm9kZS5cclxuICAgKiBAcmV0dXJucyBUaGUgZmlsdGVyLlxyXG4gICAqL1xyXG4gIHByaXZhdGUgZ2V0RmlsdGVyKG5vZGU/OiBQYWdlZFRyZWVOb2RlPEY+KTogRiB7XHJcbiAgICByZXR1cm4gbm9kZT8uZmlsdGVyXHJcbiAgICAgID8ge1xyXG4gICAgICAgICAgLi4udGhpcy5fZmlsdGVyJC52YWx1ZSxcclxuICAgICAgICAgIC4uLm5vZGUuZmlsdGVyLFxyXG4gICAgICAgIH1cclxuICAgICAgOiB0aGlzLl9maWx0ZXIkLnZhbHVlO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0cyBhbGwgdGhlIG5vZGVzIGluIHRoZSBzdG9yZS5cclxuICAgKiBAcmV0dXJucyBUaGUgbm9kZXMuXHJcbiAgICovXHJcbiAgcHVibGljIGdldE5vZGVzKCk6IFJlYWRvbmx5PFBhZ2VkVHJlZU5vZGU8Rj5bXT4ge1xyXG4gICAgcmV0dXJuIHRoaXMuX25vZGVzJC52YWx1ZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldHMgdGhlIGxpc3Qgb2Ygbm9kZXMgdGFncy5cclxuICAgKiBAcmV0dXJucyBUaGUgdGFncy5cclxuICAgKi9cclxuICBwdWJsaWMgZ2V0VGFncygpOiBSZWFkb25seTxzdHJpbmdbXT4ge1xyXG4gICAgcmV0dXJuIHRoaXMuX3RhZ3MkLnZhbHVlO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQnVpbGQgdGhlIGNhY2hlIGtleSBmb3IgdGhlIGdpdmVuIHBhZ2UgbnVtYmVyIGFuZCBmaWx0ZXIuXHJcbiAgICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24ganVzdCByZXR1cm5zIGEgc3RyaW5naWZpZWQgb2JqZWN0XHJcbiAgICogY29udGFpbmluZyB0aGUgcGFnZSBudW1iZXIgYW5kIHRoZSBmaWx0ZXIuIFlvdSBtYXkgb3ZlcnJpZGVcclxuICAgKiB0aGlzIG1ldGhvZCB0byBwcm92aWRlIGEgY3VzdG9tIGNhY2hlIGtleS5cclxuICAgKiBAcGFyYW0gcGFnZU51bWJlciBUaGUgcGFnZSBudW1iZXIuXHJcbiAgICogQHBhcmFtIGZpbHRlciBUaGUgZmlsdGVyLlxyXG4gICAqIEByZXR1cm5zIEEgc3RyaW5nIHRvIGJlIHVzZWQgYXMgY2FjaGUga2V5LlxyXG4gICAqL1xyXG4gIHByaXZhdGUgYnVpbGRDYWNoZUtleShwYWdlTnVtYmVyOiBudW1iZXIsIGZpbHRlcjogRik6IHN0cmluZyB7XHJcbiAgICBpZiAodGhpcy5fY3VzdG9tQ2FjaGVLZXlCdWlsZGVyKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9jdXN0b21DYWNoZUtleUJ1aWxkZXIocGFnZU51bWJlciwgZmlsdGVyKTtcclxuICAgIH1cclxuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh7IHBhZ2VOdW1iZXIsIC4uLmZpbHRlciB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0UGFnZUZyb21DYWNoZU9yU2VydmVyKFxyXG4gICAgZmlsdGVyOiBGLFxyXG4gICAgcGFnZU51bWJlcjogbnVtYmVyXHJcbiAgKTogT2JzZXJ2YWJsZTxEYXRhUGFnZTxUcmVlTm9kZT4+IHtcclxuICAgIGNvbnN0IGtleSA9IHRoaXMuYnVpbGRDYWNoZUtleShwYWdlTnVtYmVyLCBmaWx0ZXIpO1xyXG4gICAgY29uc3QgcGFnZUluQ2FjaGUgPSB0aGlzLl9jYWNoZS5nZXQoa2V5KTtcclxuXHJcbiAgICBpZiAocGFnZUluQ2FjaGUpIHtcclxuICAgICAgcmV0dXJuIG9mKHBhZ2VJbkNhY2hlKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9zZXJ2aWNlLmdldE5vZGVzKGZpbHRlciwgcGFnZU51bWJlciwgdGhpcy5fcGFnZVNpemUpLnBpcGUoXHJcbiAgICAgICAgdGFwKChwYWdlKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLl9jYWNoZS5wdXQoa2V5LCBwYWdlLCAwKTtcclxuICAgICAgICB9KVxyXG4gICAgICApO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjcmVhdGVQYWdlTm9kZXMocGFnZTogRGF0YVBhZ2U8VHJlZU5vZGU+KTogUGFnZWRUcmVlTm9kZTxGPltdIHtcclxuICAgIHJldHVybiBwYWdlLml0ZW1zLm1hcCgobikgPT4ge1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIC4uLm4sXHJcbiAgICAgICAgaGFzQ2hpbGRyZW46IG4uaGFzQ2hpbGRyZW4sXHJcbiAgICAgICAgcGFnaW5nOiB7XHJcbiAgICAgICAgICBwYWdlTnVtYmVyOiBwYWdlLnBhZ2VOdW1iZXIsXHJcbiAgICAgICAgICBwYWdlQ291bnQ6IHBhZ2UucGFnZUNvdW50LFxyXG4gICAgICAgICAgdG90YWw6IHBhZ2UudG90YWwsXHJcbiAgICAgICAgfSxcclxuICAgICAgfTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQXBwbGllcyB0aGUgZmlsdGVyIGZvciB0aGlzIHN0b3JlLiBXaGVuZXZlciB0aGUgZmlsdGVyIGlzIHNldCxcclxuICAgKiB0aGUgc3RvcmUgaXMgcmVzZXQuXHJcbiAgICogQHBhcmFtIGZpbHRlciBUaGUgZmlsdGVyLlxyXG4gICAqIEBwYXJhbSByYWRpeExhYmVsIFRoZSBsYWJlbCBvZiB0aGUgcmFkaXggbm9kZSwgaWYgdGhpcyBuZWVkcyB0byBiZSBzZXQuXHJcbiAgICogQHJldHVybnMgdHJ1ZSBpZiB0cmVlIHdhcyBjaGFuZ2VkLCBmYWxzZSBvdGhlcndpc2UuXHJcbiAgICovXHJcbiAgcHVibGljIGFwcGx5RmlsdGVyKGZpbHRlcjogRiwgcmFkaXhMYWJlbD86IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xyXG4gICAgaWYgKHRoaXMuX2ZpbHRlciQudmFsdWUgPT09IGZpbHRlcikge1xyXG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcclxuICAgIH1cclxuICAgIHRoaXMuX2ZpbHRlciQubmV4dChmaWx0ZXIpO1xyXG4gICAgdGhpcy5fZGlydHkgPSB0cnVlO1xyXG4gICAgcmV0dXJuIHRoaXMucmVzZXQodGhpcy5fcmFkaXg/LmxhYmVsIHx8IHJhZGl4TGFiZWwgfHwgdGhpcy5fcmFkaXhMYWJlbCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXNldCB0aGUgc3RvcmUsIGxvYWRpbmcgdGhlIHJvb3Qgbm9kZXMgYW5kIHRoZWlyIGNoaWxkcmVuLlxyXG4gICAqIEBwYXJhbSBsYWJlbCBUaGUgbGFiZWwgb2YgdGhlIHJhZGl4IG5vZGUuXHJcbiAgICogQHJldHVybnMgdHJ1ZSBpZiB0cmVlIHdhcyBjaGFuZ2VkLCBmYWxzZSBvdGhlcndpc2UuXHJcbiAgICovXHJcbiAgcHVibGljIHJlc2V0KGxhYmVsOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcclxuICAgIGlmICghdGhpcy5fZGlydHkpIHtcclxuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShmYWxzZSk7XHJcbiAgICB9XHJcbiAgICB0aGlzLl9jYWNoZS5jbGVhcigpO1xyXG4gICAgY29uc3QgZmlsdGVyID0gdGhpcy5fZmlsdGVyJC52YWx1ZTtcclxuICAgIHRoaXMuX3JhZGl4ID0ge1xyXG4gICAgICBpZDogMCxcclxuICAgICAgeTogMCxcclxuICAgICAgeDogMSxcclxuICAgICAgbGFiZWw6IGxhYmVsLFxyXG4gICAgICBwYWdpbmc6IHtcclxuICAgICAgICBwYWdlTnVtYmVyOiAwLFxyXG4gICAgICAgIHBhZ2VDb3VudDogMCxcclxuICAgICAgICB0b3RhbDogMCxcclxuICAgICAgfSxcclxuICAgIH0gYXMgRTtcclxuXHJcbiAgICByZXR1cm4gbmV3IFByb21pc2U8Ym9vbGVhbj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICB0aGlzLl9zZXJ2aWNlXHJcbiAgICAgICAgLmdldFJvb3ROb2RlcyhmaWx0ZXIudGFncylcclxuICAgICAgICAucGlwZShcclxuICAgICAgICAgIHN3aXRjaE1hcCgobm9kZXMpID0+IHtcclxuICAgICAgICAgICAgLy8gbm8gcm9vdHMsIGNsZWFyIGFuZCByZXR1cm4gZW1wdHkgc2V0XHJcbiAgICAgICAgICAgIGlmICghbm9kZXMgfHwgbm9kZXMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5fcm9vdHMgPSBbXTtcclxuICAgICAgICAgICAgICByZXR1cm4gb2YoW10pO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIC8vIGdvdCByb290cywgc2V0IHRoZW0gYW5kIGdldCB0aGVpciBjaGlsZHJlblxyXG4gICAgICAgICAgICAgIHRoaXMuX3Jvb3RzID0gbm9kZXMubWFwKFxyXG4gICAgICAgICAgICAgICAgKG5vZGUpID0+XHJcbiAgICAgICAgICAgICAgICAgICh7XHJcbiAgICAgICAgICAgICAgICAgICAgLi4ubm9kZSxcclxuICAgICAgICAgICAgICAgICAgICBwYWdpbmc6IHtcclxuICAgICAgICAgICAgICAgICAgICAgIHBhZ2VOdW1iZXI6IDEsXHJcbiAgICAgICAgICAgICAgICAgICAgICBwYWdlQ291bnQ6IDEsXHJcbiAgICAgICAgICAgICAgICAgICAgICB0b3RhbDogMSxcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICB9IGFzIEUpXHJcbiAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAvLyBmZXRjaCBjaGlsZHJlbiBmb3IgZWFjaCByb290IG5vZGVcclxuICAgICAgICAgICAgICByZXR1cm4gZm9ya0pvaW4oXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9yb290cy5tYXAoKHJvb3QpID0+XHJcbiAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0UGFnZUZyb21DYWNoZU9yU2VydmVyKFxyXG4gICAgICAgICAgICAgICAgICAgIHsgLi4uZmlsdGVyLCBwYXJlbnRJZDogcm9vdC5pZCB9LFxyXG4gICAgICAgICAgICAgICAgICAgIDFcclxuICAgICAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0pXHJcbiAgICAgICAgKVxyXG4gICAgICAgIC5zdWJzY3JpYmUoe1xyXG4gICAgICAgICAgbmV4dDogKHBhZ2VzKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuX2RpcnR5ID0gZmFsc2U7XHJcbiAgICAgICAgICAgIGlmIChwYWdlcy5zb21lKChwYWdlKSA9PiBwYWdlLnRvdGFsKSkge1xyXG4gICAgICAgICAgICAgIC8vIHJhZGl4XHJcbiAgICAgICAgICAgICAgdGhpcy5fcmFkaXghLmhhc0NoaWxkcmVuID0gdHJ1ZTtcclxuICAgICAgICAgICAgICB0aGlzLl9yYWRpeCEuZXhwYW5kZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgIHRoaXMuX3JhZGl4IS5wYWdpbmcgPSB7XHJcbiAgICAgICAgICAgICAgICBwYWdlTnVtYmVyOiAxLFxyXG4gICAgICAgICAgICAgICAgcGFnZUNvdW50OiAxLFxyXG4gICAgICAgICAgICAgICAgdG90YWw6IHBhZ2VzLmxlbmd0aCxcclxuICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgIC8vIHJvb3RzXHJcbiAgICAgICAgICAgICAgdGhpcy5fcm9vdHMuZm9yRWFjaCgocm9vdCwgaSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcm9vdC5oYXNDaGlsZHJlbiA9ICEhcGFnZXNbaV0udG90YWw7XHJcbiAgICAgICAgICAgICAgICByb290LmV4cGFuZGVkID0gISFwYWdlc1tpXS50b3RhbDtcclxuICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICBjb25zdCBub2RlcyA9IHRoaXMuX3Jvb3RzLmZsYXRNYXAoKHJvb3QsIGkpID0+IFtcclxuICAgICAgICAgICAgICAgIHJvb3QsXHJcbiAgICAgICAgICAgICAgICAuLi50aGlzLmNyZWF0ZVBhZ2VOb2RlcyhwYWdlc1tpXSksXHJcbiAgICAgICAgICAgICAgXSk7XHJcbiAgICAgICAgICAgICAgdGhpcy5fbm9kZXMkLm5leHQoW3RoaXMuX3JhZGl4ISwgLi4uKG5vZGVzIGFzIEVbXSldKTtcclxuICAgICAgICAgICAgICByZXNvbHZlKHRydWUpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIHRoaXMuX3Jvb3RzLmZvckVhY2goKHJvb3QpID0+IHtcclxuICAgICAgICAgICAgICAgIHJvb3QuaGFzQ2hpbGRyZW4gPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIHJvb3QuZXhwYW5kZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICB0aGlzLl9ub2RlcyQubmV4dChbdGhpcy5fcmFkaXghLCAuLi50aGlzLl9yb290c10pO1xyXG4gICAgICAgICAgICAgIHJlc29sdmUodHJ1ZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICBlcnJvcjogKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAgIHJlamVjdChlcnJvcik7XHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTZXQgdGhlIG5vZGUgZmlsdGVyIGZvciB0aGUgbm9kZSB3aXRoIHRoZSBzcGVjaWZpZWQgSUQuXHJcbiAgICogQHBhcmFtIGlkIFRoZSBub2RlIElELlxyXG4gICAqIEBwYXJhbSBmaWx0ZXIgVGhlIGZpbHRlciB0byBzZXQuXHJcbiAgICogQHJldHVybnMgUHJvbWlzZSB3aXRoIHRydWUgaWYgZmlsdGVyIHdhcyBzZXQsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgKi9cclxuICBwdWJsaWMgc2V0Tm9kZUZpbHRlcihpZDogbnVtYmVyLCBmaWx0ZXI/OiBGIHwgbnVsbCk6IFByb21pc2U8Ym9vbGVhbj4ge1xyXG4gICAgaWYgKCFpZCkge1xyXG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcclxuICAgIH1cclxuICAgIHJldHVybiBuZXcgUHJvbWlzZTxib29sZWFuPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgIGNvbnN0IG5vZGUgPSB0aGlzLl9ub2RlcyQudmFsdWUuZmluZCgobikgPT4gbi5pZCA9PT0gaWQpO1xyXG4gICAgICBpZiAoIW5vZGUpIHtcclxuICAgICAgICByZWplY3QoYE5vZGUgSUQgJHtpZH0gbm90IGZvdW5kIGluIHN0b3JlYCk7XHJcbiAgICAgIH1cclxuICAgICAgbm9kZSEuZmlsdGVyID0gZmlsdGVyIHx8IHVuZGVmaW5lZDtcclxuICAgICAgcmV0dXJuIHRoaXMuY2hhbmdlUGFnZShpZCwgMSk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEV4cGFuZCB0aGUgbm9kZSB3aXRoIHRoZSBzcGVjaWZpZWQgSUQuIElmIHRoZSBub2RlIGlzIG5vdCBleHBhbmRhYmxlLFxyXG4gICAqIG9yIGl0IGlzIGFscmVhZHkgZXhwYW5kZWQsIHRoaXMgbWV0aG9kIGRvZXMgbm90aGluZy5cclxuICAgKiBAcGFyYW0gbm9kZSBUaGUgSUQgb2YgdGhlIG5vZGUgdG8gZXhwYW5kLlxyXG4gICAqIEByZXR1cm5zIFByb21pc2Ugd2l0aCB0cnVlIGlmIHRoZSBub2RlIHdhcyBleHBhbmRlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAqL1xyXG4gIHB1YmxpYyBleHBhbmQoaWQ6IG51bWJlcik6IFByb21pc2U8Ym9vbGVhbj4ge1xyXG4gICAgaWYgKCFpZCkge1xyXG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcclxuICAgIH1cclxuICAgIHJldHVybiBuZXcgUHJvbWlzZTxib29sZWFuPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgIGNvbnN0IG5vZGUgPSB0aGlzLl9ub2RlcyQudmFsdWUuZmluZCgobikgPT4gbi5pZCA9PT0gaWQpO1xyXG4gICAgICBpZiAoIW5vZGUgfHwgbm9kZS5oYXNDaGlsZHJlbiA9PT0gZmFsc2UgfHwgbm9kZS5leHBhbmRlZCkge1xyXG4gICAgICAgIHJlc29sdmUoZmFsc2UpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLmdldFBhZ2VGcm9tQ2FjaGVPclNlcnZlcihcclxuICAgICAgICB7IC4uLnRoaXMuZ2V0RmlsdGVyKG5vZGUpLCBwYXJlbnRJZDogaWQgfSxcclxuICAgICAgICAxXHJcbiAgICAgICkuc3Vic2NyaWJlKChwYWdlKSA9PiB7XHJcbiAgICAgICAgLy8gbm8gY2hpbGRyZW4sIHNldCBoYXNDaGlsZHJlbiB0byBmYWxzZVxyXG4gICAgICAgIGlmICghcGFnZS50b3RhbCkge1xyXG4gICAgICAgICAgbm9kZSEuaGFzQ2hpbGRyZW4gPSBmYWxzZTtcclxuICAgICAgICAgIHJlc29sdmUoZmFsc2UpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICB0aGlzLl9kaXJ0eSA9IHRydWU7XHJcbiAgICAgICAgICAvLyBpbnNlcnQgcGFnZSBub2RlcyBhZnRlciB0aGUgY3VycmVudCBub2RlXHJcbiAgICAgICAgICBjb25zdCBub2RlcyA9IHRoaXMuX25vZGVzJC52YWx1ZTtcclxuICAgICAgICAgIGNvbnN0IGluZGV4ID0gbm9kZXMuaW5kZXhPZihub2RlISk7XHJcbiAgICAgICAgICBpZiAoaW5kZXggPT09IC0xKSB7XHJcbiAgICAgICAgICAgIHJlamVjdChgTm9kZSBJRCAke2lkfSBub3QgZm91bmQgaW4gc3RvcmVgKTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHBhZ2VOb2RlcyA9IHRoaXMuY3JlYXRlUGFnZU5vZGVzKHBhZ2UpO1xyXG4gICAgICAgICAgICBub2Rlcy5zcGxpY2UoaW5kZXggKyAxLCAwLCAuLi4ocGFnZU5vZGVzIGFzIEVbXSkpO1xyXG4gICAgICAgICAgICB0aGlzLl9ub2RlcyQubmV4dChub2Rlcyk7XHJcbiAgICAgICAgICAgIG5vZGUhLmhhc0NoaWxkcmVuID0gdHJ1ZTtcclxuICAgICAgICAgICAgbm9kZSEuZXhwYW5kZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICByZXNvbHZlKHRydWUpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBleHBhbmRBbGwoaWQ6IG51bWJlcik6IFByb21pc2U8Ym9vbGVhbj4ge1xyXG4gICAgaWYgKCFpZCkge1xyXG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcclxuICAgIH1cclxuICAgIC8vIGdldCB0aGUgcGFyZW50IG5vZGUgdG8gc3RhcnQgZnJvbVxyXG4gICAgY29uc3Qgbm9kZXMgPSB0aGlzLl9ub2RlcyQudmFsdWU7XHJcbiAgICBjb25zdCBub2RlSW5kZXggPSBub2Rlcy5maW5kSW5kZXgoKG4pID0+IG4uaWQgPT09IGlkKTtcclxuICAgIGlmIChub2RlSW5kZXggPT09IC0xKSB7XHJcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZmFsc2UpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGNvbGxlY3QgYWxsIHRoZSBkZXNjZW5kYW50IG5vZGVzIElEc1xyXG4gICAgbGV0IGkgPSBub2RlSW5kZXggKyAxO1xyXG4gICAgd2hpbGUgKGkgPCBub2Rlcy5sZW5ndGggJiYgbm9kZXNbaV0ueSA+IG5vZGVzW25vZGVJbmRleF0ueSkge1xyXG4gICAgICBpKys7XHJcbiAgICB9XHJcbiAgICBjb25zdCBub2Rlc1RvRXhwYW5kID0gbm9kZXMuc2xpY2Uobm9kZUluZGV4LCBpKS5tYXAoKG4pID0+IG4uaWQpO1xyXG5cclxuICAgIC8vIGV4cGFuZCBhbGwgdGhlIGRlc2NlbmRhbnQgbm9kZXNcclxuICAgIHJldHVybiBuZXcgUHJvbWlzZTxib29sZWFuPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgIG5vZGVzVG9FeHBhbmQuZm9yRWFjaCgoaWQpID0+IHtcclxuICAgICAgICB0aGlzLmV4cGFuZChpZCk7XHJcbiAgICAgICAgdGhpcy5leHBhbmRBbGwoaWQpO1xyXG4gICAgICB9KTtcclxuICAgICAgcmVzb2x2ZSh0cnVlKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldENoaWxkcmVuKGlkOiBudW1iZXIpOiBFW10ge1xyXG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuX25vZGVzJC52YWx1ZS5maW5kKChuKSA9PiBuLmlkID09PSBpZCk7XHJcbiAgICBpZiAoIW5vZGUgfHwgbm9kZS5oYXNDaGlsZHJlbiA9PT0gZmFsc2UpIHtcclxuICAgICAgcmV0dXJuIFtdO1xyXG4gICAgfVxyXG4gICAgY29uc3Qgbm9kZXMgPSB0aGlzLl9ub2RlcyQudmFsdWU7XHJcbiAgICBjb25zdCBpbmRleCA9IG5vZGVzLmluZGV4T2Yobm9kZSk7XHJcbiAgICBpZiAoaW5kZXggPT09IC0xKSB7XHJcbiAgICAgIHJldHVybiBbXTtcclxuICAgIH1cclxuICAgIGNvbnN0IGNoaWxkcmVuOiBFW10gPSBbXTtcclxuICAgIGxldCBpID0gaW5kZXggKyAxO1xyXG4gICAgd2hpbGUgKGkgPCBub2Rlcy5sZW5ndGggJiYgbm9kZXNbaV0ueSA+IG5vZGUueSkge1xyXG4gICAgICBjaGlsZHJlbi5wdXNoKG5vZGVzW2ldKTtcclxuICAgICAgaSsrO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGNoaWxkcmVuO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSByZW1vdmVEZXNjZW5kYW50cyhcclxuICAgIG5vZGVzOiBQYWdlZFRyZWVOb2RlPEY+W10sXHJcbiAgICBub2RlSW5kZXg6IG51bWJlclxyXG4gICk6IHZvaWQge1xyXG4gICAgbGV0IGkgPSBub2RlSW5kZXggKyAxO1xyXG4gICAgd2hpbGUgKGkgPCBub2Rlcy5sZW5ndGggJiYgbm9kZXNbaV0ueSA+IG5vZGVzW25vZGVJbmRleF0ueSkge1xyXG4gICAgICBpKys7XHJcbiAgICB9XHJcbiAgICBub2Rlcy5zcGxpY2Uobm9kZUluZGV4ICsgMSwgaSAtIG5vZGVJbmRleCAtIDEpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ29sbGFwc2UgdGhlIG5vZGUgd2l0aCB0aGUgc3BlY2lmaWVkIElELiBJZiB0aGUgbm9kZSBpcyBub3QgZXhwYW5kYWJsZSxcclxuICAgKiBvciBpdCBpcyBhbHJlYWR5IGNvbGxhcHNlZCwgdGhpcyBtZXRob2QgZG9lcyBub3RoaW5nLlxyXG4gICAqIEBwYXJhbSBub2RlIFRoZSBub2RlIHRvIGNvbGxhcHNlLlxyXG4gICAqIEByZXR1cm5zIFByb21pc2Ugd2l0aCB0cnVlIGlmIHRoZSBub2RlIHdhcyBjb2xsYXBzZWQsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgKi9cclxuICBwdWJsaWMgY29sbGFwc2UoaWQ6IG51bWJlcik6IFByb21pc2U8Ym9vbGVhbj4ge1xyXG4gICAgaWYgKCFpZCkge1xyXG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcclxuICAgIH1cclxuICAgIHJldHVybiBuZXcgUHJvbWlzZTxib29sZWFuPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgIGNvbnN0IG5vZGUgPSB0aGlzLl9ub2RlcyQudmFsdWUuZmluZCgobikgPT4gbi5pZCA9PT0gaWQpO1xyXG4gICAgICBpZiAoIW5vZGUgfHwgbm9kZS5oYXNDaGlsZHJlbiA9PT0gZmFsc2UgfHwgIW5vZGUuZXhwYW5kZWQpIHtcclxuICAgICAgICByZXNvbHZlKGZhbHNlKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gcmVtb3ZlIGFsbCB0aGUgZGVzY2VuZGFudCBub2RlcyBhZnRlciB0aGUgY3VycmVudCBub2RlXHJcbiAgICAgIGNvbnN0IG5vZGVzID0gdGhpcy5fbm9kZXMkLnZhbHVlO1xyXG4gICAgICBjb25zdCBub2RlSW5kZXggPSBub2Rlcy5pbmRleE9mKG5vZGUhKTtcclxuICAgICAgaWYgKG5vZGVJbmRleCA9PT0gLTEpIHtcclxuICAgICAgICByZWplY3QoYE5vZGUgSUQgJHtpZH0gbm90IGZvdW5kIGluIHN0b3JlYCk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5fZGlydHkgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMucmVtb3ZlRGVzY2VuZGFudHMobm9kZXMsIG5vZGVJbmRleCk7XHJcbiAgICAgICAgdGhpcy5fbm9kZXMkLm5leHQobm9kZXMpO1xyXG4gICAgICAgIG5vZGUhLmV4cGFuZGVkID0gZmFsc2U7XHJcbiAgICAgICAgcmVzb2x2ZSh0cnVlKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDaGFuZ2UgdGhlIHBhZ2UgaW5jbHVkaW5nIHRoZSBub2RlIHdpdGggdGhlIHNwZWNpZmllZCBJRC5cclxuICAgKiBAcGFyYW0gbm9kZSBUaGUgcGFyZW50IG5vZGUgd2hvc2UgY2hpbGRyZW4gYXJlIGluc2lkZSB0aGUgcGFnZSB5b3Ugd2FudCB0byBjaGFuZ2UuXHJcbiAgICogQHBhcmFtIHBhZ2VOdW1iZXIgVGhlIG5ldyBwYWdlIG51bWJlci5cclxuICAgKiBAcmV0dXJucyBQcm9taXNlIHdpdGggdHJ1ZSBpZiB0aGUgcGFnZSB3YXMgY2hhbmdlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAqL1xyXG4gIHB1YmxpYyBjaGFuZ2VQYWdlKHBhcmVudElkOiBudW1iZXIsIHBhZ2VOdW1iZXI6IG51bWJlcik6IFByb21pc2U8Ym9vbGVhbj4ge1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPGJvb2xlYW4+KChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgY29uc3QgcGFyZW50Tm9kZSA9IHRoaXMuX25vZGVzJC52YWx1ZS5maW5kKChuKSA9PiBuLmlkID09PSBwYXJlbnRJZCk7XHJcbiAgICAgIGlmICghcGFyZW50Tm9kZSkge1xyXG4gICAgICAgIHJlc29sdmUoZmFsc2UpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuZ2V0UGFnZUZyb21DYWNoZU9yU2VydmVyKFxyXG4gICAgICAgIHsgLi4udGhpcy5nZXRGaWx0ZXIocGFyZW50Tm9kZSksIHBhcmVudElkIH0sXHJcbiAgICAgICAgcGFnZU51bWJlclxyXG4gICAgICApLnN1YnNjcmliZSgocGFnZSkgPT4ge1xyXG4gICAgICAgIC8vIGlmIHBhZ2UgaXMgZW1wdHkgZG8gbm90aGluZ1xyXG4gICAgICAgIGlmICghcGFnZS50b3RhbCkge1xyXG4gICAgICAgICAgcmVzb2x2ZShmYWxzZSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRoaXMuX2RpcnR5ID0gdHJ1ZTtcclxuICAgICAgICAgIC8vIHJlbW92ZSBhbGwgdGhlIG5vZGVzIGluIHRoZSBzYW1lIHBhZ2Ugb2Ygbm9kZVxyXG4gICAgICAgICAgLy8gd2l0aCBhbGwgdGhlaXIgZGVzY2VuZGFudHNcclxuICAgICAgICAgIGNvbnN0IG5vZGVzID0gdGhpcy5fbm9kZXMkLnZhbHVlO1xyXG4gICAgICAgICAgY29uc3Qgbm9kZUluZGV4ID0gbm9kZXMuaW5kZXhPZihwYXJlbnROb2RlISkgKyAxO1xyXG4gICAgICAgICAgY29uc3QgcGFnZU5vZGVzID0gdGhpcy5jcmVhdGVQYWdlTm9kZXMocGFnZSk7XHJcbiAgICAgICAgICAvLyBmaW5kIHRoZSBmaXJzdCBub2RlIG9mIHRoZSBub2RlJ3MgcGFnZVxyXG4gICAgICAgICAgbGV0IHN0YXJ0ID0gbm9kZUluZGV4O1xyXG4gICAgICAgICAgY29uc3Qgb2xkUGFnZU5yID0gbm9kZXNbc3RhcnRdLnBhZ2luZy5wYWdlTnVtYmVyO1xyXG4gICAgICAgICAgd2hpbGUgKFxyXG4gICAgICAgICAgICBzdGFydCA+IDAgJiZcclxuICAgICAgICAgICAgbm9kZXNbc3RhcnQgLSAxXS5wYXJlbnRJZCA9PT0gcGFyZW50SWQgJiZcclxuICAgICAgICAgICAgbm9kZXNbc3RhcnQgLSAxXS5wYWdpbmcucGFnZU51bWJlciA9PT0gb2xkUGFnZU5yXHJcbiAgICAgICAgICApIHtcclxuICAgICAgICAgICAgc3RhcnQtLTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIC8vIGZpbmQgdGhlIGxhc3Qgbm9kZSBvZiB0aGUgbm9kZSdzIHBhZ2UsXHJcbiAgICAgICAgICAvLyBpbmNsdWRpbmcgYWxsIHRoZWlyIGRlc2NlbmRhbnRzXHJcbiAgICAgICAgICBsZXQgZW5kID0gbm9kZUluZGV4ICsgMTtcclxuICAgICAgICAgIHdoaWxlIChcclxuICAgICAgICAgICAgZW5kIDwgbm9kZXMubGVuZ3RoICYmXHJcbiAgICAgICAgICAgIG5vZGVzW2VuZF0ucGFyZW50SWQgPT09IHBhcmVudElkICYmXHJcbiAgICAgICAgICAgIG5vZGVzW2VuZF0ucGFnaW5nLnBhZ2VOdW1iZXIgPT09IG9sZFBhZ2VOclxyXG4gICAgICAgICAgKSB7XHJcbiAgICAgICAgICAgIGVuZCsrO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgLy8gcmVwbGFjZSBhbGwgdGhlc2Ugbm9kZXMgd2l0aCB0aGUgbmV3IG9uZXNcclxuICAgICAgICAgIG5vZGVzLnNwbGljZShzdGFydCwgZW5kIC0gc3RhcnQpO1xyXG4gICAgICAgICAgbm9kZXMuc3BsaWNlKHN0YXJ0LCAwLCAuLi4ocGFnZU5vZGVzIGFzIEVbXSkpO1xyXG4gICAgICAgICAgLy8gdXBkYXRlIHRoZSBwYXJlbnQgbm9kZSBwYWdpbmcgaW5mb1xyXG4gICAgICAgICAgcGFyZW50Tm9kZSEucGFnaW5nLnBhZ2VOdW1iZXIgPSBwYWdlLnBhZ2VOdW1iZXI7XHJcbiAgICAgICAgICB0aGlzLl9ub2RlcyQubmV4dChub2Rlcyk7XHJcbiAgICAgICAgICByZXNvbHZlKHRydWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENvbGxhcHNlIGFsbCB0aGUgbm9kZXMgaW4gdGhlIHN0b3JlLlxyXG4gICAqL1xyXG4gIHB1YmxpYyBjb2xsYXBzZUFsbCgpOiB2b2lkIHtcclxuICAgIHRoaXMuX25vZGVzJC5uZXh0KFt0aGlzLl9yYWRpeCEsIC4uLnRoaXMuX3Jvb3RzXSk7XHJcbiAgfVxyXG59XHJcbiJdfQ==
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ export * from './public-api';
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXlybWlkb24tcGFnZWQtZGF0YS1icm93c2Vycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL215cm1pZG9uL3BhZ2VkLWRhdGEtYnJvd3NlcnMvc3JjL215cm1pZG9uLXBhZ2VkLWRhdGEtYnJvd3NlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLGNBQWMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2VuZXJhdGVkIGJ1bmRsZSBpbmRleC4gRG8gbm90IGVkaXQuXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9wdWJsaWMtYXBpJztcbiJdfQ==
@@ -0,0 +1,11 @@
1
+ /*
2
+ * Public API Surface of paged-data-browsers
3
+ */
4
+ export * from './lib/components/compact-pager/compact-pager.component';
5
+ export * from './lib/components/range-view/range-view.component';
6
+ export * from './lib/components/browser-tree-node/browser-tree-node.component';
7
+ export * from './lib/services/paged-list.store';
8
+ export * from './lib/services/paged-tree.store';
9
+ export * from './lib/services/lru-cache';
10
+ export * from './lib/paged-data-browsers.module';
11
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL215cm1pZG9uL3BhZ2VkLWRhdGEtYnJvd3NlcnMvc3JjL3B1YmxpYy1hcGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLHdEQUF3RCxDQUFDO0FBQ3ZFLGNBQWMsa0RBQWtELENBQUM7QUFDakUsY0FBYyxnRUFBZ0UsQ0FBQztBQUUvRSxjQUFjLGlDQUFpQyxDQUFDO0FBQ2hELGNBQWMsaUNBQWlDLENBQUM7QUFDaEQsY0FBYywwQkFBMEIsQ0FBQztBQUV6QyxjQUFjLGtDQUFrQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIFB1YmxpYyBBUEkgU3VyZmFjZSBvZiBwYWdlZC1kYXRhLWJyb3dzZXJzXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9saWIvY29tcG9uZW50cy9jb21wYWN0LXBhZ2VyL2NvbXBhY3QtcGFnZXIuY29tcG9uZW50JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2NvbXBvbmVudHMvcmFuZ2Utdmlldy9yYW5nZS12aWV3LmNvbXBvbmVudCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb21wb25lbnRzL2Jyb3dzZXItdHJlZS1ub2RlL2Jyb3dzZXItdHJlZS1ub2RlLmNvbXBvbmVudCc7XG5cbmV4cG9ydCAqIGZyb20gJy4vbGliL3NlcnZpY2VzL3BhZ2VkLWxpc3Quc3RvcmUnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvc2VydmljZXMvcGFnZWQtdHJlZS5zdG9yZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9zZXJ2aWNlcy9scnUtY2FjaGUnO1xuXG5leHBvcnQgKiBmcm9tICcuL2xpYi9wYWdlZC1kYXRhLWJyb3dzZXJzLm1vZHVsZSc7XG4iXX0=