UNPKG

31.8 kBJavaScriptView Raw
1/**
2 * @fileoverview added by tsickle
3 * @suppress {checkTypes} checked by tsc
4 */
5import * as tslib_1 from "tslib";
6import { BehaviorSubject, } from 'rxjs';
7import { distinctUntilChanged, first, } from 'rxjs/operators';
8import { StateSwitch } from 'state-switch';
9import { _ModelMutationType, } from '../generated-schemas/';
10/**
11 * @record
12 */
13export function StoreSettings() { }
14function StoreSettings_tsickle_Closure_declarations() {
15 /** @type {?} */
16 StoreSettings.prototype.dataKey;
17 /** @type {?} */
18 StoreSettings.prototype.gqlQueryAll;
19 /** @type {?} */
20 StoreSettings.prototype.gqlSubscribe;
21}
22/**
23 * @record
24 */
25export function StoreAction() { }
26function StoreAction_tsickle_Closure_declarations() {
27 /** @type {?} */
28 StoreAction.prototype.type;
29 /** @type {?} */
30 StoreAction.prototype.node;
31}
32// unsupported: template constraints.
33// unsupported: template constraints.
34// unsupported: template constraints.
35/**
36 * @abstract
37 * @template T, AllItemsQuery, SubscribeItemSubscription
38 */
39export class Store {
40 /**
41 * @param {?} db
42 * @param {?} settings
43 */
44 constructor(db, settings) {
45 this.db = db;
46 this.settings = settings;
47 this.log = db.log;
48 this.log.verbose('Store', 'constructor()');
49 this.itemList$ = new BehaviorSubject([]);
50 this.itemList = this.itemList$.asObservable().pipe(distinctUntilChanged());
51 this.state = new StateSwitch('Store', this.log);
52 /**
53 * This subscription is for all the life cycle of Store,
54 * we will never need to unsubscribe it.
55 */
56 this.db.apollo.subscribe(apollo => this.refresh(apollo));
57 }
58 /**
59 * @return {?}
60 */
61 open() {
62 return tslib_1.__awaiter(this, void 0, void 0, function* () {
63 this.log.verbose('Store', 'open()');
64 if (!this.settings) {
65 throw new Error('Store.open() need `this.settings` to be set first!');
66 }
67 if (!this.apollo) {
68 throw new Error('Store.open() apollo not available!');
69 }
70 this.state.on('pending');
71 const /** @type {?} */ hostieQuery = this.apollo.watchQuery({
72 query: this.settings.gqlQueryAll,
73 });
74 this.initSubscribeToMore(hostieQuery);
75 this.itemListSubscription = this.initSubscription(hostieQuery);
76 // await this.initQuery()
77 // await future
78 });
79 }
80 /**
81 * @param {?} apollo
82 * @return {?}
83 */
84 refresh(apollo) {
85 return tslib_1.__awaiter(this, void 0, void 0, function* () {
86 this.log.verbose('Store', 'refresh(%s)', apollo && apollo.constructor.name);
87 /**
88 * 1. close the existing apollo if it is availble
89 */
90 if (this.apollo) {
91 yield this.close();
92 }
93 this.apollo = apollo;
94 /**
95 * 2. reopen only if the new apollo is available
96 */
97 if (apollo) {
98 yield this.open();
99 }
100 });
101 }
102 /**
103 * @return {?}
104 */
105 close() {
106 return tslib_1.__awaiter(this, void 0, void 0, function* () {
107 this.log.verbose('Store', 'close()');
108 this.state.off('pending');
109 if (this.itemListSubscription) {
110 this.itemListSubscription.unsubscribe();
111 }
112 this.state.off(true);
113 });
114 }
115 /**
116 * @param {?} itemQuery
117 * @return {?}
118 */
119 initSubscribeToMore(itemQuery) {
120 this.log.verbose('Store', 'initSubscribeToMore(itemQuery)');
121 itemQuery.subscribeToMore({
122 document: this.settings.gqlSubscribe,
123 updateQuery: (prev, { subscriptionData }) => {
124 const /** @type {?} */ data = subscriptionData.data;
125 const /** @type {?} */ dataKey = this.settings.dataKey;
126 // if (!data || !data[dataKey]) {
127 if (!data || !(dataKey in data)) {
128 return prev;
129 }
130 const /** @type {?} */ item = data[dataKey];
131 this.log.silly('Store', 'init() subscribeToMore() updateQuery() prev=%s', JSON.stringify(prev));
132 this.log.silly('Store', 'init() subscribeToMore() updateQuery() data=%s', JSON.stringify(data));
133 const /** @type {?} */ node = item.node;
134 const /** @type {?} */ previousValues = item.previousValues;
135 const /** @type {?} */ newData = /** @type {?} */ (Object.assign({}, prev));
136 newData[dataKey] = this.mutationReducer(newData[dataKey], {
137 type: item.mutation,
138 // MutationType: CREATED / DELETED / UPDATED
139 node: node || previousValues,
140 });
141 return newData;
142 },
143 onError: error => {
144 this.log.warn('Store', 'initSubscribeToMore() onError() %s', JSON.stringify(error));
145 },
146 });
147 }
148 /**
149 * @param {?} itemQuery
150 * @return {?}
151 */
152 initSubscription(itemQuery) {
153 this.log.verbose('Store', 'initSubscription(itemQuery)');
154 const /** @type {?} */ sub = /** @type {?} */ (itemQuery.subscribe(({ data }) => {
155 this.log.silly('Store', 'initSubscription() itemQuery.subscribe() data[dataKey].length=%d', data[this.settings.dataKey].length);
156 this.itemList$.next([...data[this.settings.dataKey]]);
157 /**
158 * issue #12
159 *
160 * wait subscription to be ready before open() returns
161 */
162 this.state.on(true);
163 }));
164 return sub;
165 }
166 /**
167 * @param {?=} state
168 * @param {?=} action
169 * @return {?}
170 */
171 mutationReducer(state = [], action) {
172 this.log.verbose('Store', 'mutationReducer(state.length=%d, action.type=%s)', state.length, action.type);
173 switch (action.type) {
174 case _ModelMutationType.CREATED:
175 state.push(action.node);
176 break;
177 case _ModelMutationType.UPDATED:
178 for (let /** @type {?} */ i = state.length; i--;) {
179 if (state[i].id === action.node.id) {
180 state[i] = action.node;
181 break;
182 }
183 }
184 break;
185 case _ModelMutationType.DELETED:
186 for (let /** @type {?} */ i = state.length; i--;) {
187 if (state[i].id === action.node.id) {
188 state.splice(i, 1);
189 break;
190 }
191 }
192 break;
193 default:
194 throw new Error('unknown action.type:' + action.type);
195 }
196 return state;
197 }
198 /**
199 * @param {?} mutationType
200 * @param {?} mutationDataKey
201 * @return {?}
202 */
203 mutationUpdateFnFactory(mutationType, mutationDataKey) {
204 this.log.verbose('Store', 'mutationUpdateFnFactory(mutationType=%s, mutationDataKey=%s)', mutationType, mutationDataKey);
205 return (proxy, { data }) => {
206 this.log.verbose('Store', 'mutationUpdateFnFactory(mutationType=%s, mutationDataKey=%s) (proxy, {data})', mutationType, mutationDataKey);
207 if (!data) {
208 this.log.verbose('Store', 'mutationUpdateFnFactory() (proxy, {data}) data empty???');
209 return;
210 }
211 let /** @type {?} */ cachedData = null;
212 try {
213 cachedData = proxy.readQuery({ query: this.settings.gqlQueryAll });
214 }
215 catch (/** @type {?} */ e) {
216 this.log.verbose('Store', 'mutationUpdateFnFactory(mutationType=%s, mutationDataKey=%s) (proxy, {data}), %s', mutationType, mutationDataKey, 'call proxy.readQuery() got exceptoin. it mostly like there is no query had been executed before.');
217 }
218 if (!cachedData) {
219 this.log.verbose('Store', 'mutationUpdateFnFactory(mutationType=%s, mutationDataKey=%s) (proxy, {data})proxy.readQuery() return empty???', mutationType, mutationDataKey);
220 return;
221 }
222 const /** @type {?} */ mutationNode = data[mutationDataKey];
223 /**
224 * Combinate all the data to produce a new data
225 */
226 const /** @type {?} */ newData = /** @type {?} */ (Object.assign({}, /** @type {?} */ (cachedData)));
227 newData[this.settings.dataKey] = this.mutationReducer(newData[this.settings.dataKey], {
228 type: mutationType,
229 node: mutationNode,
230 });
231 proxy.writeQuery({ query: this.settings.gqlQueryAll, data: newData });
232 };
233 }
234 /**
235 * CRUD:
236 * 1. create()
237 * 2. read()
238 * 3. update()
239 * 4. delete()
240 * @param {?} id
241 * @return {?}
242 */
243 read(id) {
244 return tslib_1.__awaiter(this, void 0, void 0, function* () {
245 this.log.verbose('Store', 'read(id=%s)', id);
246 yield this.state.ready();
247 const /** @type {?} */ itemList = yield this.itemList.pipe(first()).toPromise();
248 const /** @type {?} */ result = itemList.filter(i => i['id'] === id);
249 if (result.length !== 1) {
250 throw new Error(`Store.read(id=${id}) not found!`);
251 }
252 return result[0];
253 });
254 }
255}
256function Store_tsickle_Closure_declarations() {
257 /** @type {?} */
258 Store.prototype.state;
259 /** @type {?} */
260 Store.prototype.itemListSubscription;
261 /** @type {?} */
262 Store.prototype.apollo;
263 /** @type {?} */
264 Store.prototype.log;
265 /** @type {?} */
266 Store.prototype.itemList$;
267 /** @type {?} */
268 Store.prototype.itemList;
269 /** @type {?} */
270 Store.prototype.db;
271 /** @type {?} */
272 Store.prototype.settings;
273 /**
274 * TO BE IMPLEMENT in the sub class
275 * @abstract
276 * @param {?} id
277 * @return {?}
278 */
279 Store.prototype.delete = function (id) { };
280 /**
281 * @abstract
282 * @param {?} newItem
283 * @return {?}
284 */
285 Store.prototype.create = function (newItem) { };
286 /**
287 * @abstract
288 * @param {?} id
289 * @param {?} props
290 * @return {?}
291 */
292 Store.prototype.update = function (id, props) { };
293}
294
295//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmUuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AY2hhdGllL2RiLyIsInNvdXJjZXMiOlsic3JjL3N0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQ0EsT0FBTyxFQUNMLGVBQWUsR0FHaEIsTUFBNEIsTUFBTSxDQUFBO0FBQ25DLE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIsS0FBSyxHQUNOLE1BQThCLGdCQUFnQixDQUFBO0FBRS9DLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTyxjQUFjLENBQUE7QUFFM0MsT0FBTyxFQUNMLGtCQUFrQixHQUNuQixNQUE0Qix1QkFBdUIsQ0FBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBdUJwRCxNQUFNOzs7OztJQWVKLFlBQ1ksRUFBWSxFQUNaLFFBQXVCO1FBRHZCLE9BQUUsR0FBRixFQUFFLENBQVU7UUFDWixhQUFRLEdBQVIsUUFBUSxDQUFlO1FBRWpDLElBQUksQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQTtRQUVqQixJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsZUFBZSxDQUFDLENBQUE7UUFFMUMsSUFBSSxDQUFDLFNBQVMsR0FBSSxJQUFJLGVBQWUsQ0FBUSxFQUFFLENBQUMsQ0FBQTtRQUNoRCxJQUFJLENBQUMsUUFBUSxHQUFLLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxFQUFFLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUMsQ0FBQTtRQUU1RSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksV0FBVyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUE7Ozs7O1FBTS9DLElBQUksQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQTtLQUV6RDs7OztJQUVhLElBQUk7O1lBQ2hCLElBQUks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S0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN4QixNQUFNLElBQUksS0FBSyxDQUFDLGlCQUFpQixFQUFFLGNBQWMsQ0FBQyxDQUFBO2FBQ25EO1lBQ0QsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQTs7O0NBY25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRG9jdW1lbnROb2RlIH0gZnJvbSAnZ3JhcGhxbCdcbmltcG9ydCB7XG4gIEJlaGF2aW9yU3ViamVjdCxcbiAgT2JzZXJ2YWJsZSxcbiAgU3Vic2NyaXB0aW9uLFxufSAgICAgICAgICAgICAgICAgICAgICAgZnJvbSAncnhqcydcbmltcG9ydCB7XG4gIGRpc3RpbmN0VW50aWxDaGFuZ2VkLFxuICBmaXJzdCxcbn0gICAgICAgICAgICAgICAgICAgICAgICAgZnJvbSAncnhqcy9vcGVyYXRvcnMnXG5cbmltcG9ydCB7IFN0YXRlU3dpdGNoIH0gIGZyb20gJ3N0YXRlLXN3aXRjaCdcblxuaW1wb3J0IHtcbiAgX01vZGVsTXV0YXRpb25UeXBlLFxufSAgICAgICAgICAgICAgICAgICAgICAgZnJvbSAnLi4vZ2VuZXJhdGVkLXNjaGVtYXMvJ1xuXG5pbXBvcnQge1xuICBBcG9sbG8sXG4gIERiLFxuICBNdXRhdGlvblVwZGF0ZXJGbixcbiAgT2JzZXJ2YWJsZVF1ZXJ5LFxufSAgICAgICAgICAgICAgICAgICAgIGZyb20gJy4vZGInXG5pbXBvcnQge1xuICBsb2csXG59ICAgICAgICAgICAgICAgICAgICAgZnJvbSAnLi9jb25maWcnXG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RvcmVTZXR0aW5ncyB7XG4gIGRhdGFLZXk6ICAgICAgc3RyaW5nLFxuICBncWxRdWVyeUFsbDogIERvY3VtZW50Tm9kZSxcbiAgZ3FsU3Vic2NyaWJlOiBEb2N1bWVudE5vZGUsXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RvcmVBY3Rpb24ge1xuICB0eXBlOiBfTW9kZWxNdXRhdGlvblR5cGUsXG4gIG5vZGU6IGFueSxcbn1cblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFN0b3JlPFxuICBUIGV4dGVuZHMgeyBbaWR4OiBzdHJpbmddOiBhbnkgfSxcbiAgQWxsSXRlbXNRdWVyeSBleHRlbmRzIHsgW2lkeDogc3RyaW5nXTogYW55IH0sXG4gIFN1YnNjcmliZUl0ZW1TdWJzY3JpcHRpb24gZXh0ZW5kcyB7IFtpZHg6IHN0cmluZ106IGFueSB9XG4+IHtcbiAgcHJvdGVjdGVkIHN0YXRlOiBTdGF0ZVN3aXRjaFxuXG4gIHByaXZhdGUgaXRlbUxpc3RTdWJzY3JpcHRpb24/OiBTdWJzY3JpcHRpb25cblxuICBwcm90ZWN0ZWQgYXBvbGxvPzogIEFwb2xsb1xuICBwcm90ZWN0ZWQgbG9nOiAgICAgIHR5cGVvZiBsb2dcblxuICBwcm90ZWN0ZWQgaXRlbUxpc3QkOiAgICBCZWhhdmlvclN1YmplY3Q8IFRbXSA+XG4gIHB1YmxpYyAgICBpdGVtTGlzdDogICAgIE9ic2VydmFibGU8IFRbXSA+XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIGRiOiAgICAgICBEYixcbiAgICBwcm90ZWN0ZWQgc2V0dGluZ3M6IFN0b3JlU2V0dGluZ3MsXG4gICkge1xuICAgIHRoaXMubG9nID0gZGIubG9nXG5cbiAgICB0aGlzLmxvZy52ZXJib3NlKCdTdG9yZScsICdjb25zdHJ1Y3RvcigpJylcblxuICAgIHRoaXMuaXRlbUxpc3QkICA9IG5ldyBCZWhhdmlvclN1YmplY3Q8IFRbXSA+KFtdKVxuICAgIHRoaXMuaXRlbUxpc3QgICA9IHRoaXMuaXRlbUxpc3QkLmFzT2JzZXJ2YWJsZSgpLnBpcGUoZGlzdGluY3RVbnRpbENoYW5nZWQoKSlcblxuICAgIHRoaXMuc3RhdGUgPSBuZXcgU3RhdGVTd2l0Y2goJ1N0b3JlJywgdGhpcy5sb2cpXG5cbiAgICAvKipcbiAgICAgKiBUaGlzIHN1YnNjcmlwdGlvbiBpcyBmb3IgYWxsIHRoZSBsaWZlIGN5Y2xlIG9mIFN0b3JlLFxuICAgICAqIHdlIHdpbGwgbmV2ZXIgbmVlZCB0byB1bnN1YnNjcmliZSBpdC5cbiAgICAgKi9cbiAgICB0aGlzLmRiLmFwb2xsby5zdWJzY3JpYmUoYXBvbGxvID0+IHRoaXMucmVmcmVzaChhcG9sbG8pKVxuXG4gIH1cblxuICBwcml2YXRlIGFzeW5jIG9wZW4oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5sb2cudmVyYm9zZSgnU3RvcmUnLCAnb3BlbigpJylcbiAgICBpZiAoIXRoaXMuc2V0dGluZ3MpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignU3RvcmUub3BlbigpIG5lZWQgYHRoaXMuc2V0dGluZ3NgIHRvIGJlIHNldCBmaXJzdCEnKVxuICAgIH1cblxuICAgIGlmICghdGhpcy5hcG9sbG8pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignU3RvcmUub3BlbigpIGFwb2xsbyBub3QgYXZhaWxhYmxlIScpXG4gICAgfVxuXG4gICAgdGhpcy5zdGF0ZS5vbigncGVuZGluZycpXG5cbiAgICBjb25zdCBob3N0aWVRdWVyeSA9IHRoaXMuYXBvbGxvLndhdGNoUXVlcnk8QWxsSXRlbXNRdWVyeT4oe1xuICAgICAgcXVlcnk6IHRoaXMuc2V0dGluZ3MuZ3FsUXVlcnlBbGwsXG4gICAgfSlcblxuICAgIHRoaXMuaW5pdFN1YnNjcmliZVRvTW9yZShob3N0aWVRdWVyeSlcbiAgICB0aGlzLml0ZW1MaXN0U3Vic2NyaXB0aW9uID0gdGhpcy5pbml0U3Vic2NyaXB0aW9uKGhvc3RpZVF1ZXJ5KVxuXG4gICAgLy8gYXdhaXQgdGhpcy5pbml0UXVlcnkoKVxuICAgIC8vIGF3YWl0IGZ1dHVyZVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyByZWZyZXNoKGFwb2xsbzogQXBvbGxvIHwgdW5kZWZpbmVkKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5sb2cudmVyYm9zZSgnU3RvcmUnLCAncmVmcmVzaCglcyknLCBhcG9sbG8gJiYgYXBvbGxvLmNvbnN0cnVjdG9yLm5hbWUpXG5cbiAgICAvKipcbiAgICAgKiAxLiBjbG9zZSB0aGUgZXhpc3RpbmcgYXBvbGxvIGlmIGl0IGlzIGF2YWlsYmxlXG4gICAgICovXG4gICAgaWYgKHRoaXMuYXBvbGxvKSB7XG4gICAgICBhd2FpdCB0aGlzLmNsb3NlKClcbiAgICB9XG5cbiAgICB0aGlzLmFwb2xsbyA9IGFwb2xsb1xuXG4gICAgLyoqXG4gICAgICogMi4gcmVvcGVuIG9ubHkgaWYgdGhlIG5ldyBhcG9sbG8gaXMgYXZhaWxhYmxlXG4gICAgICovXG4gICAgaWYgKGFwb2xsbykge1xuICAgICAgYXdhaXQgdGhpcy5vcGVuKClcbiAgICB9XG5cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY2xvc2UoKTogICBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmxvZy52ZXJib3NlKCdTdG9yZScsICdjbG9zZSgpJylcblxuICAgIHRoaXMuc3RhdGUub2ZmKCdwZW5kaW5nJylcblxuICAgIGlmICh0aGlzLml0ZW1MaXN0U3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLml0ZW1MaXN0U3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKClcbiAgICB9XG5cbiAgICB0aGlzLnN0YXRlLm9mZih0cnVlKVxuXG4gIH1cblxuICBwcml2YXRlIGluaXRTdWJzY3JpYmVUb01vcmUoaXRlbVF1ZXJ5OiBPYnNlcnZhYmxlUXVlcnk8QWxsSXRlbXNRdWVyeT4pOiB2b2lkIHtcbiAgICB0aGlzLmxvZy52ZXJib3NlKCdTdG9yZScsICdpbml0U3Vic2NyaWJlVG9Nb3JlKGl0ZW1RdWVyeSknKVxuICAgIGl0ZW1RdWVyeS5zdWJzY3JpYmVUb01vcmUoe1xuICAgICAgZG9jdW1lbnQ6IHRoaXMuc2V0dGluZ3MuZ3FsU3Vic2NyaWJlLFxuICAgICAgdXBkYXRlUXVlcnk6IChwcmV2LCB7IHN1YnNjcmlwdGlvbkRhdGEgfSkgPT4ge1xuICAgICAgICBjb25zdCBkYXRhOiBTdWJzY3JpYmVJdGVtU3Vic2NyaXB0aW9uID0gc3Vic2NyaXB0aW9uRGF0YS5kYXRhXG5cbiAgICAgICAgY29uc3QgZGF0YUtleSA9IHRoaXMuc2V0dGluZ3MuZGF0YUtleVxuICAgICAgICAvLyBpZiAoIWRhdGEgfHwgIWRhdGFbZGF0YUtleV0pIHtcbiAgICAgICAgaWYgKCFkYXRhIHx8ICEoZGF0YUtleSBpbiBkYXRhKSkge1xuICAgICAgICAgIHJldHVybiBwcmV2XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBpdGVtID0gZGF0YVtkYXRhS2V5XVxuXG4gICAgICAgIHRoaXMubG9nLnNpbGx5KCdTdG9yZScsICdpbml0KCkgc3Vic2NyaWJlVG9Nb3JlKCkgdXBkYXRlUXVlcnkoKSBwcmV2PSVzJywgSlNPTi5zdHJpbmdpZnkocHJldikpXG4gICAgICAgIHRoaXMubG9nLnNpbGx5KCdTdG9yZScsICdpbml0KCkgc3Vic2NyaWJlVG9Nb3JlKCkgdXBkYXRlUXVlcnkoKSBkYXRhPSVzJywgSlNPTi5zdHJpbmdpZnkoZGF0YSkpXG5cbiAgICAgICAgY29uc3Qgbm9kZSAgICAgICAgICAgID0gaXRlbS5ub2RlXG4gICAgICAgIGNvbnN0IHByZXZpb3VzVmFsdWVzICA9IGl0ZW0ucHJldmlvdXNWYWx1ZXNcblxuICAgICAgICBjb25zdCBuZXdEYXRhID0ge1xuICAgICAgICAgIC4uLnByZXYsXG4gICAgICAgIH0gYXMge1xuICAgICAgICAgIFtpZHg6IHN0cmluZ106IGFueSxcbiAgICAgICAgfVxuXG4gICAgICAgIG5ld0RhdGFbZGF0YUtleV0gPSB0aGlzLm11dGF0aW9uUmVkdWNlcihcbiAgICAgICAgICBuZXdEYXRhW2RhdGFLZXldLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IGl0ZW0ubXV0YXRpb24sICAgICAgICAgIC8vIE11dGF0aW9uVHlwZTogQ1JFQVRFRCAvIERFTEVURUQgLyBVUERBVEVEXG4gICAgICAgICAgICBub2RlOiBub2RlIHx8IHByZXZpb3VzVmFsdWVzLCAvLyB3aGVuIERFTEVURSwgbm9kZSB3aWxsIGJlIG51bGwgYW5kIHdlIHVzZSBwcmV2aW91c1ZhbHVlc1xuICAgICAgICAgIH0sXG4gICAgICAgIClcblxuICAgICAgICByZXR1cm4gbmV3RGF0YVxuICAgICAgfSxcbiAgICAgIG9uRXJyb3I6IGVycm9yID0+IHtcbiAgICAgICAgdGhpcy5sb2cud2FybignU3RvcmUnLCAnaW5pdFN1YnNjcmliZVRvTW9yZSgpIG9uRXJyb3IoKSAlcycsIEpTT04uc3RyaW5naWZ5KGVycm9yKSlcbiAgICAgIH0sXG4gICAgfSlcbiAgfVxuXG4gIHByaXZhdGUgaW5pdFN1YnNjcmlwdGlvbihpdGVtUXVlcnk6IE9ic2VydmFibGVRdWVyeTxBbGxJdGVtc1F1ZXJ5Pik6IFN1YnNjcmlwdGlvbiB7XG4gICAgdGhpcy5sb2cudmVyYm9zZSgnU3RvcmUnLCAnaW5pdFN1YnNjcmlwdGlvbihpdGVtUXVlcnkpJylcblxuICAgIGNvbnN0IHN1YiA9IGl0ZW1RdWVyeS5zdWJzY3JpYmUoXG4gICAgICAoeyBkYXRhIH0pID0+IHtcbiAgICAgICAgdGhpcy5sb2cuc2lsbHkoJ1N0b3JlJywgJ2luaXRTdWJzY3JpcHRpb24oKSBpdGVtUXVlcnkuc3Vic2NyaWJlKCkgZGF0YVtkYXRhS2V5XS5sZW5ndGg9JWQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhW3RoaXMuc2V0dGluZ3MuZGF0YUtleV0ubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgdGhpcy5pdGVtTGlzdCQubmV4dChbLi4uZGF0YVt0aGlzLnNldHRpbmdzLmRhdGFLZXldXSlcblxuICAgICAgICAvKipcbiAgICAgICAgICogaXNzdWUgIzEyXG4gICAgICAgICAqXG4gICAgICAgICAqIHdhaXQgc3Vic2NyaXB0aW9uIHRvIGJlIHJlYWR5IGJlZm9yZSBvcGVuKCkgcmV0dXJuc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5zdGF0ZS5vbih0cnVlKVxuICAgICAgfSxcbiAgICApIGFzIFN1YnNjcmlwdGlvblxuXG4gICAgcmV0dXJuIHN1YlxuICB9XG5cbiAgcHJpdmF0ZSBtdXRhdGlvblJlZHVjZXIoXG4gICAgICBzdGF0ZTogIGFueVtdID0gW10sXG4gICAgICBhY3Rpb246IFN0b3JlQWN0aW9uLFxuICApOiBhbnlbXSB7XG4gICAgdGhpcy5sb2cudmVyYm9zZSgnU3RvcmUnLCAnbXV0YXRpb25SZWR1Y2VyKHN0YXRlLmxlbmd0aD0lZCwgYWN0aW9uLnR5cGU9JXMpJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGUubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb24udHlwZSxcbiAgICAgICAgICAgICAgICApXG4gICAgc3dpdGNoIChhY3Rpb24udHlwZSkge1xuICAgICAgY2FzZSBfTW9kZWxNdXRhdGlvblR5cGUuQ1JFQVRFRDpcbiAgICAgICAgc3RhdGUucHVzaChhY3Rpb24ubm9kZSlcbiAgICAgICAgYnJlYWtcblxuICAgICAgY2FzZSBfTW9kZWxNdXRhdGlvblR5cGUuVVBEQVRFRDpcbiAgICAgICAgZm9yIChsZXQgaSA9IHN0YXRlLmxlbmd0aDsgaS0tOykge1xuICAgICAgICAgIGlmIChzdGF0ZVtpXS5pZCA9PT0gYWN0aW9uLm5vZGUuaWQpIHtcbiAgICAgICAgICAgIHN0YXRlW2ldID0gYWN0aW9uLm5vZGVcbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGJyZWFrXG5cbiAgICAgIGNhc2UgX01vZGVsTXV0YXRpb25UeXBlLkRFTEVURUQ6XG4gICAgICAgIGZvciAobGV0IGkgPSBzdGF0ZS5sZW5ndGg7IGktLTspIHtcbiAgICAgICAgICBpZiAoc3RhdGVbaV0uaWQgPT09IGFjdGlvbi5ub2RlLmlkKSB7XG4gICAgICAgICAgICBzdGF0ZS5zcGxpY2UoaSwgMSlcbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGJyZWFrXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigndW5rbm93biBhY3Rpb24udHlwZTonICsgYWN0aW9uLnR5cGUpXG4gICAgfVxuXG4gICAgcmV0dXJuIHN0YXRlXG5cbiAgfVxuXG4gIHByb3RlY3RlZCBtdXRhdGlvblVwZGF0ZUZuRmFjdG9yeShcbiAgICBtdXRhdGlvblR5cGU6ICAgICBfTW9kZWxNdXRhdGlvblR5cGUsXG4gICAgbXV0YXRpb25EYXRhS2V5OiAgc3RyaW5nLFxuICApOiBNdXRhdGlvblVwZGF0ZXJGbjxUPiB7XG4gICAgdGhpcy5sb2cudmVyYm9zZSgnU3RvcmUnLCAnbXV0YXRpb25VcGRhdGVGbkZhY3RvcnkobXV0YXRpb25UeXBlPSVzLCBtdXRhdGlvbkRhdGFLZXk9JXMpJywgbXV0YXRpb25UeXBlLCBtdXRhdGlvbkRhdGFLZXkpXG5cbiAgICByZXR1cm4gKHByb3h5LCB7IGRhdGEgfSkgPT4ge1xuICAgICAgdGhpcy5sb2cudmVyYm9zZSgnU3RvcmUnLCAnbXV0YXRpb25VcGRhdGVGbkZhY3RvcnkobXV0YXRpb25UeXBlPSVzLCBtdXRhdGlvbkRhdGFLZXk9JXMpIChwcm94eSwge2RhdGF9KScsIG11dGF0aW9uVHlwZSwgbXV0YXRpb25EYXRhS2V5KVxuXG4gICAgICBpZiAoIWRhdGEpIHtcbiAgICAgICAgdGhpcy5sb2cudmVyYm9zZSgnU3RvcmUnLCAnbXV0YXRpb25VcGRhdGVGbkZhY3RvcnkoKSAocHJveHksIHtkYXRhfSkgZGF0YSBlbXB0eT8/PycpXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBsZXQgY2FjaGVkRGF0YTogQWxsSXRlbXNRdWVyeSB8IG51bGwgPSBudWxsXG4gICAgICB0cnkge1xuICAgICAgICBjYWNoZWREYXRhID0gcHJveHkucmVhZFF1ZXJ5PEFsbEl0ZW1zUXVlcnk+KHsgcXVlcnk6IHRoaXMuc2V0dGluZ3MuZ3FsUXVlcnlBbGwgfSlcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhpcy5sb2cudmVyYm9zZSgnU3RvcmUnLCAnbXV0YXRpb25VcGRhdGVGbkZhY3RvcnkobXV0YXRpb25UeXBlPSVzLCBtdXRhdGlvbkRhdGFLZXk9JXMpIChwcm94eSwge2RhdGF9KSwgJXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0aW9uVHlwZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGlvbkRhdGFLZXksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NhbGwgcHJveHkucmVhZFF1ZXJ5KCkgZ290IGV4Y2VwdG9pbi4gaXQgbW9zdGx5IGxpa2UgdGhlcmUgaXMgbm8gcXVlcnkgaGFkIGJlZW4gZXhlY3V0ZWQgYmVmb3JlLicpXG4gICAgICB9XG5cbiAgICAgIGlmICghY2FjaGVkRGF0YSkge1xuICAgICAgICB0aGlzLmxvZy52ZXJib3NlKCdTdG9yZScsICdtdXRhdGlvblVwZGF0ZUZuRmFjdG9yeShtdXRhdGlvblR5cGU9JXMsIG11dGF0aW9uRGF0YUtleT0lcykgKHByb3h5LCB7ZGF0YX0pcHJveHkucmVhZFF1ZXJ5KCkgcmV0dXJuIGVtcHR5Pz8/JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGlvblR5cGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRpb25EYXRhS2V5LFxuICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgY29uc3QgbXV0YXRpb25Ob2RlID0gZGF0YVttdXRhdGlvbkRhdGFLZXldXG5cbiAgICAgIC8qKlxuICAgICAgICogQ29tYmluYXRlIGFsbCB0aGUgZGF0YSB0byBwcm9kdWNlIGEgbmV3IGRhdGFcbiAgICAgICAqL1xuICAgICAgY29uc3QgbmV3RGF0YSA9IHtcbiAgICAgICAgLi4uY2FjaGVkRGF0YSBhcyBPYmplY3QsXG4gICAgICB9IGFzIHtcbiAgICAgICAgW2lkeDogc3RyaW5nXTogYW55LFxuICAgICAgfVxuICAgICAgbmV3RGF0YVt0aGlzLnNldHRpbmdzLmRhdGFLZXldID0gdGhpcy5tdXRhdGlvblJlZHVjZXIoXG4gICAgICAgIG5ld0RhdGFbdGhpcy5zZXR0aW5ncy5kYXRhS2V5XSxcbiAgICAgICAge1xuICAgICAgICAgIHR5cGU6IG11dGF0aW9uVHlwZSxcbiAgICAgICAgICBub2RlOiBtdXRhdGlvbk5vZGUsXG4gICAgICAgIH0sXG4gICAgICApXG5cbiAgICAgIHByb3h5LndyaXRlUXVlcnkoeyBxdWVyeTogdGhpcy5zZXR0aW5ncy5ncWxRdWVyeUFsbCwgZGF0YTogbmV3RGF0YSB9KVxuXG4gICAgfVxuICB9XG5cbiAgLy8gcHJpdmF0ZSBhc3luYyBpbml0UXVlcnkoKTogUHJvbWlzZTx2b2lkPiB7XG4gIC8vICAgdGhpcy5sb2cudmVyYm9zZSgnU3RvcmUnLCAnaW5pdFF1ZXJ5KCknKVxuICAvLyAgIGF3YWl0IHRoaXMuZGIuYXBvbGxvLnF1ZXJ5PEFsbEhvc3RpZXNRdWVyeT4oe1xuICAvLyAgICAgcXVlcnk6IEdRTF9RVUVSWV9BTExfSE9TVElFUyxcbiAgLy8gICB9KVxuICAvLyAgIC50aGVuKHggPT4geC5kYXRhLmFsbEhvc3RpZXMpXG4gIC8vICAgLnRoZW4oaG9zdGllTGlzdCA9PiB7XG4gIC8vICAgICBjb25zdCBxdWVyeUl0ZW1NYXA6IEhvc3RpZU1hcCA9IHt9XG4gIC8vICAgICBmb3IgKGNvbnN0IGhvc3RpZSBvZiBob3N0aWVMaXN0KSB7XG4gIC8vICAgICAgIHF1ZXJ5SXRlbU1hcFtob3N0aWUuaWRdID0gaG9zdGllXG4gIC8vICAgICB9XG4gIC8vICAgICB0aGlzLiRpdGVtTWFwLm5leHQocXVlcnlJdGVtTWFwKVxuICAvLyAgIH0pXG4gIC8vIH1cblxuICAvKipcbiAgICogQ1JVRDpcbiAgICogMS4gY3JlYXRlKClcbiAgICogMi4gcmVhZCgpXG4gICAqIDMuIHVwZGF0ZSgpXG4gICAqIDQuIGRlbGV0ZSgpXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcmVhZChpZDogc3RyaW5nKTogUHJvbWlzZTxUPiB7XG4gICAgdGhpcy5sb2cudmVyYm9zZSgnU3RvcmUnLCAncmVhZChpZD0lcyknLCBpZClcblxuICAgIGF3YWl0IHRoaXMuc3RhdGUucmVhZHkoKVxuXG4gICAgY29uc3QgaXRlbUxpc3QgPSBhd2FpdCB0aGlzLml0ZW1MaXN0LnBpcGUoZmlyc3QoKSkudG9Qcm9taXNlKClcblxuICAgIGNvbnN0IHJlc3VsdCA9IGl0ZW1MaXN0LmZpbHRlcihpID0+IGlbJ2lkJ10gPT09IGlkKVxuICAgIGlmIChyZXN1bHQubGVuZ3RoICE9PSAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFN0b3JlLnJlYWQoaWQ9JHtpZH0pIG5vdCBmb3VuZCFgKVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0WzBdXG4gIH1cblxuICAvKipcbiAgICogVE8gQkUgSU1QTEVNRU5UIGluIHRoZSBzdWIgY2xhc3NcbiAgICovXG4gIHB1YmxpYyBhYnN0cmFjdCBhc3luYyBkZWxldGUoaWQ6IHN0cmluZyk6ICAgICAgICAgICBQcm9taXNlPFQ+XG4gIHB1YmxpYyBhYnN0cmFjdCBhc3luYyBjcmVhdGUobmV3SXRlbTogUGFydGlhbDxUPik6ICBQcm9taXNlPFQ+XG4gIHB1YmxpYyBhYnN0cmFjdCBhc3luYyB1cGRhdGUgKFxuICAgIGlkOiAgICAgc3RyaW5nLFxuICAgIHByb3BzOiAgVCxcbiAgKTogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByb21pc2U8VD5cblxuICAvLyBzZWFyY2g6IChjb25kOiBhbnkpID0+IFByb21pc2U8W1RdPixcbn1cbiJdfQ==
\No newline at end of file