@sambath999/localize-token 12.3.1 → 12.3.2

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,270 @@
1
+ import { __awaiter } from "tslib";
2
+ import { HttpErrorResponse } from "@angular/common/http";
3
+ import { takeUntil, catchError, throwError } from "rxjs";
4
+ import { LocalizeToken, waitFor } from "../localize.token";
5
+ class LocalizeApiHelper {
6
+ constructor() {
7
+ this.defaultRetryOptions = {
8
+ connectionError: {
9
+ message: 'Connection error occurred. Please wait',
10
+ blockScreen: true,
11
+ blockScreenZIndex: 10000
12
+ }
13
+ };
14
+ }
15
+ performRetry(options) {
16
+ return __awaiter(this, void 0, void 0, function* () {
17
+ let attempts = 0;
18
+ let lastError;
19
+ let consoleCount = 0;
20
+ // Merge default retry options with provided options
21
+ options = Object.assign(Object.assign({}, this.defaultRetryOptions), options);
22
+ let styleElement;
23
+ while (attempts < options.maxRetries()) {
24
+ try {
25
+ const result = yield options.callback();
26
+ this.removeBlocker(styleElement);
27
+ return result;
28
+ }
29
+ catch (error) {
30
+ lastError = error;
31
+ if (consoleCount >= 7) {
32
+ console.clear();
33
+ consoleCount = 0;
34
+ }
35
+ if (options.retryUnless && !options.retryUnless(error))
36
+ throw error; // If the error should not be retried, rethrow it
37
+ // Handle connection error
38
+ styleElement = yield this.onConnectionError(options, error);
39
+ if (options.onError)
40
+ yield this.invokeHook(options.onError.bind(this, error));
41
+ if (attempts >= options.maxRetries() - 1)
42
+ throw error;
43
+ attempts++;
44
+ consoleCount++;
45
+ console.warn(`Attempt ${attempts} failed. Retrying...`, error);
46
+ yield waitFor(options.delay);
47
+ }
48
+ }
49
+ console.warn(`Failed after ${options.maxRetries} attempts`);
50
+ throw lastError;
51
+ });
52
+ }
53
+ performRequestWithRetry(options, config, performRequest) {
54
+ var _a, _b, _c, _d;
55
+ return __awaiter(this, void 0, void 0, function* () {
56
+ const retryUnless = ((_a = config.retryOptions) === null || _a === void 0 ? void 0 : _a.retryFunction)
57
+ || this.isConnectionError;
58
+ return yield this.performRetry({
59
+ connectionError: (_b = config.retryOptions) === null || _b === void 0 ? void 0 : _b.onConnectionError,
60
+ maxRetries: () => { var _a, _b; return (_b = (_a = config.retryOptions) === null || _a === void 0 ? void 0 : _a.maxRetries) !== null && _b !== void 0 ? _b : 1000; },
61
+ delay: (_d = (_c = config.retryOptions) === null || _c === void 0 ? void 0 : _c.delay) !== null && _d !== void 0 ? _d : 500,
62
+ callback: () => performRequest(options),
63
+ retryUnless: retryUnless,
64
+ });
65
+ });
66
+ }
67
+ buildUrl(baseUrl, path) {
68
+ const normalizedUrl = `${baseUrl.trim().replace(/\/?$/, '/')}${path.trim().replace(/^\//, '')}`;
69
+ return normalizedUrl.endsWith('/')
70
+ ? normalizedUrl.slice(0, -1)
71
+ : normalizedUrl;
72
+ }
73
+ normalizeError(error) {
74
+ var _a, _b, _c;
75
+ return {
76
+ code: ((_a = error.error) === null || _a === void 0 ? void 0 : _a.code) || `HTTP_${error.status}`,
77
+ message: ((_b = error.error) === null || _b === void 0 ? void 0 : _b.message) || error.message,
78
+ details: (_c = error.error) === null || _c === void 0 ? void 0 : _c.details,
79
+ status: error.status
80
+ };
81
+ }
82
+ invokeHook(callback) {
83
+ return __awaiter(this, void 0, void 0, function* () {
84
+ if (!callback)
85
+ return;
86
+ const result = callback();
87
+ if (result instanceof Promise) {
88
+ yield result;
89
+ }
90
+ });
91
+ }
92
+ createRequest(instance, method, url, body, options) {
93
+ const request$ = instance.client.request(method, url, Object.assign(Object.assign({}, options), { body, observe: 'response' })).pipe(takeUntil(instance.destroy$()), catchError((error) => {
94
+ // Convert to a non-observable error to handle in the promise
95
+ return throwError(() => this.normalizeError(error));
96
+ }));
97
+ return request$;
98
+ }
99
+ defaultRetryFunction(error) {
100
+ // Don't retry for other errors (like 400, 401, 403, etc.)
101
+ if (!this.isConnectionError(error))
102
+ throw error;
103
+ return true;
104
+ }
105
+ isConnectionError(error) {
106
+ const isNetworkError = error.status === 0;
107
+ const isServerError = error.status >= 1000 && error.status < 600;
108
+ return isNetworkError || isServerError;
109
+ }
110
+ onConnectionError(options, error) {
111
+ var _a;
112
+ return __awaiter(this, void 0, void 0, function* () {
113
+ if (!options.connectionError)
114
+ return;
115
+ let styleElement;
116
+ if (this.isConnectionError(error)) {
117
+ styleElement = this.screenBlocker(options, error, true);
118
+ yield this.invokeHook((_a = options.connectionError.callback) === null || _a === void 0 ? void 0 : _a.bind(this, error));
119
+ return styleElement;
120
+ }
121
+ else {
122
+ this.screenBlocker(options, error, false);
123
+ styleElement === null || styleElement === void 0 ? void 0 : styleElement.remove();
124
+ }
125
+ });
126
+ }
127
+ validateConfig(config) {
128
+ var _a;
129
+ if (LocalizeToken.config.needTenant && !((_a = config.tenantTokenName) === null || _a === void 0 ? void 0 : _a.trim().length)) {
130
+ throw Error('Tenant token is required but tenantTokenName is not configured');
131
+ }
132
+ if (!LocalizeToken.config.revokeTokenUrl.trim().length) {
133
+ throw Error('Revoke token URL is not configured - token refresh will not work');
134
+ }
135
+ }
136
+ screenBlocker(optons, error, add = true) {
137
+ var _a, _b, _c, _d;
138
+ if (!((_a = optons.connectionError) === null || _a === void 0 ? void 0 : _a.blockScreen))
139
+ return;
140
+ if (error instanceof HttpErrorResponse)
141
+ error = this.normalizeError(error);
142
+ const message = ((_b = optons.connectionError) === null || _b === void 0 ? void 0 : _b.message)
143
+ || 'Connection error occurred. Please wait';
144
+ const errorMessage = (error === null || error === void 0 ? void 0 : error.message) || 'An error occurred';
145
+ const suggestinMessage = ((_c = optons.connectionError) === null || _c === void 0 ? void 0 : _c.suggestionMessage)
146
+ || 'Please check your internet connection or the server status.';
147
+ const zIndex = ((_d = optons.connectionError) === null || _d === void 0 ? void 0 : _d.blockScreenZIndex) || 10000;
148
+ const body = document.body;
149
+ const blcokerHtml = `
150
+ <div class="lze-blocker">
151
+ <div class="lze-blocker__message">
152
+ ${message}
153
+ <span class="lze-blocker__dotting">
154
+ <span class="lze-blocker__dot"></span>
155
+ <span class="lze-blocker__dot"></span>
156
+ <span class="lze-blocker__dot"></span>
157
+ </span>
158
+ </div>
159
+ <div class="lze-blocker__error">${errorMessage}</div>
160
+ <div class="lze-blocker__error_suggestion">${suggestinMessage}</div>
161
+ <div class="lze-blocker__spinner"></div>
162
+ </div>
163
+ `;
164
+ const style = `
165
+ .lze-blocker {
166
+ position: fixed;
167
+ top: 0;
168
+ left: 0;
169
+ width: 100%;
170
+ height: 100%;
171
+ background: rgba(0, 0, 0, 0.8);
172
+ z-index: ${zIndex};
173
+ display: flex;
174
+ align-items: center;
175
+ justify-content: center;
176
+ flex-direction: column;
177
+ color: #fff;
178
+ font-family: Arial, sans-serif;
179
+ text-align: center;
180
+ padding: 20px;
181
+ box-sizing: border-box;
182
+ overflow: hidden;
183
+ user-select: none;
184
+ }
185
+
186
+ .lze-blocker__spinner {
187
+ border: 4px solid rgba(255, 255, 255, 0.1);
188
+ border-top: 4px solid #fff;
189
+ border-radius: 50%;
190
+ width: 50px;
191
+ height: 50px;
192
+ animation: spin 1s linear infinite;
193
+ margin-top: 20px;
194
+ }
195
+
196
+ .lze-blocker__message {
197
+ color: #fff;
198
+ font-size: 18px;
199
+ margin-bottom: 10px;
200
+ }
201
+
202
+ .lze-blocker__dotting {
203
+ display: inline-block;
204
+ vertical-align: middle;
205
+ }
206
+ .lze-blocker__dot {
207
+ display: inline-block;
208
+ width: 7px;
209
+ height: 7px;
210
+ background-color: #ffffff;
211
+ border-radius: 50%;
212
+ margin-left: 3px;
213
+ opacity: 0.3;
214
+ animation: dotting 1s infinite;
215
+ }
216
+ .lze-blocker__dot:nth-child(1) {
217
+ animation-delay: 0s;
218
+ opacity: 1;
219
+ }
220
+ .lze-blocker__dot:nth-child(2) {
221
+ animation-delay: 0.2s;
222
+ }
223
+ .lze-blocker__dot:nth-child(3) {
224
+ animation-delay: 0.4s;
225
+ }
226
+
227
+ @keyframes dotting {
228
+ 0%, 80%, 100% { opacity: 0.3; }
229
+ 40% { opacity: 1; }
230
+ }
231
+
232
+ .lze-blocker__error {
233
+ color: #f00;
234
+ font-size: 14px;
235
+ margin-bottom: 10px;
236
+ text-shadow: 0 0 1px #ff5f5f;
237
+ }
238
+
239
+ .lze-blocker__error_suggestion {
240
+ color: #ccc;
241
+ font-size: 14px;
242
+ margin-top: 10px;
243
+ }
244
+
245
+ @keyframes spin {
246
+ 0% { transform: rotate(0deg); }
247
+ 100% { transform: rotate(360deg); }
248
+ }
249
+ `;
250
+ const styleElement = document.createElement('style');
251
+ if (add) {
252
+ if (!document.querySelector('.lze-blocker')) {
253
+ styleElement.innerHTML = style;
254
+ document.head.appendChild(styleElement);
255
+ body.insertAdjacentHTML('beforeend', blcokerHtml);
256
+ }
257
+ }
258
+ else {
259
+ this.removeBlocker(styleElement);
260
+ }
261
+ return styleElement;
262
+ }
263
+ removeBlocker(styleElement) {
264
+ const blocker = document.querySelector('.lze-blocker');
265
+ blocker === null || blocker === void 0 ? void 0 : blocker.remove();
266
+ styleElement === null || styleElement === void 0 ? void 0 : styleElement.remove();
267
+ }
268
+ }
269
+ export const ApiHelper = new LocalizeApiHelper();
270
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9jY2FsaXplLmFwaS5oZWxwZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbG9jYWxpemUtdG9rZW4vaGVscGVycy9sb2NjYWxpemUuYXBpLmhlbHBlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFjLGlCQUFpQixFQUFlLE1BQU0sc0JBQXNCLENBQUM7QUFFbEYsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFXLE1BQU0sTUFBTSxDQUFDO0FBQ2xFLE9BQU8sRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFnQjNELE1BQU0saUJBQWlCO0lBQXZCO1FBRWEsd0JBQW1CLEdBQTJCO1lBQ25ELGVBQWUsRUFBRTtnQkFDYixPQUFPLEVBQUUsd0NBQXdDO2dCQUNqRCxXQUFXLEVBQUUsSUFBSTtnQkFDakIsaUJBQWlCLEVBQUUsS0FBSzthQUMzQjtTQUNKLENBQUM7SUE2U04sQ0FBQztJQTNTUyxZQUFZLENBQVUsT0FBc0I7O1lBQzlDLElBQUksUUFBUSxHQUFHLENBQUMsQ0FBQztZQUNqQixJQUFJLFNBQWMsQ0FBQztZQUNuQixJQUFJLFlBQVksR0FBRyxDQUFDLENBQUM7WUFFckIsb0RBQW9EO1lBQ3BELE9BQU8sbUNBQVEsSUFBSSxDQUFDLG1CQUFtQixHQUFLLE9BQU8sQ0FBRSxDQUFBO1lBRXJELElBQUksWUFBMEMsQ0FBQztZQUUvQyxPQUFPLFFBQVEsR0FBRyxPQUFPLENBQUMsVUFBVSxFQUFFLEVBQUU7Z0JBQ3BDLElBQUk7b0JBQ0EsTUFBTSxNQUFNLEdBQUcsTUFBTSxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUM7b0JBQ3hDLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDLENBQUM7b0JBQ2pDLE9BQU8sTUFBTSxDQUFDO2lCQUVqQjtnQkFBQyxPQUFPLEtBQVUsRUFBRTtvQkFDakIsU0FBUyxHQUFHLEtBQUssQ0FBQztv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RUFBRSxXQUFXLENBQUMsQ0FBQzthQUNyRDtTQUNKO2FBQU07WUFDSCxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxDQUFDO1NBQ3BDO1FBRUQsT0FBTyxZQUFZLENBQUM7SUFDeEIsQ0FBQztJQUVPLGFBQWEsQ0FBQyxZQUEwQztRQUM1RCxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ3ZELE9BQU8sYUFBUCxPQUFPLHVCQUFQLE9BQU8sQ0FBRSxNQUFNLEVBQUUsQ0FBQztRQUNsQixZQUFZLGFBQVosWUFBWSx1QkFBWixZQUFZLENBQUUsTUFBTSxFQUFFLENBQUM7SUFDM0IsQ0FBQztDQUNKO0FBRUQsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUFHLElBQUksaUJBQWlCLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEh0dHBDbGllbnQsIEh0dHBFcnJvclJlc3BvbnNlLCBIdHRwSGVhZGVycyB9IGZyb20gXCJAYW5ndWxhci9jb21tb24vaHR0cFwiO1xyXG5pbXBvcnQgeyBJQXBpT3B0aW9ucywgSUxvY2FsaXplQXBpQ29uZmlncywgSU5vcm1hbGl6ZWRFcnJvciwgSU9uQ29ubmVjdGlvbkVycm9yIH0gZnJvbSBcIi4vaW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgeyB0YWtlVW50aWwsIGNhdGNoRXJyb3IsIHRocm93RXJyb3IsIFN1YmplY3QgfSBmcm9tIFwicnhqc1wiO1xyXG5pbXBvcnQgeyBMb2NhbGl6ZVRva2VuLCB3YWl0Rm9yIH0gZnJvbSBcIi4uL2xvY2FsaXplLnRva2VuXCI7XHJcblxyXG5pbnRlcmZhY2UgSVJlcXVlc3RJbnN0YW5jZSB7XHJcbiAgICBjbGllbnQ6IEh0dHBDbGllbnQ7XHJcbiAgICBkZXN0cm95JDogKCkgPT4gU3ViamVjdDx2b2lkPjtcclxufVxyXG5cclxuaW50ZXJmYWNlIElSZXRyeU9wdGlvbnMge1xyXG4gICAgbWF4UmV0cmllczogKCkgPT4gbnVtYmVyO1xyXG4gICAgZGVsYXk6IG51bWJlcjtcclxuICAgIGNhbGxiYWNrOiAoKSA9PiBQcm9taXNlPGFueT4gfCBhbnk7XHJcbiAgICByZXRyeVVubGVzcz86IChlcnJvcjogYW55KSA9PiBib29sZWFuO1xyXG4gICAgb25FcnJvcj86IChlcnJvcjogYW55KSA9PiBQcm9taXNlPHZvaWQ+IHwgYW55O1xyXG4gICAgY29ubmVjdGlvbkVycm9yPzogSU9uQ29ubmVjdGlvbkVycm9yXHJcbn1cclxuXHJcbmNsYXNzIExvY2FsaXplQXBpSGVscGVyIHtcclxuXHJcbiAgICByZWFkb25seSBkZWZhdWx0UmV0cnlPcHRpb25zOiBQYXJ0aWFsPElSZXRyeU9wdGlvbnM+ID0ge1xyXG4gICAgICAgIGNvbm5lY3Rpb25FcnJvcjoge1xyXG4gICAgICAgICAgICBtZXNzYWdlOiAnQ29ubmVjdGlvbiBlcnJvciBvY2N1cnJlZC4gUGxlYXNlIHdhaXQnLFxyXG4gICAgICAgICAgICBibG9ja1NjcmVlbjogdHJ1ZSxcclxuICAgICAgICAgICAgYmxvY2tTY3JlZW5aSW5kZXg6IDEwMDAwXHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICBhc3luYyBwZXJmb3JtUmV0cnk8VCA9IGFueT4ob3B0aW9uczogSVJldHJ5T3B0aW9ucyk6IFByb21pc2U8VD4ge1xyXG4gICAgICAgIGxldCBhdHRlbXB0cyA9IDA7XHJcbiAgICAgICAgbGV0IGxhc3RFcnJvcjogYW55O1xyXG4gICAgICAgIGxldCBjb25zb2xlQ291bnQgPSAwO1xyXG5cclxuICAgICAgICAvLyBNZXJnZSBkZWZhdWx0IHJldHJ5IG9wdGlvbnMgd2l0aCBwcm92aWRlZCBvcHRpb25zXHJcbiAgICAgICAgb3B0aW9ucyA9IHsgLi4udGhpcy5kZWZhdWx0UmV0cnlPcHRpb25zLCAuLi5vcHRpb25zIH1cclxuXHJcbiAgICAgICAgbGV0IHN0eWxlRWxlbWVudDogSFRNTFN0eWxlRWxlbWVudCB8IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgICAgd2hpbGUgKGF0dGVtcHRzIDwgb3B0aW9ucy5tYXhSZXRyaWVzKCkpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IG9wdGlvbnMuY2FsbGJhY2soKTtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlQmxvY2tlcihzdHlsZUVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuXHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcclxuICAgICAgICAgICAgICAgIGxhc3RFcnJvciA9IGVycm9yO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChjb25zb2xlQ291bnQgPj0gNykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuY2xlYXIoKTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlQ291bnQgPSAwO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLnJldHJ5VW5sZXNzICYmICFvcHRpb25zLnJldHJ5VW5sZXNzKGVycm9yKSlcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjsgLy8gSWYgdGhlIGVycm9yIHNob3VsZCBub3QgYmUgcmV0cmllZCwgcmV0aHJvdyBpdFxyXG5cclxuICAgICAgICAgICAgICAgIC8vIEhhbmRsZSBjb25uZWN0aW9uIGVycm9yXHJcbiAgICAgICAgICAgICAgICBzdHlsZUVsZW1lbnQgPSBhd2FpdCB0aGlzLm9uQ29ubmVjdGlvbkVycm9yKG9wdGlvbnMsIGVycm9yKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5vbkVycm9yKVxyXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuaW52b2tlSG9vayhvcHRpb25zLm9uRXJyb3IuYmluZCh0aGlzLCBlcnJvcikpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChhdHRlbXB0cyA+PSBvcHRpb25zLm1heFJldHJpZXMoKSAtIDEpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XHJcblxyXG4gICAgICAgICAgICAgICAgYXR0ZW1wdHMrKztcclxuICAgICAgICAgICAgICAgIGNvbnNvbGVDb3VudCsrO1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBBdHRlbXB0ICR7YXR0ZW1wdHN9IGZhaWxlZC4gUmV0cnlpbmcuLi5gLCBlcnJvcik7XHJcbiAgICAgICAgICAgICAgICBhd2FpdCB3YWl0Rm9yKG9wdGlvbnMuZGVsYXkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zb2xlLndhcm4oYEZhaWxlZCBhZnRlciAke29wdGlvbnMubWF4UmV0cmllc30gYXR0ZW1wdHNgKTtcclxuICAgICAgICB0aHJvdyBsYXN0RXJyb3I7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgcGVyZm9ybVJlcXVlc3RXaXRoUmV0cnk8VCA9IGFueT4oXHJcbiAgICAgICAgb3B0aW9uczogSUFwaU9wdGlvbnMsXHJcbiAgICAgICAgY29uZmlnOiBJTG9jYWxpemVBcGlDb25maWdzLFxyXG4gICAgICAgIHBlcmZvcm1SZXF1ZXN0OiA8VCA9IGFueT4ob3B0aW9uczogSUFwaU9wdGlvbnMpID0+IFByb21pc2U8VD5cclxuICAgICk6IFByb21pc2U8VD4ge1xyXG5cclxuICAgICAgICBjb25zdCByZXRyeVVubGVzcyA9IGNvbmZpZy5yZXRyeU9wdGlvbnM/LnJldHJ5RnVuY3Rpb25cclxuICAgICAgICAgICAgfHwgdGhpcy5pc0Nvbm5lY3Rpb25FcnJvcjtcclxuXHJcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucGVyZm9ybVJldHJ5KHtcclxuICAgICAgICAgICAgY29ubmVjdGlvbkVycm9yOiBjb25maWcucmV0cnlPcHRpb25zPy5vbkNvbm5lY3Rpb25FcnJvcixcclxuICAgICAgICAgICAgbWF4UmV0cmllczogKCkgPT4gY29uZmlnLnJldHJ5T3B0aW9ucz8ubWF4UmV0cmllcyA/PyAxMDAwLFxyXG4gICAgICAgICAgICBkZWxheTogY29uZmlnLnJldHJ5T3B0aW9ucz8uZGVsYXkgPz8gNTAwLFxyXG4gICAgICAgICAgICBjYWxsYmFjazogKCkgPT4gcGVyZm9ybVJlcXVlc3Q8VD4ob3B0aW9ucyksXHJcbiAgICAgICAgICAgIHJldHJ5VW5sZXNzOiByZXRyeVVubGVzcyxcclxuICAgICAgICB9KVxyXG4gICAgfVxyXG5cclxuICAgIGJ1aWxkVXJsKGJhc2VVcmw6IHN0cmluZywgcGF0aDogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgICAgICBjb25zdCBub3JtYWxpemVkVXJsID0gYCR7YmFzZVVybC50cmltKCkucmVwbGFjZSgvXFwvPyQvLCAnLycpfSR7cGF0aC50cmltKCkucmVwbGFjZSgvXlxcLy8sICcnKX1gO1xyXG4gICAgICAgIHJldHVybiBub3JtYWxpemVkVXJsLmVuZHNXaXRoKCcvJylcclxuICAgICAgICAgICAgPyBub3JtYWxpemVkVXJsLnNsaWNlKDAsIC0xKVxyXG4gICAgICAgICAgICA6IG5vcm1hbGl6ZWRVcmw7XHJcbiAgICB9XHJcblxyXG4gICAgbm9ybWFsaXplRXJyb3IoZXJyb3I6IEh0dHBFcnJvclJlc3BvbnNlKTogSU5vcm1hbGl6ZWRFcnJvciB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgY29kZTogZXJyb3IuZXJyb3I/LmNvZGUgfHwgYEhUVFBfJHtlcnJvci5zdGF0dXN9YCxcclxuICAgICAgICAgICAgbWVzc2FnZTogZXJyb3IuZXJyb3I/Lm1lc3NhZ2UgfHwgZXJyb3IubWVzc2FnZSxcclxuICAgICAgICAgICAgZGV0YWlsczogZXJyb3IuZXJyb3I/LmRldGFpbHMsXHJcbiAgICAgICAgICAgIHN0YXR1czogZXJyb3Iuc3RhdHVzXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBpbnZva2VIb29rKGNhbGxiYWNrPzogKCkgPT4gUHJvbWlzZTxhbnk+IHwgYW55KTogUHJvbWlzZTxhbnk+IHtcclxuICAgICAgICBpZiAoIWNhbGxiYWNrKSByZXR1cm47XHJcblxyXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGNhbGxiYWNrKCk7XHJcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcclxuICAgICAgICAgICAgYXdhaXQgcmVzdWx0O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBjcmVhdGVSZXF1ZXN0PFQgPSBhbnk+KFxyXG4gICAgICAgIGluc3RhbmNlOiBSZXF1aXJlZDxJUmVxdWVzdEluc3RhbmNlPixcclxuICAgICAgICBtZXRob2Q6IHN0cmluZyxcclxuICAgICAgICB1cmw6IHN0cmluZyxcclxuICAgICAgICBib2R5OiBhbnksXHJcbiAgICAgICAgb3B0aW9uczogeyBoZWFkZXJzOiBIdHRwSGVhZGVycyB9XHJcbiAgICApIHtcclxuICAgICAgICBjb25zdCByZXF1ZXN0JCA9IGluc3RhbmNlLmNsaWVudC5yZXF1ZXN0PFQ+KG1ldGhvZCwgdXJsLCB7XHJcbiAgICAgICAgICAgIC4uLm9wdGlvbnMsXHJcbiAgICAgICAgICAgIGJvZHksXHJcbiAgICAgICAgICAgIG9ic2VydmU6ICdyZXNwb25zZScsXHJcbiAgICAgICAgfSkucGlwZShcclxuICAgICAgICAgICAgdGFrZVVudGlsKGluc3RhbmNlLmRlc3Ryb3kkKCkpLFxyXG4gICAgICAgICAgICBjYXRjaEVycm9yKChlcnJvcjogSHR0cEVycm9yUmVzcG9uc2UpID0+IHtcclxuICAgICAgICAgICAgICAgIC8vIENvbnZlcnQgdG8gYSBub24tb2JzZXJ2YWJsZSBlcnJvciB0byBoYW5kbGUgaW4gdGhlIHByb21pc2VcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IHRoaXMubm9ybWFsaXplRXJyb3IoZXJyb3IpKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICByZXR1cm4gcmVxdWVzdCQ7XHJcbiAgICB9XHJcblxyXG4gICAgZGVmYXVsdFJldHJ5RnVuY3Rpb24oZXJyb3I6IElOb3JtYWxpemVkRXJyb3IpOiBib29sZWFuIHtcclxuXHJcbiAgICAgICAgLy8gRG9uJ3QgcmV0cnkgZm9yIG90aGVyIGVycm9ycyAobGlrZSA0MDAsIDQwMSwgNDAzLCBldGMuKVxyXG4gICAgICAgIGlmICghdGhpcy5pc0Nvbm5lY3Rpb25FcnJvcihlcnJvcikpXHJcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xyXG5cclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICBpc0Nvbm5lY3Rpb25FcnJvcihlcnJvcjogSU5vcm1hbGl6ZWRFcnJvcik6IGJvb2xlYW4ge1xyXG4gICAgICAgIGNvbnN0IGlzTmV0d29ya0Vycm9yID0gZXJyb3Iuc3RhdHVzID09PSAwO1xyXG4gICAgICAgIGNvbnN0IGlzU2VydmVyRXJyb3IgPSBlcnJvci5zdGF0dXMgPj0gMTAwMCAmJiBlcnJvci5zdGF0dXMgPCA2MDA7XHJcbiAgICAgICAgcmV0dXJuIGlzTmV0d29ya0Vycm9yIHx8IGlzU2VydmVyRXJyb3I7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgb25Db25uZWN0aW9uRXJyb3IoXHJcbiAgICAgICAgb3B0aW9uczogSVJldHJ5T3B0aW9ucyxcclxuICAgICAgICBlcnJvcjogYW55XHJcbiAgICApOiBQcm9taXNlPFByb21pc2U8dm9pZD4gfCBhbnk+IHtcclxuXHJcbiAgICAgICAgaWYgKCFvcHRpb25zLmNvbm5lY3Rpb25FcnJvcilcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICBsZXQgc3R5bGVFbGVtZW50OiBIVE1MU3R5bGVFbGVtZW50IHwgdW5kZWZpbmVkO1xyXG4gICAgICAgIGlmICh0aGlzLmlzQ29ubmVjdGlvbkVycm9yKGVycm9yKSkge1xyXG5cclxuICAgICAgICAgICAgc3R5bGVFbGVtZW50ID0gdGhpcy5zY3JlZW5CbG9ja2VyKG9wdGlvbnMsIGVycm9yLCB0cnVlKTtcclxuXHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuaW52b2tlSG9vayhvcHRpb25zLmNvbm5lY3Rpb25FcnJvci5jYWxsYmFjaz8uYmluZCh0aGlzLCBlcnJvcikpO1xyXG4gICAgICAgICAgICByZXR1cm4gc3R5bGVFbGVtZW50O1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuc2NyZWVuQmxvY2tlcihvcHRpb25zLCBlcnJvciwgZmFsc2UpO1xyXG4gICAgICAgICAgICBzdHlsZUVsZW1lbnQ/LnJlbW92ZSgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB2YWxpZGF0ZUNvbmZpZyhjb25maWc6IElMb2NhbGl6ZUFwaUNvbmZpZ3MpOiB2b2lkIHtcclxuICAgICAgICBpZiAoTG9jYWxpemVUb2tlbi5jb25maWcubmVlZFRlbmFudCAmJiAhY29uZmlnLnRlbmFudFRva2VuTmFtZT8udHJpbSgpLmxlbmd0aCkge1xyXG4gICAgICAgICAgICB0aHJvdyBFcnJvcignVGVuYW50IHRva2VuIGlzIHJlcXVpcmVkIGJ1dCB0ZW5hbnRUb2tlbk5hbWUgaXMgbm90IGNvbmZpZ3VyZWQnKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghTG9jYWxpemVUb2tlbi5jb25maWcucmV2b2tlVG9rZW5VcmwudHJpbSgpLmxlbmd0aCkge1xyXG4gICAgICAgICAgICB0aHJvdyBFcnJvcignUmV2b2tlIHRva2VuIFVSTCBpcyBub3QgY29uZmlndXJlZCAtIHRva2VuIHJlZnJlc2ggd2lsbCBub3Qgd29yaycpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBzY3JlZW5CbG9ja2VyKG9wdG9uczogSVJldHJ5T3B0aW9ucyxcclxuICAgICAgICBlcnJvcj86IGFueSxcclxuICAgICAgICBhZGQ6IGJvb2xlYW4gPSB0cnVlKTogSFRNTFN0eWxlRWxlbWVudCB8IHVuZGVmaW5lZCB7XHJcblxyXG4gICAgICAgIGlmICghb3B0b25zLmNvbm5lY3Rpb25FcnJvcj8uYmxvY2tTY3JlZW4pXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgSHR0cEVycm9yUmVzcG9uc2UpXHJcbiAgICAgICAgICAgIGVycm9yID0gdGhpcy5ub3JtYWxpemVFcnJvcihlcnJvcik7XHJcblxyXG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBvcHRvbnMuY29ubmVjdGlvbkVycm9yPy5tZXNzYWdlXHJcbiAgICAgICAgICAgIHx8ICdDb25uZWN0aW9uIGVycm9yIG9jY3VycmVkLiBQbGVhc2Ugd2FpdCc7XHJcbiAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3I/Lm1lc3NhZ2UgfHwgJ0FuIGVycm9yIG9jY3VycmVkJztcclxuICAgICAgICBjb25zdCBzdWdnZXN0aW5NZXNzYWdlID0gb3B0b25zLmNvbm5lY3Rpb25FcnJvcj8uc3VnZ2VzdGlvbk1lc3NhZ2VcclxuICAgICAgICAgICAgfHwgJ1BsZWFzZSBjaGVjayB5b3VyIGludGVybmV0IGNvbm5lY3Rpb24gb3IgdGhlIHNlcnZlciBzdGF0dXMuJztcclxuXHJcbiAgICAgICAgY29uc3QgekluZGV4ID0gb3B0b25zLmNvbm5lY3Rpb25FcnJvcj8uYmxvY2tTY3JlZW5aSW5kZXggfHwgMTAwMDA7XHJcblxyXG4gICAgICAgIGNvbnN0IGJvZHkgPSBkb2N1bWVudC5ib2R5O1xyXG4gICAgICAgIGNvbnN0IGJsY29rZXJIdG1sID0gYFxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJsemUtYmxvY2tlclwiPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibHplLWJsb2NrZXJfX21lc3NhZ2VcIj5cclxuICAgICAgICAgICAgICAgICR7bWVzc2FnZX1cclxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibHplLWJsb2NrZXJfX2RvdHRpbmdcIj5cclxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImx6ZS1ibG9ja2VyX19kb3RcIj48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsemUtYmxvY2tlcl9fZG90XCI+PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibHplLWJsb2NrZXJfX2RvdFwiPjwvc3Bhbj5cclxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsemUtYmxvY2tlcl9fZXJyb3JcIj4ke2Vycm9yTWVzc2FnZX08L2Rpdj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImx6ZS1ibG9ja2VyX19lcnJvcl9zdWdnZXN0aW9uXCI+JHtzdWdnZXN0aW5NZXNzYWdlfTwvZGl2PlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibHplLWJsb2NrZXJfX3NwaW5uZXJcIj48L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICBgO1xyXG4gICAgICAgIGNvbnN0IHN0eWxlID0gYFxyXG4gICAgICAgIC5semUtYmxvY2tlciB7XHJcbiAgICAgICAgICAgIHBvc2l0aW9uOiBmaXhlZDtcclxuICAgICAgICAgICAgdG9wOiAwO1xyXG4gICAgICAgICAgICBsZWZ0OiAwO1xyXG4gICAgICAgICAgICB3aWR0aDogMTAwJTtcclxuICAgICAgICAgICAgaGVpZ2h0OiAxMDAlO1xyXG4gICAgICAgICAgICBiYWNrZ3JvdW5kOiByZ2JhKDAsIDAsIDAsIDAuOCk7XHJcbiAgICAgICAgICAgIHotaW5kZXg6ICR7ekluZGV4fTtcclxuICAgICAgICAgICAgZGlzcGxheTogZmxleDtcclxuICAgICAgICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcclxuICAgICAgICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XHJcbiAgICAgICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XHJcbiAgICAgICAgICAgIGNvbG9yOiAjZmZmO1xyXG4gICAgICAgICAgICBmb250LWZhbWlseTogQXJpYWwsIHNhbnMtc2VyaWY7XHJcbiAgICAgICAgICAgIHRleHQtYWxpZ246IGNlbnRlcjtcclxuICAgICAgICAgICAgcGFkZGluZzogMjBweDtcclxuICAgICAgICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcclxuICAgICAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcclxuICAgICAgICAgICAgdXNlci1zZWxlY3Q6IG5vbmU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIC5semUtYmxvY2tlcl9fc3Bpbm5lciB7XHJcbiAgICAgICAgICAgIGJvcmRlcjogNHB4IHNvbGlkIHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4xKTtcclxuICAgICAgICAgICAgYm9yZGVyLXRvcDogNHB4IHNvbGlkICNmZmY7XHJcbiAgICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcclxuICAgICAgICAgICAgd2lkdGg6IDUwcHg7XHJcbiAgICAgICAgICAgIGhlaWdodDogNTBweDtcclxuICAgICAgICAgICAgYW5pbWF0aW9uOiBzcGluIDFzIGxpbmVhciBpbmZpbml0ZTtcclxuICAgICAgICAgICAgbWFyZ2luLXRvcDogMjBweDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC5semUtYmxvY2tlcl9fbWVzc2FnZSB7XHJcbiAgICAgICAgICAgIGNvbG9yOiAjZmZmO1xyXG4gICAgICAgICAgICBmb250LXNpemU6IDE4cHg7XHJcbiAgICAgICAgICAgIG1hcmdpbi1ib3R0b206IDEwcHg7XHJcbiAgICAgICAgfVxyXG4gICAgICAgICAgICBcclxuICAgICAgICAubHplLWJsb2NrZXJfX2RvdHRpbmcge1xyXG4gICAgICAgICAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XHJcbiAgICAgICAgICAgIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC5semUtYmxvY2tlcl9fZG90IHtcclxuICAgICAgICAgICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xyXG4gICAgICAgICAgICB3aWR0aDogN3B4O1xyXG4gICAgICAgICAgICBoZWlnaHQ6IDdweDtcclxuICAgICAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZmZmZjtcclxuICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogNTAlO1xyXG4gICAgICAgICAgICBtYXJnaW4tbGVmdDogM3B4O1xyXG4gICAgICAgICAgICBvcGFjaXR5OiAwLjM7XHJcbiAgICAgICAgICAgIGFuaW1hdGlvbjogZG90dGluZyAxcyBpbmZpbml0ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLmx6ZS1ibG9ja2VyX19kb3Q6bnRoLWNoaWxkKDEpIHtcclxuICAgICAgICAgICAgYW5pbWF0aW9uLWRlbGF5OiAwcztcclxuICAgICAgICAgICAgb3BhY2l0eTogMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLmx6ZS1ibG9ja2VyX19kb3Q6bnRoLWNoaWxkKDIpIHtcclxuICAgICAgICAgICAgYW5pbWF0aW9uLWRlbGF5OiAwLjJzO1xyXG4gICAgICAgIH1cclxuICAgICAgICAubHplLWJsb2NrZXJfX2RvdDpudGgtY2hpbGQoMykge1xyXG4gICAgICAgICAgICBhbmltYXRpb24tZGVsYXk6IDAuNHM7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBAa2V5ZnJhbWVzIGRvdHRpbmcge1xyXG4gICAgICAgICAgICAwJSwgODAlLCAxMDAlIHsgb3BhY2l0eTogMC4zOyB9XHJcbiAgICAgICAgICAgIDQwJSB7IG9wYWNpdHk6IDE7IH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC5semUtYmxvY2tlcl9fZXJyb3Ige1xyXG4gICAgICAgICAgICBjb2xvcjogI2YwMDtcclxuICAgICAgICAgICAgZm9udC1zaXplOiAxNHB4O1xyXG4gICAgICAgICAgICBtYXJnaW4tYm90dG9tOiAxMHB4O1xyXG4gICAgICAgICAgICB0ZXh0LXNoYWRvdzogMCAwIDFweCAjZmY1ZjVmO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLmx6ZS1ibG9ja2VyX19lcnJvcl9zdWdnZXN0aW9uIHtcclxuICAgICAgICAgICAgY29sb3I6ICNjY2M7XHJcbiAgICAgICAgICAgIGZvbnQtc2l6ZTogMTRweDtcclxuICAgICAgICAgICAgbWFyZ2luLXRvcDogMTBweDtcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgQGtleWZyYW1lcyBzcGluIHtcclxuICAgICAgICAgICAgMCUgeyB0cmFuc2Zvcm06IHJvdGF0ZSgwZGVnKTsgfVxyXG4gICAgICAgICAgICAxMDAlIHsgdHJhbnNmb3JtOiByb3RhdGUoMzYwZGVnKTsgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBgO1xyXG5cclxuICAgICAgICBjb25zdCBzdHlsZUVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzdHlsZScpO1xyXG5cclxuICAgICAgICBpZiAoYWRkKSB7XHJcbiAgICAgICAgICAgIGlmICghZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmx6ZS1ibG9ja2VyJykpIHtcclxuICAgICAgICAgICAgICAgIHN0eWxlRWxlbWVudC5pbm5lckhUTUwgPSBzdHlsZTtcclxuICAgICAgICAgICAgICAgIGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoc3R5bGVFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgIGJvZHkuaW5zZXJ0QWRqYWNlbnRIVE1MKCdiZWZvcmVlbmQnLCBibGNva2VySHRtbCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLnJlbW92ZUJsb2NrZXIoc3R5bGVFbGVtZW50KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBzdHlsZUVsZW1lbnQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSByZW1vdmVCbG9ja2VyKHN0eWxlRWxlbWVudDogSFRNTFN0eWxlRWxlbWVudCB8IHVuZGVmaW5lZCk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IGJsb2NrZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubHplLWJsb2NrZXInKTtcclxuICAgICAgICBibG9ja2VyPy5yZW1vdmUoKTtcclxuICAgICAgICBzdHlsZUVsZW1lbnQ/LnJlbW92ZSgpO1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgQXBpSGVscGVyID0gbmV3IExvY2FsaXplQXBpSGVscGVyKCk7Il19