@almatar/smart-booking-dashboard 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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +132 -0
  3. package/esm2022/almatar-smart-booking-dashboard.mjs +5 -0
  4. package/esm2022/lib/components/action-card/action-card.component.mjs +19 -0
  5. package/esm2022/lib/components/action-dialog/action-dialog.component.mjs +177 -0
  6. package/esm2022/lib/components/action-grid/action-grid.component.mjs +18 -0
  7. package/esm2022/lib/components/add-note-dialog/add-note-dialog.component.mjs +62 -0
  8. package/esm2022/lib/components/booking-input/booking-input.component.mjs +43 -0
  9. package/esm2022/lib/components/cancel-dialog/cancel-dialog.component.mjs +1441 -0
  10. package/esm2022/lib/components/data-search/data-search.component.mjs +84 -0
  11. package/esm2022/lib/components/flight-itinerary-card/flight-itinerary-card.component.mjs +73 -0
  12. package/esm2022/lib/components/result-panel/result-panel.component.mjs +46 -0
  13. package/esm2022/lib/components/workflow-actions/workflow-actions.component.mjs +19 -0
  14. package/esm2022/lib/config/dashboard.config.mjs +16 -0
  15. package/esm2022/lib/config/flight-actions.config.mjs +906 -0
  16. package/esm2022/lib/config/hotel-actions.config.mjs +53 -0
  17. package/esm2022/lib/config/labels.ar.mjs +116 -0
  18. package/esm2022/lib/models/action.types.mjs +2 -0
  19. package/esm2022/lib/models/booking.types.mjs +2 -0
  20. package/esm2022/lib/pages/smart-booking-dashboard/smart-booking-dashboard.component.mjs +145 -0
  21. package/esm2022/lib/services/booking.service.mjs +65 -0
  22. package/esm2022/lib/services/toast.service.mjs +19 -0
  23. package/esm2022/lib/smart-booking-dashboard.module.mjs +17 -0
  24. package/esm2022/lib/smart-booking-dashboard.routes.mjs +7 -0
  25. package/esm2022/public-api.mjs +9 -0
  26. package/fesm2022/almatar-smart-booking-dashboard.mjs +3259 -0
  27. package/fesm2022/almatar-smart-booking-dashboard.mjs.map +1 -0
  28. package/index.d.ts +5 -0
  29. package/lib/components/action-card/action-card.component.d.ts +10 -0
  30. package/lib/components/action-dialog/action-dialog.component.d.ts +26 -0
  31. package/lib/components/action-grid/action-grid.component.d.ts +10 -0
  32. package/lib/components/add-note-dialog/add-note-dialog.component.d.ts +25 -0
  33. package/lib/components/booking-input/booking-input.component.d.ts +23 -0
  34. package/lib/components/cancel-dialog/cancel-dialog.component.d.ts +395 -0
  35. package/lib/components/data-search/data-search.component.d.ts +21 -0
  36. package/lib/components/flight-itinerary-card/flight-itinerary-card.component.d.ts +17 -0
  37. package/lib/components/result-panel/result-panel.component.d.ts +14 -0
  38. package/lib/components/workflow-actions/workflow-actions.component.d.ts +7 -0
  39. package/lib/config/dashboard.config.d.ts +15 -0
  40. package/lib/config/flight-actions.config.d.ts +2 -0
  41. package/lib/config/hotel-actions.config.d.ts +2 -0
  42. package/lib/config/labels.ar.d.ts +2 -0
  43. package/lib/models/action.types.d.ts +34 -0
  44. package/lib/models/booking.types.d.ts +6 -0
  45. package/lib/pages/smart-booking-dashboard/smart-booking-dashboard.component.d.ts +43 -0
  46. package/lib/services/booking.service.d.ts +22 -0
  47. package/lib/services/toast.service.d.ts +10 -0
  48. package/lib/smart-booking-dashboard.module.d.ts +7 -0
  49. package/lib/smart-booking-dashboard.routes.d.ts +2 -0
  50. package/package.json +50 -0
  51. package/public-api.d.ts +5 -0
@@ -0,0 +1,1441 @@
1
+ import { Component, input, output, inject, effect, signal, computed } from '@angular/core';
2
+ import { NgTemplateOutlet, NgClass } from '@angular/common';
3
+ import { DialogModule } from 'primeng/dialog';
4
+ import { ButtonModule } from 'primeng/button';
5
+ import { SkeletonModule } from 'primeng/skeleton';
6
+ import { SbdBookingService } from '../../services/booking.service';
7
+ import { SbdToastService } from '../../services/toast.service';
8
+ import * as i0 from "@angular/core";
9
+ import * as i1 from "primeng/dialog";
10
+ import * as i2 from "primeng/button";
11
+ const DEDUCTION_DEFS = [
12
+ { key: 'totalPenaltyPoints', label: 'Airline Cancellation Fee', badge: '' },
13
+ { key: 'handlingFee', label: 'Handling Fee', badge: '' },
14
+ { key: 'totalNonRefundableServiceCharge', label: 'Service Charge', badge: '' },
15
+ { key: 'totalAncillaryRefundAmount', label: 'Ancillary Fee', badge: '' },
16
+ { key: 'totalGiftAmount', label: 'Add on Fee', badge: '' },
17
+ // `totalLoyaltyPoints` (points spent at booking time, now forfeited) is
18
+ // intentionally not listed here — it's already surfaced under its own
19
+ // program name (e.g. "Qitaf") in the "Total Paid" breakdown, so listing it
20
+ // again here would double up the same amount under two different sections.
21
+ ];
22
+ const REFUND_DEFS = [
23
+ { key: 'totalCardRefundAmount', label: 'Refund Amount' },
24
+ { key: 'totalCreditRefundAmount', label: 'Credit Shell Refund' },
25
+ { key: 'walletRefundAmount', label: 'Almatar Wallet' },
26
+ { key: 'totalLoyaltyPointsRefundAmount', label: 'Loyalty Points Refund' },
27
+ ];
28
+ /** Labels for `paymentMethodCustomerUsed` gateway codes returned by the backend. */
29
+ const PAYMENT_GATEWAY_LABELS = {
30
+ CH: 'Card',
31
+ HP: 'Hyperpay',
32
+ MF: 'My Fatoora',
33
+ WT: 'Wire Transfer',
34
+ STC: 'STC',
35
+ TM: 'Tamara',
36
+ TB: 'Tabby',
37
+ RAJHI: 'Al Rajhi Mokafaa',
38
+ PPB: 'Customer Balance',
39
+ PP: 'Postpay',
40
+ TAMAM: 'Tamam',
41
+ QITAF: 'Qitaf',
42
+ MIS: 'MIS Pay',
43
+ MATAR: 'Almatar Pay',
44
+ CB: 'Company Balance',
45
+ ANB: 'ANB',
46
+ AMWAL: 'Amwal',
47
+ WALA: 'Wala',
48
+ YGG: 'YGG',
49
+ };
50
+ /** Gateway codes that refund to an installment plan rather than the original card. */
51
+ const INSTALLMENT_GATEWAY_CODES = ['TM', 'TB'];
52
+ /** Gateway codes that refund to a loyalty-program account rather than the original card. */
53
+ const LOYALTY_GATEWAY_CODES = ['RAJHI', 'QITAF', 'STC', 'WALA'];
54
+ /**
55
+ * Internal payment-processor/gateway names, never customer-recognizable
56
+ * brands — must not be surfaced verbatim (e.g. a card refund processed
57
+ * through Hyperpay must read as "Card"/"Original Payment Method", never
58
+ * "Hyperpay"). Callers fall back to a generic label whenever the normalized
59
+ * lookup returns ''.
60
+ */
61
+ const INTERNAL_GATEWAY_CODES = ['HP', 'MF', 'WT', 'PPB', 'PP', 'TAMAM'];
62
+ /**
63
+ * Result/confirmation-screen-only override: these gateways process card
64
+ * payments through Mada — shown specifically as "Mada Card" instead of
65
+ * falling back to the generic "Original Payment Method" label used
66
+ * everywhere else `INTERNAL_GATEWAY_CODES` applies.
67
+ */
68
+ const MADA_GATEWAY_CODES = ['HP', 'CH'];
69
+ const CREDIT_SHELL_SUFFIX = 'It can be used only for future booking on the airline website.';
70
+ const GIFT_HINT = 'Please note: If you cancel either leg of your round-trip booking, the add-on/gift service will be cancelled automatically.';
71
+ export class SbdCancelDialogComponent {
72
+ /**
73
+ * The return leg is matched by an explicit 'Return' direction; the onward
74
+ * leg is whatever's left (some bookings don't tag the outbound leg with an
75
+ * explicit 'Departure' value), falling back to the first entry.
76
+ */
77
+ itineraryLeg(kind) {
78
+ const legs = this.itineraryLegs();
79
+ if (!legs.length)
80
+ return null;
81
+ const returnLeg = legs.find((l) => (l.direction ?? '').toLowerCase() === 'return') ?? null;
82
+ if (kind === 'return')
83
+ return returnLeg;
84
+ return (legs.find((l) => (l.direction ?? '').toLowerCase() === 'departure') ??
85
+ legs.find((l) => l !== returnLeg) ??
86
+ legs[0] ??
87
+ null);
88
+ }
89
+ fmtTime(dt) {
90
+ if (!dt)
91
+ return '—';
92
+ try {
93
+ return new Date(dt).toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit' });
94
+ }
95
+ catch {
96
+ return dt;
97
+ }
98
+ }
99
+ fmtShortDate(dt) {
100
+ if (!dt)
101
+ return '—';
102
+ try {
103
+ return new Date(dt).toLocaleDateString('en-GB', { weekday: 'short', day: '2-digit', month: 'short' });
104
+ }
105
+ catch {
106
+ return dt;
107
+ }
108
+ }
109
+ fmtMins(mins) {
110
+ if (mins == null)
111
+ return '';
112
+ return `${Math.floor(mins / 60)}h ${mins % 60}m`;
113
+ }
114
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
115
+ applySourceOverride(base, breakdown) {
116
+ const sel = this.selectedSource();
117
+ if (!sel || !breakdown || !breakdown[sel])
118
+ return this.reconcileSoleDestination(base);
119
+ const src = breakdown[sel];
120
+ const sourceRefundable = src.isRefundable !== false; // default true if not set
121
+ if (!sourceRefundable) {
122
+ // Source cannot process refund — zero out financial fields
123
+ return this.reconcileSoleDestination({
124
+ ...base,
125
+ isRefundable: false,
126
+ totalPenaltyPoints: 0,
127
+ totalSupplierPenaltyPoints: 0,
128
+ totalCancellationFee: 0,
129
+ totalRefundAmount: 0,
130
+ totalCardRefundAmount: 0,
131
+ handlingFee: 0,
132
+ });
133
+ }
134
+ // Prefer the source's own walletRefundAmount/totalCardRefundAmount when
135
+ // the API provides them (they're already net of each other for this
136
+ // source) — only fall back to deriving cardRefund when the API doesn't.
137
+ const newTotal = Number(src.totalRefundAmount || 0);
138
+ const walletRefund = src.walletRefundAmount !== undefined
139
+ ? Number(src.walletRefundAmount || 0)
140
+ : Number(base.walletRefundAmount || 0);
141
+ const cardRefund = src.totalCardRefundAmount !== undefined
142
+ ? Number(src.totalCardRefundAmount || 0)
143
+ : Math.max(0, newTotal -
144
+ Number(base.totalCreditRefundAmount || 0) -
145
+ walletRefund -
146
+ Number(base.totalLoyaltyPointsRefundAmount || 0));
147
+ return this.reconcileSoleDestination({
148
+ ...base,
149
+ isRefundable: true,
150
+ totalPenaltyPoints: Number(src.totalSupplierPenaltyPoints || 0),
151
+ totalSupplierPenaltyPoints: Number(src.totalSupplierPenaltyPoints || 0),
152
+ totalCancellationFee: Number(src.totalCancellationFee || 0),
153
+ totalRefundAmount: newTotal,
154
+ walletRefundAmount: walletRefund,
155
+ totalCardRefundAmount: cardRefund,
156
+ handlingFee: Number(src.handlingFee || 0),
157
+ });
158
+ }
159
+ /**
160
+ * When exactly one of the four refund-destination fields (wallet / card /
161
+ * credit / loyalty) is non-zero, the backend has occasionally sent that
162
+ * field as a pre-deduction value that disagrees with the declared total
163
+ * (e.g. wallet = total + cancellation fee) — there's no ambiguity about
164
+ * *where* the money goes, only a stale number in that one field, so trust
165
+ * the declared total and correct the sole destination to match rather
166
+ * than surfacing a false discrepancy.
167
+ */
168
+ reconcileSoleDestination(d) {
169
+ if (!d?.isRefundable)
170
+ return d;
171
+ const wallet = Number(d.walletRefundAmount ?? 0);
172
+ const card = Number(d.totalCardRefundAmount ?? 0);
173
+ const credit = Number(d.totalCreditRefundAmount ?? 0);
174
+ const loyalty = Number(d.totalLoyaltyPointsRefundAmount ?? 0);
175
+ // A forfeited-points destination (e.g. Qitaf points funded separately
176
+ // from the card refund) also counts as a real destination here — without
177
+ // this, a legitimately split card+loyalty-points refund (e.g. 918 card +
178
+ // 50 Qitaf points = 968 total) looks like a single stale "card" field to
179
+ // this heuristic, which then force-overwrites the correct 918 with the
180
+ // full 968 total and silently erases the split.
181
+ const forfeitedLoyalty = this.forfeitedLoyaltyPointsFallback(d);
182
+ const nonZero = [wallet, card, credit, loyalty, forfeitedLoyalty].filter((v) => v > 0);
183
+ if (nonZero.length !== 1)
184
+ return d;
185
+ const total = Number(d.totalRefundAmountBeforeCeil ?? d.totalRefundAmount ?? 0);
186
+ if (wallet > 0 && Math.abs(wallet - total) >= 0.01)
187
+ return { ...d, walletRefundAmount: total };
188
+ if (card > 0 && Math.abs(card - total) >= 0.01)
189
+ return { ...d, totalCardRefundAmount: total };
190
+ if (credit > 0 && Math.abs(credit - total) >= 0.01)
191
+ return { ...d, totalCreditRefundAmount: total };
192
+ if (loyalty > 0 && Math.abs(loyalty - total) >= 0.01)
193
+ return { ...d, totalLoyaltyPointsRefundAmount: total };
194
+ return d;
195
+ }
196
+ /**
197
+ * Per-leg refund view (independent of the checkbox inclusion state) — used
198
+ * to render both legs' own breakdown cards simultaneously.
199
+ */
200
+ legAdjustedData(legType) {
201
+ const root = this.refundData();
202
+ const leg = root?.legInfo?.[legType];
203
+ if (!root || !leg)
204
+ return null;
205
+ const base = this.buildLegData(root, leg, legType);
206
+ return this.applySourceOverride(base, leg.sourceBreakdown ?? null);
207
+ }
208
+ /** Deduction rows for a single leg's card. */
209
+ legDeductions(legType) {
210
+ return this.deductionRows(this.legAdjustedData(legType));
211
+ }
212
+ /**
213
+ * Refundable pool ("Fare") for a leg — that leg's own paid amount
214
+ * (`totalSupplierBookingAmount`). `totalRefundAmount + totalCancellationFee`
215
+ * isn't reliable: `totalCancellationFee` doesn't include every deduction
216
+ * (e.g. `handlingFee`), which produced a Fare that didn't reconcile with
217
+ * Total Refund + the shown deductions.
218
+ */
219
+ legRefundPool(legType) {
220
+ const d = this.legAdjustedData(legType);
221
+ if (!d)
222
+ return 0;
223
+ return Number(d.totalSupplierBookingAmount || 0);
224
+ }
225
+ /** True once a leg's own departure time has passed. */
226
+ legAlreadyFlown(legType) {
227
+ const depTime = this.itineraryLeg(legType)?.depTime;
228
+ if (!depTime)
229
+ return false;
230
+ const t = new Date(depTime).getTime();
231
+ return !Number.isNaN(t) && t < Date.now();
232
+ }
233
+ /**
234
+ * Toggle a leg's inclusion. A non-refundable leg can't be checked, and the
235
+ * last checked leg can't be unchecked. Used on both the select-leg screen
236
+ * and the round-trip leg cards.
237
+ */
238
+ toggleLeg(legType) {
239
+ const refundable = legType === 'onward' ? this.onwardRefundable() : this.returnRefundable();
240
+ if (!refundable)
241
+ return;
242
+ const self = legType === 'onward' ? this.onwardChecked : this.returnChecked;
243
+ const other = legType === 'onward' ? this.returnChecked : this.onwardChecked;
244
+ if (self() && !other())
245
+ return;
246
+ const isTurningOff = self();
247
+ if (isTurningOff &&
248
+ this.isRoundTrip() &&
249
+ !this.isCrossSeller() &&
250
+ !this.legAlreadyFlown(legType)) {
251
+ // Airline doesn't allow cancelling this leg on its own — block the
252
+ // uncheck, keep it checked+frozen, and surface the note.
253
+ this.forcedLegType.set(legType);
254
+ return;
255
+ }
256
+ this.forcedLegType.set(null);
257
+ self.set(!self());
258
+ // A leg may carry its own source list — re-resolve the selection.
259
+ const breakdown = this.activeSourceBreakdown() ?? {};
260
+ const sources = Object.keys(breakdown);
261
+ if (sources.length && !breakdown[this.selectedSource()]) {
262
+ this.selectedSource.set(sources[0]);
263
+ }
264
+ }
265
+ /** Toggle a leg card's expanded/collapsed state. */
266
+ toggleLegExpanded(legType) {
267
+ const sig = legType === 'onward' ? this.onwardExpanded : this.returnExpanded;
268
+ sig.set(!sig());
269
+ }
270
+ /**
271
+ * Itemized refundable rows ("Fare" + named refundable add-ons/ancillaries)
272
+ * from `refundBreakdown.refundable`. Empty when the backend hasn't sent a
273
+ * breakdown yet — callers fall back to the single aggregate Fare row.
274
+ */
275
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
276
+ refundableBreakdownRows(d) {
277
+ const b = d?.refundBreakdown?.refundable;
278
+ if (!b)
279
+ return [];
280
+ // Fare always shows from refundBreakdown.refundable.fare, even when 0 —
281
+ // never falls back to originalAmount.
282
+ const rows = [{ label: 'Fare', value: Number(b.fare ?? 0) }];
283
+ [...(b.addOns ?? []), ...(b.ancillaries ?? [])]
284
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
285
+ .filter((item) => Number(item.amount) > 0)
286
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
287
+ .forEach((item) => rows.push({ label: item.name, value: Number(item.amount) }));
288
+ return rows;
289
+ }
290
+ /** Named refundable add-ons/ancillaries only (excludes Fare) — drives the "processed separately" note. */
291
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
292
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
293
+ refundableAddonItems(d) {
294
+ // Only `addOns` need manual Customer Service processing — `ancillaries`
295
+ // (baggage, seat, auto check-in, …) are already itemized/refunded
296
+ // automatically as part of the total, no separate note needed for them.
297
+ const b = d?.refundBreakdown?.refundable;
298
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
299
+ return (b?.addOns ?? []).filter((item) => Number(item.amount) > 0);
300
+ }
301
+ /** Whether to show the "add-on refund processed separately by Customer Service" note. */
302
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
303
+ hasRefundableAddonNote(d) {
304
+ return this.refundableAddonItems(d).length > 0;
305
+ }
306
+ /**
307
+ * Deduction rows for the "Not Refunded" section. When an itemized
308
+ * breakdown is present, its named add-ons/ancillaries replace the
309
+ * aggregate `totalAncillaryRefundAmount`/`totalGiftAmount` rows (same
310
+ * money, named instead of lumped); the other generic rows (cancellation
311
+ * fee, handling fee, service charge) are unaffected.
312
+ */
313
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
314
+ deductionRows(d) {
315
+ if (!d)
316
+ return [];
317
+ const b = d.refundBreakdown?.nonRefundable;
318
+ if (!b) {
319
+ return DEDUCTION_DEFS
320
+ .filter(def => Number(d[def.key]) > 0)
321
+ .map(def => ({ label: def.label, value: Number(d[def.key]), badge: def.badge }));
322
+ }
323
+ const itemRows = [...(b.addOns ?? []), ...(b.ancillaries ?? [])]
324
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
325
+ .filter((item) => Number(item.amount) > 0)
326
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
327
+ .map((item) => ({ label: item.name, value: Number(item.amount), badge: '' }));
328
+ const aggregateRows = DEDUCTION_DEFS
329
+ .filter(def => def.key !== 'totalAncillaryRefundAmount' && def.key !== 'totalGiftAmount')
330
+ .filter(def => Number(d[def.key]) > 0)
331
+ .map(def => ({ label: def.label, value: Number(d[def.key]), badge: def.badge }));
332
+ return [...itemRows, ...aggregateRows];
333
+ }
334
+ // Resolve the PNR for the currently selected leg from the booking's pnr_info list.
335
+ resolvePnr() {
336
+ const list = this.pnrInfo() ?? [];
337
+ if (!list.length)
338
+ return '';
339
+ const sel = this.selectedLeg();
340
+ const byDir = (dir) => list.find(p => p.LegDirectionality === dir)?.pnr;
341
+ if (sel === 'return')
342
+ return byDir('Return') ?? list[0]?.pnr ?? '';
343
+ if (sel === 'onward')
344
+ return byDir('Departure') ?? list[0]?.pnr ?? '';
345
+ return byDir('Departure') ?? list[0]?.pnr ?? '';
346
+ }
347
+ /** Rows that land in the wallet — plain wallet, wallet+loyalty combined, or loyalty-only — share the wallet icon/layout on the result screen. */
348
+ isWalletDestinationRow(r) {
349
+ return r.key === 'walletRefundAmount' || r.key === 'totalLoyaltyPoints';
350
+ }
351
+ fmtResult(value) {
352
+ const cur = this.cancelResult()?.currency ?? this.refundData()?.currency ?? 'SAR';
353
+ return `${Number(value || 0).toLocaleString('en-SA', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} ${cur}`;
354
+ }
355
+ /**
356
+ * `totalLoyaltyPoints` is normally the forfeited-at-booking points count
357
+ * (no refund destination of its own). But when the backend never
358
+ * populates `totalLoyaltyPointsRefundAmount` for a `loyaltyPaymentType`
359
+ * booking, this is the only signal that a loyalty program was involved,
360
+ * so it doubles as a split-refund row (alongside Card/Wallet) rather than
361
+ * disappearing from the refund breakdown entirely. Always shown as its
362
+ * own row under the program name (e.g. "Wala") — never merged into the
363
+ * generic Wallet row, even when `walletRefundAmount` is also non-zero.
364
+ */
365
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
366
+ forfeitedLoyaltyPointsFallback(d) {
367
+ if (!d?.loyaltyPaymentType)
368
+ return 0;
369
+ if (Number(d.totalLoyaltyPointsRefundAmount ?? 0) > 0)
370
+ return 0;
371
+ return Number(d.totalLoyaltyPoints ?? 0);
372
+ }
373
+ /**
374
+ * Some `/confirm` responses for a single-leg (non-cross-seller) booking
375
+ * put `walletRefundAmount`/`totalLoyaltyPoints` on the wrong side at the
376
+ * root — e.g. root reads `walletRefundAmount: 40, totalLoyaltyPoints: 0`
377
+ * while the single leg (which should mirror root exactly here) reads
378
+ * `walletRefundAmount: 0, totalLoyaltyPoints: 40`. Detected narrowly: root
379
+ * shows no forfeited loyalty despite `loyaltyPaymentType` being set, the
380
+ * root wallet amount exactly equals the leg's loyalty points, and the
381
+ * leg's own wallet amount disagrees — in that specific case the leg's
382
+ * values are trusted instead, since with only one leg they're unambiguous.
383
+ *
384
+ * A second, more common shape: root doesn't swap at all, it folds the
385
+ * points straight into `walletRefundAmount` as one opaque lump sum (e.g.
386
+ * root wallet 340 = the leg's own cash wallet 300 + the leg's forfeited
387
+ * loyalty points 40). Split that back into the two parts the leg already
388
+ * tells us about too, so the result screen can show a combined wallet card
389
+ * with the program named instead of one unexplained total.
390
+ */
391
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
392
+ correctedConfirmWalletAndLoyalty(d) {
393
+ const rootWallet = Number(d.walletRefundAmount ?? 0);
394
+ const forfeitedFromRoot = this.forfeitedLoyaltyPointsFallback(d);
395
+ if (forfeitedFromRoot > 0 || !d.loyaltyPaymentType) {
396
+ return { wallet: rootWallet, forfeitedLoyalty: forfeitedFromRoot };
397
+ }
398
+ const onward = d.legInfo?.onward;
399
+ const ret = d.legInfo?.return;
400
+ const leg = onward && !ret ? onward : ret && !onward ? ret : null;
401
+ if (!leg)
402
+ return { wallet: rootWallet, forfeitedLoyalty: 0 };
403
+ const legLoyalty = Number(leg.totalLoyaltyPoints ?? 0);
404
+ const legWallet = Number(leg.walletRefundAmount ?? 0);
405
+ // Full swap: root reads the leg's loyalty amount where its wallet should be.
406
+ if (legLoyalty > 0 &&
407
+ rootWallet === legLoyalty &&
408
+ legWallet !== rootWallet &&
409
+ Number(d.totalLoyaltyPointsRefundAmount ?? 0) === 0) {
410
+ return { wallet: legWallet, forfeitedLoyalty: legLoyalty };
411
+ }
412
+ // Lump sum: root wallet = leg's cash wallet + leg's forfeited loyalty.
413
+ if (legLoyalty > 0 &&
414
+ legWallet > 0 &&
415
+ Math.abs(rootWallet - (legWallet + legLoyalty)) < 1 &&
416
+ Number(d.totalLoyaltyPointsRefundAmount ?? 0) === 0) {
417
+ return { wallet: legWallet, forfeitedLoyalty: legLoyalty };
418
+ }
419
+ // Newer `/confirm` responses drop the loyalty portion from both root and
420
+ // leg totals — `walletRefundAmount` arrives as one opaque lump that's the
421
+ // cash-wallet portion (`totalWalletAmount`) plus a loyalty-program amount.
422
+ // When `loyaltyPaymentType` is set, the lump exceeds the cash-wallet
423
+ // portion, and it's a genuine card+wallet split (not a "send everything to
424
+ // the wallet" refund), the difference is that loyalty amount.
425
+ const cashWallet = Number(d.totalWalletAmount ?? 0);
426
+ const impliedLoyalty = rootWallet - cashWallet;
427
+ if (impliedLoyalty > 0.01 &&
428
+ cashWallet > 0 &&
429
+ Number(d.totalCardRefundAmount ?? 0) > 0 &&
430
+ Number(d.totalLoyaltyPointsRefundAmount ?? 0) === 0) {
431
+ return { wallet: cashWallet, forfeitedLoyalty: impliedLoyalty };
432
+ }
433
+ // The whole wallet refund is the loyalty-program balance — no cash-wallet
434
+ // portion (`totalWalletAmount` 0) and no card portion, but
435
+ // `loyaltyPaymentType` is set. Attribute all of it to the program so the
436
+ // popup names it (e.g. "Wala") with the permanent-points note.
437
+ if (cashWallet === 0 &&
438
+ rootWallet > 0 &&
439
+ Number(d.totalCardRefundAmount ?? 0) === 0 &&
440
+ Number(d.totalLoyaltyPointsRefundAmount ?? 0) === 0) {
441
+ return { wallet: 0, forfeitedLoyalty: rootWallet };
442
+ }
443
+ return { wallet: rootWallet, forfeitedLoyalty: 0 };
444
+ }
445
+ togglePaidSummary() {
446
+ this.paidSummaryExpanded.set(!this.paidSummaryExpanded());
447
+ }
448
+ /**
449
+ * The backend has sent `paymentMethodCustomerUsed` as both a short code
450
+ * (`"CH"`) and a full gateway name (`"Card"`) at different times — match
451
+ * either, case-insensitively, against the known codes/labels rather than
452
+ * assuming one format.
453
+ */
454
+ normalizeGatewayCode(raw) {
455
+ if (!raw)
456
+ return '';
457
+ const needle = raw.trim().toLowerCase();
458
+ const codes = Object.keys(PAYMENT_GATEWAY_LABELS);
459
+ const byCode = codes.find((code) => code.toLowerCase() === needle);
460
+ if (byCode)
461
+ return byCode;
462
+ return codes.find((code) => PAYMENT_GATEWAY_LABELS[code].toLowerCase() === needle) ?? '';
463
+ }
464
+ /**
465
+ * Wallet-row label for a loyalty-program redemption — `loyaltyPaymentType`
466
+ * (e.g. Wala, Qitaf) names the program that redeemed into the wallet
467
+ * balance and applies regardless of `paymentMethodCustomerUsed`; the
468
+ * backend can report an unrelated original payment gateway (e.g. Tabby)
469
+ * alongside a wallet portion that's actually a loyalty redemption.
470
+ */
471
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
472
+ walletOrLoyaltyLabel(d) {
473
+ const loyalty = d?.loyaltyPaymentType ?? '';
474
+ return PAYMENT_GATEWAY_LABELS[loyalty] ?? '';
475
+ }
476
+ constructor() {
477
+ this.bookingService = inject(SbdBookingService);
478
+ this.toast = inject(SbdToastService);
479
+ this.visible = input(false);
480
+ this.bookingId = input('');
481
+ this.product = input('flight');
482
+ this.pnrInfo = input([]);
483
+ /** Same `booking_info` payload the dashboard already fetches (getBooking(..., 'booking_info')) — reused here to render real route/time details on the select-leg cards, instead of a second API call. */
484
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
485
+ this.bookingInfo = input(null);
486
+ this.closed = output();
487
+ this.confirmed = output();
488
+ /** Per-leg route/time details, mirroring app-sbd-flight-itinerary-card's mapping of booking_info.leg_info. */
489
+ this.itineraryLegs = computed(() => {
490
+ const bi = this.bookingInfo()?.data?.booking_info;
491
+ if (!bi)
492
+ return [];
493
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
494
+ return (bi.leg_info ?? []).map((leg, i) => ({
495
+ direction: leg.LegDirectionality,
496
+ airlineName: (leg.LegAirlinesNames ?? []).join(', '),
497
+ cabin: leg.LegCabins?.[0]?.Name ?? '',
498
+ from: leg.LegDepartureAirportCode,
499
+ to: leg.LegArrivalAirportCode,
500
+ depTime: leg.LegDepartureDateTime,
501
+ arrTime: leg.LegArrivalDateTime,
502
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
503
+ stops: (leg.Stops ?? []),
504
+ totalMinutes: bi.duration?.legs?.[i]?.Segments
505
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
506
+ ?.reduce((sum, s) => sum + (s.SegmentElapsedTimeMinutes ?? 0), 0) ?? null,
507
+ operatedBy: leg.supplierName ? [leg.supplierName] : [],
508
+ }));
509
+ });
510
+ this.refundData = signal(null);
511
+ this.cancelResult = signal(null);
512
+ this.loading = signal(false);
513
+ this.cancelling = signal(false);
514
+ this.confirming = signal(false);
515
+ /**
516
+ * 'select-leg' shown once the refund preview resolves, for round-trip
517
+ * bookings the backend hasn't already restricted to a single leg — mirrors
518
+ * almatar-b2c's select-leg screen. Skipped straight to 'details' otherwise.
519
+ */
520
+ this.step = signal('loading');
521
+ /** Per-leg inclusion (checkbox) and expand/collapse state — round-trip only. */
522
+ this.onwardChecked = signal(true);
523
+ this.returnChecked = signal(true);
524
+ this.onwardExpanded = signal(true);
525
+ this.returnExpanded = signal(true);
526
+ this.selectedSource = signal('');
527
+ this.cancelHint = signal('');
528
+ this.paidSummaryExpanded = signal(false);
529
+ this.preferredRefundMethod = signal('originalPaymentMethod');
530
+ this.CANCEL_HINTS = [
531
+ 'Loading your data...',
532
+ 'Fetching Sabre data...',
533
+ 'Fetching ATC data...',
534
+ 'Calculating refund amount...',
535
+ 'We are almost done, please wait...',
536
+ ];
537
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
538
+ this.hintTimer = null;
539
+ this.hasOnward = computed(() => !!this.refundData()?.legInfo?.onward);
540
+ this.hasReturn = computed(() => !!this.refundData()?.legInfo?.return);
541
+ this.isRoundTrip = computed(() => this.hasOnward() && this.hasReturn());
542
+ /** Which leg(s) the backend allows cancelling, from the refund preview response. */
543
+ this.legDirectionality = computed(() => this.refundData()?.legDirectionality);
544
+ /**
545
+ * Whether to render the round-trip "two leg cards" UI. Only when the
546
+ * backend explicitly allows cancelling both legs — otherwise (ONWARD-only /
547
+ * RETURN-only) show a single card for that leg, same as a one-way booking.
548
+ */
549
+ this.showRoundTripLegCards = computed(() => this.isRoundTrip() && (this.legDirectionality() ?? 'BOTH') === 'BOTH');
550
+ /** Derived from the per-leg checkboxes — 'both' unless exactly one is unchecked. */
551
+ this.selectedLeg = computed(() => {
552
+ if (!this.isRoundTrip())
553
+ return 'both';
554
+ const dir = this.legDirectionality();
555
+ if (dir === 'ONWARD')
556
+ return 'onward';
557
+ if (dir === 'RETURN')
558
+ return 'return';
559
+ const onward = this.onwardChecked();
560
+ const ret = this.returnChecked();
561
+ if (onward && ret)
562
+ return 'both';
563
+ return onward ? 'onward' : 'return';
564
+ });
565
+ // Returns the sourceBreakdown for the currently selected leg (or root for "both")
566
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
567
+ this.activeSourceBreakdown = computed(() => {
568
+ const sel = this.selectedLeg();
569
+ const root = this.refundData();
570
+ if (!root)
571
+ return null;
572
+ // A leg-scoped view (single leg, or both legs summed) must not fall back
573
+ // to root.sourceBreakdown — its totals are for the whole/original
574
+ // itinerary, not scoped to the leg(s) actually shown, and applying it
575
+ // would clobber the correctly leg-scoped totals computed in
576
+ // `currentData()`.
577
+ if (sel === 'onward')
578
+ return root.legInfo?.onward?.sourceBreakdown ?? null;
579
+ if (sel === 'return')
580
+ return root.legInfo?.return?.sourceBreakdown ?? null;
581
+ if (root.legInfo?.onward && root.legInfo?.return)
582
+ return null;
583
+ return root.sourceBreakdown ?? null;
584
+ });
585
+ this.availableSources = computed(() => Object.keys(this.activeSourceBreakdown() ?? {}));
586
+ this.currentData = computed(() => {
587
+ const root = this.refundData();
588
+ if (!root)
589
+ return null;
590
+ const sel = this.selectedLeg();
591
+ if (sel === 'onward' && root.legInfo?.onward)
592
+ return this.buildLegData(root, root.legInfo.onward, 'onward');
593
+ if (sel === 'return' && root.legInfo?.return)
594
+ return this.buildLegData(root, root.legInfo.return, 'return');
595
+ // Payment/refund figures come from `legInfo`, never root (root isn't
596
+ // reliably scoped to whichever leg(s) ended up selected) — combine both
597
+ // legs when both are in play, otherwise use whichever one exists.
598
+ const onward = root.legInfo?.onward;
599
+ const ret = root.legInfo?.return;
600
+ if (onward && ret)
601
+ return this.buildCombinedLegData(root, onward, ret);
602
+ if (onward && !ret)
603
+ return this.buildLegData(root, onward, 'onward');
604
+ if (ret && !onward)
605
+ return this.buildLegData(root, ret, 'return');
606
+ return root;
607
+ });
608
+ // currentData with source-specific penalty/refund/refundability overrides applied
609
+ this.adjustedData = computed(() => {
610
+ const base = this.currentData();
611
+ if (!base)
612
+ return null;
613
+ return this.applySourceOverride(base, this.activeSourceBreakdown());
614
+ });
615
+ /**
616
+ * Non-CrossSeller airlines require the whole round-trip/multicity
617
+ * itinerary to be cancelled together — a leg can't be excluded on its own
618
+ * unless it has already flown (which naturally degrades to a one-way
619
+ * cancellation of just the remaining leg). Set when an uncheck attempt was
620
+ * blocked for this reason, so the leg's checkbox can be frozen (locked)
621
+ * and the note shown.
622
+ */
623
+ this.forcedLegType = signal(null);
624
+ this.sourceNonRefundableHint = computed(() => {
625
+ const sel = this.selectedSource();
626
+ if (!sel)
627
+ return '';
628
+ const src = (this.activeSourceBreakdown() ?? {})[sel];
629
+ if (!src || src.isRefundable !== false)
630
+ return '';
631
+ return `Cancellation via ${sel} is not eligible for a refund. Please select a different source.`;
632
+ });
633
+ this.deductions = computed(() => this.deductionRows(this.adjustedData()));
634
+ this.refunds = computed(() => {
635
+ const d = this.adjustedData();
636
+ if (!d)
637
+ return [];
638
+ const isLoyalty = this.isLoyaltyMethod();
639
+ const paymentLabel = this.customerPaymentLabel();
640
+ const rows = REFUND_DEFS
641
+ .filter(def => Number(d[def.key]) > 0)
642
+ .map(def => ({
643
+ // Wallet row always reads "Almatar Wallet" (def.label) — the loyalty
644
+ // program that funded it gets its own dedicated row below via
645
+ // `forfeitedLoyaltyPointsFallback`, so the two stay visually
646
+ // distinct instead of merging into one label.
647
+ // Card row: card/loyalty stay distinct — don't relabel the card
648
+ // portion with the loyalty program name too, and never surface an
649
+ // internal processor name (empty `paymentLabel` falls back to the
650
+ // generic def.label, e.g. "Refund Amount").
651
+ label: def.key === 'totalCardRefundAmount' && !isLoyalty && paymentLabel
652
+ ? `${def.label} ${paymentLabel}`
653
+ : def.label,
654
+ value: Number(d[def.key]),
655
+ }));
656
+ const forfeitedLoyalty = this.forfeitedLoyaltyPointsFallback(d);
657
+ if (forfeitedLoyalty > 0) {
658
+ rows.push({ label: this.walletOrLoyaltyLabel(d), value: forfeitedLoyalty });
659
+ }
660
+ return rows;
661
+ });
662
+ this.creditShellNote = computed(() => {
663
+ // Golden Guarantee overrides credit-shell messaging entirely — the
664
+ // dedicated success notice (`goldenGuaranteeNote`) is shown instead.
665
+ if (this.hasGoldenGuaranteeGift())
666
+ return '';
667
+ const d = this.currentData();
668
+ if (!d)
669
+ return '';
670
+ const legInfo = d.legInfo ?? {};
671
+ const hasO = !!legInfo.onward;
672
+ const hasR = !!legInfo.return;
673
+ const oShell = legInfo.onward?.isCreditShell === true;
674
+ const rShell = legInfo.return?.isCreditShell === true;
675
+ const isShell = (hasO && hasR && oShell && rShell) ||
676
+ (hasO && !hasR && oShell) ||
677
+ (!hasO && hasR && rShell) ||
678
+ (hasO && hasR && (oShell || rShell));
679
+ if (!isShell)
680
+ return '';
681
+ const amount = this.fmt(Number(this.adjustedData()?.totalRefundAmount ?? d.totalRefundAmount ?? 0));
682
+ const pnr = this.resolvePnr();
683
+ const pnrText = pnr ? `the same PNR (${pnr})` : 'the same PNR';
684
+ return `The refund of ${amount} will be issued as airline credit under ${pnrText}. ${CREDIT_SHELL_SUFFIX}`;
685
+ });
686
+ /**
687
+ * Booking includes a Golden Guarantee gift ("Cancel for any reason") —
688
+ * overrides all credit-shell handling below, since a Golden Guarantee
689
+ * cancellation always refunds 100% through the standard payment method
690
+ * rather than the airline credit shell. May be carried on either the
691
+ * preview (`refundData`) or the confirm (`cancelResult`) response — both
692
+ * share the same shape, and either one may set it independently of the
693
+ * other.
694
+ */
695
+ this.hasGoldenGuaranteeGift = computed(() => this.refundData()?.hasGoldenGuaranteeGift === true ||
696
+ this.cancelResult()?.hasGoldenGuaranteeGift === true);
697
+ // Whether the refund is a credit-shell refund (whole booking or either leg).
698
+ // Such refunds can only return to the airline credit shell, so the
699
+ // refund-method picker is replaced with a single read-only credit notice.
700
+ // A Golden Guarantee gift overrides this to `false` — that portion needs an
701
+ // actual destination choice, so the booking falls back to the standard
702
+ // refund-method flow despite being flagged credit-shell.
703
+ this.isCreditShell = computed(() => {
704
+ if (this.hasGoldenGuaranteeGift())
705
+ return false;
706
+ const d = this.refundData();
707
+ return (d?.isCreditShell === true ||
708
+ d?.legInfo?.onward?.isCreditShell === true ||
709
+ d?.legInfo?.return?.isCreditShell === true);
710
+ });
711
+ /**
712
+ * Refundable ancillaries (baggage, seats, …) that carry their own
713
+ * `isCreditShell` flag, independent of the booking-level flag — rendered
714
+ * as individual cards on the credit-shell refund-method screen so each
715
+ * one can show either the credit-shell card style or the normal wallet
716
+ * card style (both include the same nested credit-shell note when true).
717
+ */
718
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
719
+ this.creditShellAncillaryItems = computed(() => (this.adjustedData()?.refundBreakdown?.refundable?.ancillaries ?? [])
720
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
721
+ .filter((item) => Number(item.amount) > 0));
722
+ // Airline that issues the credit shell, for the "<supplier> website credit" card.
723
+ this.creditShellSupplierName = computed(() => {
724
+ const d = this.refundData();
725
+ return (d?.legInfo?.onward?.supplierName ??
726
+ d?.legInfo?.return?.supplierName ??
727
+ d?.supplierName ??
728
+ d?.appliedSource ??
729
+ '');
730
+ });
731
+ // Header title reflecting the refund type for the active selection.
732
+ this.refundTypeLabel = computed(() => {
733
+ if (!this.refundData()?.isRefundable)
734
+ return 'Refund Details';
735
+ return this.creditShellNote() ? 'Credit Shell Refund' : 'Refund Details';
736
+ });
737
+ this.currency = computed(() => this.refundData()?.currency ?? 'SAR');
738
+ // Self-consistency check between the paid amount, deductions and the system refund.
739
+ // Surfaced to the agent so mismatched/over-deducted refunds can be caught before confirming.
740
+ this.discrepancyNote = computed(() => {
741
+ const d = this.adjustedData();
742
+ if (!d || !d.isRefundable)
743
+ return '';
744
+ const paid = Number(d.originalAmount || 0);
745
+ const deduction = Number(d.totalCancellationFee || 0);
746
+ const refund = Number(d.totalRefundAmount || 0);
747
+ const issues = [];
748
+ if (deduction > paid + 0.01)
749
+ issues.push(`Total deduction (${this.fmt(deduction)}) exceeds the paid amount (${this.fmt(paid)}).`);
750
+ if (Math.abs((paid - deduction) - refund) > 0.01)
751
+ issues.push(`Computed refund (${this.fmt(paid - deduction)}) doesn't match the system refund (${this.fmt(refund)}).`);
752
+ return issues.join(' ');
753
+ });
754
+ /** Real per-booking CrossSeller flag from the refund preview — CrossSeller suppliers allow cancelling either leg independently. */
755
+ this.isCrossSeller = computed(() => this.refundData()?.isCrossSeller === true);
756
+ // Non-CrossSeller round trips are one itinerary sold as a single fare —
757
+ // both legs share the same refundability, sourced from root, even when
758
+ // the backend's legInfo entry for a leg is missing or inconsistent.
759
+ // CrossSeller legs are independently sellable, so each leg's own field
760
+ // still governs there.
761
+ this.onwardRefundable = computed(() => {
762
+ if (!this.hasOnward())
763
+ return false;
764
+ return this.isCrossSeller()
765
+ ? this.refundData()?.legInfo?.onward?.isRefundable === true
766
+ : this.refundData()?.isRefundable === true;
767
+ });
768
+ this.returnRefundable = computed(() => {
769
+ if (!this.hasReturn())
770
+ return false;
771
+ return this.isCrossSeller()
772
+ ? this.refundData()?.legInfo?.return?.isRefundable === true
773
+ : this.refundData()?.isRefundable === true;
774
+ });
775
+ this.isMixed = computed(() => this.isRoundTrip() && this.onwardRefundable() !== this.returnRefundable());
776
+ /** Both legs present and BOTH non-refundable — nothing can be refunded for this booking. */
777
+ this.allLegsNonRefundable = computed(() => this.isRoundTrip() && !this.onwardRefundable() && !this.returnRefundable());
778
+ this.mixedHint = computed(() => {
779
+ // Only relevant when agent is about to cancel both legs together —
780
+ // individual leg tabs already show their own non-refundable notice.
781
+ if (!this.isMixed() || this.selectedLeg() !== 'both')
782
+ return '';
783
+ if (!this.onwardRefundable())
784
+ return '⚠️ Onward leg is not eligible for refund. Please contact customer service if you want to cancel it.';
785
+ if (!this.returnRefundable())
786
+ return '⚠️ Return leg is not eligible for refund. Please contact customer service if you want to cancel it.';
787
+ return '';
788
+ });
789
+ this.giftHint = computed(() => {
790
+ const root = this.refundData();
791
+ if (!root || !this.isRoundTrip())
792
+ return '';
793
+ const hasGift = Number(root.totalGiftAmount || 0) > 0 ||
794
+ Number(root.legInfo?.onward?.totalGiftAmount || 0) > 0 ||
795
+ Number(root.legInfo?.return?.totalGiftAmount || 0) > 0;
796
+ return hasGift ? GIFT_HINT : '';
797
+ });
798
+ this.selectionHint = computed(() => {
799
+ if (!this.isRoundTrip())
800
+ return '';
801
+ const map = {
802
+ onward: 'You are about to cancel: Onward leg only',
803
+ return: 'You are about to cancel: Return leg only',
804
+ both: 'You are about to cancel: Both legs',
805
+ };
806
+ return map[this.selectedLeg()];
807
+ });
808
+ this.confirmDeductions = computed(() => {
809
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
810
+ const d = this.cancelResult();
811
+ if (!d)
812
+ return [];
813
+ return DEDUCTION_DEFS.filter(def => Number(d[def.key]) > 0).map(def => ({ label: def.label, value: Number(d[def.key]) }));
814
+ });
815
+ this.confirmRefunds = computed(() => {
816
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
817
+ const d = this.cancelResult();
818
+ if (!d)
819
+ return [];
820
+ const code = this.normalizeGatewayCode(d.paymentMethodCustomerUsed);
821
+ const isLoyalty = LOYALTY_GATEWAY_CODES.includes(code);
822
+ const isMada = this.confirmIsMadaMethod();
823
+ const paymentLabel = code && !INTERNAL_GATEWAY_CODES.includes(code) ? PAYMENT_GATEWAY_LABELS[code] : '';
824
+ const rows = [];
825
+ const { wallet, forfeitedLoyalty } = this.correctedConfirmWalletAndLoyalty(d);
826
+ // Golden Guarantee overrides credit-shell handling on the result screen
827
+ // too — whatever landed as a credit-shell amount folds into the normal
828
+ // original-payment-method row instead of getting its own "airline
829
+ // credit" card, so the confirmation reads like an ordinary Sabre/Amadeus
830
+ // refund.
831
+ const goldenGuaranteeOverride = this.hasGoldenGuaranteeGift();
832
+ // Credit-shell row goes first — matches the design (airline credit above
833
+ // the wallet row) — before the card and wallet rows below.
834
+ if (!goldenGuaranteeOverride) {
835
+ const credit = Number(d.totalCreditRefundAmount ?? 0);
836
+ if (credit > 0) {
837
+ const supplier = d.appliedSource || this.creditShellSupplierName();
838
+ rows.push({
839
+ key: 'totalCreditRefundAmount',
840
+ label: supplier ? `${supplier} website credit` : 'Credit Shell Refund',
841
+ value: credit,
842
+ });
843
+ }
844
+ }
845
+ const cardAmount = Number(d.totalCardRefundAmount ?? 0) +
846
+ (goldenGuaranteeOverride ? Number(d.totalCreditRefundAmount ?? 0) : 0);
847
+ if (cardAmount > 0) {
848
+ rows.push({
849
+ key: 'totalCardRefundAmount',
850
+ label: isMada
851
+ ? 'Mada Card'
852
+ : !isLoyalty && paymentLabel
853
+ ? `Refund Amount ${paymentLabel}`
854
+ : 'Refund Amount',
855
+ value: cardAmount,
856
+ });
857
+ }
858
+ if (wallet > 0 && forfeitedLoyalty > 0) {
859
+ // Wallet cash + a loyalty program's points both landed in the wallet —
860
+ // shown as one combined card with the two sources broken out as named
861
+ // sub-rows, rather than two separate top-level cards.
862
+ rows.push({
863
+ key: 'walletRefundAmount',
864
+ label: 'Almatar Wallet',
865
+ value: wallet + forfeitedLoyalty,
866
+ subRows: [
867
+ { label: 'Almatar wallet points', value: wallet },
868
+ { label: `${this.walletOrLoyaltyLabel(d)} points`, value: forfeitedLoyalty },
869
+ ],
870
+ hasLoyaltyNote: true,
871
+ });
872
+ }
873
+ else if (wallet > 0) {
874
+ rows.push({ key: 'walletRefundAmount', label: 'Almatar Wallet', value: wallet });
875
+ }
876
+ else if (forfeitedLoyalty > 0) {
877
+ // Loyalty-only — no wallet cash involved, still lands as permanent
878
+ // wallet points, so it keeps the wallet-style card + note.
879
+ rows.push({
880
+ key: 'totalLoyaltyPoints',
881
+ label: this.walletOrLoyaltyLabel(d),
882
+ value: forfeitedLoyalty,
883
+ hasLoyaltyNote: true,
884
+ });
885
+ }
886
+ REFUND_DEFS
887
+ .filter((def) => def.key !== 'walletRefundAmount' &&
888
+ def.key !== 'totalCardRefundAmount' &&
889
+ def.key !== 'totalCreditRefundAmount' &&
890
+ Number(d[def.key]) > 0)
891
+ .forEach((def) => {
892
+ rows.push({ key: def.key, label: def.label, value: Number(d[def.key]) });
893
+ });
894
+ return rows;
895
+ });
896
+ /**
897
+ * The result screen's "issued as an Airline Credit Shell" note. Golden
898
+ * Guarantee overrides this to '' — the confirmation renders like a
899
+ * standard Sabre/Amadeus refund instead (see `confirmRefunds`' folding
900
+ * of any credit-shell amount into the normal payment-method row).
901
+ */
902
+ this.confirmCreditShellNote = computed(() => {
903
+ if (this.hasGoldenGuaranteeGift())
904
+ return '';
905
+ const d = this.cancelResult();
906
+ if (!d)
907
+ return '';
908
+ const legInfo = d.legInfo ?? {};
909
+ const hasO = !!legInfo.onward;
910
+ const hasR = !!legInfo.return;
911
+ const oShell = legInfo.onward?.isCreditShell === true;
912
+ const rShell = legInfo.return?.isCreditShell === true;
913
+ const topShell = d.isCreditShell === true;
914
+ if ((hasO && hasR && oShell && rShell) || (hasO && !hasR && oShell) || (!hasO && hasR && rShell) || topShell)
915
+ return 'The refund has been issued as an Airline Credit Shell and can be used for future bookings on the airline website.';
916
+ if (hasO && hasR) {
917
+ if (oShell)
918
+ return 'The refund for the onward flight has been issued as an Airline Credit Shell.';
919
+ if (rShell)
920
+ return 'The refund for the return flight has been issued as an Airline Credit Shell.';
921
+ }
922
+ return '';
923
+ });
924
+ /**
925
+ * The customer-facing total (ceiled) must match the pre-rounding total the
926
+ * refund is actually computed from — i.e. `totalRefundAmount` must be
927
+ * `totalRefundAmountBeforeCeil` rounded up to a whole currency unit (e.g.
928
+ * 1454.5 → 1455). A mismatch here means the supplier response itself is
929
+ * internally inconsistent and must block confirmation.
930
+ */
931
+ this.refundReconciles = computed(() => {
932
+ const d = this.adjustedData();
933
+ if (!d || !d.isRefundable)
934
+ return true;
935
+ const beforeCeil = Number(d.totalRefundAmountBeforeCeil ?? d.totalRefundAmount ?? 0);
936
+ const total = Number(d.totalRefundAmount ?? beforeCeil);
937
+ return Math.abs(Math.ceil(beforeCeil) - total) < 1;
938
+ });
939
+ this.canConfirm = computed(() => {
940
+ const d = this.adjustedData();
941
+ return !!d?.isRefundable && this.refundReconciles() && !this.cancelling();
942
+ });
943
+ /** How many of {wallet, card, loyalty} the refund is actually split across. */
944
+ this.splitPartsCount = computed(() => {
945
+ const d = this.adjustedData();
946
+ if (!d)
947
+ return 0;
948
+ return [
949
+ d.walletRefundAmount,
950
+ d.totalCardRefundAmount,
951
+ d.totalLoyaltyPointsRefundAmount,
952
+ this.forfeitedLoyaltyPointsFallback(d),
953
+ ].filter((v) => Number(v ?? 0) > 0).length;
954
+ });
955
+ /**
956
+ * A portion of the refund is forced to the wallet (e.g. loyalty points used)
957
+ * — in that case offer a "Split Refund" option instead of a pure
958
+ * original-payment-method option, since the whole amount can't go to card.
959
+ */
960
+ this.hasSplitRefund = computed(() => Number(this.adjustedData()?.totalRefundAmount ?? 0) > 0 && this.splitPartsCount() >= 2);
961
+ /**
962
+ * Wallet covers the whole refund (no card or loyalty portion at all) — show
963
+ * the wallet option alone rather than a "split" with empty other sides.
964
+ */
965
+ this.isWalletOnlyRefund = computed(() => {
966
+ const d = this.adjustedData();
967
+ return (Number(d?.walletRefundAmount ?? 0) > 0 &&
968
+ Number(d?.totalCardRefundAmount ?? 0) === 0 &&
969
+ Number(d?.totalLoyaltyPointsRefundAmount ?? 0) === 0 &&
970
+ this.forfeitedLoyaltyPointsFallback(d) === 0);
971
+ });
972
+ /**
973
+ * The entire refund is forfeited loyalty points (e.g. Wala) landing back as
974
+ * wallet balance — no cash-wallet, card, credit or real
975
+ * loyalty-points-refund portion at all. Without this the picker falls
976
+ * through to the "Original Payment Method" card and mislabels the
977
+ * destination as the original gateway (e.g. "Tabby"), even though
978
+ * `totalCardRefundAmount` is 0 and nothing goes back to that card.
979
+ */
980
+ this.isLoyaltyOnlyRefund = computed(() => {
981
+ const d = this.adjustedData();
982
+ return (this.forfeitedLoyaltyPointsFallback(d) > 0 &&
983
+ Number(d?.walletRefundAmount ?? 0) === 0 &&
984
+ Number(d?.totalCardRefundAmount ?? 0) === 0 &&
985
+ Number(d?.totalCreditRefundAmount ?? 0) === 0 &&
986
+ Number(d?.totalLoyaltyPointsRefundAmount ?? 0) === 0);
987
+ });
988
+ /** A real cash-wallet portion is part of the refund (distinct from forfeited loyalty points landing in the wallet). */
989
+ this.hasCashWalletRefund = computed(() => Number(this.adjustedData()?.walletRefundAmount ?? 0) > 0);
990
+ /**
991
+ * Wallet card's title — normally "Almatar Wallet", but the loyalty program
992
+ * name (Wala, Qitaf, …) when the whole refund is that program's forfeited
993
+ * balance landing back in the wallet.
994
+ */
995
+ this.walletCardLabel = computed(() => this.isLoyaltyOnlyRefund()
996
+ ? this.walletOrLoyaltyLabel(this.adjustedData()) || 'Almatar Wallet'
997
+ : 'Almatar Wallet');
998
+ /**
999
+ * Part of the refund came from converting external loyalty points into
1000
+ * wallet funds — surfaced as a note under the wallet destination so the
1001
+ * agent knows those points land as permanent wallet balance, not cash.
1002
+ */
1003
+ this.hasLoyaltyPointsRefund = computed(() => Number(this.adjustedData()?.totalLoyaltyPoints ?? 0) > 0);
1004
+ /**
1005
+ * The booking is refundable but nets to 0.00 after deductions — a
1006
+ * dedicated NIL Refund state, distinct from "not refundable": no refund
1007
+ * method to choose between, just confirmation that nothing is owed back.
1008
+ */
1009
+ this.isNilRefund = computed(() => {
1010
+ const d = this.adjustedData();
1011
+ return !!d?.isRefundable && Number(d.totalRefundAmount ?? 0) === 0;
1012
+ });
1013
+ /** Same as `isNilRefund`, scoped to the confirmed cancellation result — drives the result screen's title. */
1014
+ this.confirmIsNilRefund = computed(() => {
1015
+ const d = this.cancelResult();
1016
+ return !!d?.isRefundable && Number(d.totalRefundAmount ?? 0) === 0;
1017
+ });
1018
+ /** Whether the customer may send the whole refund to their Almatar Wallet. */
1019
+ this.isFullWalletRefundAllowed = computed(() => !!this.adjustedData()?.isFullWalletRefundAllowed);
1020
+ /** Whether the customer paid via an installment gateway (Tamara, Tabby, …). */
1021
+ this.isInstallmentMethod = computed(() => INSTALLMENT_GATEWAY_CODES.includes(this.normalizeGatewayCode(this.adjustedData()?.paymentMethodCustomerUsed)));
1022
+ /** Whether the customer paid via a loyalty-program gateway (Al Rajhi Mokafaa, …). */
1023
+ this.isLoyaltyMethod = computed(() => LOYALTY_GATEWAY_CODES.includes(this.normalizeGatewayCode(this.adjustedData()?.paymentMethodCustomerUsed)));
1024
+ /** Any gateway that refunds somewhere other than a plain card — used for the wallet-style icon. */
1025
+ this.isSpecialGatewayMethod = computed(() => this.isInstallmentMethod() || this.isLoyaltyMethod());
1026
+ /**
1027
+ * Card-refund settlement-timeline badge — Tabby and Tamara each have their
1028
+ * own processing window, distinct from a plain card's generic bank policy.
1029
+ */
1030
+ this.cardBadgeText = computed(() => {
1031
+ const code = this.normalizeGatewayCode(this.adjustedData()?.paymentMethodCustomerUsed);
1032
+ if (code === 'TB')
1033
+ return 'From 5-7 business days';
1034
+ if (code === 'TM')
1035
+ return 'Up to 10 business days';
1036
+ if (this.isLoyaltyMethod())
1037
+ return 'Loyalty Program Policy';
1038
+ return 'Up to 15 business days, bank policy';
1039
+ });
1040
+ /** Same as `cardBadgeText`, scoped to the confirmed cancellation result. */
1041
+ this.confirmCardBadgeText = computed(() => {
1042
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1043
+ const d = this.cancelResult();
1044
+ const code = this.normalizeGatewayCode(d?.paymentMethodCustomerUsed);
1045
+ if (code === 'TB')
1046
+ return 'From 5-7 business days';
1047
+ if (code === 'TM')
1048
+ return 'Up to 10 business days';
1049
+ if (LOYALTY_GATEWAY_CODES.includes(code))
1050
+ return 'Loyalty Program Policy';
1051
+ return 'Up to 15 business days, bank policy';
1052
+ });
1053
+ /**
1054
+ * Per-method breakdown of the "Total paid" amount. The backend doesn't
1055
+ * (yet) expose a dedicated original-payment breakdown, so the known
1056
+ * refund-destination fields (card / wallet / loyalty) are used as a proxy
1057
+ * for how the booking was originally paid, and whatever's left over after
1058
+ * those (e.g. a non-refundable leg/fee that never shows up in any refund
1059
+ * field) is folded into the primary payment method — so the rows always
1060
+ * add up to the full `originalAmount` shown above them, instead of only
1061
+ * covering the refundable portion.
1062
+ */
1063
+ this.paidBreakdownRows = computed(() => {
1064
+ const d = this.adjustedData();
1065
+ if (!d)
1066
+ return [];
1067
+ // Card and loyalty stay distinct labels (same categorization as
1068
+ // `refunds`) so a gateway like Al Rajhi Mokafaa doesn't swallow an
1069
+ // actual separate card portion under one label.
1070
+ const cardLabel = (!this.isLoyaltyMethod() && this.customerPaymentLabel()) || 'Original Payment Method';
1071
+ // The wallet destination row always reads "Almatar Wallet" — unlike
1072
+ // `refunds`/`confirmRefunds`, this row never swaps to the loyalty
1073
+ // program name, since `forfeitedLoyaltyLabel` below is that program's
1074
+ // own dedicated row and the two must stay visually distinct here.
1075
+ const walletLabel = 'Almatar Wallet';
1076
+ const forfeitedLoyaltyLabel = this.walletOrLoyaltyLabel(d) || 'Loyalty Points';
1077
+ const loyaltyLabel = this.customerPaymentLabel() || 'Loyalty Points Refund';
1078
+ const amounts = new Map();
1079
+ const add = (label, value) => {
1080
+ if (value <= 0)
1081
+ return;
1082
+ amounts.set(label, (amounts.get(label) ?? 0) + value);
1083
+ };
1084
+ add(cardLabel, Number(d.totalCardRefundAmount ?? 0));
1085
+ // This row shows how much of the *original* payment went through the
1086
+ // wallet — `totalWalletAmount`, not `walletRefundAmount` (a refund
1087
+ // destination amount that can differ, e.g. only part of the wallet
1088
+ // payment is refundable after deductions).
1089
+ add(walletLabel, Number(d.totalWalletAmount ?? 0));
1090
+ add(loyaltyLabel, Number(d.totalLoyaltyPointsRefundAmount ?? 0));
1091
+ // `totalLoyaltyPoints` is the portion of the *original* payment made with
1092
+ // loyalty points (now forfeited/deducted, not refunded) — distinct from
1093
+ // `totalLoyaltyPointsRefundAmount` above and from `walletRefundAmount`
1094
+ // (an unrelated refund-destination amount). Always shown as its own row
1095
+ // under the program name (e.g. "Qitaf"/"Wala") rather than merged into
1096
+ // the generic Wallet row or silently folded into the leftover remainder.
1097
+ add(forfeitedLoyaltyLabel, Number(d.totalLoyaltyPoints ?? 0));
1098
+ const total = Number(d.originalAmount ?? 0);
1099
+ const known = [...amounts.values()].reduce((a, b) => a + b, 0);
1100
+ const remainder = total - known;
1101
+ if (remainder > 0.01) {
1102
+ // Unaccounted leftover (e.g. a non-refundable portion) is folded into
1103
+ // the primary/default payment channel rather than a fabricated 4th row.
1104
+ add(cardLabel, remainder);
1105
+ }
1106
+ return [...amounts.entries()].map(([label, value]) => ({ label, value }));
1107
+ });
1108
+ /** The "Total paid" row always expands — there's always at least one method to show. */
1109
+ this.hasPaidBreakdown = computed(() => this.paidBreakdownRows().length > 0);
1110
+ /**
1111
+ * Display label for `paymentMethodCustomerUsed`, or '' if unknown/internal.
1112
+ * Never surfaces an internal processor name (e.g. Hyperpay) to the agent —
1113
+ * callers fall back to a generic "Original Payment Method" label whenever
1114
+ * this returns ''.
1115
+ */
1116
+ this.customerPaymentLabel = computed(() => {
1117
+ const code = this.normalizeGatewayCode(this.adjustedData()?.paymentMethodCustomerUsed);
1118
+ if (code && INTERNAL_GATEWAY_CODES.includes(code))
1119
+ return '';
1120
+ return code ? PAYMENT_GATEWAY_LABELS[code] : '';
1121
+ });
1122
+ /** Whether the confirmed cancellation's card refund settles via Mada. */
1123
+ this.isMadaMethod = computed(() => {
1124
+ const code = this.normalizeGatewayCode(this.adjustedData()?.paymentMethodCustomerUsed);
1125
+ return !!code && MADA_GATEWAY_CODES.includes(code);
1126
+ });
1127
+ /**
1128
+ * Label for the standalone "Original Payment Method" option card (shown
1129
+ * when the whole refund goes to one destination). Mada wins over
1130
+ * everything else, reading "Mada Card" instead of the generic gateway
1131
+ * name or the "Original Payment Method" fallback.
1132
+ */
1133
+ this.originalPaymentLabel = computed(() => {
1134
+ if (this.isMadaMethod())
1135
+ return 'Mada Card';
1136
+ return this.customerPaymentLabel() || 'Original Payment Method';
1137
+ });
1138
+ /** Same as `isMadaMethod`, scoped to the confirmed cancellation result. */
1139
+ this.confirmIsMadaMethod = computed(() => {
1140
+ const code = this.normalizeGatewayCode(this.cancelResult()?.paymentMethodCustomerUsed);
1141
+ return !!code && MADA_GATEWAY_CODES.includes(code);
1142
+ });
1143
+ /**
1144
+ * Split-refund destination rows — up to four: Almatar Wallet (generic
1145
+ * label), the original payment method (card/installment gateway), a
1146
+ * separate loyalty-points-refund row when the backend sends one, and a
1147
+ * dedicated loyalty-program row (Wala, Qitaf, …) for forfeited points
1148
+ * (`forfeitedLoyaltyPointsFallback`) — kept distinct from the Wallet row
1149
+ * even when both are non-zero.
1150
+ */
1151
+ this.splitRefundRows = computed(() => {
1152
+ const d = this.adjustedData();
1153
+ if (!d)
1154
+ return [];
1155
+ const rows = [];
1156
+ const wallet = Number(d.walletRefundAmount ?? 0);
1157
+ if (wallet > 0) {
1158
+ rows.push({ label: 'Almatar Wallet', value: wallet, instant: true, isLoyalty: false, badgeText: 'Instant' });
1159
+ }
1160
+ const card = Number(d.totalCardRefundAmount ?? 0);
1161
+ if (card > 0) {
1162
+ const badgeText = this.cardBadgeText();
1163
+ rows.push({
1164
+ label: this.isMadaMethod()
1165
+ ? 'Mada Card'
1166
+ : (!this.isLoyaltyMethod() && this.customerPaymentLabel()) || 'Original Payment Method',
1167
+ value: card,
1168
+ instant: false,
1169
+ isLoyalty: false,
1170
+ badgeText,
1171
+ isMada: this.isMadaMethod(),
1172
+ });
1173
+ }
1174
+ const loyalty = Number(d.totalLoyaltyPointsRefundAmount ?? 0);
1175
+ if (loyalty > 0) {
1176
+ rows.push({
1177
+ label: this.customerPaymentLabel() || 'Loyalty Points Refund',
1178
+ value: loyalty,
1179
+ instant: true,
1180
+ isLoyalty: true,
1181
+ badgeText: 'Instant',
1182
+ });
1183
+ }
1184
+ const forfeitedLoyalty = this.forfeitedLoyaltyPointsFallback(d);
1185
+ if (forfeitedLoyalty > 0) {
1186
+ rows.push({
1187
+ label: this.walletOrLoyaltyLabel(d) || 'Loyalty Points',
1188
+ value: forfeitedLoyalty,
1189
+ instant: true,
1190
+ isLoyalty: true,
1191
+ badgeText: 'Instant',
1192
+ });
1193
+ }
1194
+ return rows;
1195
+ });
1196
+ effect(() => {
1197
+ if (this.visible() && this.bookingId()) {
1198
+ this.loadRefund();
1199
+ }
1200
+ else {
1201
+ this.stopHints();
1202
+ this.refundData.set(null);
1203
+ this.cancelResult.set(null);
1204
+ this.onwardChecked.set(true);
1205
+ this.returnChecked.set(true);
1206
+ this.forcedLegType.set(null);
1207
+ this.onwardExpanded.set(true);
1208
+ this.returnExpanded.set(true);
1209
+ this.selectedSource.set('');
1210
+ this.preferredRefundMethod.set('originalPaymentMethod');
1211
+ this.confirming.set(false);
1212
+ this.cancelling.set(false);
1213
+ this.step.set('loading');
1214
+ }
1215
+ }, { allowSignalWrites: true });
1216
+ }
1217
+ loadRefund() {
1218
+ this.loading.set(true);
1219
+ this.startHints();
1220
+ this.bookingService.getRefundDetails(this.bookingId(), this.product()).subscribe({
1221
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1222
+ next: (raw) => {
1223
+ let data = raw?.data ?? raw;
1224
+ this.stopHints();
1225
+ this.refundData.set(data);
1226
+ // Auto-select source: prefer appliedSource, otherwise pick first available
1227
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1228
+ const breakdown = data?.sourceBreakdown ?? {};
1229
+ const sources = Object.keys(breakdown);
1230
+ if (sources.length > 0) {
1231
+ const applied = data?.appliedSource;
1232
+ this.selectedSource.set(applied && breakdown[applied] ? applied : sources[0]);
1233
+ }
1234
+ this.loading.set(false);
1235
+ // Only show the leg picker for a genuine round-trip the backend hasn't
1236
+ // already restricted to a single leg — otherwise go straight to details.
1237
+ if (this.showRoundTripLegCards()) {
1238
+ // Pre-check whichever legs are actually refundable, matching the
1239
+ // consumer app's "non-refundable legs can't be selected" behavior.
1240
+ this.onwardChecked.set(this.onwardRefundable());
1241
+ this.returnChecked.set(this.returnRefundable());
1242
+ this.step.set('select-leg');
1243
+ }
1244
+ else {
1245
+ this.step.set('details');
1246
+ }
1247
+ },
1248
+ error: () => { this.stopHints(); this.loading.set(false); this.toast.error('Could not load refund details.'); },
1249
+ });
1250
+ }
1251
+ /**
1252
+ * Both legs in play — sum each leg's own figures instead of trusting root
1253
+ * (root isn't reliably scoped to the picked alternatives, e.g. rounding
1254
+ * can drift between leg totals and the combined root total).
1255
+ */
1256
+ buildCombinedLegData(root, onward, ret) {
1257
+ const onwardData = this.buildLegData(root, onward, 'onward');
1258
+ const returnData = this.buildLegData(root, ret, 'return');
1259
+ const sum = (key) => Number(onwardData[key] || 0) + Number(returnData[key] || 0);
1260
+ return {
1261
+ ...root,
1262
+ isRefundable: onward.isRefundable === true && ret.isRefundable === true,
1263
+ totalRefundAmount: sum('totalRefundAmount'),
1264
+ totalRefundAmountBeforeCeil: sum('totalRefundAmountBeforeCeil'),
1265
+ totalCardRefundAmount: sum('totalCardRefundAmount'),
1266
+ totalCreditRefundAmount: sum('totalCreditRefundAmount'),
1267
+ totalNonRefundableServiceCharge: sum('totalNonRefundableServiceCharge'),
1268
+ totalCouponAmount: sum('totalCouponAmount'),
1269
+ walletRefundAmount: sum('walletRefundAmount'),
1270
+ totalPenaltyPoints: sum('totalPenaltyPoints'),
1271
+ totalSupplierPenaltyPoints: sum('totalSupplierPenaltyPoints'),
1272
+ totalLoyaltyPoints: sum('totalLoyaltyPoints'),
1273
+ totalGiftAmount: sum('totalGiftAmount'),
1274
+ totalAncillaryRefundAmount: sum('totalAncillaryRefundAmount'),
1275
+ totalLoyaltyPointsRefundAmount: sum('totalLoyaltyPointsRefundAmount'),
1276
+ totalCancellationFee: sum('totalCancellationFee'),
1277
+ totalSupplierBookingAmount: sum('totalSupplierBookingAmount'),
1278
+ originalAmount: Number(root.originalAmount || 0),
1279
+ refundBreakdown: this.mergeBreakdowns(onwardData.refundBreakdown, returnData.refundBreakdown),
1280
+ legInfo: { onward, return: ret },
1281
+ };
1282
+ }
1283
+ /** Combine two legs' itemized breakdowns for the "both legs" combined view. */
1284
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1285
+ mergeBreakdowns(a, b) {
1286
+ if (!a && !b)
1287
+ return undefined;
1288
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1289
+ const mergeSide = (sa, sb) => ({
1290
+ fare: Number(sa?.fare || 0) + Number(sb?.fare || 0) || undefined,
1291
+ addOns: [...(sa?.addOns ?? []), ...(sb?.addOns ?? [])],
1292
+ ancillaries: [...(sa?.ancillaries ?? []), ...(sb?.ancillaries ?? [])],
1293
+ serviceFee: Number(sa?.serviceFee || 0) + Number(sb?.serviceFee || 0) || undefined,
1294
+ handlingFee: Number(sa?.handlingFee || 0) + Number(sb?.handlingFee || 0) || undefined,
1295
+ cancellationPenalty: Number(sa?.cancellationPenalty || 0) + Number(sb?.cancellationPenalty || 0) || undefined,
1296
+ });
1297
+ return {
1298
+ refundable: mergeSide(a?.refundable, b?.refundable),
1299
+ nonRefundable: mergeSide(a?.nonRefundable, b?.nonRefundable),
1300
+ };
1301
+ }
1302
+ buildLegData(root, leg, legType) {
1303
+ // When this leg has no sibling in `legInfo` (a genuine one-way booking,
1304
+ // or a narrowed CrossSeller selection where the API only ever sent the
1305
+ // one leg), root necessarily describes this same single leg — so a
1306
+ // destination total the leg's own object left at 0 can safely fall back
1307
+ // to root's figure instead of silently zeroing out a real refund
1308
+ // destination. With a sibling leg present, root aggregates both legs and
1309
+ // is not trustworthy per-leg, so the leg's own value (even 0) wins.
1310
+ const hasSiblingLeg = legType === 'onward' ? !!root.legInfo?.return : !!root.legInfo?.onward;
1311
+ const fallback = (value, rootValue) => Number(value || (hasSiblingLeg ? 0 : rootValue) || 0);
1312
+ const isCreditShell = leg.isCreditShell === true;
1313
+ const legRefund = Number(leg.totalRefundAmount ?? 0);
1314
+ const cardRefund = isCreditShell ? 0 : fallback(leg.totalCardRefundAmount, root.totalCardRefundAmount);
1315
+ const creditRefund = isCreditShell ? legRefund : fallback(leg.totalCreditRefundAmount, root.totalCreditRefundAmount);
1316
+ // The backend sometimes omits `isRefundable` on a single-leg booking's
1317
+ // leg object entirely (not `false`, just absent) while the root/source
1318
+ // breakdown both say the booking is refundable — trust the root flag
1319
+ // rather than defaulting a missing field to "not eligible for a refund".
1320
+ const legIsRefundable = leg.isRefundable === undefined ? root.isRefundable === true : leg.isRefundable === true;
1321
+ return {
1322
+ ...root,
1323
+ isRefundable: legIsRefundable,
1324
+ totalRefundAmount: legRefund,
1325
+ // Pre-rounding total — the backend ceils `totalRefundAmount` to a whole
1326
+ // currency unit, so wallet+card+credit+loyalty legitimately fall a few
1327
+ // cents short of it; reconciliation must compare against this instead.
1328
+ totalRefundAmountBeforeCeil: Number(leg.totalRefundAmountBeforeCeil ?? leg.totalRefundAmount ?? 0),
1329
+ totalCardRefundAmount: cardRefund,
1330
+ totalCreditRefundAmount: creditRefund,
1331
+ totalNonRefundableServiceCharge: Number(leg.totalNonRefundableServiceCharge || 0),
1332
+ totalCouponAmount: Number(leg.totalCouponAmount || 0),
1333
+ walletRefundAmount: fallback(leg.walletRefundAmount, root.walletRefundAmount),
1334
+ totalPenaltyPoints: Number(leg.totalPenaltyPoints || 0),
1335
+ totalSupplierPenaltyPoints: Number(leg.totalSupplierPenaltyPoints || 0),
1336
+ totalLoyaltyPoints: Number(leg.totalLoyaltyPoints || 0),
1337
+ totalGiftAmount: Number(leg.totalGiftAmount || 0),
1338
+ totalAncillaryRefundAmount: Number(leg.totalAncillaryRefundAmount || 0),
1339
+ totalLoyaltyPointsRefundAmount: fallback(leg.totalLoyaltyPointsRefundAmount, root.totalLoyaltyPointsRefundAmount),
1340
+ totalCancellationFee: Number(leg.totalCancellationFee ?? leg.totalPenaltyPoints ?? 0),
1341
+ totalSupplierBookingAmount: Number(leg.totalSupplierBookingAmount || 0),
1342
+ originalAmount: Number(root.originalAmount || 0),
1343
+ // Leg-scoped breakdown wins when the backend sends one; a single-leg
1344
+ // booking may only carry it at the root instead.
1345
+ refundBreakdown: leg.refundBreakdown ?? root.refundBreakdown,
1346
+ legInfo: legType === 'onward' ? { onward: leg } : { return: leg },
1347
+ };
1348
+ }
1349
+ startHints() {
1350
+ let i = 0;
1351
+ this.cancelHint.set(this.CANCEL_HINTS[0]);
1352
+ this.hintTimer = setInterval(() => {
1353
+ if (i < this.CANCEL_HINTS.length - 1) {
1354
+ i++;
1355
+ this.cancelHint.set(this.CANCEL_HINTS[i]);
1356
+ }
1357
+ else {
1358
+ clearInterval(this.hintTimer);
1359
+ this.hintTimer = null;
1360
+ }
1361
+ }, 1800);
1362
+ }
1363
+ stopHints() {
1364
+ if (this.hintTimer) {
1365
+ clearInterval(this.hintTimer);
1366
+ this.hintTimer = null;
1367
+ }
1368
+ this.cancelHint.set('');
1369
+ }
1370
+ fmt(value, currency) {
1371
+ const cur = currency ?? this.refundData()?.currency ?? 'SAR';
1372
+ return `${this.fmtNum(value)} ${cur}`;
1373
+ }
1374
+ // Plain formatted number without a currency suffix (used by the calc divider / formula box).
1375
+ fmtNum(value) {
1376
+ return Number(value || 0).toLocaleString('en-SA', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
1377
+ }
1378
+ fmtNeg(value, currency) {
1379
+ const n = Number(value || 0);
1380
+ const str = this.fmt(n, currency);
1381
+ return n > 0 ? `− ${str}` : str;
1382
+ }
1383
+ fmtNegResult(value) {
1384
+ const n = Number(value || 0);
1385
+ const str = this.fmtResult(n);
1386
+ return n > 0 ? `− ${str}` : str;
1387
+ }
1388
+ // Entry point from the details screen: always goes to the refund-method
1389
+ // step. For credit-shell refunds that step shows a single read-only credit
1390
+ // notice instead of a picker, since the refund can only go to the shell —
1391
+ // but the agent still sees it before confirming, same as the standard flow.
1392
+ requestCancel() {
1393
+ // NIL refund: nothing to refund at all — skip the refund-method popup
1394
+ // and cancel directly.
1395
+ if (this.isNilRefund()) {
1396
+ this.confirm();
1397
+ }
1398
+ else {
1399
+ this.confirming.set(true);
1400
+ }
1401
+ }
1402
+ confirm() {
1403
+ const sel = this.selectedLeg();
1404
+ // Build legInfo array: omit when cancelling both (backend treats absence as both)
1405
+ const legInfo = sel === 'onward' ? ['onward'] :
1406
+ sel === 'return' ? ['return'] :
1407
+ undefined; // both legs — omit the field
1408
+ const source = this.selectedSource() || undefined;
1409
+ const preferredRefundMethod = this.preferredRefundMethod();
1410
+ const splitAmounts = preferredRefundMethod === 'split'
1411
+ ? {
1412
+ walletRefundAmount: Number(this.adjustedData()?.walletRefundAmount ?? 0),
1413
+ totalCardRefundAmount: Number(this.adjustedData()?.totalCardRefundAmount ?? 0),
1414
+ }
1415
+ : undefined;
1416
+ this.confirming.set(false);
1417
+ this.stopHints();
1418
+ this.cancelling.set(true);
1419
+ this.bookingService.confirmCancel(this.bookingId(), this.product(), legInfo, source, preferredRefundMethod, splitAmounts).subscribe({
1420
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1421
+ next: (raw) => {
1422
+ this.stopHints();
1423
+ this.cancelling.set(false);
1424
+ this.cancelResult.set(raw?.data ?? raw);
1425
+ this.confirmed.emit(sel);
1426
+ },
1427
+ error: () => {
1428
+ this.stopHints();
1429
+ this.cancelling.set(false);
1430
+ this.toast.error('Cancellation failed. Please try again.');
1431
+ },
1432
+ });
1433
+ }
1434
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdCancelDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1435
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SbdCancelDialogComponent, isStandalone: true, selector: "app-sbd-cancel-dialog", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, bookingId: { classPropertyName: "bookingId", publicName: "bookingId", isSignal: true, isRequired: false, transformFunction: null }, product: { classPropertyName: "product", publicName: "product", isSignal: true, isRequired: false, transformFunction: null }, pnrInfo: { classPropertyName: "pnrInfo", publicName: "pnrInfo", isSignal: true, isRequired: false, transformFunction: null }, bookingInfo: { classPropertyName: "bookingInfo", publicName: "bookingInfo", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed", confirmed: "confirmed" }, ngImport: i0, template: "<p-dialog [visible]=\"visible()\" (visibleChange)=\"$event ? null : closed.emit()\"\n [modal]=\"true\" [blockScroll]=\"true\" [draggable]=\"false\" [resizable]=\"false\"\n [showHeader]=\"false\" [style]=\"{ width: '560px', padding: '0' }\" styleClass=\"sbd-cancel-dialog-wrapper\">\n\n <div class=\"sbd-cancel\">\n\n <!-- Loading refund details \u2014 shows cycling hints -->\n @if (loading()) {\n <div class=\"sbd-cancel__are-you-sure\">\n <button type=\"button\" class=\"sbd-cancel__close-btn sbd-cancel__close-btn--floating\" (click)=\"closed.emit()\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n <div class=\"sbd-cancel__ays-icon\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n </div>\n @for (h of [cancelHint()]; track h) {\n <div class=\"sbd-cancel__ays-hint\">{{ h }}</div>\n }\n <div class=\"sbd-cancel__ays-dots\">\n <span></span><span></span><span></span>\n </div>\n </div>\n }\n\n <!-- Select leg \u2014 shown once the refund preview has fully loaded, before the\n refund breakdown, for round-trip bookings the backend hasn't already\n restricted to a single leg. Same card design as almatar-b2c's\n select-leg screen (checkbox overlay, refundable badge, disclaimer). -->\n @else if (step() === 'select-leg') {\n <div class=\"sbd-cancel__method-header\">\n <button type=\"button\" class=\"sbd-cancel__method-close\" (click)=\"closed.emit()\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n <div class=\"sbd-cancel__method-header-text\">\n <h3 class=\"sbd-cancel__method-title\">Select Leg to Cancel</h3>\n <span class=\"sbd-cancel__method-sub\">Booking ID #{{ bookingId() }}</span>\n </div>\n </div>\n\n <div class=\"sbd-cancel__select-leg-body\">\n @if (forcedLegType(); as forced) {\n <div class=\"sbd-cancel__single-leg-note\">\n <i class=\"pi pi-info-circle\"></i>\n <span>This airline doesn't allow cancelling a single flight \u2014 {{ itineraryLeg(forced)?.from }} to {{ itineraryLeg(forced)?.to }} will be included automatically.</span>\n </div>\n }\n @if (allLegsNonRefundable()) {\n <div class=\"sbd-cancel__all-non-refundable-note\">\n <i class=\"pi pi-exclamation-triangle\"></i>\n <span>Sorry, we're unable to provide a refund for this booking, as both flights are non-refundable based on airline rules.</span>\n </div>\n }\n <!-- Onward -->\n <div class=\"sbd-cancel__leg-select-card\"\n [ngClass]=\"{\n 'sbd-cancel__leg-select-card--selected': onwardChecked() && onwardRefundable(),\n 'sbd-cancel__leg-select-card--disabled': !onwardRefundable(),\n 'sbd-cancel__leg-select-card--frozen': forcedLegType() === 'onward'\n }\">\n @if (forcedLegType() !== 'onward') {\n <label class=\"sbd-cancel__leg-select-checkbox\">\n <input type=\"checkbox\" [checked]=\"onwardChecked()\" [disabled]=\"!onwardRefundable()\"\n (change)=\"toggleLeg('onward')\" />\n <span class=\"sbd-cancel__leg-select-icon\"><i class=\"pi pi-check\"></i></span>\n </label>\n } @else {\n <i class=\"pi pi-lock sbd-cancel__leg-select-lock\"></i>\n }\n <div class=\"sbd-cancel__leg-select-content\">\n @if (itineraryLeg('onward'); as leg) {\n <div class=\"sbd-cancel__leg-select-top\">\n <div>\n <span class=\"sbd-cancel__leg-select-name\">{{ leg.from }} to {{ leg.to }}</span>\n <div class=\"sbd-cancel__leg-select-date\">{{ fmtShortDate(leg.depTime) }}</div>\n </div>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"onwardRefundable() && forcedLegType() !== 'onward' ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--muted'\">\n {{ onwardRefundable() ? 'Refundable' : 'Non-Refundable' }}\n </span>\n </div>\n <div class=\"sbd-cancel__leg-select-times\">\n <span class=\"sbd-cancel__leg-select-time\">{{ fmtTime(leg.depTime) }}</span>\n <span class=\"sbd-cancel__leg-select-line\">\n <span class=\"sbd-cancel__leg-select-line-stops\">{{ leg.stops.length > 0 ? (leg.stops.length + ' stop' + (leg.stops.length > 1 ? 's' : '')) : 'Direct' }}</span>\n @if (fmtMins(leg.totalMinutes)) { <span class=\"sbd-cancel__leg-select-line-dur\">{{ fmtMins(leg.totalMinutes) }}</span> }\n <i class=\"pi pi-arrow-right sbd-cancel__leg-select-line-arrow\"></i>\n </span>\n <span class=\"sbd-cancel__leg-select-time\">{{ fmtTime(leg.arrTime) }}</span>\n </div>\n @if (leg.airlineName || leg.cabin) {\n <span class=\"sbd-cancel__leg-select-airline\">\n {{ leg.airlineName }}{{ leg.airlineName && leg.cabin ? ' \u00B7 ' : '' }}{{ leg.cabin }}\n </span>\n }\n <div class=\"sbd-cancel__leg-select-footer\">\n @if (leg.operatedBy.length) {\n <span class=\"sbd-cancel__leg-select-operated-by\">Operated by {{ leg.operatedBy.join(', ') }}</span>\n }\n <!-- <i class=\"pi pi-chevron-down sbd-cancel__leg-select-chevron\"></i> -->\n </div>\n } @else {\n <div class=\"sbd-cancel__leg-select-top\">\n <span class=\"sbd-cancel__leg-select-name\">Onward</span>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"onwardRefundable() && forcedLegType() !== 'onward' ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--muted'\">\n {{ onwardRefundable() ? 'Refundable' : 'Non-Refundable' }}\n </span>\n </div>\n }\n @if (!onwardRefundable()) {\n <div class=\"sbd-cancel__leg-select-notice\">\n <i class=\"pi pi-info-circle\"></i>\n <span>This flight type doesn't allow refunds on cancellation, based on the airline's fare rules.</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Return -->\n <div class=\"sbd-cancel__leg-select-card\"\n [ngClass]=\"{\n 'sbd-cancel__leg-select-card--selected': returnChecked() && returnRefundable(),\n 'sbd-cancel__leg-select-card--disabled': !returnRefundable(),\n 'sbd-cancel__leg-select-card--frozen': forcedLegType() === 'return'\n }\">\n @if (forcedLegType() !== 'return') {\n <label class=\"sbd-cancel__leg-select-checkbox\">\n <input type=\"checkbox\" [checked]=\"returnChecked()\" [disabled]=\"!returnRefundable()\"\n (change)=\"toggleLeg('return')\" />\n <span class=\"sbd-cancel__leg-select-icon\"><i class=\"pi pi-check\"></i></span>\n </label>\n } @else {\n <i class=\"pi pi-lock sbd-cancel__leg-select-lock\"></i>\n }\n <div class=\"sbd-cancel__leg-select-content\">\n @if (itineraryLeg('return'); as leg) {\n <div class=\"sbd-cancel__leg-select-top\">\n <div>\n <span class=\"sbd-cancel__leg-select-name\">{{ leg.from }} to {{ leg.to }}</span>\n <div class=\"sbd-cancel__leg-select-date\">{{ fmtShortDate(leg.depTime) }}</div>\n </div>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"returnRefundable() && forcedLegType() !== 'return' ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--muted'\">\n {{ returnRefundable() ? 'Refundable' : 'Non-Refundable' }}\n </span>\n </div>\n <div class=\"sbd-cancel__leg-select-times\">\n <span class=\"sbd-cancel__leg-select-time\">{{ fmtTime(leg.depTime) }}</span>\n <span class=\"sbd-cancel__leg-select-line\">\n <span class=\"sbd-cancel__leg-select-line-stops\">{{ leg.stops.length > 0 ? (leg.stops.length + ' stop' + (leg.stops.length > 1 ? 's' : '')) : 'Direct' }}</span>\n @if (fmtMins(leg.totalMinutes)) { <span class=\"sbd-cancel__leg-select-line-dur\">{{ fmtMins(leg.totalMinutes) }}</span> }\n <i class=\"pi pi-arrow-right sbd-cancel__leg-select-line-arrow\"></i>\n </span>\n <span class=\"sbd-cancel__leg-select-time\">{{ fmtTime(leg.arrTime) }}</span>\n </div>\n @if (leg.airlineName || leg.cabin) {\n <span class=\"sbd-cancel__leg-select-airline\">\n {{ leg.airlineName }}{{ leg.airlineName && leg.cabin ? ' \u00B7 ' : '' }}{{ leg.cabin }}\n </span>\n }\n <div class=\"sbd-cancel__leg-select-footer\">\n @if (leg.operatedBy.length) {\n <span class=\"sbd-cancel__leg-select-operated-by\">Operated by {{ leg.operatedBy.join(', ') }}</span>\n }\n <!-- <i class=\"pi pi-chevron-down sbd-cancel__leg-select-chevron\"></i> -->\n </div>\n } @else {\n <div class=\"sbd-cancel__leg-select-top\">\n <span class=\"sbd-cancel__leg-select-name\">Return</span>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"returnRefundable() && forcedLegType() !== 'return' ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--muted'\">\n {{ returnRefundable() ? 'Refundable' : 'Non-Refundable' }}\n </span>\n </div>\n }\n @if (!returnRefundable()) {\n <div class=\"sbd-cancel__leg-select-notice\">\n <i class=\"pi pi-info-circle\"></i>\n <span>This flight type doesn't allow refunds on cancellation, based on the airline's fare rules.</span>\n </div>\n }\n </div>\n </div>\n </div>\n\n @if (!allLegsNonRefundable() && !onwardChecked() && !returnChecked()) {\n <div class=\"sbd-cancel__leg-select-hint\">Select at least one flight to continue</div>\n }\n\n <div class=\"sbd-cancel__footer\">\n <button pButton\n styleClass=\"sbd-cancel__btn-primary\"\n label=\"Continue\"\n [disabled]=\"allLegsNonRefundable() || (!onwardChecked() && !returnChecked())\"\n (click)=\"step.set('details')\"></button>\n </div>\n }\n\n <!-- Refund method \u2014 replaces the old are-you-sure + radio picker.\n Stays mounted (dimmed) behind the result overlay once confirmed. -->\n @else if (confirming() || cancelResult()) {\n <div class=\"sbd-cancel__method-header\">\n <button type=\"button\" class=\"sbd-cancel__method-close\" (click)=\"confirming.set(false)\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n <div class=\"sbd-cancel__method-header-text\">\n <h3 class=\"sbd-cancel__method-title\">Refund Method</h3>\n <span class=\"sbd-cancel__method-sub\">Booking ID #{{ bookingId() }}</span>\n </div>\n </div>\n\n <div class=\"sbd-cancel__method-body\">\n <div class=\"sbd-cancel__method-amount\">\n <span>You will get back</span>\n <strong>{{ fmt(adjustedData()?.totalRefundAmount) }}</strong>\n </div>\n\n @if (isCreditShell()) {\n <!-- Credit-shell refunds have exactly one destination \u2014 the airline\n credit shell \u2014 so show it as a read-only card, not a picker. -->\n <div class=\"sbd-cancel__method-option sbd-cancel__method-option--active\">\n <span class=\"sbd-cancel__method-icon\"><i class=\"pi pi-wallet\"></i></span>\n <span class=\"sbd-cancel__method-body-text\">\n <span class=\"sbd-cancel__method-name\">{{ creditShellSupplierName() }} website credit</span>\n <span class=\"sbd-cancel__method-desc\">Your refund will be issued instantly by {{ creditShellSupplierName() }}.</span>\n <span class=\"sbd-cancel__method-badge sbd-cancel__method-badge--instant\">\n <svg width=\"12\" height=\"9\" viewBox=\"0 0 12 9\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M7.31818 0C8.42727 0 9.49093 0.440583 10.2752 1.22483C11.0594 2.00907 11.5 3.07273 11.5 4.18182C11.5 5.2909 11.0594 6.35457 10.2752 7.13881C9.49093 7.92305 8.42727 8.36364 7.31818 8.36364C6.20909 8.36364 5.14543 7.92305 4.36119 7.13881C3.57695 6.35457 3.13636 5.2909 3.13636 4.18182C3.13636 3.07273 3.57695 2.00907 4.36119 1.22483C5.14543 0.440583 6.20909 0 7.31818 0ZM7.31818 1.04545C6.48637 1.04545 5.68862 1.37589 5.10044 1.96407C4.51226 2.55226 4.18182 3.35 4.18182 4.18182C4.18182 5.01363 4.51226 5.81138 5.10044 6.39956C5.68862 6.98774 6.48637 7.31818 7.31818 7.31818C8.15 7.31818 8.94774 6.98774 9.53593 6.39956C10.1241 5.81138 10.4545 5.01363 10.4545 4.18182C10.4545 3.35 10.1241 2.55226 9.53593 1.96407C8.94774 1.37589 8.15 1.04545 7.31818 1.04545ZM6.79545 2.09091H7.57955V4.06682L8.7975 5.28477L8.24341 5.83886L6.79545 4.39091V2.09091ZM0.522727 7.31818C0.384091 7.31818 0.251134 7.26311 0.153103 7.16508C0.0550729 7.06705 0 6.93409 0 6.79545C0 6.65682 0.0550729 6.52386 0.153103 6.42583C0.251134 6.3278 0.384091 6.27273 0.522727 6.27273H2.52477C2.68682 6.64386 2.89591 6.99409 3.13636 7.31818H0.522727ZM1.04545 4.70455C0.906819 4.70455 0.773861 4.64947 0.67583 4.55144C0.5778 4.45341 0.522727 4.32045 0.522727 4.18182C0.522727 4.04318 0.5778 3.91022 0.67583 3.81219C0.773861 3.71416 0.906819 3.65909 1.04545 3.65909H2.11705L2.09091 4.18182L2.11705 4.70455H1.04545ZM1.56818 2.09091C1.42955 2.09091 1.29659 2.03584 1.19856 1.93781C1.10053 1.83978 1.04545 1.70682 1.04545 1.56818C1.04545 1.42955 1.10053 1.29659 1.19856 1.19856C1.29659 1.10053 1.42955 1.04545 1.56818 1.04545H3.13636C2.89591 1.36955 2.68682 1.71977 2.52477 2.09091H1.56818Z\"\n fill=\"#15803C\"\n />\n </svg>\n Instant\n </span>\n </span>\n </div>\n\n <div class=\"sbd-cancel__notice sbd-cancel__notice--credit\">\n <i class=\"pi pi-info-circle\"></i>\n <span>\n Your refund will be issued as airline credit under the same PNR.\n It can be used only for future booking on {{ creditShellSupplierName() }} website.\n </span>\n </div>\n\n <!-- Refundable ancillaries (baggage, seats, \u2026) can independently be\n flagged credit-shell or not \u2014 each renders as its own card,\n matching either the credit-shell style above or the normal\n wallet style, both with the same nested note when credit-shell. -->\n @for (item of creditShellAncillaryItems(); track item.name) {\n <div class=\"sbd-cancel__method-option sbd-cancel__method-option--active\">\n <span class=\"sbd-cancel__method-icon\"><i class=\"pi pi-wallet\"></i></span>\n <span class=\"sbd-cancel__method-body-text\">\n <span class=\"sbd-cancel__method-name\">\n {{ item.isCreditShell ? (creditShellSupplierName() + ' website credit') : 'Almatar Wallet' }}\n \u2014 {{ item.name }}\n </span>\n <span class=\"sbd-cancel__method-desc\">\n @if (item.isCreditShell) {\n Your refund will be issued instantly by {{ creditShellSupplierName() }}.\n } @else {\n Usable for future bookings\n }\n </span>\n <span class=\"sbd-cancel__method-badge sbd-cancel__method-badge--instant\">\n <svg width=\"12\" height=\"9\" viewBox=\"0 0 12 9\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M7.31818 0C8.42727 0 9.49093 0.440583 10.2752 1.22483C11.0594 2.00907 11.5 3.07273 11.5 4.18182C11.5 5.2909 11.0594 6.35457 10.2752 7.13881C9.49093 7.92305 8.42727 8.36364 7.31818 8.36364C6.20909 8.36364 5.14543 7.92305 4.36119 7.13881C3.57695 6.35457 3.13636 5.2909 3.13636 4.18182C3.13636 3.07273 3.57695 2.00907 4.36119 1.22483C5.14543 0.440583 6.20909 0 7.31818 0ZM7.31818 1.04545C6.48637 1.04545 5.68862 1.37589 5.10044 1.96407C4.51226 2.55226 4.18182 3.35 4.18182 4.18182C4.18182 5.01363 4.51226 5.81138 5.10044 6.39956C5.68862 6.98774 6.48637 7.31818 7.31818 7.31818C8.15 7.31818 8.94774 6.98774 9.53593 6.39956C10.1241 5.81138 10.4545 5.01363 10.4545 4.18182C10.4545 3.35 10.1241 2.55226 9.53593 1.96407C8.94774 1.37589 8.15 1.04545 7.31818 1.04545ZM6.79545 2.09091H7.57955V4.06682L8.7975 5.28477L8.24341 5.83886L6.79545 4.39091V2.09091ZM0.522727 7.31818C0.384091 7.31818 0.251134 7.26311 0.153103 7.16508C0.0550729 7.06705 0 6.93409 0 6.79545C0 6.65682 0.0550729 6.52386 0.153103 6.42583C0.251134 6.3278 0.384091 6.27273 0.522727 6.27273H2.52477C2.68682 6.64386 2.89591 6.99409 3.13636 7.31818H0.522727ZM1.04545 4.70455C0.906819 4.70455 0.773861 4.64947 0.67583 4.55144C0.5778 4.45341 0.522727 4.32045 0.522727 4.18182C0.522727 4.04318 0.5778 3.91022 0.67583 3.81219C0.773861 3.71416 0.906819 3.65909 1.04545 3.65909H2.11705L2.09091 4.18182L2.11705 4.70455H1.04545ZM1.56818 2.09091C1.42955 2.09091 1.29659 2.03584 1.19856 1.93781C1.10053 1.83978 1.04545 1.70682 1.04545 1.56818C1.04545 1.42955 1.10053 1.29659 1.19856 1.19856C1.29659 1.10053 1.42955 1.04545 1.56818 1.04545H3.13636C2.89591 1.36955 2.68682 1.71977 2.52477 2.09091H1.56818Z\"\n fill=\"#15803C\"\n />\n </svg>\n Instant\n </span>\n @if (item.isCreditShell) {\n <span class=\"sbd-cancel__notice sbd-cancel__notice--info\">\n <i class=\"pi pi-info-circle\"></i>\n <span>Your refund will be issued as airline credit under the same PNR. It can be used only for future booking on {{ creditShellSupplierName() }} website.</span>\n </span>\n }\n </span>\n <strong>{{ fmt(item.amount) }}</strong>\n </div>\n }\n } @else {\n\n @if (isFullWalletRefundAllowed() || isWalletOnlyRefund() || isLoyaltyOnlyRefund()) {\n <button type=\"button\" class=\"sbd-cancel__method-option\"\n [ngClass]=\"{ 'sbd-cancel__method-option--active': preferredRefundMethod() === 'wallet' }\"\n (click)=\"preferredRefundMethod.set('wallet')\">\n <span class=\"sbd-cancel__method-icon\"><i class=\"pi pi-wallet\"></i></span>\n <span class=\"sbd-cancel__method-body-text\">\n <span class=\"sbd-cancel__method-name\">{{ walletCardLabel() }}</span>\n <span class=\"sbd-cancel__method-desc\">Usable for future bookings</span>\n <span class=\"sbd-cancel__method-badge sbd-cancel__method-badge--instant\">\n <svg width=\"12\" height=\"9\" viewBox=\"0 0 12 9\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M7.31818 0C8.42727 0 9.49093 0.440583 10.2752 1.22483C11.0594 2.00907 11.5 3.07273 11.5 4.18182C11.5 5.2909 11.0594 6.35457 10.2752 7.13881C9.49093 7.92305 8.42727 8.36364 7.31818 8.36364C6.20909 8.36364 5.14543 7.92305 4.36119 7.13881C3.57695 6.35457 3.13636 5.2909 3.13636 4.18182C3.13636 3.07273 3.57695 2.00907 4.36119 1.22483C5.14543 0.440583 6.20909 0 7.31818 0ZM7.31818 1.04545C6.48637 1.04545 5.68862 1.37589 5.10044 1.96407C4.51226 2.55226 4.18182 3.35 4.18182 4.18182C4.18182 5.01363 4.51226 5.81138 5.10044 6.39956C5.68862 6.98774 6.48637 7.31818 7.31818 7.31818C8.15 7.31818 8.94774 6.98774 9.53593 6.39956C10.1241 5.81138 10.4545 5.01363 10.4545 4.18182C10.4545 3.35 10.1241 2.55226 9.53593 1.96407C8.94774 1.37589 8.15 1.04545 7.31818 1.04545ZM6.79545 2.09091H7.57955V4.06682L8.7975 5.28477L8.24341 5.83886L6.79545 4.39091V2.09091ZM0.522727 7.31818C0.384091 7.31818 0.251134 7.26311 0.153103 7.16508C0.0550729 7.06705 0 6.93409 0 6.79545C0 6.65682 0.0550729 6.52386 0.153103 6.42583C0.251134 6.3278 0.384091 6.27273 0.522727 6.27273H2.52477C2.68682 6.64386 2.89591 6.99409 3.13636 7.31818H0.522727ZM1.04545 4.70455C0.906819 4.70455 0.773861 4.64947 0.67583 4.55144C0.5778 4.45341 0.522727 4.32045 0.522727 4.18182C0.522727 4.04318 0.5778 3.91022 0.67583 3.81219C0.773861 3.71416 0.906819 3.65909 1.04545 3.65909H2.11705L2.09091 4.18182L2.11705 4.70455H1.04545ZM1.56818 2.09091C1.42955 2.09091 1.29659 2.03584 1.19856 1.93781C1.10053 1.83978 1.04545 1.70682 1.04545 1.56818C1.04545 1.42955 1.10053 1.29659 1.19856 1.19856C1.29659 1.10053 1.42955 1.04545 1.56818 1.04545H3.13636C2.89591 1.36955 2.68682 1.71977 2.52477 2.09091H1.56818Z\"\n fill=\"#15803C\"\n />\n </svg>\n Instant Refund\n </span>\n @if (hasLoyaltyPointsRefund() && !hasCashWalletRefund()) {\n <span class=\"sbd-cancel__notice sbd-cancel__notice--info\">\n <i class=\"pi pi-info-circle\"></i>\n <span>External loyalty points are refunded to your almatar Wallet as permanent points and ready to use in your next booking.</span>\n </span>\n }\n </span>\n <span class=\"sbd-cancel__method-radio\"></span>\n </button>\n }\n\n <!-- Original payment method \u2014 replaced with a \"Split Refund\" card whenever\n part of the refund is forced to the wallet (e.g. loyalty points used),\n since the total can't go 100% to the original payment method.\n Name/desc/badge/icon become gateway-specific for installment (Tamara,\n Tabby) and loyalty (Al Rajhi Mokafaa) payment methods. -->\n @if (!hasSplitRefund() && !isWalletOnlyRefund() && !isLoyaltyOnlyRefund()) {\n <button type=\"button\" class=\"sbd-cancel__method-option\"\n [ngClass]=\"{ 'sbd-cancel__method-option--active': preferredRefundMethod() === 'originalPaymentMethod' }\"\n (click)=\"preferredRefundMethod.set('originalPaymentMethod')\">\n <span class=\"sbd-cancel__method-icon\">\n <i class=\"pi\" [ngClass]=\"isSpecialGatewayMethod() ? 'pi-wallet' : 'pi-credit-card'\"></i>\n </span>\n <span class=\"sbd-cancel__method-body-text\">\n <span class=\"sbd-cancel__method-name\">{{ originalPaymentLabel() }}</span>\n <span class=\"sbd-cancel__method-desc\">\n @if (isInstallmentMethod()) {\n Returned to your {{ customerPaymentLabel() }} installment plan\n } @else if (isLoyaltyMethod()) {\n Refunded to your {{ customerPaymentLabel() }} account\n } @else {\n Returned to your original payment method\n }\n </span>\n <span class=\"sbd-cancel__method-badge\" [ngClass]=\"isLoyaltyMethod() ? 'sbd-cancel__method-badge--loyalty' : 'sbd-cancel__method-badge--days'\">\n @if (!isLoyaltyMethod()) {\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M3.30078 6.50195C3.20312 6.50195 3.12174 6.4694 3.05664 6.4043C2.99154 6.33919 2.95898 6.25781 2.95898 6.16016C2.95898 6.06576 2.99154 5.986 3.05664 5.9209C3.12174 5.85579 3.20312 5.82324 3.30078 5.82324H5.5127V2.86914C5.5127 2.77474 5.54525 2.69499 5.61035 2.62988C5.67546 2.56478 5.75521 2.53223 5.84961 2.53223C5.94727 2.53223 6.02865 2.56478 6.09375 2.62988C6.15885 2.69499 6.19141 2.77474 6.19141 2.86914V6.16016C6.19141 6.25781 6.15885 6.33919 6.09375 6.4043C6.02865 6.4694 5.94727 6.50195 5.84961 6.50195H3.30078ZM5.85449 10.9551C5.16764 10.9551 4.52311 10.8249 3.9209 10.5645C3.31868 10.3073 2.78971 9.95085 2.33398 9.49512C1.87826 9.03939 1.52018 8.51042 1.25977 7.9082C1.0026 7.30599 0.874023 6.66146 0.874023 5.97461C0.874023 5.28776 1.0026 4.64323 1.25977 4.04102C1.52018 3.4388 1.87826 2.90983 2.33398 2.4541C2.78971 1.99512 3.31868 1.63704 3.9209 1.37988C4.52311 1.12272 5.16764 0.994141 5.85449 0.994141C6.54134 0.994141 7.18587 1.12272 7.78809 1.37988C8.3903 1.63704 8.91927 1.99512 9.375 2.4541C9.83073 2.90983 10.1872 3.4388 10.4443 4.04102C10.7048 4.64323 10.835 5.28776 10.835 5.97461C10.835 6.66146 10.7048 7.30599 10.4443 7.9082C10.1872 8.51042 9.83073 9.03939 9.375 9.49512C8.91927 9.95085 8.3903 10.3073 7.78809 10.5645C7.18587 10.8249 6.54134 10.9551 5.85449 10.9551ZM5.85449 10.125C6.42741 10.125 6.96452 10.0176 7.46582 9.80273C7.96712 9.58789 8.4082 9.29004 8.78906 8.90918C9.16992 8.52832 9.46777 8.08724 9.68262 7.58594C9.89746 7.08464 10.0049 6.54753 10.0049 5.97461C10.0049 5.40169 9.89746 4.86458 9.68262 4.36328C9.46777 3.85872 9.16992 3.41764 8.78906 3.04004C8.4082 2.65918 7.96712 2.36133 7.46582 2.14648C6.96452 1.93164 6.42741 1.82422 5.85449 1.82422C5.28158 1.82422 4.74447 1.93164 4.24316 2.14648C3.74186 2.36133 3.30078 2.65918 2.91992 3.04004C2.53906 3.41764 2.24121 3.85872 2.02637 4.36328C1.81152 4.86458 1.7041 5.40169 1.7041 5.97461C1.7041 6.54753 1.81152 7.08464 2.02637 7.58594C2.24121 8.08724 2.53906 8.52832 2.91992 8.90918C3.30078 9.29004 3.74186 9.58789 4.24316 9.80273C4.74447 10.0176 5.28158 10.125 5.85449 10.125Z\"\n fill=\"#0B54C2\"\n />\n </svg>\n } @else {\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"#0B54C2\" stroke-width=\"1.2\" />\n <path d=\"M6 5.5v3M6 3.9v.01\" stroke=\"#0B54C2\" stroke-width=\"1.2\" stroke-linecap=\"round\" />\n </svg>\n }\n {{ cardBadgeText() }}\n </span>\n </span>\n <span class=\"sbd-cancel__option-end\">\n @if (isMadaMethod()) {\n <span class=\"sbd-cancel__mada-logo\" aria-hidden=\"true\">\n <ng-container *ngTemplateOutlet=\"madaLogo\"></ng-container>\n </span>\n }\n <span class=\"sbd-cancel__method-radio\"></span>\n </span>\n </button>\n }\n\n <!-- Split Refund -->\n @if (hasSplitRefund()) {\n <button type=\"button\" class=\"sbd-cancel__method-option sbd-cancel__method-option--split\"\n [ngClass]=\"{ 'sbd-cancel__method-option--active': preferredRefundMethod() === 'split' }\"\n (click)=\"preferredRefundMethod.set('split')\">\n <span class=\"sbd-cancel__method-icon\"><i class=\"pi pi-wallet\"></i></span>\n <span class=\"sbd-cancel__method-body-text\">\n <span class=\"sbd-cancel__method-name\">Split Refund</span>\n <span class=\"sbd-cancel__method-desc\">Returned to your original payment method</span>\n </span>\n <strong class=\"sbd-cancel__method-split-total\">{{ fmt(adjustedData()?.totalRefundAmount) }}</strong>\n <span class=\"sbd-cancel__method-radio\"></span>\n\n <span class=\"sbd-cancel__method-split-breakdown\">\n @for (row of splitRefundRows(); track row.label) {\n <span class=\"sbd-cancel__method-split-row\">\n <span class=\"sbd-cancel__method-split-label\">\n {{ row.label }}\n @if (row.isMada) {\n <span class=\"sbd-cancel__mada-logo\" aria-hidden=\"true\">\n <ng-container *ngTemplateOutlet=\"madaLogo\"></ng-container>\n </span>\n }\n </span>\n <strong>{{ fmt(row.value) }}</strong>\n </span>\n <span class=\"sbd-cancel__method-badge\"\n [ngClass]=\"row.instant ? 'sbd-cancel__method-badge--instant' : (isLoyaltyMethod() ? 'sbd-cancel__method-badge--loyalty' : 'sbd-cancel__method-badge--days')\">\n {{ row.badgeText }}\n </span>\n @if (row.isLoyalty) {\n <span class=\"sbd-cancel__notice sbd-cancel__notice--info\">\n <i class=\"pi pi-info-circle\"></i>\n <span>External loyalty points are refunded to your almatar Wallet as permanent points and ready to use in your next booking.</span>\n </span>\n }\n }\n </span>\n </button>\n }\n }\n </div>\n\n <div class=\"sbd-cancel__footer\">\n <button pButton\n styleClass=\"sbd-cancel__btn-danger-pill\"\n [label]=\"cancelling() ? 'Cancelling...' : 'Confirm Cancellation'\"\n [disabled]=\"cancelling()\" (click)=\"confirm()\"></button>\n </div>\n }\n\n <!-- Main card -->\n @else if (refundData() && step() === 'details') {\n <!-- Card header -->\n <div class=\"sbd-cancel__header sbd-cancel__header--stack\">\n <div class=\"sbd-cancel__header-titles\">\n <span class=\"sbd-cancel__header-title\">Cancel Booking Request</span>\n <span class=\"sbd-cancel__header-sub\">#{{ refundData()?.bookingId ?? bookingId() }}</span>\n </div>\n <button type=\"button\" class=\"sbd-cancel__close-btn\" (click)=\"closed.emit()\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n </div>\n\n <div class=\"sbd-cancel__body\">\n\n <!-- Non-refundable -->\n @if (!refundData()?.isRefundable) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-exclamation-triangle\"></i>\n <div>\n <strong>This booking is not eligible for a refund.</strong>\n @if (refundData()?.cause) {\n <p>{{ refundData()?.cause }}</p>\n } @else {\n <p>Please escalate to the relevant team for manual handling.</p>\n }\n </div>\n </div>\n }\n\n <!-- Refundable flow -->\n @else {\n\n <!-- Top summary: paid / get back -->\n <div class=\"sbd-cancel__summary\">\n <div class=\"sbd-cancel__summary-row\"\n [ngClass]=\"{ 'sbd-cancel__summary-row--toggle': hasPaidBreakdown() && !!adjustedData()?.totalWalletAmount }\"\n (click)=\"hasPaidBreakdown() && !!adjustedData()?.totalWalletAmount && togglePaidSummary()\">\n <span class=\"sbd-cancel__summary-label\"><i class=\"pi pi-wallet\"></i> Total paid</span>\n <span class=\"sbd-cancel__summary-value\">\n <strong>{{ fmt(adjustedData()?.originalAmount) }}</strong>\n @if (hasPaidBreakdown() && !!adjustedData()?.totalWalletAmount) {\n <button type=\"button\" class=\"sbd-cancel__leg-chevron\"\n [ngClass]=\"{ 'sbd-cancel__leg-chevron--collapsed': !paidSummaryExpanded() }\"\n aria-label=\"Toggle paid breakdown\">\n <i class=\"pi pi-chevron-up\"></i>\n </button>\n }\n </span>\n </div>\n\n @if (hasPaidBreakdown() && paidSummaryExpanded() && !!adjustedData()?.totalWalletAmount) {\n <div class=\"sbd-cancel__summary-breakdown\">\n @for (row of paidBreakdownRows(); track row.label) {\n @if (row.label === 'Almatar Wallet') {\n <div class=\"sbd-cancel__summary-breakdown-row\">\n <span>{{ row.label }}</span>\n <span>{{ fmt(row.value) }}</span>\n </div>\n }\n }\n </div>\n }\n\n <div class=\"sbd-cancel__summary-row sbd-cancel__summary-row--refund\">\n <span class=\"sbd-cancel__summary-label\"><i class=\"pi pi-dollar\"></i> You will get back</span>\n <strong>{{ fmt(adjustedData()?.totalRefundAmount) }}</strong>\n </div>\n </div>\n\n <!-- Golden Guarantee gift \u2014 overrides credit-shell messaging below -->\n @if (hasGoldenGuaranteeGift()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--success\">\n <i class=\"pi pi-shield\"></i>\n <span>You're covered by Cancel for any reason service, you'll get 100% refund, minus any applicable fees. See the breakdown below.</span>\n </div>\n }\n\n <!-- One-way (or a round-trip restricted to a single leg): single card -->\n @if (!showRoundTripLegCards()) {\n <!-- Source selector (multiple suppliers) -->\n @if (availableSources().length > 1) {\n <div class=\"sbd-cancel__source-selector\">\n <span class=\"sbd-cancel__source-label\">Cancel via</span>\n @for (src of availableSources(); track src) {\n <button class=\"sbd-cancel__source-chip\"\n [ngClass]=\"{\n 'sbd-cancel__source-chip--active': selectedSource() === src,\n 'sbd-cancel__source-chip--no-refund': activeSourceBreakdown()?.[src]?.isRefundable === false\n }\"\n (click)=\"selectedSource.set(src)\">\n {{ src }}\n @if (activeSourceBreakdown()?.[src]?.isRefundable === false) {\n <i class=\"pi pi-ban\" style=\"font-size:10px; margin-left:4px;\"></i>\n }\n </button>\n }\n </div>\n @if (sourceNonRefundableHint()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-ban\"></i>\n <span>{{ sourceNonRefundableHint() }}</span>\n </div>\n }\n }\n\n <!-- Not refundable -->\n @if (!currentData()?.isRefundable) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-ban\"></i>\n <div>\n <strong>This leg is not eligible for a refund.</strong>\n <p>Please escalate to the relevant team for manual handling.</p>\n </div>\n </div>\n } @else {\n <div class=\"sbd-cancel__section-title\">Refund Details</div>\n\n <div class=\"sbd-cancel__refund-card\">\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline sbd-cancel__badge--green\">Refundable</span>\n\n @if (refundableBreakdownRows(adjustedData()).length) {\n @for (r of refundableBreakdownRows(adjustedData()); track r.label) {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>{{ r.label }}</span>\n <strong>{{ fmt(r.value) }}</strong>\n </div>\n }\n } @else {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>Fare</span>\n <strong>{{ fmt(adjustedData()?.originalAmount) }}</strong>\n </div>\n }\n\n <!-- hide addon note new CR from CX -->\n <!-- @if (hasRefundableAddonNote(adjustedData())) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--neutral\">\n <i class=\"pi pi-info-circle\"></i>\n <span>Your add-on service/s refund will be processed separately by our Customer Service team shortly.</span>\n </div>\n } -->\n\n <!-- Deductions -->\n @if (deductions().length) {\n <div class=\"sbd-cancel__refund-card-divider\"></div>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline sbd-cancel__badge--muted\">Not Refunded - Deductions</span>\n @for (d of deductions(); track d.label) {\n <div class=\"sbd-cancel__refund-card-line\">\n <span>\n {{ d.label }}\n @if (d.badge) { <span class=\"sbd-cancel__tag\">{{ d.badge }}</span> }\n </span>\n <span class=\"sbd-cancel__refund-card-line--neg\">{{ fmtNeg(d.value) }}</span>\n </div>\n }\n }\n\n <div class=\"sbd-cancel__refund-card-divider sbd-cancel__refund-card-divider--dashed\"></div>\n <div class=\"sbd-cancel__refund-card-total\">\n <span>Total Refund</span>\n <strong>{{ fmt(adjustedData()?.totalRefundAmount) }}</strong>\n </div>\n </div>\n\n <!-- Credit shell -->\n @if (creditShellNote()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--credit\">\n <i class=\"pi pi-wallet\"></i>\n <span>\u2139\uFE0F {{ creditShellNote() }}</span>\n </div>\n }\n }\n }\n\n <!-- Round trip: one collapsible card per leg (only when both legs are cancellable) -->\n @if (showRoundTripLegCards()) {\n <!-- Gift hint -->\n @if (giftHint()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--tip\">\n <i class=\"pi pi-info-circle\"></i>\n <span>{{ giftHint() }}</span>\n </div>\n }\n\n <!-- Mixed hint -->\n @if (mixedHint()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-exclamation-triangle\"></i>\n <span>{{ mixedHint() }}</span>\n </div>\n }\n\n <!-- Source selector (multiple suppliers) -->\n @if (availableSources().length > 1) {\n <div class=\"sbd-cancel__source-selector\">\n <span class=\"sbd-cancel__source-label\">Cancel via</span>\n @for (src of availableSources(); track src) {\n <button class=\"sbd-cancel__source-chip\"\n [ngClass]=\"{\n 'sbd-cancel__source-chip--active': selectedSource() === src,\n 'sbd-cancel__source-chip--no-refund': activeSourceBreakdown()?.[src]?.isRefundable === false\n }\"\n (click)=\"selectedSource.set(src)\">\n {{ src }}\n @if (activeSourceBreakdown()?.[src]?.isRefundable === false) {\n <i class=\"pi pi-ban\" style=\"font-size:10px; margin-left:4px;\"></i>\n }\n </button>\n }\n </div>\n @if (sourceNonRefundableHint()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-ban\"></i>\n <span>{{ sourceNonRefundableHint() }}</span>\n </div>\n }\n }\n\n <!-- Onward leg card -->\n @if (onwardChecked()) {\n <div class=\"sbd-cancel__leg-card\">\n <div class=\"sbd-cancel__leg-card-header\" (click)=\"toggleLegExpanded('onward')\">\n <span class=\"sbd-cancel__leg-checkbox\">Onward</span>\n <button type=\"button\" class=\"sbd-cancel__leg-chevron\"\n [ngClass]=\"{ 'sbd-cancel__leg-chevron--collapsed': !onwardExpanded() }\"\n aria-label=\"Toggle\">\n <i class=\"pi pi-chevron-up\"></i>\n </button>\n </div>\n\n @if (onwardExpanded()) {\n <div class=\"sbd-cancel__leg-card-body\">\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"legAdjustedData('onward')?.isRefundable ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--red'\">\n {{ legAdjustedData('onward')?.isRefundable ? 'Refundable' : 'Non-Refundable' }}\n </span>\n\n @if (legAdjustedData('onward')?.isRefundable) {\n @if (refundableBreakdownRows(legAdjustedData('onward')).length) {\n @for (r of refundableBreakdownRows(legAdjustedData('onward')); track r.label) {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>{{ r.label }}</span>\n <strong>{{ fmt(r.value) }}</strong>\n </div>\n }\n } @else {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>Fare</span>\n <strong>{{ fmt(legRefundPool('onward')) }}</strong>\n </div>\n }\n\n <!-- hide addon note new CR from CX -->\n <!-- @if (hasRefundableAddonNote(legAdjustedData('onward'))) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--neutral\">\n <i class=\"pi pi-info-circle\"></i>\n <span>Your add-on service/s refund will be processed separately by our Customer Service team shortly.</span>\n </div>\n } -->\n\n @if (legDeductions('onward').length && !isCreditShell()) {\n <div class=\"sbd-cancel__refund-card-divider\"></div>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline sbd-cancel__badge--muted\">Not Refunded - Deductions</span>\n @for (d of legDeductions('onward'); track d.label) {\n <div class=\"sbd-cancel__refund-card-line\">\n <span>\n {{ d.label }}\n @if (d.badge) { <span class=\"sbd-cancel__tag\">{{ d.badge }}</span> }\n </span>\n <span class=\"sbd-cancel__refund-card-line--neg\">{{ fmtNeg(d.value) }}</span>\n </div>\n }\n }\n\n <div class=\"sbd-cancel__refund-card-divider sbd-cancel__refund-card-divider--dashed\"></div>\n <div class=\"sbd-cancel__refund-card-total\">\n <span>Departure Total Refund</span>\n <strong>{{ fmt(legAdjustedData('onward')?.totalRefundAmount) }}</strong>\n </div>\n\n @if (refundData()?.legInfo?.onward?.isCreditShell && !hasGoldenGuaranteeGift()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--credit\">\n <i class=\"pi pi-wallet\"></i>\n <span>\u2139\uFE0F The refund for the onward flight has been issued as an Airline Credit Shell.</span>\n </div>\n }\n } @else {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-ban\"></i>\n <span>This leg is not eligible for a refund.</span>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Return leg card -->\n @if (returnChecked()) {\n <div class=\"sbd-cancel__leg-card\">\n <div class=\"sbd-cancel__leg-card-header\" (click)=\"toggleLegExpanded('return')\">\n <span class=\"sbd-cancel__leg-checkbox\">Return</span>\n <button type=\"button\" class=\"sbd-cancel__leg-chevron\"\n [ngClass]=\"{ 'sbd-cancel__leg-chevron--collapsed': !returnExpanded() }\"\n aria-label=\"Toggle\">\n <i class=\"pi pi-chevron-up\"></i>\n </button>\n </div>\n\n @if (returnExpanded()) {\n <div class=\"sbd-cancel__leg-card-body\">\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"legAdjustedData('return')?.isRefundable ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--red'\">\n {{ legAdjustedData('return')?.isRefundable ? 'Refundable' : 'Non-Refundable' }}\n </span>\n\n @if (legAdjustedData('return')?.isRefundable) {\n @if (refundableBreakdownRows(legAdjustedData('return')).length) {\n @for (r of refundableBreakdownRows(legAdjustedData('return')); track r.label) {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>{{ r.label }}</span>\n <strong>{{ fmt(r.value) }}</strong>\n </div>\n }\n } @else {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>Fare</span>\n <strong>{{ fmt(legRefundPool('return')) }}</strong>\n </div>\n }\n\n <!-- hide addon note new CR from CX -->\n <!-- @if (hasRefundableAddonNote(legAdjustedData('return'))) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--neutral\">\n <i class=\"pi pi-info-circle\"></i>\n <span>Your add-on service/s refund will be processed separately by our Customer Service team shortly.</span>\n </div>\n } -->\n\n @if (legDeductions('return').length && !isCreditShell()) {\n <div class=\"sbd-cancel__refund-card-divider\"></div>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline sbd-cancel__badge--muted\">Not Refunded - Deductions</span>\n @for (d of legDeductions('return'); track d.label) {\n <div class=\"sbd-cancel__refund-card-line\">\n <span>\n {{ d.label }}\n @if (d.badge) { <span class=\"sbd-cancel__tag\">{{ d.badge }}</span> }\n </span>\n <span class=\"sbd-cancel__refund-card-line--neg\">{{ fmtNeg(d.value) }}</span>\n </div>\n }\n }\n\n <div class=\"sbd-cancel__refund-card-divider sbd-cancel__refund-card-divider--dashed\"></div>\n <div class=\"sbd-cancel__refund-card-total\">\n <span>Return Total Refund</span>\n <strong>{{ fmt(legAdjustedData('return')?.totalRefundAmount) }}</strong>\n </div>\n\n @if (refundData()?.legInfo?.return?.isCreditShell && !hasGoldenGuaranteeGift()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--credit\">\n <i class=\"pi pi-wallet\"></i>\n <span>\u2139\uFE0F The refund for the return flight has been issued as an Airline Credit Shell.</span>\n </div>\n }\n } @else {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-ban\"></i>\n <span>This leg is not eligible for a refund.</span>\n </div>\n }\n </div>\n }\n </div>\n }\n }\n\n <!-- Instant refund notice -->\n @if (currentData()?.isRefundable) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--shield\">\n <i class=\"pi pi-shield\"></i>\n <span>\n @if (isNilRefund()) {\n We're sorry, as per airline policy, no refund applies because the cancellation fees equal or exceed your refundable fare amount.\n } @else {\n @if (isWalletOnlyRefund() || isLoyaltyOnlyRefund()) {\n Your refund is instant to the customer's almatar Wallet.\n } @else {\n Your refund is instant from our side, your bank may take up to 15 business days to reflect it.\n }\n }\n @if (!isNilRefund() && !isCreditShell()) {\n <strong>You can select refund option in the next step</strong>\n }\n </span>\n </div>\n }\n }\n\n </div>\n\n <!-- Footer -->\n <div class=\"sbd-cancel__footer\">\n @if (refundData()?.isRefundable) {\n <button pButton label=\"Keep booking\" styleClass=\"p-button-outlined p-button-secondary sbd-cancel__btn-keep\" (click)=\"closed.emit()\"></button>\n @if (currentData()?.isRefundable) {\n <button pButton\n styleClass=\"sbd-cancel__btn-primary\"\n [label]=\"isCreditShell() ? 'Continue Cancellation' : 'Select refund option'\"\n [disabled]=\"!canConfirm()\" (click)=\"requestCancel()\"></button>\n }\n } @else {\n <button pButton label=\"Close\" styleClass=\"p-button-outlined p-button-secondary\" (click)=\"closed.emit()\"></button>\n }\n </div>\n }\n\n <!-- \u2500\u2500 Result overlay: floating modal over the dimmed refund-method screen (scoped to this dialog, not the whole viewport) \u2500\u2500 -->\n @if (cancelResult()) {\n <div class=\"sbd-cancel__result-overlay\">\n <div class=\"sbd-cancel__result-backdrop\"></div>\n <div class=\"sbd-cancel__result-modal\">\n <div class=\"sbd-cancel__result-hero\">\n <span class=\"sbd-cancel__result-icon sbd-cancel__result-icon--green\">\n <i class=\"pi pi-check\"></i>\n </span>\n <h3 class=\"sbd-cancel__result-title\">{{ confirmIsNilRefund() ? 'Cancel Confirmed' : 'Refund Confirmed' }}</h3>\n </div>\n\n @for (r of confirmRefunds(); track r.label) {\n <div class=\"sbd-cancel__result-row\">\n <span class=\"sbd-cancel__method-icon\">\n <i class=\"pi\" [ngClass]=\"isWalletDestinationRow(r) ? 'pi-wallet' : 'pi-credit-card'\"></i>\n </span>\n <span class=\"sbd-cancel__result-body-text\">\n <span class=\"sbd-cancel__method-name\">{{ r.label }}</span>\n @if (r.subRows?.length) {\n <span class=\"sbd-cancel__result-sub-rows\">\n @for (sub of r.subRows; track sub.label) {\n <span class=\"sbd-cancel__result-sub-row\">\n <span>{{ sub.label }}</span>\n <strong>{{ fmtResult(sub.value) }}</strong>\n </span>\n }\n </span>\n }\n <span class=\"sbd-cancel__method-badge\"\n [ngClass]=\"isWalletDestinationRow(r) ? 'sbd-cancel__method-badge--instant' : 'sbd-cancel__method-badge--days'\">\n {{ isWalletDestinationRow(r) ? 'Ready Now' : (r.key === 'totalCardRefundAmount' ? confirmCardBadgeText() : 'Up to 15 business days, bank policy') }}\n </span>\n @if (r.hasLoyaltyNote) {\n <span class=\"sbd-cancel__notice sbd-cancel__notice--info\">\n <i class=\"pi pi-info-circle\"></i>\n <span>External loyalty points are refunded to your almatar Wallet as permanent points and ready to use in your next booking.</span>\n </span>\n }\n </span>\n <strong class=\"sbd-cancel__result-amount\">{{ fmtResult(r.value) }}</strong>\n </div>\n }\n\n @if (confirmCreditShellNote()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--credit\">\n <i class=\"pi pi-wallet\"></i>\n <span>\u2139\uFE0F {{ confirmCreditShellNote() }}</span>\n </div>\n }\n\n <button pButton styleClass=\"sbd-cancel__btn-primary sbd-cancel__result-done\" label=\"Close\" (click)=\"closed.emit()\"></button>\n </div>\n </div>\n }\n\n </div>\n\n</p-dialog>\n\n<ng-template #madaLogo>\n <svg width=\"43\" height=\"15\" viewBox=\"0 0 43 15\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <g clip-path=\"url(#clip0_sbd_mada)\">\n <path d=\"M18.1894 8.6543H0V14.9933H18.1894V8.6543Z\" fill=\"#84B740\" />\n <path d=\"M18.1894 0H0V6.34463H18.1894V0Z\" fill=\"#259BD6\" />\n <path\n d=\"M36.3779 13.7034L36.2969 13.7203C36.016 13.7768 35.9134 13.7994 35.7082 13.7994C35.233 13.7994 34.6713 13.5452 34.6713 12.3475C34.6713 11.7316 34.7685 10.9124 35.6542 10.9124H35.6596C35.8108 10.9237 35.9836 10.9407 36.3077 11.0424L36.3779 11.065V13.7034ZM36.5237 7.73164L36.3779 7.75989V9.97458L36.2483 9.93503L36.2105 9.92373C36.0647 9.87853 35.7298 9.77684 35.4058 9.77684C33.6344 9.77684 33.2617 11.178 33.2617 12.3531C33.2617 13.9633 34.1258 14.8898 35.6326 14.8898C36.2699 14.8898 36.7397 14.822 37.215 14.6582C37.6524 14.5113 37.8091 14.3023 37.8091 13.8559V7.5C37.3878 7.5791 36.9504 7.65819 36.5237 7.73164Z\"\n fill=\"#747583\"\n />\n <path\n d=\"M41.651 13.7385L41.5754 13.7611L41.3053 13.8345C41.0515 13.9023 40.8247 13.9419 40.6519 13.9419C40.236 13.9419 39.9876 13.7272 39.9876 13.36C39.9876 13.1227 40.0902 12.7215 40.7707 12.7215H41.651V13.7385ZM41.0299 9.74414C40.4844 9.74414 39.9228 9.84584 39.2261 10.0718L38.7724 10.2131L38.9236 11.2865L39.3665 11.134C39.831 10.9758 40.4088 10.8741 40.8409 10.8741C41.0353 10.8741 41.6294 10.8741 41.6294 11.5464V11.8402H40.8031C39.2963 11.8402 38.5996 12.343 38.5996 13.4221C38.5996 14.343 39.2423 14.8967 40.3224 14.8967C40.6573 14.8967 41.1217 14.8289 41.5214 14.7272L41.543 14.7215L41.5646 14.7272L41.6996 14.7498C42.1208 14.8289 42.5583 14.908 42.9849 14.9927V11.4673C42.9849 10.3261 42.3261 9.74414 41.0299 9.74414Z\"\n fill=\"#747583\"\n />\n <path\n d=\"M31.1527 13.7385L31.0771 13.7611L30.807 13.8345C30.5532 13.9023 30.3318 13.9419 30.1536 13.9419C29.7377 13.9419 29.4893 13.7272 29.4893 13.36C29.4893 13.1227 29.5919 12.7215 30.267 12.7215H31.1473L31.1527 13.7385ZM30.537 9.74414C29.9861 9.74414 29.4299 9.84584 28.7332 10.0718L28.2795 10.2131L28.4308 11.2865L28.8736 11.134C29.3381 10.9758 29.9159 10.8741 30.348 10.8741C30.5424 10.8741 31.1365 10.8741 31.1365 11.5464V11.8402H30.3102C28.8034 11.8402 28.1013 12.343 28.1013 13.4221C28.1013 14.343 28.744 14.8967 29.8295 14.8967C30.1644 14.8967 30.6288 14.8289 31.0285 14.7272L31.0501 14.7215L31.0717 14.7272L31.2013 14.7498C31.6279 14.8289 32.06 14.908 32.4866 14.9984V11.473C32.492 10.3204 31.8332 9.74414 30.537 9.74414Z\"\n fill=\"#747583\"\n />\n <path\n d=\"M25.4701 9.7576C24.7842 9.7576 24.2172 9.99489 24.0065 10.0966L23.9525 10.1248L23.9039 10.0853C23.6123 9.86495 23.1856 9.75195 22.5916 9.75195C22.0677 9.75195 21.5762 9.83105 21.0416 9.99489C20.5825 10.1418 20.4043 10.3734 20.4043 10.8085V14.8367H21.8409V11.1135L21.9111 11.0909C22.2027 10.9892 22.3755 10.9723 22.543 10.9723C22.9588 10.9723 23.1694 11.2039 23.1694 11.6559V14.8423H24.5844V11.5938C24.5844 11.4017 24.5466 11.2887 24.5412 11.2661L24.4926 11.17L24.5898 11.1248C24.8058 11.0231 25.0435 10.9723 25.2919 10.9723C25.5781 10.9723 25.9184 11.0909 25.9184 11.6559V14.8423H27.3279V11.509C27.3279 10.3282 26.7231 9.7576 25.4701 9.7576Z\"\n fill=\"#747583\"\n />\n <path\n d=\"M40.5866 4.13559C40.3759 4.13559 40.0249 4.113 39.7495 4.0565L39.6684 4.03955V1.86441C39.6684 1.68362 39.636 1.57062 39.6306 1.55367L39.5874 1.46328L39.6793 1.42373C39.7009 1.41243 39.7225 1.40678 39.7495 1.39548L39.7657 1.38418C39.7981 1.37288 39.8305 1.36158 39.8629 1.35028C39.8791 1.34463 39.8899 1.33898 39.9007 1.33898C40.2193 1.24859 40.511 1.25989 40.6406 1.24859H40.646C41.5263 1.24859 41.6289 2.0678 41.6289 2.68362C41.6235 3.88136 41.0564 4.13559 40.5866 4.13559ZM40.5812 0C40.5704 0 40.5542 0 40.5434 0C39.7171 0 38.8692 0.237288 38.5667 0.700565C38.4047 0.926554 38.3129 1.20904 38.3075 1.54237V3.78531C38.3075 3.9774 38.2697 4.05085 38.2643 4.0678L38.2157 4.16384H35.6072V2.60452H35.6018C35.5694 0.960452 34.6404 0.0564972 33.2957 0.0564972H33.1391H31.9833C31.9293 0.457627 31.8861 0.740113 31.8321 1.14124H33.1391C33.8249 1.14124 34.1868 1.75141 34.1868 2.68927V4.25989L34.095 4.20904C34.0788 4.20339 33.9654 4.16384 33.7871 4.16384H31.5297C31.4865 4.46328 31.4325 4.85311 31.373 5.24294H38.3129C38.5505 5.19209 38.8259 5.14689 39.0636 5.10735C39.4146 5.28814 40.0681 5.38418 40.5164 5.38418C42.0231 5.38418 43.0007 4.32768 43.0007 2.70057C42.9953 1.0904 42.0501 0.0338983 40.5812 0Z\"\n fill=\"#747583\"\n />\n <path\n d=\"M28.4189 5.90821H28.4837C29.9905 5.90821 30.6925 5.38844 30.6925 4.10595C30.6925 3.18505 30.0499 2.45059 28.9697 2.45059H27.5818C27.1659 2.45059 26.9175 2.202 26.9175 1.78392C26.9175 1.50143 27.0201 1.15115 27.7006 1.15115H30.7357C30.8006 0.738723 30.833 0.478836 30.8924 0.0664062H27.7384C26.2694 0.0664062 25.5295 0.710474 25.5295 1.78392C25.5295 2.84607 26.1722 3.39974 27.2523 3.39974H28.6403C29.0561 3.39974 29.3046 3.74437 29.3046 4.10595C29.3046 4.34324 29.202 4.83477 28.5269 4.83477H28.2947L23.8499 4.82347H23.0398C22.3539 4.82347 21.8733 4.41669 21.8733 3.47319V2.82347C21.8733 1.84042 22.2459 1.23025 23.0398 1.23025H24.3576C24.417 0.812169 24.4548 0.546632 24.5088 0.151152H22.867H22.7104C21.3656 0.151152 20.4367 1.09466 20.4043 2.73872V2.80087V3.47319C20.4367 5.11725 21.3656 5.90256 22.7104 5.90256H22.867H24.0227L26.4314 5.90821H27.868H28.4189Z\"\n fill=\"#747583\"\n />\n </g>\n <defs>\n <clipPath id=\"clip0_sbd_mada\">\n <rect width=\"43\" height=\"15\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n</ng-template>\n", styles: [":host ::ng-deep .sbd-cancel-dialog-wrapper{border-radius:16px;overflow:hidden;box-shadow:0 24px 60px #0f172a38}:host ::ng-deep .sbd-cancel-dialog-wrapper .p-dialog-content{padding:0;border-radius:16px;overflow-y:auto;overflow-x:hidden}.sbd-cancel{font-family:inherit;border-radius:16px;overflow:visible;position:relative}.sbd-cancel__loading{padding:24px}.sbd-cancel__loading-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px}.sbd-cancel__loading-rows{display:flex;flex-direction:column;gap:10px;margin-top:20px}.sbd-cancel__loading-row{display:flex;justify-content:space-between}.sbd-cancel__are-you-sure{padding:36px 24px 28px;display:flex;flex-direction:column;align-items:center;gap:14px;text-align:center;border-top:1px solid #e2e8f0}.sbd-cancel__ays-icon{width:56px;height:56px;border-radius:50%;background:#fff7ed;border:2px solid #fed7aa;display:flex;align-items:center;justify-content:center}.sbd-cancel__ays-icon .pi{font-size:24px;color:#f97316}.sbd-cancel__ays-icon--warn{background:#fef2f2;border-color:#fecaca}.sbd-cancel__ays-icon--warn .pi{color:#ef4444}.sbd-cancel__ays-hint{font-size:13px;color:#64748b;min-height:20px;animation:sbd-hint-fade .35s ease-out}.sbd-cancel__ays-dots{display:flex;gap:6px}.sbd-cancel__ays-dots span{width:7px;height:7px;border-radius:50%;background:#f97316;opacity:.3;animation:sbd-dot-pulse 1.2s ease-in-out infinite}.sbd-cancel__ays-dots span:nth-child(2){animation-delay:.2s}.sbd-cancel__ays-dots span:nth-child(3){animation-delay:.4s}@keyframes sbd-hint-fade{0%{opacity:0;transform:translateY(5px)}to{opacity:1;transform:translateY(0)}}@keyframes sbd-dot-pulse{0%,to{opacity:.3;transform:scale(1)}50%{opacity:1;transform:scale(1.4)}}.sbd-cancel__header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid #e2e8f0;background:#f8fafc}.sbd-cancel__header-left{display:flex;align-items:center;gap:10px}.sbd-cancel__header-icon{font-size:18px;color:#475569}.sbd-cancel__header-title{font-size:15px;font-weight:700;color:#1e2e4a}.sbd-cancel__header--stack{align-items:flex-start}.sbd-cancel__header-titles{display:flex;flex-direction:column;gap:2px}.sbd-cancel__header-sub{font-size:12.5px;font-weight:600;color:#94a3b8;font-variant-numeric:tabular-nums}.sbd-cancel__badge{font-size:11.5px;font-weight:700;border-radius:20px;padding:3px 12px;letter-spacing:.03em;width:max-content;text-transform:uppercase}.sbd-cancel__badge--green{background:#dcfce7;color:#166534}.sbd-cancel__badge--red{background:#fee2e2;color:#991b1b}.sbd-cancel__badge--orange{background:#fff7ed;color:#9a3412}.sbd-cancel__badge--outline{background:transparent;box-shadow:inset 0 0 0 1.5px currentColor;padding:4px 14px}.sbd-cancel__badge--outline.sbd-cancel__badge--green{color:#16a34a}.sbd-cancel__badge--outline.sbd-cancel__badge--red{color:#dc2626}.sbd-cancel__badge--muted{background:#f8fafc;color:#64748b;box-shadow:inset 0 0 0 1px #e2e8f0}.sbd-cancel__close-btn{width:30px;height:30px;border-radius:8px;border:none;background:transparent;color:#64748b;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:background .15s,color .15s}.sbd-cancel__close-btn .pi{font-size:14px}.sbd-cancel__close-btn:hover{background:#e2e8f0;color:#1e2e4a}.sbd-cancel__close-btn--floating{position:absolute;top:12px;inset-inline-end:12px}.sbd-cancel__summary{background:#f8fafc;border:1px solid #e2e8f0;border-radius:12px;padding:14px 16px;display:flex;flex-direction:column;gap:10px}.sbd-cancel__summary-row{display:flex;align-items:center;justify-content:space-between;font-size:13.5px}.sbd-cancel__summary-row strong{font-size:15px;font-weight:800;color:#1e2e4a;font-variant-numeric:tabular-nums}.sbd-cancel__summary-row--refund .sbd-cancel__summary-label,.sbd-cancel__summary-row--refund strong{color:#16a34a}.sbd-cancel__summary-row--toggle{cursor:pointer}.sbd-cancel__summary-label{display:inline-flex;align-items:center;gap:8px;font-weight:600;color:#475569}.sbd-cancel__summary-label .pi{font-size:13px}.sbd-cancel__summary-value{display:flex;align-items:center;gap:4px}.sbd-cancel__summary-breakdown{display:flex;flex-direction:column;gap:6px;padding:2px 0 2px 22px}.sbd-cancel__summary-breakdown-row{display:flex;align-items:center;justify-content:space-between;font-size:12.5px;color:#64748b}.sbd-cancel__summary-breakdown-row span:last-child{font-variant-numeric:tabular-nums;font-weight:600;color:#475569}.sbd-cancel__section-title{font-size:14px;font-weight:700;color:#1e2e4a}.sbd-cancel__refund-card{border:1px solid #e2e8f0;border-radius:12px;padding:16px;display:flex;flex-direction:column;gap:4px}.sbd-cancel__refund-card-row{display:flex;align-items:center;justify-content:space-between;margin-top:10px;font-size:14px}.sbd-cancel__refund-card-row span{color:#334155;font-weight:600}.sbd-cancel__refund-card-row strong{color:#1e2e4a;font-weight:700;font-variant-numeric:tabular-nums}.sbd-cancel__refund-card-divider{border-top:1px solid #e2e8f0;margin:10px 0}.sbd-cancel__refund-card-divider--dashed{border-top-style:dashed}.sbd-cancel__refund-card-line{display:flex;align-items:center;justify-content:space-between;padding:5px 0;font-size:13px}.sbd-cancel__refund-card-line span:first-child{color:#64748b;display:inline-flex;align-items:center}.sbd-cancel__refund-card-line--neg{color:#64748b;font-weight:600;font-variant-numeric:tabular-nums}.sbd-cancel__refund-card-total{display:flex;align-items:center;justify-content:space-between}.sbd-cancel__refund-card-total span{font-size:14.5px;font-weight:700;color:#1e2e4a}.sbd-cancel__refund-card-total strong{font-size:17px;font-weight:800;color:#1e2e4a;font-variant-numeric:tabular-nums}.sbd-cancel__btn-keep{flex:1 1 0}.sbd-cancel__btn-primary{flex:1 1 0;background:#6d4aff!important;border-color:#6d4aff!important;color:#fff!important}.sbd-cancel__btn-primary:hover:not(:disabled){background:#5c3ce6!important;border-color:#5c3ce6!important}.sbd-cancel__btn-primary:disabled{opacity:.5}.sbd-cancel__paid{display:flex;align-items:center;justify-content:space-between;margin:0 -20px;padding:14px 20px;border-radius:0;background:#f1f0fb;border-top:1px solid #e7e5f7;border-bottom:1px solid #e7e5f7}.sbd-cancel__paid span{font-size:13.5px;font-weight:600;color:#4b4670}.sbd-cancel__paid strong{font-size:18px;font-weight:800;color:#2b2747;font-variant-numeric:tabular-nums;letter-spacing:.01em}.sbd-cancel__group{display:flex;flex-direction:column}.sbd-cancel__group-label{font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.07em;margin-bottom:2px}.sbd-cancel__group-label--deduct{color:#e05656}.sbd-cancel__group-label--refund{color:#16a34a}.sbd-cancel__line{display:flex;justify-content:space-between;align-items:center;padding:11px 0;font-size:13.5px;border-bottom:1px dashed #e5e7eb}.sbd-cancel__line:last-child{border-bottom:none}.sbd-cancel__line-label{display:inline-flex;align-items:center;color:#334155}.sbd-cancel__line-val{font-weight:700;font-variant-numeric:tabular-nums}.sbd-cancel__line-val--neg{color:#dc2626}.sbd-cancel__line-val--pos{color:#16a34a}.sbd-cancel__tag{margin-left:8px;font-size:10px;font-weight:700;line-height:1;padding:3px 8px;border-radius:6px;background:#ede9fe;color:#6d28d9;letter-spacing:.02em}.sbd-cancel__total-deduct{display:flex;align-items:center;justify-content:space-between;padding:13px 16px;border-radius:10px;background:#fdf2f2;border:1px solid #f6c9c9}.sbd-cancel__total-deduct span{font-size:14px;font-weight:700;color:#b3344a}.sbd-cancel__total-deduct strong{font-size:15px;font-weight:800;color:#dc2626;font-variant-numeric:tabular-nums}.sbd-cancel__calc{display:flex;align-items:center;gap:12px;margin:2px 0;color:#94a3b8;font-size:13px;font-variant-numeric:tabular-nums}.sbd-cancel__calc:before,.sbd-cancel__calc:after{content:\"\";flex:1;height:1px;background:#e5e7eb}.sbd-cancel__refund-total{display:flex;align-items:center;justify-content:space-between}.sbd-cancel__refund-total span{font-size:16px;font-weight:800;color:#1e2e4a}.sbd-cancel__refund-total strong{font-size:26px;font-weight:800;color:#16a34a;font-variant-numeric:tabular-nums;letter-spacing:.01em}.sbd-cancel__formula{text-align:center;padding:14px 16px;border-radius:10px;background:#1f2438;color:#f1f5f9;font-family:SFMono-Regular,ui-monospace,Menlo,Consolas,monospace;font-size:14px;font-weight:600;letter-spacing:.04em;font-variant-numeric:tabular-nums}.sbd-cancel__discrepancy{display:flex;align-items:flex-start;gap:10px;padding:11px 13px;border-radius:8px;font-size:12.5px;line-height:1.45;background:#fffbeb;border:1px solid #fde68a;color:#92400e}.sbd-cancel__discrepancy i{flex-shrink:0;margin-top:1px;font-size:14px;color:#d97706}.sbd-cancel__body{padding:16px 20px;display:flex;flex-direction:column;gap:12px}.sbd-cancel__leg-card{width:100%;border-radius:12px;border:1px solid #e2e8f0;background:#fff;overflow:hidden}.sbd-cancel__leg-card-header{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:14px 16px;cursor:pointer}.sbd-cancel__leg-checkbox{display:flex;align-items:center;gap:10px;font-size:13.5px;font-weight:700;color:#1e2e4a;cursor:pointer}.sbd-cancel__leg-checkbox input[type=checkbox]{width:17px;height:17px;accent-color:#6d4aff;cursor:pointer}.sbd-cancel__leg-chevron{flex-shrink:0;width:26px;height:26px;display:flex;align-items:center;justify-content:center;border:none;background:transparent;color:#64748b;cursor:pointer;transition:transform .15s}.sbd-cancel__leg-chevron i{font-size:13px}.sbd-cancel__leg-chevron--collapsed{transform:rotate(180deg)}.sbd-cancel__leg-card-body{display:flex;flex-direction:column;gap:4px;padding:0 16px 16px}.sbd-cancel__leg-card-body--excluded{opacity:.5}.sbd-cancel__notice{display:flex;align-items:flex-start;gap:10px;padding:10px 12px;border-radius:8px;font-size:12.5px}.sbd-cancel__notice i{flex-shrink:0;margin-top:1px;font-size:14px}.sbd-cancel__notice p{margin:2px 0 0;font-size:12px;opacity:.8}.sbd-cancel__notice strong{display:block;font-weight:700}.sbd-cancel__notice--warning{background:#fff7ed;border:1px solid #fed7aa;color:#9a3412}.sbd-cancel__notice--warning i{color:#f97316}.sbd-cancel__notice--info{background:#eff6ff;border:1px solid #bfdbfe;color:#1e40af}.sbd-cancel__notice--info i{color:#3b82f6}.sbd-cancel__notice--neutral{background:#f7f7f8;border:1px solid #e5e7eb;color:#111827}.sbd-cancel__notice--neutral i{color:#111827}.sbd-cancel__notice--tip{background:#f0fdf4;border:1px solid #bbf7d0;color:#14532d}.sbd-cancel__notice--tip i{color:#22c55e}.sbd-cancel__notice--success{background:#f0fdf4;border:1px solid #bbf7d0;color:#15803c}.sbd-cancel__notice--success i{color:#16a34a}.sbd-cancel__notice--credit{background:#faf5ff;border:1px solid #e9d5ff;color:#5b21b6;font-size:12px}.sbd-cancel__notice--credit i{color:#a855f7}.sbd-cancel__notice--shield{background:#eff6ff;border:1px solid #bfdbfe;color:#1e40af}.sbd-cancel__notice--shield strong{display:inline;font-weight:700}.sbd-cancel__notice--shield i{color:#3b82f6}.sbd-cancel__source-selector{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:4px 0}.sbd-cancel__source-label{font-size:11px;font-weight:700;color:#94a3b8;text-transform:uppercase;letter-spacing:.06em;white-space:nowrap;margin-right:2px}.sbd-cancel__source-chip{font-size:12px;font-weight:600;padding:4px 14px;border-radius:20px;border:1.5px solid #e2e8f0;background:#f8fafc;color:#475569;cursor:pointer;transition:border-color .15s,color .15s,background .15s;display:inline-flex;align-items:center}.sbd-cancel__source-chip:hover{border-color:#94a3b8;color:#475569;background:#f1f5f9}.sbd-cancel__source-chip--active{background:#eff6ff;color:#1d4ed8;border-color:#93c5fd}.sbd-cancel__source-chip--active:hover{background:#dbeafe;color:#1d4ed8;border-color:#93c5fd}.sbd-cancel__source-chip--no-refund{border-color:#fecaca;color:#b91c1c;background:#fff5f5}.sbd-cancel__source-chip--no-refund:hover{border-color:#fca5a5;background:#fee2e2;color:#b91c1c}.sbd-cancel__source-chip--active.sbd-cancel__source-chip--no-refund{background:#fee2e2;color:#991b1b;border-color:#fca5a5}.sbd-cancel__source-chip--active.sbd-cancel__source-chip--no-refund:hover{background:#fecaca}.sbd-cancel__footer{display:flex;justify-content:flex-end;gap:10px;align-items:stretch;padding:14px 20px;border-top:1px solid #e2e8f0;background:#fff}.sbd-cancel__btn-danger-pill{flex:1 1 0;border-radius:999px!important;background:#fee2e2!important;border-color:#fee2e2!important;color:#dc2626!important;font-weight:700!important}.sbd-cancel__btn-danger-pill:hover:not(:disabled){background:#fecaca!important;border-color:#fecaca!important}.sbd-cancel__btn-danger-pill:disabled{opacity:.5}.sbd-cancel__method-header{display:flex;align-items:flex-start;gap:12px;padding:20px 20px 0}.sbd-cancel__method-close{flex-shrink:0;width:32px;height:32px;border-radius:50%;background:#f8fafc;border:none;color:#1e2e4a;display:flex;align-items:center;justify-content:center;cursor:pointer}.sbd-cancel__method-close .pi{font-size:13px}.sbd-cancel__method-close:hover{background:#e2e8f0}.sbd-cancel__method-header-text{flex:1;display:flex;flex-direction:column;align-items:center;gap:4px;text-align:center;margin-right:32px}.sbd-cancel__method-title{font-size:19px;font-weight:800;color:#1e2e4a;margin:0}.sbd-cancel__method-sub{font-size:12.5px;color:#94a3b8}.sbd-cancel__method-body{padding:16px 20px 20px;display:flex;flex-direction:column;gap:14px}.sbd-cancel__select-leg-body{padding:16px 20px 20px;display:flex;flex-direction:column;gap:12px}.sbd-cancel__leg-select-card{position:relative;border:1.5px solid #e2e8f0;border-radius:16px;padding:16px 16px 16px 48px;transition:border-color .15s}.sbd-cancel__leg-select-card--selected:not(.sbd-cancel__leg-select-card--frozen){border-color:#6d4aff}.sbd-cancel__leg-select-card--disabled{opacity:.7}.sbd-cancel__leg-select-card--frozen{opacity:.6;border-color:#e2e8f0}.sbd-cancel__leg-select-lock{position:absolute;top:16px;left:16px;width:22px;height:22px;display:flex;align-items:center;justify-content:center;font-size:14px;color:#94a3b8}.sbd-cancel__single-leg-note{display:flex;align-items:flex-start;gap:10px;padding:12px 14px;border-radius:12px;background:#eaf2ff;border:1px solid #b9d6ff;color:#1a5fd6;font-size:13px;line-height:1.5}.sbd-cancel__single-leg-note i{flex-shrink:0;margin-top:1px}.sbd-cancel__all-non-refundable-note{display:flex;align-items:flex-start;gap:10px;padding:12px 14px;border-radius:12px;background:#fdf3e3;border:1px solid #f3d9a4;color:#8a5a1e;font-size:13px;line-height:1.5}.sbd-cancel__all-non-refundable-note i{flex-shrink:0;margin-top:1px;color:#b98a3e}.sbd-cancel__leg-select-checkbox{position:absolute;top:16px;left:16px;width:22px;height:22px;cursor:pointer}.sbd-cancel__leg-select-checkbox input{position:absolute;inset:0;opacity:0;margin:0;cursor:pointer}.sbd-cancel__leg-select-checkbox input:disabled{cursor:not-allowed}.sbd-cancel__leg-select-icon{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:6px;border:1.5px solid #cbd5e1;background:#fff;color:#fff;font-size:12px}input:checked+.sbd-cancel__leg-select-icon{background:#6d4aff;border-color:#6d4aff}input:disabled+.sbd-cancel__leg-select-icon{background:#f1f5f9;border-color:#e2e8f0}.sbd-cancel__leg-select-content{display:flex;flex-direction:column;gap:8px}.sbd-cancel__leg-select-top{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}.sbd-cancel__leg-select-name{font-size:15px;font-weight:700;color:#1e2e4a}.sbd-cancel__leg-select-date{font-size:13px;color:#64748b;margin-top:2px}.sbd-cancel__leg-select-times{display:flex;align-items:center;gap:8px}.sbd-cancel__leg-select-time{font-size:18px;font-weight:700;color:#1e2e4a;font-variant-numeric:tabular-nums}.sbd-cancel__leg-select-line{flex:1;position:relative;display:flex;flex-direction:column;align-items:center;gap:2px;padding:0 16px 0 8px}.sbd-cancel__leg-select-line:before{content:\"\";position:absolute;left:0;right:14px;top:50%;height:2px;background:#cbd5e1;z-index:1}.sbd-cancel__leg-select-line-stops{font-size:12px;color:#64748b}.sbd-cancel__leg-select-line-dur{font-size:11px;color:#94a3b8}.sbd-cancel__leg-select-line-arrow{position:absolute;right:4px;top:51%;transform:translateY(-50%);font-size:11px;color:#64748b}.sbd-cancel__leg-select-footer{display:flex;align-items:center;gap:8px}.sbd-cancel__leg-select-airline{font-size:12.5px;color:#64748b}.sbd-cancel__leg-select-operated-by{font-size:12px;color:#94a3b8}.sbd-cancel__leg-select-chevron{font-size:12px;color:#94a3b8;margin-inline-start:auto}.sbd-cancel__leg-select-hint{text-align:center;padding:8px 20px 0;font-size:13px;color:#94a3b8}.sbd-cancel__leg-select-notice{display:flex;align-items:flex-start;gap:8px;padding:10px 12px;border-radius:10px;background:#fdf1e0;color:#6b4a16;font-size:12.5px;line-height:1.4}.sbd-cancel__leg-select-notice i{flex-shrink:0;margin-top:1px;color:#b98a3e}.sbd-cancel__method-amount{display:flex;align-items:center;justify-content:space-between}.sbd-cancel__method-amount span{font-size:14px;color:#1e2e4a}.sbd-cancel__method-amount strong{font-size:22px;font-weight:800;color:#1e2e4a;font-variant-numeric:tabular-nums}.sbd-cancel__method-option{display:flex;align-items:flex-start;gap:12px;width:100%;text-align:left;padding:16px;border-radius:16px;border:1.5px solid #e2e8f0;background:#fff;cursor:pointer;transition:border-color .15s,box-shadow .15s}.sbd-cancel__method-option--active{border-color:#6d4aff;box-shadow:0 0 0 1px #6d4aff}.sbd-cancel__method-option:disabled{opacity:.5;cursor:not-allowed}.sbd-cancel__method-icon{flex-shrink:0;width:44px;height:44px;border-radius:10px;display:flex;align-items:center;justify-content:center;border:1px solid #e2e8f0;color:#1e2e4a}.sbd-cancel__method-icon .pi{font-size:16px}.sbd-cancel__method-body-text{flex:1;display:flex;flex-direction:column;align-items:flex-start;gap:4px}.sbd-cancel__method-name{font-size:16px;font-weight:700;color:#1e2e4a;display:inline-flex;align-items:center;gap:6px}.sbd-cancel__method-desc{font-size:13px;color:#64748b}.sbd-cancel__method-badge{display:inline-flex;align-items:center;gap:5px;margin-top:4px;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;padding:4px 10px;border-radius:20px}.sbd-cancel__method-badge svg{flex-shrink:0}.sbd-cancel__method-badge--instant{background:#dcfce7;color:#166534}.sbd-cancel__method-badge--days,.sbd-cancel__method-badge--loyalty{background:#eff6ff;color:#1e40af}.sbd-cancel__option-end{flex-shrink:0;display:flex;align-items:center;gap:8px}.sbd-cancel__method-radio{flex-shrink:0;width:18px;height:18px;margin-top:2px;border-radius:50%;border:2px solid #7c3aed;position:relative}.sbd-cancel__method-option--active .sbd-cancel__method-radio{border-color:#6d4aff}.sbd-cancel__method-option--active .sbd-cancel__method-radio:after{content:\"\";position:absolute;inset:3px;border-radius:50%;background:#6d4aff}.sbd-cancel__method-option--split{flex-wrap:wrap}.sbd-cancel__method-split-total{flex-shrink:0;font-size:16px;font-weight:700;color:#1e2e4a;font-variant-numeric:tabular-nums}.sbd-cancel__method-split-breakdown{flex-basis:100%;display:flex;flex-wrap:wrap;align-items:center;gap:6px 12px;margin-top:12px;padding-top:12px;border-top:1px solid #e2e8f0}.sbd-cancel__method-split-row{flex:1 1 auto;display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;font-size:14px;color:#1e2e4a}.sbd-cancel__method-split-row strong{font-weight:700;font-variant-numeric:tabular-nums}.sbd-cancel__method-split-label{color:#64748b;display:inline-flex;align-items:center;gap:6px}.sbd-cancel__mada-logo{display:inline-flex;align-items:center;flex-shrink:0}.sbd-cancel__mada-logo svg{display:block}.sbd-cancel__result-hero{display:flex;flex-direction:column;align-items:center;gap:18px;padding:28px 0 8px}.sbd-cancel__result-icon{width:84px;height:84px;border-radius:50%;display:flex;align-items:center;justify-content:center}.sbd-cancel__result-icon .pi{font-size:30px;color:#fff}.sbd-cancel__result-icon--green{background:#4ade80}.sbd-cancel__result-icon--orange{background:#fb923c}.sbd-cancel__result-title{font-size:19px;font-weight:800;color:#1e2e4a;margin:0;text-align:center}.sbd-cancel__result-row{display:flex;align-items:flex-start;gap:12px;width:100%;padding:12px 14px;border-radius:14px;background:#f8fafc}.sbd-cancel__result-body-text{flex:1;min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:5px}.sbd-cancel__result-body-text .sbd-cancel__method-badge{text-transform:none;letter-spacing:normal;line-height:1.35;white-space:normal}.sbd-cancel__result-sub-rows{display:flex;flex-direction:column;gap:2px;width:100%}.sbd-cancel__result-sub-row{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;font-size:12.5px;color:#64748b}.sbd-cancel__result-sub-row strong{font-weight:700;color:#64748b;font-variant-numeric:tabular-nums}.sbd-cancel__result-amount{font-size:16px;font-weight:800;color:#1e2e4a;font-variant-numeric:tabular-nums;white-space:nowrap}.sbd-cancel__result-overlay{position:absolute;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;padding:24px}.sbd-cancel__result-backdrop{position:absolute;inset:0;background:#0000008c}.sbd-cancel__result-modal{position:relative;width:100%;max-width:400px;max-height:90%;overflow-y:auto;display:flex;flex-direction:column;gap:16px;padding:24px 20px;border-radius:20px;background:#fff;box-shadow:0 24px 60px #00000059}.sbd-cancel__result-done{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: DialogModule }, { kind: "component", type: i1.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "visible", "style", "position"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
1436
+ }
1437
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdCancelDialogComponent, decorators: [{
1438
+ type: Component,
1439
+ args: [{ selector: 'app-sbd-cancel-dialog', standalone: true, imports: [DialogModule, ButtonModule, SkeletonModule, NgTemplateOutlet, NgClass], template: "<p-dialog [visible]=\"visible()\" (visibleChange)=\"$event ? null : closed.emit()\"\n [modal]=\"true\" [blockScroll]=\"true\" [draggable]=\"false\" [resizable]=\"false\"\n [showHeader]=\"false\" [style]=\"{ width: '560px', padding: '0' }\" styleClass=\"sbd-cancel-dialog-wrapper\">\n\n <div class=\"sbd-cancel\">\n\n <!-- Loading refund details \u2014 shows cycling hints -->\n @if (loading()) {\n <div class=\"sbd-cancel__are-you-sure\">\n <button type=\"button\" class=\"sbd-cancel__close-btn sbd-cancel__close-btn--floating\" (click)=\"closed.emit()\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n <div class=\"sbd-cancel__ays-icon\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n </div>\n @for (h of [cancelHint()]; track h) {\n <div class=\"sbd-cancel__ays-hint\">{{ h }}</div>\n }\n <div class=\"sbd-cancel__ays-dots\">\n <span></span><span></span><span></span>\n </div>\n </div>\n }\n\n <!-- Select leg \u2014 shown once the refund preview has fully loaded, before the\n refund breakdown, for round-trip bookings the backend hasn't already\n restricted to a single leg. Same card design as almatar-b2c's\n select-leg screen (checkbox overlay, refundable badge, disclaimer). -->\n @else if (step() === 'select-leg') {\n <div class=\"sbd-cancel__method-header\">\n <button type=\"button\" class=\"sbd-cancel__method-close\" (click)=\"closed.emit()\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n <div class=\"sbd-cancel__method-header-text\">\n <h3 class=\"sbd-cancel__method-title\">Select Leg to Cancel</h3>\n <span class=\"sbd-cancel__method-sub\">Booking ID #{{ bookingId() }}</span>\n </div>\n </div>\n\n <div class=\"sbd-cancel__select-leg-body\">\n @if (forcedLegType(); as forced) {\n <div class=\"sbd-cancel__single-leg-note\">\n <i class=\"pi pi-info-circle\"></i>\n <span>This airline doesn't allow cancelling a single flight \u2014 {{ itineraryLeg(forced)?.from }} to {{ itineraryLeg(forced)?.to }} will be included automatically.</span>\n </div>\n }\n @if (allLegsNonRefundable()) {\n <div class=\"sbd-cancel__all-non-refundable-note\">\n <i class=\"pi pi-exclamation-triangle\"></i>\n <span>Sorry, we're unable to provide a refund for this booking, as both flights are non-refundable based on airline rules.</span>\n </div>\n }\n <!-- Onward -->\n <div class=\"sbd-cancel__leg-select-card\"\n [ngClass]=\"{\n 'sbd-cancel__leg-select-card--selected': onwardChecked() && onwardRefundable(),\n 'sbd-cancel__leg-select-card--disabled': !onwardRefundable(),\n 'sbd-cancel__leg-select-card--frozen': forcedLegType() === 'onward'\n }\">\n @if (forcedLegType() !== 'onward') {\n <label class=\"sbd-cancel__leg-select-checkbox\">\n <input type=\"checkbox\" [checked]=\"onwardChecked()\" [disabled]=\"!onwardRefundable()\"\n (change)=\"toggleLeg('onward')\" />\n <span class=\"sbd-cancel__leg-select-icon\"><i class=\"pi pi-check\"></i></span>\n </label>\n } @else {\n <i class=\"pi pi-lock sbd-cancel__leg-select-lock\"></i>\n }\n <div class=\"sbd-cancel__leg-select-content\">\n @if (itineraryLeg('onward'); as leg) {\n <div class=\"sbd-cancel__leg-select-top\">\n <div>\n <span class=\"sbd-cancel__leg-select-name\">{{ leg.from }} to {{ leg.to }}</span>\n <div class=\"sbd-cancel__leg-select-date\">{{ fmtShortDate(leg.depTime) }}</div>\n </div>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"onwardRefundable() && forcedLegType() !== 'onward' ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--muted'\">\n {{ onwardRefundable() ? 'Refundable' : 'Non-Refundable' }}\n </span>\n </div>\n <div class=\"sbd-cancel__leg-select-times\">\n <span class=\"sbd-cancel__leg-select-time\">{{ fmtTime(leg.depTime) }}</span>\n <span class=\"sbd-cancel__leg-select-line\">\n <span class=\"sbd-cancel__leg-select-line-stops\">{{ leg.stops.length > 0 ? (leg.stops.length + ' stop' + (leg.stops.length > 1 ? 's' : '')) : 'Direct' }}</span>\n @if (fmtMins(leg.totalMinutes)) { <span class=\"sbd-cancel__leg-select-line-dur\">{{ fmtMins(leg.totalMinutes) }}</span> }\n <i class=\"pi pi-arrow-right sbd-cancel__leg-select-line-arrow\"></i>\n </span>\n <span class=\"sbd-cancel__leg-select-time\">{{ fmtTime(leg.arrTime) }}</span>\n </div>\n @if (leg.airlineName || leg.cabin) {\n <span class=\"sbd-cancel__leg-select-airline\">\n {{ leg.airlineName }}{{ leg.airlineName && leg.cabin ? ' \u00B7 ' : '' }}{{ leg.cabin }}\n </span>\n }\n <div class=\"sbd-cancel__leg-select-footer\">\n @if (leg.operatedBy.length) {\n <span class=\"sbd-cancel__leg-select-operated-by\">Operated by {{ leg.operatedBy.join(', ') }}</span>\n }\n <!-- <i class=\"pi pi-chevron-down sbd-cancel__leg-select-chevron\"></i> -->\n </div>\n } @else {\n <div class=\"sbd-cancel__leg-select-top\">\n <span class=\"sbd-cancel__leg-select-name\">Onward</span>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"onwardRefundable() && forcedLegType() !== 'onward' ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--muted'\">\n {{ onwardRefundable() ? 'Refundable' : 'Non-Refundable' }}\n </span>\n </div>\n }\n @if (!onwardRefundable()) {\n <div class=\"sbd-cancel__leg-select-notice\">\n <i class=\"pi pi-info-circle\"></i>\n <span>This flight type doesn't allow refunds on cancellation, based on the airline's fare rules.</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Return -->\n <div class=\"sbd-cancel__leg-select-card\"\n [ngClass]=\"{\n 'sbd-cancel__leg-select-card--selected': returnChecked() && returnRefundable(),\n 'sbd-cancel__leg-select-card--disabled': !returnRefundable(),\n 'sbd-cancel__leg-select-card--frozen': forcedLegType() === 'return'\n }\">\n @if (forcedLegType() !== 'return') {\n <label class=\"sbd-cancel__leg-select-checkbox\">\n <input type=\"checkbox\" [checked]=\"returnChecked()\" [disabled]=\"!returnRefundable()\"\n (change)=\"toggleLeg('return')\" />\n <span class=\"sbd-cancel__leg-select-icon\"><i class=\"pi pi-check\"></i></span>\n </label>\n } @else {\n <i class=\"pi pi-lock sbd-cancel__leg-select-lock\"></i>\n }\n <div class=\"sbd-cancel__leg-select-content\">\n @if (itineraryLeg('return'); as leg) {\n <div class=\"sbd-cancel__leg-select-top\">\n <div>\n <span class=\"sbd-cancel__leg-select-name\">{{ leg.from }} to {{ leg.to }}</span>\n <div class=\"sbd-cancel__leg-select-date\">{{ fmtShortDate(leg.depTime) }}</div>\n </div>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"returnRefundable() && forcedLegType() !== 'return' ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--muted'\">\n {{ returnRefundable() ? 'Refundable' : 'Non-Refundable' }}\n </span>\n </div>\n <div class=\"sbd-cancel__leg-select-times\">\n <span class=\"sbd-cancel__leg-select-time\">{{ fmtTime(leg.depTime) }}</span>\n <span class=\"sbd-cancel__leg-select-line\">\n <span class=\"sbd-cancel__leg-select-line-stops\">{{ leg.stops.length > 0 ? (leg.stops.length + ' stop' + (leg.stops.length > 1 ? 's' : '')) : 'Direct' }}</span>\n @if (fmtMins(leg.totalMinutes)) { <span class=\"sbd-cancel__leg-select-line-dur\">{{ fmtMins(leg.totalMinutes) }}</span> }\n <i class=\"pi pi-arrow-right sbd-cancel__leg-select-line-arrow\"></i>\n </span>\n <span class=\"sbd-cancel__leg-select-time\">{{ fmtTime(leg.arrTime) }}</span>\n </div>\n @if (leg.airlineName || leg.cabin) {\n <span class=\"sbd-cancel__leg-select-airline\">\n {{ leg.airlineName }}{{ leg.airlineName && leg.cabin ? ' \u00B7 ' : '' }}{{ leg.cabin }}\n </span>\n }\n <div class=\"sbd-cancel__leg-select-footer\">\n @if (leg.operatedBy.length) {\n <span class=\"sbd-cancel__leg-select-operated-by\">Operated by {{ leg.operatedBy.join(', ') }}</span>\n }\n <!-- <i class=\"pi pi-chevron-down sbd-cancel__leg-select-chevron\"></i> -->\n </div>\n } @else {\n <div class=\"sbd-cancel__leg-select-top\">\n <span class=\"sbd-cancel__leg-select-name\">Return</span>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"returnRefundable() && forcedLegType() !== 'return' ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--muted'\">\n {{ returnRefundable() ? 'Refundable' : 'Non-Refundable' }}\n </span>\n </div>\n }\n @if (!returnRefundable()) {\n <div class=\"sbd-cancel__leg-select-notice\">\n <i class=\"pi pi-info-circle\"></i>\n <span>This flight type doesn't allow refunds on cancellation, based on the airline's fare rules.</span>\n </div>\n }\n </div>\n </div>\n </div>\n\n @if (!allLegsNonRefundable() && !onwardChecked() && !returnChecked()) {\n <div class=\"sbd-cancel__leg-select-hint\">Select at least one flight to continue</div>\n }\n\n <div class=\"sbd-cancel__footer\">\n <button pButton\n styleClass=\"sbd-cancel__btn-primary\"\n label=\"Continue\"\n [disabled]=\"allLegsNonRefundable() || (!onwardChecked() && !returnChecked())\"\n (click)=\"step.set('details')\"></button>\n </div>\n }\n\n <!-- Refund method \u2014 replaces the old are-you-sure + radio picker.\n Stays mounted (dimmed) behind the result overlay once confirmed. -->\n @else if (confirming() || cancelResult()) {\n <div class=\"sbd-cancel__method-header\">\n <button type=\"button\" class=\"sbd-cancel__method-close\" (click)=\"confirming.set(false)\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n <div class=\"sbd-cancel__method-header-text\">\n <h3 class=\"sbd-cancel__method-title\">Refund Method</h3>\n <span class=\"sbd-cancel__method-sub\">Booking ID #{{ bookingId() }}</span>\n </div>\n </div>\n\n <div class=\"sbd-cancel__method-body\">\n <div class=\"sbd-cancel__method-amount\">\n <span>You will get back</span>\n <strong>{{ fmt(adjustedData()?.totalRefundAmount) }}</strong>\n </div>\n\n @if (isCreditShell()) {\n <!-- Credit-shell refunds have exactly one destination \u2014 the airline\n credit shell \u2014 so show it as a read-only card, not a picker. -->\n <div class=\"sbd-cancel__method-option sbd-cancel__method-option--active\">\n <span class=\"sbd-cancel__method-icon\"><i class=\"pi pi-wallet\"></i></span>\n <span class=\"sbd-cancel__method-body-text\">\n <span class=\"sbd-cancel__method-name\">{{ creditShellSupplierName() }} website credit</span>\n <span class=\"sbd-cancel__method-desc\">Your refund will be issued instantly by {{ creditShellSupplierName() }}.</span>\n <span class=\"sbd-cancel__method-badge sbd-cancel__method-badge--instant\">\n <svg width=\"12\" height=\"9\" viewBox=\"0 0 12 9\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M7.31818 0C8.42727 0 9.49093 0.440583 10.2752 1.22483C11.0594 2.00907 11.5 3.07273 11.5 4.18182C11.5 5.2909 11.0594 6.35457 10.2752 7.13881C9.49093 7.92305 8.42727 8.36364 7.31818 8.36364C6.20909 8.36364 5.14543 7.92305 4.36119 7.13881C3.57695 6.35457 3.13636 5.2909 3.13636 4.18182C3.13636 3.07273 3.57695 2.00907 4.36119 1.22483C5.14543 0.440583 6.20909 0 7.31818 0ZM7.31818 1.04545C6.48637 1.04545 5.68862 1.37589 5.10044 1.96407C4.51226 2.55226 4.18182 3.35 4.18182 4.18182C4.18182 5.01363 4.51226 5.81138 5.10044 6.39956C5.68862 6.98774 6.48637 7.31818 7.31818 7.31818C8.15 7.31818 8.94774 6.98774 9.53593 6.39956C10.1241 5.81138 10.4545 5.01363 10.4545 4.18182C10.4545 3.35 10.1241 2.55226 9.53593 1.96407C8.94774 1.37589 8.15 1.04545 7.31818 1.04545ZM6.79545 2.09091H7.57955V4.06682L8.7975 5.28477L8.24341 5.83886L6.79545 4.39091V2.09091ZM0.522727 7.31818C0.384091 7.31818 0.251134 7.26311 0.153103 7.16508C0.0550729 7.06705 0 6.93409 0 6.79545C0 6.65682 0.0550729 6.52386 0.153103 6.42583C0.251134 6.3278 0.384091 6.27273 0.522727 6.27273H2.52477C2.68682 6.64386 2.89591 6.99409 3.13636 7.31818H0.522727ZM1.04545 4.70455C0.906819 4.70455 0.773861 4.64947 0.67583 4.55144C0.5778 4.45341 0.522727 4.32045 0.522727 4.18182C0.522727 4.04318 0.5778 3.91022 0.67583 3.81219C0.773861 3.71416 0.906819 3.65909 1.04545 3.65909H2.11705L2.09091 4.18182L2.11705 4.70455H1.04545ZM1.56818 2.09091C1.42955 2.09091 1.29659 2.03584 1.19856 1.93781C1.10053 1.83978 1.04545 1.70682 1.04545 1.56818C1.04545 1.42955 1.10053 1.29659 1.19856 1.19856C1.29659 1.10053 1.42955 1.04545 1.56818 1.04545H3.13636C2.89591 1.36955 2.68682 1.71977 2.52477 2.09091H1.56818Z\"\n fill=\"#15803C\"\n />\n </svg>\n Instant\n </span>\n </span>\n </div>\n\n <div class=\"sbd-cancel__notice sbd-cancel__notice--credit\">\n <i class=\"pi pi-info-circle\"></i>\n <span>\n Your refund will be issued as airline credit under the same PNR.\n It can be used only for future booking on {{ creditShellSupplierName() }} website.\n </span>\n </div>\n\n <!-- Refundable ancillaries (baggage, seats, \u2026) can independently be\n flagged credit-shell or not \u2014 each renders as its own card,\n matching either the credit-shell style above or the normal\n wallet style, both with the same nested note when credit-shell. -->\n @for (item of creditShellAncillaryItems(); track item.name) {\n <div class=\"sbd-cancel__method-option sbd-cancel__method-option--active\">\n <span class=\"sbd-cancel__method-icon\"><i class=\"pi pi-wallet\"></i></span>\n <span class=\"sbd-cancel__method-body-text\">\n <span class=\"sbd-cancel__method-name\">\n {{ item.isCreditShell ? (creditShellSupplierName() + ' website credit') : 'Almatar Wallet' }}\n \u2014 {{ item.name }}\n </span>\n <span class=\"sbd-cancel__method-desc\">\n @if (item.isCreditShell) {\n Your refund will be issued instantly by {{ creditShellSupplierName() }}.\n } @else {\n Usable for future bookings\n }\n </span>\n <span class=\"sbd-cancel__method-badge sbd-cancel__method-badge--instant\">\n <svg width=\"12\" height=\"9\" viewBox=\"0 0 12 9\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M7.31818 0C8.42727 0 9.49093 0.440583 10.2752 1.22483C11.0594 2.00907 11.5 3.07273 11.5 4.18182C11.5 5.2909 11.0594 6.35457 10.2752 7.13881C9.49093 7.92305 8.42727 8.36364 7.31818 8.36364C6.20909 8.36364 5.14543 7.92305 4.36119 7.13881C3.57695 6.35457 3.13636 5.2909 3.13636 4.18182C3.13636 3.07273 3.57695 2.00907 4.36119 1.22483C5.14543 0.440583 6.20909 0 7.31818 0ZM7.31818 1.04545C6.48637 1.04545 5.68862 1.37589 5.10044 1.96407C4.51226 2.55226 4.18182 3.35 4.18182 4.18182C4.18182 5.01363 4.51226 5.81138 5.10044 6.39956C5.68862 6.98774 6.48637 7.31818 7.31818 7.31818C8.15 7.31818 8.94774 6.98774 9.53593 6.39956C10.1241 5.81138 10.4545 5.01363 10.4545 4.18182C10.4545 3.35 10.1241 2.55226 9.53593 1.96407C8.94774 1.37589 8.15 1.04545 7.31818 1.04545ZM6.79545 2.09091H7.57955V4.06682L8.7975 5.28477L8.24341 5.83886L6.79545 4.39091V2.09091ZM0.522727 7.31818C0.384091 7.31818 0.251134 7.26311 0.153103 7.16508C0.0550729 7.06705 0 6.93409 0 6.79545C0 6.65682 0.0550729 6.52386 0.153103 6.42583C0.251134 6.3278 0.384091 6.27273 0.522727 6.27273H2.52477C2.68682 6.64386 2.89591 6.99409 3.13636 7.31818H0.522727ZM1.04545 4.70455C0.906819 4.70455 0.773861 4.64947 0.67583 4.55144C0.5778 4.45341 0.522727 4.32045 0.522727 4.18182C0.522727 4.04318 0.5778 3.91022 0.67583 3.81219C0.773861 3.71416 0.906819 3.65909 1.04545 3.65909H2.11705L2.09091 4.18182L2.11705 4.70455H1.04545ZM1.56818 2.09091C1.42955 2.09091 1.29659 2.03584 1.19856 1.93781C1.10053 1.83978 1.04545 1.70682 1.04545 1.56818C1.04545 1.42955 1.10053 1.29659 1.19856 1.19856C1.29659 1.10053 1.42955 1.04545 1.56818 1.04545H3.13636C2.89591 1.36955 2.68682 1.71977 2.52477 2.09091H1.56818Z\"\n fill=\"#15803C\"\n />\n </svg>\n Instant\n </span>\n @if (item.isCreditShell) {\n <span class=\"sbd-cancel__notice sbd-cancel__notice--info\">\n <i class=\"pi pi-info-circle\"></i>\n <span>Your refund will be issued as airline credit under the same PNR. It can be used only for future booking on {{ creditShellSupplierName() }} website.</span>\n </span>\n }\n </span>\n <strong>{{ fmt(item.amount) }}</strong>\n </div>\n }\n } @else {\n\n @if (isFullWalletRefundAllowed() || isWalletOnlyRefund() || isLoyaltyOnlyRefund()) {\n <button type=\"button\" class=\"sbd-cancel__method-option\"\n [ngClass]=\"{ 'sbd-cancel__method-option--active': preferredRefundMethod() === 'wallet' }\"\n (click)=\"preferredRefundMethod.set('wallet')\">\n <span class=\"sbd-cancel__method-icon\"><i class=\"pi pi-wallet\"></i></span>\n <span class=\"sbd-cancel__method-body-text\">\n <span class=\"sbd-cancel__method-name\">{{ walletCardLabel() }}</span>\n <span class=\"sbd-cancel__method-desc\">Usable for future bookings</span>\n <span class=\"sbd-cancel__method-badge sbd-cancel__method-badge--instant\">\n <svg width=\"12\" height=\"9\" viewBox=\"0 0 12 9\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M7.31818 0C8.42727 0 9.49093 0.440583 10.2752 1.22483C11.0594 2.00907 11.5 3.07273 11.5 4.18182C11.5 5.2909 11.0594 6.35457 10.2752 7.13881C9.49093 7.92305 8.42727 8.36364 7.31818 8.36364C6.20909 8.36364 5.14543 7.92305 4.36119 7.13881C3.57695 6.35457 3.13636 5.2909 3.13636 4.18182C3.13636 3.07273 3.57695 2.00907 4.36119 1.22483C5.14543 0.440583 6.20909 0 7.31818 0ZM7.31818 1.04545C6.48637 1.04545 5.68862 1.37589 5.10044 1.96407C4.51226 2.55226 4.18182 3.35 4.18182 4.18182C4.18182 5.01363 4.51226 5.81138 5.10044 6.39956C5.68862 6.98774 6.48637 7.31818 7.31818 7.31818C8.15 7.31818 8.94774 6.98774 9.53593 6.39956C10.1241 5.81138 10.4545 5.01363 10.4545 4.18182C10.4545 3.35 10.1241 2.55226 9.53593 1.96407C8.94774 1.37589 8.15 1.04545 7.31818 1.04545ZM6.79545 2.09091H7.57955V4.06682L8.7975 5.28477L8.24341 5.83886L6.79545 4.39091V2.09091ZM0.522727 7.31818C0.384091 7.31818 0.251134 7.26311 0.153103 7.16508C0.0550729 7.06705 0 6.93409 0 6.79545C0 6.65682 0.0550729 6.52386 0.153103 6.42583C0.251134 6.3278 0.384091 6.27273 0.522727 6.27273H2.52477C2.68682 6.64386 2.89591 6.99409 3.13636 7.31818H0.522727ZM1.04545 4.70455C0.906819 4.70455 0.773861 4.64947 0.67583 4.55144C0.5778 4.45341 0.522727 4.32045 0.522727 4.18182C0.522727 4.04318 0.5778 3.91022 0.67583 3.81219C0.773861 3.71416 0.906819 3.65909 1.04545 3.65909H2.11705L2.09091 4.18182L2.11705 4.70455H1.04545ZM1.56818 2.09091C1.42955 2.09091 1.29659 2.03584 1.19856 1.93781C1.10053 1.83978 1.04545 1.70682 1.04545 1.56818C1.04545 1.42955 1.10053 1.29659 1.19856 1.19856C1.29659 1.10053 1.42955 1.04545 1.56818 1.04545H3.13636C2.89591 1.36955 2.68682 1.71977 2.52477 2.09091H1.56818Z\"\n fill=\"#15803C\"\n />\n </svg>\n Instant Refund\n </span>\n @if (hasLoyaltyPointsRefund() && !hasCashWalletRefund()) {\n <span class=\"sbd-cancel__notice sbd-cancel__notice--info\">\n <i class=\"pi pi-info-circle\"></i>\n <span>External loyalty points are refunded to your almatar Wallet as permanent points and ready to use in your next booking.</span>\n </span>\n }\n </span>\n <span class=\"sbd-cancel__method-radio\"></span>\n </button>\n }\n\n <!-- Original payment method \u2014 replaced with a \"Split Refund\" card whenever\n part of the refund is forced to the wallet (e.g. loyalty points used),\n since the total can't go 100% to the original payment method.\n Name/desc/badge/icon become gateway-specific for installment (Tamara,\n Tabby) and loyalty (Al Rajhi Mokafaa) payment methods. -->\n @if (!hasSplitRefund() && !isWalletOnlyRefund() && !isLoyaltyOnlyRefund()) {\n <button type=\"button\" class=\"sbd-cancel__method-option\"\n [ngClass]=\"{ 'sbd-cancel__method-option--active': preferredRefundMethod() === 'originalPaymentMethod' }\"\n (click)=\"preferredRefundMethod.set('originalPaymentMethod')\">\n <span class=\"sbd-cancel__method-icon\">\n <i class=\"pi\" [ngClass]=\"isSpecialGatewayMethod() ? 'pi-wallet' : 'pi-credit-card'\"></i>\n </span>\n <span class=\"sbd-cancel__method-body-text\">\n <span class=\"sbd-cancel__method-name\">{{ originalPaymentLabel() }}</span>\n <span class=\"sbd-cancel__method-desc\">\n @if (isInstallmentMethod()) {\n Returned to your {{ customerPaymentLabel() }} installment plan\n } @else if (isLoyaltyMethod()) {\n Refunded to your {{ customerPaymentLabel() }} account\n } @else {\n Returned to your original payment method\n }\n </span>\n <span class=\"sbd-cancel__method-badge\" [ngClass]=\"isLoyaltyMethod() ? 'sbd-cancel__method-badge--loyalty' : 'sbd-cancel__method-badge--days'\">\n @if (!isLoyaltyMethod()) {\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M3.30078 6.50195C3.20312 6.50195 3.12174 6.4694 3.05664 6.4043C2.99154 6.33919 2.95898 6.25781 2.95898 6.16016C2.95898 6.06576 2.99154 5.986 3.05664 5.9209C3.12174 5.85579 3.20312 5.82324 3.30078 5.82324H5.5127V2.86914C5.5127 2.77474 5.54525 2.69499 5.61035 2.62988C5.67546 2.56478 5.75521 2.53223 5.84961 2.53223C5.94727 2.53223 6.02865 2.56478 6.09375 2.62988C6.15885 2.69499 6.19141 2.77474 6.19141 2.86914V6.16016C6.19141 6.25781 6.15885 6.33919 6.09375 6.4043C6.02865 6.4694 5.94727 6.50195 5.84961 6.50195H3.30078ZM5.85449 10.9551C5.16764 10.9551 4.52311 10.8249 3.9209 10.5645C3.31868 10.3073 2.78971 9.95085 2.33398 9.49512C1.87826 9.03939 1.52018 8.51042 1.25977 7.9082C1.0026 7.30599 0.874023 6.66146 0.874023 5.97461C0.874023 5.28776 1.0026 4.64323 1.25977 4.04102C1.52018 3.4388 1.87826 2.90983 2.33398 2.4541C2.78971 1.99512 3.31868 1.63704 3.9209 1.37988C4.52311 1.12272 5.16764 0.994141 5.85449 0.994141C6.54134 0.994141 7.18587 1.12272 7.78809 1.37988C8.3903 1.63704 8.91927 1.99512 9.375 2.4541C9.83073 2.90983 10.1872 3.4388 10.4443 4.04102C10.7048 4.64323 10.835 5.28776 10.835 5.97461C10.835 6.66146 10.7048 7.30599 10.4443 7.9082C10.1872 8.51042 9.83073 9.03939 9.375 9.49512C8.91927 9.95085 8.3903 10.3073 7.78809 10.5645C7.18587 10.8249 6.54134 10.9551 5.85449 10.9551ZM5.85449 10.125C6.42741 10.125 6.96452 10.0176 7.46582 9.80273C7.96712 9.58789 8.4082 9.29004 8.78906 8.90918C9.16992 8.52832 9.46777 8.08724 9.68262 7.58594C9.89746 7.08464 10.0049 6.54753 10.0049 5.97461C10.0049 5.40169 9.89746 4.86458 9.68262 4.36328C9.46777 3.85872 9.16992 3.41764 8.78906 3.04004C8.4082 2.65918 7.96712 2.36133 7.46582 2.14648C6.96452 1.93164 6.42741 1.82422 5.85449 1.82422C5.28158 1.82422 4.74447 1.93164 4.24316 2.14648C3.74186 2.36133 3.30078 2.65918 2.91992 3.04004C2.53906 3.41764 2.24121 3.85872 2.02637 4.36328C1.81152 4.86458 1.7041 5.40169 1.7041 5.97461C1.7041 6.54753 1.81152 7.08464 2.02637 7.58594C2.24121 8.08724 2.53906 8.52832 2.91992 8.90918C3.30078 9.29004 3.74186 9.58789 4.24316 9.80273C4.74447 10.0176 5.28158 10.125 5.85449 10.125Z\"\n fill=\"#0B54C2\"\n />\n </svg>\n } @else {\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"#0B54C2\" stroke-width=\"1.2\" />\n <path d=\"M6 5.5v3M6 3.9v.01\" stroke=\"#0B54C2\" stroke-width=\"1.2\" stroke-linecap=\"round\" />\n </svg>\n }\n {{ cardBadgeText() }}\n </span>\n </span>\n <span class=\"sbd-cancel__option-end\">\n @if (isMadaMethod()) {\n <span class=\"sbd-cancel__mada-logo\" aria-hidden=\"true\">\n <ng-container *ngTemplateOutlet=\"madaLogo\"></ng-container>\n </span>\n }\n <span class=\"sbd-cancel__method-radio\"></span>\n </span>\n </button>\n }\n\n <!-- Split Refund -->\n @if (hasSplitRefund()) {\n <button type=\"button\" class=\"sbd-cancel__method-option sbd-cancel__method-option--split\"\n [ngClass]=\"{ 'sbd-cancel__method-option--active': preferredRefundMethod() === 'split' }\"\n (click)=\"preferredRefundMethod.set('split')\">\n <span class=\"sbd-cancel__method-icon\"><i class=\"pi pi-wallet\"></i></span>\n <span class=\"sbd-cancel__method-body-text\">\n <span class=\"sbd-cancel__method-name\">Split Refund</span>\n <span class=\"sbd-cancel__method-desc\">Returned to your original payment method</span>\n </span>\n <strong class=\"sbd-cancel__method-split-total\">{{ fmt(adjustedData()?.totalRefundAmount) }}</strong>\n <span class=\"sbd-cancel__method-radio\"></span>\n\n <span class=\"sbd-cancel__method-split-breakdown\">\n @for (row of splitRefundRows(); track row.label) {\n <span class=\"sbd-cancel__method-split-row\">\n <span class=\"sbd-cancel__method-split-label\">\n {{ row.label }}\n @if (row.isMada) {\n <span class=\"sbd-cancel__mada-logo\" aria-hidden=\"true\">\n <ng-container *ngTemplateOutlet=\"madaLogo\"></ng-container>\n </span>\n }\n </span>\n <strong>{{ fmt(row.value) }}</strong>\n </span>\n <span class=\"sbd-cancel__method-badge\"\n [ngClass]=\"row.instant ? 'sbd-cancel__method-badge--instant' : (isLoyaltyMethod() ? 'sbd-cancel__method-badge--loyalty' : 'sbd-cancel__method-badge--days')\">\n {{ row.badgeText }}\n </span>\n @if (row.isLoyalty) {\n <span class=\"sbd-cancel__notice sbd-cancel__notice--info\">\n <i class=\"pi pi-info-circle\"></i>\n <span>External loyalty points are refunded to your almatar Wallet as permanent points and ready to use in your next booking.</span>\n </span>\n }\n }\n </span>\n </button>\n }\n }\n </div>\n\n <div class=\"sbd-cancel__footer\">\n <button pButton\n styleClass=\"sbd-cancel__btn-danger-pill\"\n [label]=\"cancelling() ? 'Cancelling...' : 'Confirm Cancellation'\"\n [disabled]=\"cancelling()\" (click)=\"confirm()\"></button>\n </div>\n }\n\n <!-- Main card -->\n @else if (refundData() && step() === 'details') {\n <!-- Card header -->\n <div class=\"sbd-cancel__header sbd-cancel__header--stack\">\n <div class=\"sbd-cancel__header-titles\">\n <span class=\"sbd-cancel__header-title\">Cancel Booking Request</span>\n <span class=\"sbd-cancel__header-sub\">#{{ refundData()?.bookingId ?? bookingId() }}</span>\n </div>\n <button type=\"button\" class=\"sbd-cancel__close-btn\" (click)=\"closed.emit()\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n </div>\n\n <div class=\"sbd-cancel__body\">\n\n <!-- Non-refundable -->\n @if (!refundData()?.isRefundable) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-exclamation-triangle\"></i>\n <div>\n <strong>This booking is not eligible for a refund.</strong>\n @if (refundData()?.cause) {\n <p>{{ refundData()?.cause }}</p>\n } @else {\n <p>Please escalate to the relevant team for manual handling.</p>\n }\n </div>\n </div>\n }\n\n <!-- Refundable flow -->\n @else {\n\n <!-- Top summary: paid / get back -->\n <div class=\"sbd-cancel__summary\">\n <div class=\"sbd-cancel__summary-row\"\n [ngClass]=\"{ 'sbd-cancel__summary-row--toggle': hasPaidBreakdown() && !!adjustedData()?.totalWalletAmount }\"\n (click)=\"hasPaidBreakdown() && !!adjustedData()?.totalWalletAmount && togglePaidSummary()\">\n <span class=\"sbd-cancel__summary-label\"><i class=\"pi pi-wallet\"></i> Total paid</span>\n <span class=\"sbd-cancel__summary-value\">\n <strong>{{ fmt(adjustedData()?.originalAmount) }}</strong>\n @if (hasPaidBreakdown() && !!adjustedData()?.totalWalletAmount) {\n <button type=\"button\" class=\"sbd-cancel__leg-chevron\"\n [ngClass]=\"{ 'sbd-cancel__leg-chevron--collapsed': !paidSummaryExpanded() }\"\n aria-label=\"Toggle paid breakdown\">\n <i class=\"pi pi-chevron-up\"></i>\n </button>\n }\n </span>\n </div>\n\n @if (hasPaidBreakdown() && paidSummaryExpanded() && !!adjustedData()?.totalWalletAmount) {\n <div class=\"sbd-cancel__summary-breakdown\">\n @for (row of paidBreakdownRows(); track row.label) {\n @if (row.label === 'Almatar Wallet') {\n <div class=\"sbd-cancel__summary-breakdown-row\">\n <span>{{ row.label }}</span>\n <span>{{ fmt(row.value) }}</span>\n </div>\n }\n }\n </div>\n }\n\n <div class=\"sbd-cancel__summary-row sbd-cancel__summary-row--refund\">\n <span class=\"sbd-cancel__summary-label\"><i class=\"pi pi-dollar\"></i> You will get back</span>\n <strong>{{ fmt(adjustedData()?.totalRefundAmount) }}</strong>\n </div>\n </div>\n\n <!-- Golden Guarantee gift \u2014 overrides credit-shell messaging below -->\n @if (hasGoldenGuaranteeGift()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--success\">\n <i class=\"pi pi-shield\"></i>\n <span>You're covered by Cancel for any reason service, you'll get 100% refund, minus any applicable fees. See the breakdown below.</span>\n </div>\n }\n\n <!-- One-way (or a round-trip restricted to a single leg): single card -->\n @if (!showRoundTripLegCards()) {\n <!-- Source selector (multiple suppliers) -->\n @if (availableSources().length > 1) {\n <div class=\"sbd-cancel__source-selector\">\n <span class=\"sbd-cancel__source-label\">Cancel via</span>\n @for (src of availableSources(); track src) {\n <button class=\"sbd-cancel__source-chip\"\n [ngClass]=\"{\n 'sbd-cancel__source-chip--active': selectedSource() === src,\n 'sbd-cancel__source-chip--no-refund': activeSourceBreakdown()?.[src]?.isRefundable === false\n }\"\n (click)=\"selectedSource.set(src)\">\n {{ src }}\n @if (activeSourceBreakdown()?.[src]?.isRefundable === false) {\n <i class=\"pi pi-ban\" style=\"font-size:10px; margin-left:4px;\"></i>\n }\n </button>\n }\n </div>\n @if (sourceNonRefundableHint()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-ban\"></i>\n <span>{{ sourceNonRefundableHint() }}</span>\n </div>\n }\n }\n\n <!-- Not refundable -->\n @if (!currentData()?.isRefundable) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-ban\"></i>\n <div>\n <strong>This leg is not eligible for a refund.</strong>\n <p>Please escalate to the relevant team for manual handling.</p>\n </div>\n </div>\n } @else {\n <div class=\"sbd-cancel__section-title\">Refund Details</div>\n\n <div class=\"sbd-cancel__refund-card\">\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline sbd-cancel__badge--green\">Refundable</span>\n\n @if (refundableBreakdownRows(adjustedData()).length) {\n @for (r of refundableBreakdownRows(adjustedData()); track r.label) {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>{{ r.label }}</span>\n <strong>{{ fmt(r.value) }}</strong>\n </div>\n }\n } @else {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>Fare</span>\n <strong>{{ fmt(adjustedData()?.originalAmount) }}</strong>\n </div>\n }\n\n <!-- hide addon note new CR from CX -->\n <!-- @if (hasRefundableAddonNote(adjustedData())) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--neutral\">\n <i class=\"pi pi-info-circle\"></i>\n <span>Your add-on service/s refund will be processed separately by our Customer Service team shortly.</span>\n </div>\n } -->\n\n <!-- Deductions -->\n @if (deductions().length) {\n <div class=\"sbd-cancel__refund-card-divider\"></div>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline sbd-cancel__badge--muted\">Not Refunded - Deductions</span>\n @for (d of deductions(); track d.label) {\n <div class=\"sbd-cancel__refund-card-line\">\n <span>\n {{ d.label }}\n @if (d.badge) { <span class=\"sbd-cancel__tag\">{{ d.badge }}</span> }\n </span>\n <span class=\"sbd-cancel__refund-card-line--neg\">{{ fmtNeg(d.value) }}</span>\n </div>\n }\n }\n\n <div class=\"sbd-cancel__refund-card-divider sbd-cancel__refund-card-divider--dashed\"></div>\n <div class=\"sbd-cancel__refund-card-total\">\n <span>Total Refund</span>\n <strong>{{ fmt(adjustedData()?.totalRefundAmount) }}</strong>\n </div>\n </div>\n\n <!-- Credit shell -->\n @if (creditShellNote()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--credit\">\n <i class=\"pi pi-wallet\"></i>\n <span>\u2139\uFE0F {{ creditShellNote() }}</span>\n </div>\n }\n }\n }\n\n <!-- Round trip: one collapsible card per leg (only when both legs are cancellable) -->\n @if (showRoundTripLegCards()) {\n <!-- Gift hint -->\n @if (giftHint()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--tip\">\n <i class=\"pi pi-info-circle\"></i>\n <span>{{ giftHint() }}</span>\n </div>\n }\n\n <!-- Mixed hint -->\n @if (mixedHint()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-exclamation-triangle\"></i>\n <span>{{ mixedHint() }}</span>\n </div>\n }\n\n <!-- Source selector (multiple suppliers) -->\n @if (availableSources().length > 1) {\n <div class=\"sbd-cancel__source-selector\">\n <span class=\"sbd-cancel__source-label\">Cancel via</span>\n @for (src of availableSources(); track src) {\n <button class=\"sbd-cancel__source-chip\"\n [ngClass]=\"{\n 'sbd-cancel__source-chip--active': selectedSource() === src,\n 'sbd-cancel__source-chip--no-refund': activeSourceBreakdown()?.[src]?.isRefundable === false\n }\"\n (click)=\"selectedSource.set(src)\">\n {{ src }}\n @if (activeSourceBreakdown()?.[src]?.isRefundable === false) {\n <i class=\"pi pi-ban\" style=\"font-size:10px; margin-left:4px;\"></i>\n }\n </button>\n }\n </div>\n @if (sourceNonRefundableHint()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-ban\"></i>\n <span>{{ sourceNonRefundableHint() }}</span>\n </div>\n }\n }\n\n <!-- Onward leg card -->\n @if (onwardChecked()) {\n <div class=\"sbd-cancel__leg-card\">\n <div class=\"sbd-cancel__leg-card-header\" (click)=\"toggleLegExpanded('onward')\">\n <span class=\"sbd-cancel__leg-checkbox\">Onward</span>\n <button type=\"button\" class=\"sbd-cancel__leg-chevron\"\n [ngClass]=\"{ 'sbd-cancel__leg-chevron--collapsed': !onwardExpanded() }\"\n aria-label=\"Toggle\">\n <i class=\"pi pi-chevron-up\"></i>\n </button>\n </div>\n\n @if (onwardExpanded()) {\n <div class=\"sbd-cancel__leg-card-body\">\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"legAdjustedData('onward')?.isRefundable ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--red'\">\n {{ legAdjustedData('onward')?.isRefundable ? 'Refundable' : 'Non-Refundable' }}\n </span>\n\n @if (legAdjustedData('onward')?.isRefundable) {\n @if (refundableBreakdownRows(legAdjustedData('onward')).length) {\n @for (r of refundableBreakdownRows(legAdjustedData('onward')); track r.label) {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>{{ r.label }}</span>\n <strong>{{ fmt(r.value) }}</strong>\n </div>\n }\n } @else {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>Fare</span>\n <strong>{{ fmt(legRefundPool('onward')) }}</strong>\n </div>\n }\n\n <!-- hide addon note new CR from CX -->\n <!-- @if (hasRefundableAddonNote(legAdjustedData('onward'))) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--neutral\">\n <i class=\"pi pi-info-circle\"></i>\n <span>Your add-on service/s refund will be processed separately by our Customer Service team shortly.</span>\n </div>\n } -->\n\n @if (legDeductions('onward').length && !isCreditShell()) {\n <div class=\"sbd-cancel__refund-card-divider\"></div>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline sbd-cancel__badge--muted\">Not Refunded - Deductions</span>\n @for (d of legDeductions('onward'); track d.label) {\n <div class=\"sbd-cancel__refund-card-line\">\n <span>\n {{ d.label }}\n @if (d.badge) { <span class=\"sbd-cancel__tag\">{{ d.badge }}</span> }\n </span>\n <span class=\"sbd-cancel__refund-card-line--neg\">{{ fmtNeg(d.value) }}</span>\n </div>\n }\n }\n\n <div class=\"sbd-cancel__refund-card-divider sbd-cancel__refund-card-divider--dashed\"></div>\n <div class=\"sbd-cancel__refund-card-total\">\n <span>Departure Total Refund</span>\n <strong>{{ fmt(legAdjustedData('onward')?.totalRefundAmount) }}</strong>\n </div>\n\n @if (refundData()?.legInfo?.onward?.isCreditShell && !hasGoldenGuaranteeGift()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--credit\">\n <i class=\"pi pi-wallet\"></i>\n <span>\u2139\uFE0F The refund for the onward flight has been issued as an Airline Credit Shell.</span>\n </div>\n }\n } @else {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-ban\"></i>\n <span>This leg is not eligible for a refund.</span>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Return leg card -->\n @if (returnChecked()) {\n <div class=\"sbd-cancel__leg-card\">\n <div class=\"sbd-cancel__leg-card-header\" (click)=\"toggleLegExpanded('return')\">\n <span class=\"sbd-cancel__leg-checkbox\">Return</span>\n <button type=\"button\" class=\"sbd-cancel__leg-chevron\"\n [ngClass]=\"{ 'sbd-cancel__leg-chevron--collapsed': !returnExpanded() }\"\n aria-label=\"Toggle\">\n <i class=\"pi pi-chevron-up\"></i>\n </button>\n </div>\n\n @if (returnExpanded()) {\n <div class=\"sbd-cancel__leg-card-body\">\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"legAdjustedData('return')?.isRefundable ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--red'\">\n {{ legAdjustedData('return')?.isRefundable ? 'Refundable' : 'Non-Refundable' }}\n </span>\n\n @if (legAdjustedData('return')?.isRefundable) {\n @if (refundableBreakdownRows(legAdjustedData('return')).length) {\n @for (r of refundableBreakdownRows(legAdjustedData('return')); track r.label) {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>{{ r.label }}</span>\n <strong>{{ fmt(r.value) }}</strong>\n </div>\n }\n } @else {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>Fare</span>\n <strong>{{ fmt(legRefundPool('return')) }}</strong>\n </div>\n }\n\n <!-- hide addon note new CR from CX -->\n <!-- @if (hasRefundableAddonNote(legAdjustedData('return'))) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--neutral\">\n <i class=\"pi pi-info-circle\"></i>\n <span>Your add-on service/s refund will be processed separately by our Customer Service team shortly.</span>\n </div>\n } -->\n\n @if (legDeductions('return').length && !isCreditShell()) {\n <div class=\"sbd-cancel__refund-card-divider\"></div>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline sbd-cancel__badge--muted\">Not Refunded - Deductions</span>\n @for (d of legDeductions('return'); track d.label) {\n <div class=\"sbd-cancel__refund-card-line\">\n <span>\n {{ d.label }}\n @if (d.badge) { <span class=\"sbd-cancel__tag\">{{ d.badge }}</span> }\n </span>\n <span class=\"sbd-cancel__refund-card-line--neg\">{{ fmtNeg(d.value) }}</span>\n </div>\n }\n }\n\n <div class=\"sbd-cancel__refund-card-divider sbd-cancel__refund-card-divider--dashed\"></div>\n <div class=\"sbd-cancel__refund-card-total\">\n <span>Return Total Refund</span>\n <strong>{{ fmt(legAdjustedData('return')?.totalRefundAmount) }}</strong>\n </div>\n\n @if (refundData()?.legInfo?.return?.isCreditShell && !hasGoldenGuaranteeGift()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--credit\">\n <i class=\"pi pi-wallet\"></i>\n <span>\u2139\uFE0F The refund for the return flight has been issued as an Airline Credit Shell.</span>\n </div>\n }\n } @else {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-ban\"></i>\n <span>This leg is not eligible for a refund.</span>\n </div>\n }\n </div>\n }\n </div>\n }\n }\n\n <!-- Instant refund notice -->\n @if (currentData()?.isRefundable) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--shield\">\n <i class=\"pi pi-shield\"></i>\n <span>\n @if (isNilRefund()) {\n We're sorry, as per airline policy, no refund applies because the cancellation fees equal or exceed your refundable fare amount.\n } @else {\n @if (isWalletOnlyRefund() || isLoyaltyOnlyRefund()) {\n Your refund is instant to the customer's almatar Wallet.\n } @else {\n Your refund is instant from our side, your bank may take up to 15 business days to reflect it.\n }\n }\n @if (!isNilRefund() && !isCreditShell()) {\n <strong>You can select refund option in the next step</strong>\n }\n </span>\n </div>\n }\n }\n\n </div>\n\n <!-- Footer -->\n <div class=\"sbd-cancel__footer\">\n @if (refundData()?.isRefundable) {\n <button pButton label=\"Keep booking\" styleClass=\"p-button-outlined p-button-secondary sbd-cancel__btn-keep\" (click)=\"closed.emit()\"></button>\n @if (currentData()?.isRefundable) {\n <button pButton\n styleClass=\"sbd-cancel__btn-primary\"\n [label]=\"isCreditShell() ? 'Continue Cancellation' : 'Select refund option'\"\n [disabled]=\"!canConfirm()\" (click)=\"requestCancel()\"></button>\n }\n } @else {\n <button pButton label=\"Close\" styleClass=\"p-button-outlined p-button-secondary\" (click)=\"closed.emit()\"></button>\n }\n </div>\n }\n\n <!-- \u2500\u2500 Result overlay: floating modal over the dimmed refund-method screen (scoped to this dialog, not the whole viewport) \u2500\u2500 -->\n @if (cancelResult()) {\n <div class=\"sbd-cancel__result-overlay\">\n <div class=\"sbd-cancel__result-backdrop\"></div>\n <div class=\"sbd-cancel__result-modal\">\n <div class=\"sbd-cancel__result-hero\">\n <span class=\"sbd-cancel__result-icon sbd-cancel__result-icon--green\">\n <i class=\"pi pi-check\"></i>\n </span>\n <h3 class=\"sbd-cancel__result-title\">{{ confirmIsNilRefund() ? 'Cancel Confirmed' : 'Refund Confirmed' }}</h3>\n </div>\n\n @for (r of confirmRefunds(); track r.label) {\n <div class=\"sbd-cancel__result-row\">\n <span class=\"sbd-cancel__method-icon\">\n <i class=\"pi\" [ngClass]=\"isWalletDestinationRow(r) ? 'pi-wallet' : 'pi-credit-card'\"></i>\n </span>\n <span class=\"sbd-cancel__result-body-text\">\n <span class=\"sbd-cancel__method-name\">{{ r.label }}</span>\n @if (r.subRows?.length) {\n <span class=\"sbd-cancel__result-sub-rows\">\n @for (sub of r.subRows; track sub.label) {\n <span class=\"sbd-cancel__result-sub-row\">\n <span>{{ sub.label }}</span>\n <strong>{{ fmtResult(sub.value) }}</strong>\n </span>\n }\n </span>\n }\n <span class=\"sbd-cancel__method-badge\"\n [ngClass]=\"isWalletDestinationRow(r) ? 'sbd-cancel__method-badge--instant' : 'sbd-cancel__method-badge--days'\">\n {{ isWalletDestinationRow(r) ? 'Ready Now' : (r.key === 'totalCardRefundAmount' ? confirmCardBadgeText() : 'Up to 15 business days, bank policy') }}\n </span>\n @if (r.hasLoyaltyNote) {\n <span class=\"sbd-cancel__notice sbd-cancel__notice--info\">\n <i class=\"pi pi-info-circle\"></i>\n <span>External loyalty points are refunded to your almatar Wallet as permanent points and ready to use in your next booking.</span>\n </span>\n }\n </span>\n <strong class=\"sbd-cancel__result-amount\">{{ fmtResult(r.value) }}</strong>\n </div>\n }\n\n @if (confirmCreditShellNote()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--credit\">\n <i class=\"pi pi-wallet\"></i>\n <span>\u2139\uFE0F {{ confirmCreditShellNote() }}</span>\n </div>\n }\n\n <button pButton styleClass=\"sbd-cancel__btn-primary sbd-cancel__result-done\" label=\"Close\" (click)=\"closed.emit()\"></button>\n </div>\n </div>\n }\n\n </div>\n\n</p-dialog>\n\n<ng-template #madaLogo>\n <svg width=\"43\" height=\"15\" viewBox=\"0 0 43 15\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <g clip-path=\"url(#clip0_sbd_mada)\">\n <path d=\"M18.1894 8.6543H0V14.9933H18.1894V8.6543Z\" fill=\"#84B740\" />\n <path d=\"M18.1894 0H0V6.34463H18.1894V0Z\" fill=\"#259BD6\" />\n <path\n d=\"M36.3779 13.7034L36.2969 13.7203C36.016 13.7768 35.9134 13.7994 35.7082 13.7994C35.233 13.7994 34.6713 13.5452 34.6713 12.3475C34.6713 11.7316 34.7685 10.9124 35.6542 10.9124H35.6596C35.8108 10.9237 35.9836 10.9407 36.3077 11.0424L36.3779 11.065V13.7034ZM36.5237 7.73164L36.3779 7.75989V9.97458L36.2483 9.93503L36.2105 9.92373C36.0647 9.87853 35.7298 9.77684 35.4058 9.77684C33.6344 9.77684 33.2617 11.178 33.2617 12.3531C33.2617 13.9633 34.1258 14.8898 35.6326 14.8898C36.2699 14.8898 36.7397 14.822 37.215 14.6582C37.6524 14.5113 37.8091 14.3023 37.8091 13.8559V7.5C37.3878 7.5791 36.9504 7.65819 36.5237 7.73164Z\"\n fill=\"#747583\"\n />\n <path\n d=\"M41.651 13.7385L41.5754 13.7611L41.3053 13.8345C41.0515 13.9023 40.8247 13.9419 40.6519 13.9419C40.236 13.9419 39.9876 13.7272 39.9876 13.36C39.9876 13.1227 40.0902 12.7215 40.7707 12.7215H41.651V13.7385ZM41.0299 9.74414C40.4844 9.74414 39.9228 9.84584 39.2261 10.0718L38.7724 10.2131L38.9236 11.2865L39.3665 11.134C39.831 10.9758 40.4088 10.8741 40.8409 10.8741C41.0353 10.8741 41.6294 10.8741 41.6294 11.5464V11.8402H40.8031C39.2963 11.8402 38.5996 12.343 38.5996 13.4221C38.5996 14.343 39.2423 14.8967 40.3224 14.8967C40.6573 14.8967 41.1217 14.8289 41.5214 14.7272L41.543 14.7215L41.5646 14.7272L41.6996 14.7498C42.1208 14.8289 42.5583 14.908 42.9849 14.9927V11.4673C42.9849 10.3261 42.3261 9.74414 41.0299 9.74414Z\"\n fill=\"#747583\"\n />\n <path\n d=\"M31.1527 13.7385L31.0771 13.7611L30.807 13.8345C30.5532 13.9023 30.3318 13.9419 30.1536 13.9419C29.7377 13.9419 29.4893 13.7272 29.4893 13.36C29.4893 13.1227 29.5919 12.7215 30.267 12.7215H31.1473L31.1527 13.7385ZM30.537 9.74414C29.9861 9.74414 29.4299 9.84584 28.7332 10.0718L28.2795 10.2131L28.4308 11.2865L28.8736 11.134C29.3381 10.9758 29.9159 10.8741 30.348 10.8741C30.5424 10.8741 31.1365 10.8741 31.1365 11.5464V11.8402H30.3102C28.8034 11.8402 28.1013 12.343 28.1013 13.4221C28.1013 14.343 28.744 14.8967 29.8295 14.8967C30.1644 14.8967 30.6288 14.8289 31.0285 14.7272L31.0501 14.7215L31.0717 14.7272L31.2013 14.7498C31.6279 14.8289 32.06 14.908 32.4866 14.9984V11.473C32.492 10.3204 31.8332 9.74414 30.537 9.74414Z\"\n fill=\"#747583\"\n />\n <path\n d=\"M25.4701 9.7576C24.7842 9.7576 24.2172 9.99489 24.0065 10.0966L23.9525 10.1248L23.9039 10.0853C23.6123 9.86495 23.1856 9.75195 22.5916 9.75195C22.0677 9.75195 21.5762 9.83105 21.0416 9.99489C20.5825 10.1418 20.4043 10.3734 20.4043 10.8085V14.8367H21.8409V11.1135L21.9111 11.0909C22.2027 10.9892 22.3755 10.9723 22.543 10.9723C22.9588 10.9723 23.1694 11.2039 23.1694 11.6559V14.8423H24.5844V11.5938C24.5844 11.4017 24.5466 11.2887 24.5412 11.2661L24.4926 11.17L24.5898 11.1248C24.8058 11.0231 25.0435 10.9723 25.2919 10.9723C25.5781 10.9723 25.9184 11.0909 25.9184 11.6559V14.8423H27.3279V11.509C27.3279 10.3282 26.7231 9.7576 25.4701 9.7576Z\"\n fill=\"#747583\"\n />\n <path\n d=\"M40.5866 4.13559C40.3759 4.13559 40.0249 4.113 39.7495 4.0565L39.6684 4.03955V1.86441C39.6684 1.68362 39.636 1.57062 39.6306 1.55367L39.5874 1.46328L39.6793 1.42373C39.7009 1.41243 39.7225 1.40678 39.7495 1.39548L39.7657 1.38418C39.7981 1.37288 39.8305 1.36158 39.8629 1.35028C39.8791 1.34463 39.8899 1.33898 39.9007 1.33898C40.2193 1.24859 40.511 1.25989 40.6406 1.24859H40.646C41.5263 1.24859 41.6289 2.0678 41.6289 2.68362C41.6235 3.88136 41.0564 4.13559 40.5866 4.13559ZM40.5812 0C40.5704 0 40.5542 0 40.5434 0C39.7171 0 38.8692 0.237288 38.5667 0.700565C38.4047 0.926554 38.3129 1.20904 38.3075 1.54237V3.78531C38.3075 3.9774 38.2697 4.05085 38.2643 4.0678L38.2157 4.16384H35.6072V2.60452H35.6018C35.5694 0.960452 34.6404 0.0564972 33.2957 0.0564972H33.1391H31.9833C31.9293 0.457627 31.8861 0.740113 31.8321 1.14124H33.1391C33.8249 1.14124 34.1868 1.75141 34.1868 2.68927V4.25989L34.095 4.20904C34.0788 4.20339 33.9654 4.16384 33.7871 4.16384H31.5297C31.4865 4.46328 31.4325 4.85311 31.373 5.24294H38.3129C38.5505 5.19209 38.8259 5.14689 39.0636 5.10735C39.4146 5.28814 40.0681 5.38418 40.5164 5.38418C42.0231 5.38418 43.0007 4.32768 43.0007 2.70057C42.9953 1.0904 42.0501 0.0338983 40.5812 0Z\"\n fill=\"#747583\"\n />\n <path\n d=\"M28.4189 5.90821H28.4837C29.9905 5.90821 30.6925 5.38844 30.6925 4.10595C30.6925 3.18505 30.0499 2.45059 28.9697 2.45059H27.5818C27.1659 2.45059 26.9175 2.202 26.9175 1.78392C26.9175 1.50143 27.0201 1.15115 27.7006 1.15115H30.7357C30.8006 0.738723 30.833 0.478836 30.8924 0.0664062H27.7384C26.2694 0.0664062 25.5295 0.710474 25.5295 1.78392C25.5295 2.84607 26.1722 3.39974 27.2523 3.39974H28.6403C29.0561 3.39974 29.3046 3.74437 29.3046 4.10595C29.3046 4.34324 29.202 4.83477 28.5269 4.83477H28.2947L23.8499 4.82347H23.0398C22.3539 4.82347 21.8733 4.41669 21.8733 3.47319V2.82347C21.8733 1.84042 22.2459 1.23025 23.0398 1.23025H24.3576C24.417 0.812169 24.4548 0.546632 24.5088 0.151152H22.867H22.7104C21.3656 0.151152 20.4367 1.09466 20.4043 2.73872V2.80087V3.47319C20.4367 5.11725 21.3656 5.90256 22.7104 5.90256H22.867H24.0227L26.4314 5.90821H27.868H28.4189Z\"\n fill=\"#747583\"\n />\n </g>\n <defs>\n <clipPath id=\"clip0_sbd_mada\">\n <rect width=\"43\" height=\"15\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n</ng-template>\n", styles: [":host ::ng-deep .sbd-cancel-dialog-wrapper{border-radius:16px;overflow:hidden;box-shadow:0 24px 60px #0f172a38}:host ::ng-deep .sbd-cancel-dialog-wrapper .p-dialog-content{padding:0;border-radius:16px;overflow-y:auto;overflow-x:hidden}.sbd-cancel{font-family:inherit;border-radius:16px;overflow:visible;position:relative}.sbd-cancel__loading{padding:24px}.sbd-cancel__loading-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px}.sbd-cancel__loading-rows{display:flex;flex-direction:column;gap:10px;margin-top:20px}.sbd-cancel__loading-row{display:flex;justify-content:space-between}.sbd-cancel__are-you-sure{padding:36px 24px 28px;display:flex;flex-direction:column;align-items:center;gap:14px;text-align:center;border-top:1px solid #e2e8f0}.sbd-cancel__ays-icon{width:56px;height:56px;border-radius:50%;background:#fff7ed;border:2px solid #fed7aa;display:flex;align-items:center;justify-content:center}.sbd-cancel__ays-icon .pi{font-size:24px;color:#f97316}.sbd-cancel__ays-icon--warn{background:#fef2f2;border-color:#fecaca}.sbd-cancel__ays-icon--warn .pi{color:#ef4444}.sbd-cancel__ays-hint{font-size:13px;color:#64748b;min-height:20px;animation:sbd-hint-fade .35s ease-out}.sbd-cancel__ays-dots{display:flex;gap:6px}.sbd-cancel__ays-dots span{width:7px;height:7px;border-radius:50%;background:#f97316;opacity:.3;animation:sbd-dot-pulse 1.2s ease-in-out infinite}.sbd-cancel__ays-dots span:nth-child(2){animation-delay:.2s}.sbd-cancel__ays-dots span:nth-child(3){animation-delay:.4s}@keyframes sbd-hint-fade{0%{opacity:0;transform:translateY(5px)}to{opacity:1;transform:translateY(0)}}@keyframes sbd-dot-pulse{0%,to{opacity:.3;transform:scale(1)}50%{opacity:1;transform:scale(1.4)}}.sbd-cancel__header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid #e2e8f0;background:#f8fafc}.sbd-cancel__header-left{display:flex;align-items:center;gap:10px}.sbd-cancel__header-icon{font-size:18px;color:#475569}.sbd-cancel__header-title{font-size:15px;font-weight:700;color:#1e2e4a}.sbd-cancel__header--stack{align-items:flex-start}.sbd-cancel__header-titles{display:flex;flex-direction:column;gap:2px}.sbd-cancel__header-sub{font-size:12.5px;font-weight:600;color:#94a3b8;font-variant-numeric:tabular-nums}.sbd-cancel__badge{font-size:11.5px;font-weight:700;border-radius:20px;padding:3px 12px;letter-spacing:.03em;width:max-content;text-transform:uppercase}.sbd-cancel__badge--green{background:#dcfce7;color:#166534}.sbd-cancel__badge--red{background:#fee2e2;color:#991b1b}.sbd-cancel__badge--orange{background:#fff7ed;color:#9a3412}.sbd-cancel__badge--outline{background:transparent;box-shadow:inset 0 0 0 1.5px currentColor;padding:4px 14px}.sbd-cancel__badge--outline.sbd-cancel__badge--green{color:#16a34a}.sbd-cancel__badge--outline.sbd-cancel__badge--red{color:#dc2626}.sbd-cancel__badge--muted{background:#f8fafc;color:#64748b;box-shadow:inset 0 0 0 1px #e2e8f0}.sbd-cancel__close-btn{width:30px;height:30px;border-radius:8px;border:none;background:transparent;color:#64748b;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:background .15s,color .15s}.sbd-cancel__close-btn .pi{font-size:14px}.sbd-cancel__close-btn:hover{background:#e2e8f0;color:#1e2e4a}.sbd-cancel__close-btn--floating{position:absolute;top:12px;inset-inline-end:12px}.sbd-cancel__summary{background:#f8fafc;border:1px solid #e2e8f0;border-radius:12px;padding:14px 16px;display:flex;flex-direction:column;gap:10px}.sbd-cancel__summary-row{display:flex;align-items:center;justify-content:space-between;font-size:13.5px}.sbd-cancel__summary-row strong{font-size:15px;font-weight:800;color:#1e2e4a;font-variant-numeric:tabular-nums}.sbd-cancel__summary-row--refund .sbd-cancel__summary-label,.sbd-cancel__summary-row--refund strong{color:#16a34a}.sbd-cancel__summary-row--toggle{cursor:pointer}.sbd-cancel__summary-label{display:inline-flex;align-items:center;gap:8px;font-weight:600;color:#475569}.sbd-cancel__summary-label .pi{font-size:13px}.sbd-cancel__summary-value{display:flex;align-items:center;gap:4px}.sbd-cancel__summary-breakdown{display:flex;flex-direction:column;gap:6px;padding:2px 0 2px 22px}.sbd-cancel__summary-breakdown-row{display:flex;align-items:center;justify-content:space-between;font-size:12.5px;color:#64748b}.sbd-cancel__summary-breakdown-row span:last-child{font-variant-numeric:tabular-nums;font-weight:600;color:#475569}.sbd-cancel__section-title{font-size:14px;font-weight:700;color:#1e2e4a}.sbd-cancel__refund-card{border:1px solid #e2e8f0;border-radius:12px;padding:16px;display:flex;flex-direction:column;gap:4px}.sbd-cancel__refund-card-row{display:flex;align-items:center;justify-content:space-between;margin-top:10px;font-size:14px}.sbd-cancel__refund-card-row span{color:#334155;font-weight:600}.sbd-cancel__refund-card-row strong{color:#1e2e4a;font-weight:700;font-variant-numeric:tabular-nums}.sbd-cancel__refund-card-divider{border-top:1px solid #e2e8f0;margin:10px 0}.sbd-cancel__refund-card-divider--dashed{border-top-style:dashed}.sbd-cancel__refund-card-line{display:flex;align-items:center;justify-content:space-between;padding:5px 0;font-size:13px}.sbd-cancel__refund-card-line span:first-child{color:#64748b;display:inline-flex;align-items:center}.sbd-cancel__refund-card-line--neg{color:#64748b;font-weight:600;font-variant-numeric:tabular-nums}.sbd-cancel__refund-card-total{display:flex;align-items:center;justify-content:space-between}.sbd-cancel__refund-card-total span{font-size:14.5px;font-weight:700;color:#1e2e4a}.sbd-cancel__refund-card-total strong{font-size:17px;font-weight:800;color:#1e2e4a;font-variant-numeric:tabular-nums}.sbd-cancel__btn-keep{flex:1 1 0}.sbd-cancel__btn-primary{flex:1 1 0;background:#6d4aff!important;border-color:#6d4aff!important;color:#fff!important}.sbd-cancel__btn-primary:hover:not(:disabled){background:#5c3ce6!important;border-color:#5c3ce6!important}.sbd-cancel__btn-primary:disabled{opacity:.5}.sbd-cancel__paid{display:flex;align-items:center;justify-content:space-between;margin:0 -20px;padding:14px 20px;border-radius:0;background:#f1f0fb;border-top:1px solid #e7e5f7;border-bottom:1px solid #e7e5f7}.sbd-cancel__paid span{font-size:13.5px;font-weight:600;color:#4b4670}.sbd-cancel__paid strong{font-size:18px;font-weight:800;color:#2b2747;font-variant-numeric:tabular-nums;letter-spacing:.01em}.sbd-cancel__group{display:flex;flex-direction:column}.sbd-cancel__group-label{font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.07em;margin-bottom:2px}.sbd-cancel__group-label--deduct{color:#e05656}.sbd-cancel__group-label--refund{color:#16a34a}.sbd-cancel__line{display:flex;justify-content:space-between;align-items:center;padding:11px 0;font-size:13.5px;border-bottom:1px dashed #e5e7eb}.sbd-cancel__line:last-child{border-bottom:none}.sbd-cancel__line-label{display:inline-flex;align-items:center;color:#334155}.sbd-cancel__line-val{font-weight:700;font-variant-numeric:tabular-nums}.sbd-cancel__line-val--neg{color:#dc2626}.sbd-cancel__line-val--pos{color:#16a34a}.sbd-cancel__tag{margin-left:8px;font-size:10px;font-weight:700;line-height:1;padding:3px 8px;border-radius:6px;background:#ede9fe;color:#6d28d9;letter-spacing:.02em}.sbd-cancel__total-deduct{display:flex;align-items:center;justify-content:space-between;padding:13px 16px;border-radius:10px;background:#fdf2f2;border:1px solid #f6c9c9}.sbd-cancel__total-deduct span{font-size:14px;font-weight:700;color:#b3344a}.sbd-cancel__total-deduct strong{font-size:15px;font-weight:800;color:#dc2626;font-variant-numeric:tabular-nums}.sbd-cancel__calc{display:flex;align-items:center;gap:12px;margin:2px 0;color:#94a3b8;font-size:13px;font-variant-numeric:tabular-nums}.sbd-cancel__calc:before,.sbd-cancel__calc:after{content:\"\";flex:1;height:1px;background:#e5e7eb}.sbd-cancel__refund-total{display:flex;align-items:center;justify-content:space-between}.sbd-cancel__refund-total span{font-size:16px;font-weight:800;color:#1e2e4a}.sbd-cancel__refund-total strong{font-size:26px;font-weight:800;color:#16a34a;font-variant-numeric:tabular-nums;letter-spacing:.01em}.sbd-cancel__formula{text-align:center;padding:14px 16px;border-radius:10px;background:#1f2438;color:#f1f5f9;font-family:SFMono-Regular,ui-monospace,Menlo,Consolas,monospace;font-size:14px;font-weight:600;letter-spacing:.04em;font-variant-numeric:tabular-nums}.sbd-cancel__discrepancy{display:flex;align-items:flex-start;gap:10px;padding:11px 13px;border-radius:8px;font-size:12.5px;line-height:1.45;background:#fffbeb;border:1px solid #fde68a;color:#92400e}.sbd-cancel__discrepancy i{flex-shrink:0;margin-top:1px;font-size:14px;color:#d97706}.sbd-cancel__body{padding:16px 20px;display:flex;flex-direction:column;gap:12px}.sbd-cancel__leg-card{width:100%;border-radius:12px;border:1px solid #e2e8f0;background:#fff;overflow:hidden}.sbd-cancel__leg-card-header{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:14px 16px;cursor:pointer}.sbd-cancel__leg-checkbox{display:flex;align-items:center;gap:10px;font-size:13.5px;font-weight:700;color:#1e2e4a;cursor:pointer}.sbd-cancel__leg-checkbox input[type=checkbox]{width:17px;height:17px;accent-color:#6d4aff;cursor:pointer}.sbd-cancel__leg-chevron{flex-shrink:0;width:26px;height:26px;display:flex;align-items:center;justify-content:center;border:none;background:transparent;color:#64748b;cursor:pointer;transition:transform .15s}.sbd-cancel__leg-chevron i{font-size:13px}.sbd-cancel__leg-chevron--collapsed{transform:rotate(180deg)}.sbd-cancel__leg-card-body{display:flex;flex-direction:column;gap:4px;padding:0 16px 16px}.sbd-cancel__leg-card-body--excluded{opacity:.5}.sbd-cancel__notice{display:flex;align-items:flex-start;gap:10px;padding:10px 12px;border-radius:8px;font-size:12.5px}.sbd-cancel__notice i{flex-shrink:0;margin-top:1px;font-size:14px}.sbd-cancel__notice p{margin:2px 0 0;font-size:12px;opacity:.8}.sbd-cancel__notice strong{display:block;font-weight:700}.sbd-cancel__notice--warning{background:#fff7ed;border:1px solid #fed7aa;color:#9a3412}.sbd-cancel__notice--warning i{color:#f97316}.sbd-cancel__notice--info{background:#eff6ff;border:1px solid #bfdbfe;color:#1e40af}.sbd-cancel__notice--info i{color:#3b82f6}.sbd-cancel__notice--neutral{background:#f7f7f8;border:1px solid #e5e7eb;color:#111827}.sbd-cancel__notice--neutral i{color:#111827}.sbd-cancel__notice--tip{background:#f0fdf4;border:1px solid #bbf7d0;color:#14532d}.sbd-cancel__notice--tip i{color:#22c55e}.sbd-cancel__notice--success{background:#f0fdf4;border:1px solid #bbf7d0;color:#15803c}.sbd-cancel__notice--success i{color:#16a34a}.sbd-cancel__notice--credit{background:#faf5ff;border:1px solid #e9d5ff;color:#5b21b6;font-size:12px}.sbd-cancel__notice--credit i{color:#a855f7}.sbd-cancel__notice--shield{background:#eff6ff;border:1px solid #bfdbfe;color:#1e40af}.sbd-cancel__notice--shield strong{display:inline;font-weight:700}.sbd-cancel__notice--shield i{color:#3b82f6}.sbd-cancel__source-selector{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:4px 0}.sbd-cancel__source-label{font-size:11px;font-weight:700;color:#94a3b8;text-transform:uppercase;letter-spacing:.06em;white-space:nowrap;margin-right:2px}.sbd-cancel__source-chip{font-size:12px;font-weight:600;padding:4px 14px;border-radius:20px;border:1.5px solid #e2e8f0;background:#f8fafc;color:#475569;cursor:pointer;transition:border-color .15s,color .15s,background .15s;display:inline-flex;align-items:center}.sbd-cancel__source-chip:hover{border-color:#94a3b8;color:#475569;background:#f1f5f9}.sbd-cancel__source-chip--active{background:#eff6ff;color:#1d4ed8;border-color:#93c5fd}.sbd-cancel__source-chip--active:hover{background:#dbeafe;color:#1d4ed8;border-color:#93c5fd}.sbd-cancel__source-chip--no-refund{border-color:#fecaca;color:#b91c1c;background:#fff5f5}.sbd-cancel__source-chip--no-refund:hover{border-color:#fca5a5;background:#fee2e2;color:#b91c1c}.sbd-cancel__source-chip--active.sbd-cancel__source-chip--no-refund{background:#fee2e2;color:#991b1b;border-color:#fca5a5}.sbd-cancel__source-chip--active.sbd-cancel__source-chip--no-refund:hover{background:#fecaca}.sbd-cancel__footer{display:flex;justify-content:flex-end;gap:10px;align-items:stretch;padding:14px 20px;border-top:1px solid #e2e8f0;background:#fff}.sbd-cancel__btn-danger-pill{flex:1 1 0;border-radius:999px!important;background:#fee2e2!important;border-color:#fee2e2!important;color:#dc2626!important;font-weight:700!important}.sbd-cancel__btn-danger-pill:hover:not(:disabled){background:#fecaca!important;border-color:#fecaca!important}.sbd-cancel__btn-danger-pill:disabled{opacity:.5}.sbd-cancel__method-header{display:flex;align-items:flex-start;gap:12px;padding:20px 20px 0}.sbd-cancel__method-close{flex-shrink:0;width:32px;height:32px;border-radius:50%;background:#f8fafc;border:none;color:#1e2e4a;display:flex;align-items:center;justify-content:center;cursor:pointer}.sbd-cancel__method-close .pi{font-size:13px}.sbd-cancel__method-close:hover{background:#e2e8f0}.sbd-cancel__method-header-text{flex:1;display:flex;flex-direction:column;align-items:center;gap:4px;text-align:center;margin-right:32px}.sbd-cancel__method-title{font-size:19px;font-weight:800;color:#1e2e4a;margin:0}.sbd-cancel__method-sub{font-size:12.5px;color:#94a3b8}.sbd-cancel__method-body{padding:16px 20px 20px;display:flex;flex-direction:column;gap:14px}.sbd-cancel__select-leg-body{padding:16px 20px 20px;display:flex;flex-direction:column;gap:12px}.sbd-cancel__leg-select-card{position:relative;border:1.5px solid #e2e8f0;border-radius:16px;padding:16px 16px 16px 48px;transition:border-color .15s}.sbd-cancel__leg-select-card--selected:not(.sbd-cancel__leg-select-card--frozen){border-color:#6d4aff}.sbd-cancel__leg-select-card--disabled{opacity:.7}.sbd-cancel__leg-select-card--frozen{opacity:.6;border-color:#e2e8f0}.sbd-cancel__leg-select-lock{position:absolute;top:16px;left:16px;width:22px;height:22px;display:flex;align-items:center;justify-content:center;font-size:14px;color:#94a3b8}.sbd-cancel__single-leg-note{display:flex;align-items:flex-start;gap:10px;padding:12px 14px;border-radius:12px;background:#eaf2ff;border:1px solid #b9d6ff;color:#1a5fd6;font-size:13px;line-height:1.5}.sbd-cancel__single-leg-note i{flex-shrink:0;margin-top:1px}.sbd-cancel__all-non-refundable-note{display:flex;align-items:flex-start;gap:10px;padding:12px 14px;border-radius:12px;background:#fdf3e3;border:1px solid #f3d9a4;color:#8a5a1e;font-size:13px;line-height:1.5}.sbd-cancel__all-non-refundable-note i{flex-shrink:0;margin-top:1px;color:#b98a3e}.sbd-cancel__leg-select-checkbox{position:absolute;top:16px;left:16px;width:22px;height:22px;cursor:pointer}.sbd-cancel__leg-select-checkbox input{position:absolute;inset:0;opacity:0;margin:0;cursor:pointer}.sbd-cancel__leg-select-checkbox input:disabled{cursor:not-allowed}.sbd-cancel__leg-select-icon{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:6px;border:1.5px solid #cbd5e1;background:#fff;color:#fff;font-size:12px}input:checked+.sbd-cancel__leg-select-icon{background:#6d4aff;border-color:#6d4aff}input:disabled+.sbd-cancel__leg-select-icon{background:#f1f5f9;border-color:#e2e8f0}.sbd-cancel__leg-select-content{display:flex;flex-direction:column;gap:8px}.sbd-cancel__leg-select-top{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}.sbd-cancel__leg-select-name{font-size:15px;font-weight:700;color:#1e2e4a}.sbd-cancel__leg-select-date{font-size:13px;color:#64748b;margin-top:2px}.sbd-cancel__leg-select-times{display:flex;align-items:center;gap:8px}.sbd-cancel__leg-select-time{font-size:18px;font-weight:700;color:#1e2e4a;font-variant-numeric:tabular-nums}.sbd-cancel__leg-select-line{flex:1;position:relative;display:flex;flex-direction:column;align-items:center;gap:2px;padding:0 16px 0 8px}.sbd-cancel__leg-select-line:before{content:\"\";position:absolute;left:0;right:14px;top:50%;height:2px;background:#cbd5e1;z-index:1}.sbd-cancel__leg-select-line-stops{font-size:12px;color:#64748b}.sbd-cancel__leg-select-line-dur{font-size:11px;color:#94a3b8}.sbd-cancel__leg-select-line-arrow{position:absolute;right:4px;top:51%;transform:translateY(-50%);font-size:11px;color:#64748b}.sbd-cancel__leg-select-footer{display:flex;align-items:center;gap:8px}.sbd-cancel__leg-select-airline{font-size:12.5px;color:#64748b}.sbd-cancel__leg-select-operated-by{font-size:12px;color:#94a3b8}.sbd-cancel__leg-select-chevron{font-size:12px;color:#94a3b8;margin-inline-start:auto}.sbd-cancel__leg-select-hint{text-align:center;padding:8px 20px 0;font-size:13px;color:#94a3b8}.sbd-cancel__leg-select-notice{display:flex;align-items:flex-start;gap:8px;padding:10px 12px;border-radius:10px;background:#fdf1e0;color:#6b4a16;font-size:12.5px;line-height:1.4}.sbd-cancel__leg-select-notice i{flex-shrink:0;margin-top:1px;color:#b98a3e}.sbd-cancel__method-amount{display:flex;align-items:center;justify-content:space-between}.sbd-cancel__method-amount span{font-size:14px;color:#1e2e4a}.sbd-cancel__method-amount strong{font-size:22px;font-weight:800;color:#1e2e4a;font-variant-numeric:tabular-nums}.sbd-cancel__method-option{display:flex;align-items:flex-start;gap:12px;width:100%;text-align:left;padding:16px;border-radius:16px;border:1.5px solid #e2e8f0;background:#fff;cursor:pointer;transition:border-color .15s,box-shadow .15s}.sbd-cancel__method-option--active{border-color:#6d4aff;box-shadow:0 0 0 1px #6d4aff}.sbd-cancel__method-option:disabled{opacity:.5;cursor:not-allowed}.sbd-cancel__method-icon{flex-shrink:0;width:44px;height:44px;border-radius:10px;display:flex;align-items:center;justify-content:center;border:1px solid #e2e8f0;color:#1e2e4a}.sbd-cancel__method-icon .pi{font-size:16px}.sbd-cancel__method-body-text{flex:1;display:flex;flex-direction:column;align-items:flex-start;gap:4px}.sbd-cancel__method-name{font-size:16px;font-weight:700;color:#1e2e4a;display:inline-flex;align-items:center;gap:6px}.sbd-cancel__method-desc{font-size:13px;color:#64748b}.sbd-cancel__method-badge{display:inline-flex;align-items:center;gap:5px;margin-top:4px;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;padding:4px 10px;border-radius:20px}.sbd-cancel__method-badge svg{flex-shrink:0}.sbd-cancel__method-badge--instant{background:#dcfce7;color:#166534}.sbd-cancel__method-badge--days,.sbd-cancel__method-badge--loyalty{background:#eff6ff;color:#1e40af}.sbd-cancel__option-end{flex-shrink:0;display:flex;align-items:center;gap:8px}.sbd-cancel__method-radio{flex-shrink:0;width:18px;height:18px;margin-top:2px;border-radius:50%;border:2px solid #7c3aed;position:relative}.sbd-cancel__method-option--active .sbd-cancel__method-radio{border-color:#6d4aff}.sbd-cancel__method-option--active .sbd-cancel__method-radio:after{content:\"\";position:absolute;inset:3px;border-radius:50%;background:#6d4aff}.sbd-cancel__method-option--split{flex-wrap:wrap}.sbd-cancel__method-split-total{flex-shrink:0;font-size:16px;font-weight:700;color:#1e2e4a;font-variant-numeric:tabular-nums}.sbd-cancel__method-split-breakdown{flex-basis:100%;display:flex;flex-wrap:wrap;align-items:center;gap:6px 12px;margin-top:12px;padding-top:12px;border-top:1px solid #e2e8f0}.sbd-cancel__method-split-row{flex:1 1 auto;display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;font-size:14px;color:#1e2e4a}.sbd-cancel__method-split-row strong{font-weight:700;font-variant-numeric:tabular-nums}.sbd-cancel__method-split-label{color:#64748b;display:inline-flex;align-items:center;gap:6px}.sbd-cancel__mada-logo{display:inline-flex;align-items:center;flex-shrink:0}.sbd-cancel__mada-logo svg{display:block}.sbd-cancel__result-hero{display:flex;flex-direction:column;align-items:center;gap:18px;padding:28px 0 8px}.sbd-cancel__result-icon{width:84px;height:84px;border-radius:50%;display:flex;align-items:center;justify-content:center}.sbd-cancel__result-icon .pi{font-size:30px;color:#fff}.sbd-cancel__result-icon--green{background:#4ade80}.sbd-cancel__result-icon--orange{background:#fb923c}.sbd-cancel__result-title{font-size:19px;font-weight:800;color:#1e2e4a;margin:0;text-align:center}.sbd-cancel__result-row{display:flex;align-items:flex-start;gap:12px;width:100%;padding:12px 14px;border-radius:14px;background:#f8fafc}.sbd-cancel__result-body-text{flex:1;min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:5px}.sbd-cancel__result-body-text .sbd-cancel__method-badge{text-transform:none;letter-spacing:normal;line-height:1.35;white-space:normal}.sbd-cancel__result-sub-rows{display:flex;flex-direction:column;gap:2px;width:100%}.sbd-cancel__result-sub-row{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;font-size:12.5px;color:#64748b}.sbd-cancel__result-sub-row strong{font-weight:700;color:#64748b;font-variant-numeric:tabular-nums}.sbd-cancel__result-amount{font-size:16px;font-weight:800;color:#1e2e4a;font-variant-numeric:tabular-nums;white-space:nowrap}.sbd-cancel__result-overlay{position:absolute;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;padding:24px}.sbd-cancel__result-backdrop{position:absolute;inset:0;background:#0000008c}.sbd-cancel__result-modal{position:relative;width:100%;max-width:400px;max-height:90%;overflow-y:auto;display:flex;flex-direction:column;gap:16px;padding:24px 20px;border-radius:20px;background:#fff;box-shadow:0 24px 60px #00000059}.sbd-cancel__result-done{width:100%}\n"] }]
1440
+ }], ctorParameters: () => [] });
1441
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FuY2VsLWRpYWxvZy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zbWFydC1ib29raW5nLWRhc2hib2FyZC9zcmMvbGliL2NvbXBvbmVudHMvY2FuY2VsLWRpYWxvZy9jYW5jZWwtZGlhbG9nLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NtYXJ0LWJvb2tpbmctZGFzaGJvYXJkL3NyYy9saWIvY29tcG9uZW50cy9jYW5jZWwtZGlhbG9nL2NhbmNlbC1kaWFsb2cuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzRixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsT0FBTyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDNUQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDbkUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDhCQUE4QixDQUFDOzs7O0FBVS9ELE1BQU0sY0FBYyxHQUFHO0lBQ3JCLEVBQUUsR0FBRyxFQUFFLG9CQUFvQixFQUFnQixLQUFLLEVBQUUsMEJBQTBCLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRTtJQUN6RixFQUFFLEdBQUcsRUFBRSxhQUFhLEVBQXVCLEtBQUssRUFBRSxjQUFjLEVBQWMsS0FBSyxFQUFFLEVBQUUsRUFBRTtJQUN6RixFQUFFLEdBQUcsRUFBRSxpQ0FBaUMs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MTBCWSxZQUFZLDB0QkFBRSxZQUFZLHNLQUFFLGNBQWMsK0JBQUUsZ0JBQWdCLG9KQUFFLE9BQU87OzRGQUlwRSx3QkFBd0I7a0JBUHBDLFNBQVM7K0JBQ0UsdUJBQXVCLGNBQ3JCLElBQUksV0FDUCxDQUFDLFlBQVksRUFBRSxZQUFZLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLE9BQU8sQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgaW5wdXQsIG91dHB1dCwgaW5qZWN0LCBlZmZlY3QsIHNpZ25hbCwgY29tcHV0ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE5nVGVtcGxhdGVPdXRsZXQsIE5nQ2xhc3MgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgRGlhbG9nTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9kaWFsb2cnO1xuaW1wb3J0IHsgQnV0dG9uTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9idXR0b24nO1xuaW1wb3J0IHsgU2tlbGV0b25Nb2R1bGUgfSBmcm9tICdwcmltZW5nL3NrZWxldG9uJztcbmltcG9ydCB7IFNiZEJvb2tpbmdTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvYm9va2luZy5zZXJ2aWNlJztcbmltcG9ydCB7IFNiZFRvYXN0U2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3RvYXN0LnNlcnZpY2UnO1xuXG50eXBlIExlZ1NlbGVjdGlvbiA9ICdvbndhcmQnIHwgJ3JldHVybicgfCAnYm90aCc7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG50eXBlIExlZ0RldGFpbHMgPSBhbnk7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG50eXBlIFJlZnVuZERhdGEgPSBhbnk7XG5cbmNvbnN0IERFRFVDVElPTl9ERUZTID0gW1xuICB7IGtleTogJ3RvdGFsUGVuYWx0eVBvaW50cycsICAgICAgICAgICAgICAgbGFiZWw6ICdBaXJsaW5lIENhbmNlbGxhdGlvbiBGZWUnLCBiYWRnZTogJycgfSxcbiAgeyBrZXk6ICdoYW5kbGluZ0ZlZScsICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiAnSGFuZGxpbmcgRmVlJywgICAgICAgICAgICAgYmFkZ2U6ICcnIH0sXG4gIHsga2V5OiAndG90YWxOb25SZWZ1bmRhYmxlU2VydmljZUNoYXJnZScsICBsYWJlbDogJ1NlcnZpY2UgQ2hhcmdlJywgICAgICAgICAgIGJhZGdlOiAnJyB9LFxuICB7IGtleTogJ3RvdGFsQW5jaWxsYXJ5UmVmdW5kQW1vdW50JywgICAgICAgbGFiZWw6ICdBbmNpbGxhcnkgRmVlJywgICAgICAgICAgICBiYWRnZTogJycgfSxcbiAgeyBrZXk6ICd0b3RhbEdpZnRBbW91bnQnLCAgICAgICAgICAgICAgICAgIGxhYmVsOiAnQWRkIG9uIEZlZScsICAgICAgICAgICAgICAgYmFkZ2U6ICcnIH0sXG4gIC8vIGB0b3RhbExveWFsdHlQb2ludHNgIChwb2ludHMgc3BlbnQgYXQgYm9va2luZyB0aW1lLCBub3cgZm9yZmVpdGVkKSBpc1xuICAvLyBpbnRlbnRpb25hbGx5IG5vdCBsaXN0ZWQgaGVyZSDigJQgaXQncyBhbHJlYWR5IHN1cmZhY2VkIHVuZGVyIGl0cyBvd25cbiAgLy8gcHJvZ3JhbSBuYW1lIChlLmcuIFwiUWl0YWZcIikgaW4gdGhlIFwiVG90YWwgUGFpZFwiIGJyZWFrZG93biwgc28gbGlzdGluZyBpdFxuICAvLyBhZ2FpbiBoZXJlIHdvdWxkIGRvdWJsZSB1cCB0aGUgc2FtZSBhbW91bnQgdW5kZXIgdHdvIGRpZmZlcmVudCBzZWN0aW9ucy5cbl07XG5cbmNvbnN0IFJFRlVORF9ERUZTID0gW1xuICB7IGtleTogJ3RvdGFsQ2FyZFJlZnVuZEFtb3VudCcsICAgICAgICAgICAgbGFiZWw6ICdSZWZ1bmQgQW1vdW50JyB9LFxuICB7IGtleTogJ3RvdGFsQ3JlZGl0UmVmdW5kQW1vdW50JywgICAgICAgICAgbGFiZWw6ICdDcmVkaXQgU2hlbGwgUmVmdW5kJyB9LFxuICB7IGtleTogJ3dhbGxldFJlZnVuZEFtb3VudCcsICAgICAgICAgICAgICAgbGFiZWw6ICdBbG1hdGFyIFdhbGxldCcgfSxcbiAgeyBrZXk6ICd0b3RhbExveWFsdHlQb2ludHNSZWZ1bmRBbW91bnQnLCAgIGxhYmVsOiAnTG95YWx0eSBQb2ludHMgUmVmdW5kJyB9LFxuXTtcblxuLyoqIExhYmVscyBmb3IgYHBheW1lbnRNZXRob2RDdXN0b21lclVzZWRgIGdhdGV3YXkgY29kZXMgcmV0dXJuZWQgYnkgdGhlIGJhY2tlbmQuICovXG5jb25zdCBQQVlNRU5UX0dBVEVXQVlfTEFCRUxTOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICBDSDogJ0NhcmQnLFxuICBIUDogJ0h5cGVycGF5JyxcbiAgTUY6ICdNeSBGYXRvb3JhJyxcbiAgV1Q6ICdXaXJlIFRyYW5zZmVyJyxcbiAgU1RDOiAnU1RDJyxcbiAgVE06ICdUYW1hcmEnLFxuICBUQjogJ1RhYmJ5JyxcbiAgUkFKSEk6ICdBbCBSYWpoaSBNb2thZmFhJyxcbiAgUFBCOiAnQ3VzdG9tZXIgQmFsYW5jZScsXG4gIFBQOiAnUG9zdHBheScsXG4gIFRBTUFNOiAnVGFtYW0nLFxuICBRSVRBRjogJ1FpdGFmJyxcbiAgTUlTOiAnTUlTIFBheScsXG4gIE1BVEFSOiAnQWxtYXRhciBQYXknLFxuICBDQjogJ0NvbXBhbnkgQmFsYW5jZScsXG4gIEFOQjogJ0FOQicsXG4gIEFNV0FMOiAnQW13YWwnLFxuICBXQUxBOiAnV2FsYScsXG4gIFlHRzogJ1lHRycsXG59O1xuXG4vKiogR2F0ZXdheSBjb2RlcyB0aGF0IHJlZnVuZCB0byBhbiBpbnN0YWxsbWVudCBwbGFuIHJhdGhlciB0aGFuIHRoZSBvcmlnaW5hbCBjYXJkLiAqL1xuY29uc3QgSU5TVEFMTE1FTlRfR0FURVdBWV9DT0RFUyA9IFsnVE0nLCAnVEInXTtcblxuLyoqIEdhdGV3YXkgY29kZXMgdGhhdCByZWZ1bmQgdG8gYSBsb3lhbHR5LXByb2dyYW0gYWNjb3VudCByYXRoZXIgdGhhbiB0aGUgb3JpZ2luYWwgY2FyZC4gKi9cbmNvbnN0IExPWUFMVFlfR0FURVdBWV9DT0RFUyA9IFsnUkFKSEknLCAnUUlUQUYnLCAnU1RDJywgJ1dBTEEnXTtcblxuLyoqXG4gKiBJbnRlcm5hbCBwYXltZW50LXByb2Nlc3Nvci9nYXRld2F5IG5hbWVzLCBuZXZlciBjdXN0b21lci1yZWNvZ25pemFibGVcbiAqIGJyYW5kcyDigJQgbXVzdCBub3QgYmUgc3VyZmFjZWQgdmVyYmF0aW0gKGUuZy4gYSBjYXJkIHJlZnVuZCBwcm9jZXNzZWRcbiAqIHRocm91Z2ggSHlwZXJwYXkgbXVzdCByZWFkIGFzIFwiQ2FyZFwiL1wiT3JpZ2luYWwgUGF5bWVudCBNZXRob2RcIiwgbmV2ZXJcbiAqIFwiSHlwZXJwYXlcIikuIENhbGxlcnMgZmFsbCBiYWNrIHRvIGEgZ2VuZXJpYyBsYWJlbCB3aGVuZXZlciB0aGUgbm9ybWFsaXplZFxuICogbG9va3VwIHJldHVybnMgJycuXG4gKi9cbmNvbnN0IElOVEVSTkFMX0dBVEVXQVlfQ09ERVMgPSBbJ0hQJywgJ01GJywgJ1dUJywgJ1BQQicsICdQUCcsICdUQU1BTSddO1xuXG4vKipcbiAqIFJlc3VsdC9jb25maXJtYXRpb24tc2NyZWVuLW9ubHkgb3ZlcnJpZGU6IHRoZXNlIGdhdGV3YXlzIHByb2Nlc3MgY2FyZFxuICogcGF5bWVudHMgdGhyb3VnaCBNYWRhIOKAlCBzaG93biBzcGVjaWZpY2FsbHkgYXMgXCJNYWRhIENhcmRcIiBpbnN0ZWFkIG9mXG4gKiBmYWxsaW5nIGJhY2sgdG8gdGhlIGdlbmVyaWMgXCJPcmlnaW5hbCBQYXltZW50IE1ldGhvZFwiIGxhYmVsIHVzZWRcbiAqIGV2ZXJ5d2hlcmUgZWxzZSBgSU5URVJOQUxfR0FURVdBWV9DT0RFU2AgYXBwbGllcy5cbiAqL1xuY29uc3QgTUFEQV9HQVRFV0FZX0NPREVTID0gWydIUCcsICdDSCddO1xuXG5jb25zdCBDUkVESVRfU0hFTExfU1VGRklYID0gJ0l0IGNhbiBiZSB1c2VkIG9ubHkgZm9yIGZ1dHVyZSBib29raW5nIG9uIHRoZSBhaXJsaW5lIHdlYnNpdGUuJztcblxuY29uc3QgR0lGVF9ISU5UID0gJ1BsZWFzZSBub3RlOiBJZiB5b3UgY2FuY2VsIGVpdGhlciBsZWcgb2YgeW91ciByb3VuZC10cmlwIGJvb2tpbmcsIHRoZSBhZGQtb24vZ2lmdCBzZXJ2aWNlIHdpbGwgYmUgY2FuY2VsbGVkIGF1dG9tYXRpY2FsbHkuJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLXNiZC1jYW5jZWwtZGlhbG9nJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0RpYWxvZ01vZHVsZSwgQnV0dG9uTW9kdWxlLCBTa2VsZXRvbk1vZHVsZSwgTmdUZW1wbGF0ZU91dGxldCwgTmdDbGFzc10sXG4gIHRlbXBsYXRlVXJsOiAnLi9jYW5jZWwtZGlhbG9nLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmw6ICcuL2NhbmNlbC1kaWFsb2cuY29tcG9uZW50LnNjc3MnLFxufSlcbmV4cG9ydCBjbGFzcyBTYmRDYW5jZWxEaWFsb2dDb21wb25lbnQge1xuICBwcml2YXRlIGJvb2tpbmdTZXJ2aWNlID0gaW5qZWN0KFNiZEJvb2tpbmdTZXJ2aWNlKTtcbiAgcHJpdmF0ZSB0b2FzdCA9IGluamVjdChTYmRUb2FzdFNlcnZpY2UpO1xuXG4gIHZpc2libGUgPSBpbnB1dChmYWxzZSk7XG4gIGJvb2tpbmdJZCA9IGlucHV0KCcnKTtcbiAgcHJvZHVjdCA9IGlucHV0PCdmbGlnaHQnIHwgJ2hvdGVsJz4oJ2ZsaWdodCcpO1xuICBwbnJJbmZvID0gaW5wdXQ8eyBwbnI/OiBzdHJpbmc7IExlZ0RpcmVjdGlvbmFsaXR5Pzogc3RyaW5nIH1bXT4oW10pO1xuICAvKiogU2FtZSBgYm9va2luZ19pbmZvYCBwYXlsb2FkIHRoZSBkYXNoYm9hcmQgYWxyZWFkeSBmZXRjaGVzIChnZXRCb29raW5nKC4uLiwgJ2Jvb2tpbmdfaW5mbycpKSDigJQgcmV1c2VkIGhlcmUgdG8gcmVuZGVyIHJlYWwgcm91dGUvdGltZSBkZXRhaWxzIG9uIHRoZSBzZWxlY3QtbGVnIGNhcmRzLCBpbnN0ZWFkIG9mIGEgc2Vjb25kIEFQSSBjYWxsLiAqL1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICBib29raW5nSW5mbyA9IGlucHV0PGFueT4obnVsbCk7XG4gIGNsb3NlZCA9IG91dHB1dDx2b2lkPigpO1xuICBjb25maXJtZWQgPSBvdXRwdXQ8TGVnU2VsZWN0aW9uPigpO1xuXG4gIC8qKiBQZXItbGVnIHJvdXRlL3RpbWUgZGV0YWlscywgbWlycm9yaW5nIGFwcC1zYmQtZmxpZ2h0LWl0aW5lcmFyeS1jYXJkJ3MgbWFwcGluZyBvZiBib29raW5nX2luZm8ubGVnX2luZm8uICovXG4gIGl0aW5lcmFyeUxlZ3MgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3QgYmkgPSB0aGlzLmJvb2tpbmdJbmZvKCk/LmRhdGE/LmJvb2tpbmdfaW5mbztcbiAgICBpZiAoIWJpKSByZXR1cm4gW107XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICByZXR1cm4gKGJpLmxlZ19pbmZvID8/IFtdKS5tYXAoKGxlZzogYW55LCBpOiBudW1iZXIpID0+ICh7XG4gICAgICBkaXJlY3Rpb246IGxlZy5MZWdEaXJlY3Rpb25hbGl0eSBhcyBzdHJpbmcsXG4gICAgICBhaXJsaW5lTmFtZTogKGxlZy5MZWdBaXJsaW5lc05hbWVzID8/IFtdKS5qb2luKCcsICcpLFxuICAgICAgY2FiaW46IGxlZy5MZWdDYWJpbnM/LlswXT8uTmFtZSA/PyAnJyxcbiAgICAgIGZyb206IGxlZy5MZWdEZXBhcnR1cmVBaXJwb3J0Q29kZSBhcyBzdHJpbmcsXG4gICAgICB0bzogbGVnLkxlZ0Fycml2YWxBaXJwb3J0Q29kZSBhcyBzdHJpbmcsXG4gICAgICBkZXBUaW1lOiBsZWcuTGVnRGVwYXJ0dXJlRGF0ZVRpbWUgYXMgc3RyaW5nLFxuICAgICAgYXJyVGltZTogbGVnLkxlZ0Fycml2YWxEYXRlVGltZSBhcyBzdHJpbmcsXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgc3RvcHM6IChsZWcuU3RvcHMgPz8gW10pIGFzIGFueVtdLFxuICAgICAgdG90YWxNaW51dGVzOiBiaS5kdXJhdGlvbj8ubGVncz8uW2ldPy5TZWdtZW50c1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICA/LnJlZHVjZSgoc3VtOiBudW1iZXIsIHM6IGFueSkgPT4gc3VtICsgKHMuU2VnbWVudEVsYXBzZWRUaW1lTWludXRlcyA/PyAwKSwgMCkgPz8gbnVsbCxcbiAgICAgIG9wZXJhdGVkQnk6IGxlZy5zdXBwbGllck5hbWUgPyBbbGVnLnN1cHBsaWVyTmFtZSBhcyBzdHJpbmddIDogW10sXG4gICAgfSkpO1xuICB9KTtcblxuICAvKipcbiAgICogVGhlIHJldHVybiBsZWcgaXMgbWF0Y2hlZCBieSBhbiBleHBsaWNpdCAnUmV0dXJuJyBkaXJlY3Rpb247IHRoZSBvbndhcmRcbiAgICogbGVnIGlzIHdoYXRldmVyJ3MgbGVmdCAoc29tZSBib29raW5ncyBkb24ndCB0YWcgdGhlIG91dGJvdW5kIGxlZyB3aXRoIGFuXG4gICAqIGV4cGxpY2l0ICdEZXBhcnR1cmUnIHZhbHVlKSwgZmFsbGluZyBiYWNrIHRvIHRoZSBmaXJzdCBlbnRyeS5cbiAgICovXG4gIGl0aW5lcmFyeUxlZyhraW5kOiAnb253YXJkJyB8ICdyZXR1cm4nKSB7XG4gICAgY29uc3QgbGVncyA9IHRoaXMuaXRpbmVyYXJ5TGVncygpO1xuICAgIGlmICghbGVncy5sZW5ndGgpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IHJldHVybkxlZyA9IGxlZ3MuZmluZCgobDogeyBkaXJlY3Rpb246IHN0cmluZyB9KSA9PiAobC5kaXJlY3Rpb24gPz8gJycpLnRvTG93ZXJDYXNlKCkgPT09ICdyZXR1cm4nKSA/PyBudWxsO1xuICAgIGlmIChraW5kID09PSAncmV0dXJuJykgcmV0dXJuIHJldHVybkxlZztcbiAgICByZXR1cm4gKFxuICAgICAgbGVncy5maW5kKChsOiB7IGRpcmVjdGlvbjogc3RyaW5nIH0pID0+IChsLmRpcmVjdGlvbiA/PyAnJykudG9Mb3dlckNhc2UoKSA9PT0gJ2RlcGFydHVyZScpID8/XG4gICAgICBsZWdzLmZpbmQoKGwpID0+IGwgIT09IHJldHVybkxlZykgPz9cbiAgICAgIGxlZ3NbMF0gPz9cbiAgICAgIG51bGxcbiAgICApO1xuICB9XG5cbiAgZm10VGltZShkdDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoIWR0KSByZXR1cm4gJ+KAlCc7XG4gICAgdHJ5IHsgcmV0dXJuIG5ldyBEYXRlKGR0KS50b0xvY2FsZVRpbWVTdHJpbmcoJ2VuLUdCJywgeyBob3VyOiAnMi1kaWdpdCcsIG1pbnV0ZTogJzItZGlnaXQnIH0pOyB9XG4gICAgY2F0Y2ggeyByZXR1cm4gZHQ7IH1cbiAgfVxuXG4gIGZtdFNob3J0RGF0ZShkdDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoIWR0KSByZXR1cm4gJ+KAlCc7XG4gICAgdHJ5IHsgcmV0dXJuIG5ldyBEYXRlKGR0KS50b0xvY2FsZURhdGVTdHJpbmcoJ2VuLUdCJywgeyB3ZWVrZGF5OiAnc2hvcnQnLCBkYXk6ICcyLWRpZ2l0JywgbW9udGg6ICdzaG9ydCcgfSk7IH1cbiAgICBjYXRjaCB7IHJldHVybiBkdDsgfVxuICB9XG5cbiAgZm10TWlucyhtaW5zOiBudW1iZXIgfCBudWxsKTogc3RyaW5nIHtcbiAgICBpZiAobWlucyA9PSBudWxsKSByZXR1cm4gJyc7XG4gICAgcmV0dXJuIGAke01hdGguZmxvb3IobWlucyAvIDYwKX1oICR7bWlucyAlIDYwfW1gO1xuICB9XG5cbiAgcmVmdW5kRGF0YSAgICAgPSBzaWduYWw8UmVmdW5kRGF0YSB8IG51bGw+KG51bGwpO1xuICBjYW5jZWxSZXN1bHQgICA9IHNpZ25hbDxSZWZ1bmREYXRhIHwgbnVsbD4obnVsbCk7XG4gIGxvYWRpbmcgICAgICAgID0gc2lnbmFsKGZhbHNlKTtcbiAgY2FuY2VsbGluZyAgICAgPSBzaWduYWwoZmFsc2UpO1xuICBjb25maXJtaW5nICAgICA9IHNpZ25hbChmYWxzZSk7XG4gIC8qKlxuICAgKiAnc2VsZWN0LWxlZycgc2hvd24gb25jZSB0aGUgcmVmdW5kIHByZXZpZXcgcmVzb2x2ZXMsIGZvciByb3VuZC10cmlwXG4gICAqIGJvb2tpbmdzIHRoZSBiYWNrZW5kIGhhc24ndCBhbHJlYWR5IHJlc3RyaWN0ZWQgdG8gYSBzaW5nbGUgbGVnIOKAlCBtaXJyb3JzXG4gICAqIGFsbWF0YXItYjJjJ3Mgc2VsZWN0LWxlZyBzY3JlZW4uIFNraXBwZWQgc3RyYWlnaHQgdG8gJ2RldGFpbHMnIG90aGVyd2lzZS5cbiAgICovXG4gIHN0ZXAgICAgICAgICAgID0gc2lnbmFsPCdsb2FkaW5nJyB8ICdzZWxlY3QtbGVnJyB8ICdkZXRhaWxzJz4oJ2xvYWRpbmcnKTtcbiAgLyoqIFBlci1sZWcgaW5jbHVzaW9uIChjaGVja2JveCkgYW5kIGV4cGFuZC9jb2xsYXBzZSBzdGF0ZSDigJQgcm91bmQtdHJpcCBvbmx5LiAqL1xuICBvbndhcmRDaGVja2VkICA9IHNpZ25hbCh0cnVlKTtcbiAgcmV0dXJuQ2hlY2tlZCAgPSBzaWduYWwodHJ1ZSk7XG4gIG9ud2FyZEV4cGFuZGVkID0gc2lnbmFsKHRydWUpO1xuICByZXR1cm5FeHBhbmRlZCA9IHNpZ25hbCh0cnVlKTtcbiAgc2VsZWN0ZWRTb3VyY2UgPSBzaWduYWw8c3RyaW5nPignJyk7XG4gIGNhbmNlbEhpbnQgICAgID0gc2lnbmFsPHN0cmluZz4oJycpO1xuICBwYWlkU3VtbWFyeUV4cGFuZGVkID0gc2lnbmFsKGZhbHNlKTtcbiAgcHJlZmVycmVkUmVmdW5kTWV0aG9kID0gc2lnbmFsPCd3YWxsZXQnIHwgJ29yaWdpbmFsUGF5bWVudE1ldGhvZCcgfCAnc3BsaXQnPignb3JpZ2luYWxQYXltZW50TWV0aG9kJyk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBDQU5DRUxfSElOVFMgPSBbXG4gICAgJ0xvYWRpbmcgeW91ciBkYXRhLi4uJyxcbiAgICAnRmV0Y2hpbmcgU2FicmUgZGF0YS4uLicsXG4gICAgJ0ZldGNoaW5nIEFUQyBkYXRhLi4uJyxcbiAgICAnQ2FsY3VsYXRpbmcgcmVmdW5kIGFtb3VudC4uLicsXG4gICAgJ1dlIGFyZSBhbG1vc3QgZG9uZSwgcGxlYXNlIHdhaXQuLi4nLFxuICBdO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICBwcml2YXRlIGhpbnRUaW1lcjogYW55ID0gbnVsbDtcblxuICBoYXNPbndhcmQgID0gY29tcHV0ZWQoKCkgPT4gISF0aGlzLnJlZnVuZERhdGEoKT8ubGVnSW5mbz8ub253YXJkKTtcbiAgaGFzUmV0dXJuICA9IGNvbXB1dGVkKCgpID0+ICEhdGhpcy5yZWZ1bmREYXRhKCk/LmxlZ0luZm8/LnJldHVybik7XG4gIGlzUm91bmRUcmlwID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5oYXNPbndhcmQoKSAmJiB0aGlzLmhhc1JldHVybigpKTtcblxuICAvKiogV2hpY2ggbGVnKHMpIHRoZSBiYWNrZW5kIGFsbG93cyBjYW5jZWxsaW5nLCBmcm9tIHRoZSByZWZ1bmQgcHJldmlldyByZXNwb25zZS4gKi9cbiAgbGVnRGlyZWN0aW9uYWxpdHkgPSBjb21wdXRlZDwnT05XQVJEJyB8ICdSRVRVUk4nIHwgJ0JPVEgnIHwgdW5kZWZpbmVkPihcbiAgICAoKSA9PiB0aGlzLnJlZnVuZERhdGEoKT8ubGVnRGlyZWN0aW9uYWxpdHksXG4gICk7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gcmVuZGVyIHRoZSByb3VuZC10cmlwIFwidHdvIGxlZyBjYXJkc1wiIFVJLiBPbmx5IHdoZW4gdGhlXG4gICAqIGJhY2tlbmQgZXhwbGljaXRseSBhbGxvd3MgY2FuY2VsbGluZyBib3RoIGxlZ3Mg4oCUIG90aGVyd2lzZSAoT05XQVJELW9ubHkgL1xuICAgKiBSRVRVUk4tb25seSkgc2hvdyBhIHNpbmdsZSBjYXJkIGZvciB0aGF0IGxlZywgc2FtZSBhcyBhIG9uZS13YXkgYm9va2luZy5cbiAgICovXG4gIHNob3dSb3VuZFRyaXBMZWdDYXJkcyA9IGNvbXB1dGVkKFxuICAgICgpID0+IHRoaXMuaXNSb3VuZFRyaXAoKSAmJiAodGhpcy5sZWdEaXJlY3Rpb25hbGl0eSgpID8/ICdCT1RIJykgPT09ICdCT1RIJyxcbiAgKTtcblxuICAvKiogRGVyaXZlZCBmcm9tIHRoZSBwZXItbGVnIGNoZWNrYm94ZXMg4oCUICdib3RoJyB1bmxlc3MgZXhhY3RseSBvbmUgaXMgdW5jaGVja2VkLiAqL1xuICBzZWxlY3RlZExlZyA9IGNvbXB1dGVkPExlZ1NlbGVjdGlvbj4oKCkgPT4ge1xuICAgIGlmICghdGhpcy5pc1JvdW5kVHJpcCgpKSByZXR1cm4gJ2JvdGgnO1xuICAgIGNvbnN0IGRpciA9IHRoaXMubGVnRGlyZWN0aW9uYWxpdHkoKTtcbiAgICBpZiAoZGlyID09PSAnT05XQVJEJykgcmV0dXJuICdvbndhcmQnO1xuICAgIGlmIChkaXIgPT09ICdSRVRVUk4nKSByZXR1cm4gJ3JldHVybic7XG4gICAgY29uc3Qgb253YXJkID0gdGhpcy5vbndhcmRDaGVja2VkKCk7XG4gICAgY29uc3QgcmV0ID0gdGhpcy5yZXR1cm5DaGVja2VkKCk7XG4gICAgaWYgKG9ud2FyZCAmJiByZXQpIHJldHVybiAnYm90aCc7XG4gICAgcmV0dXJuIG9ud2FyZCA/ICdvbndhcmQnIDogJ3JldHVybic7XG4gIH0pO1xuXG4gIC8vIFJldHVybnMgdGhlIHNvdXJjZUJyZWFrZG93biBmb3IgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBsZWcgKG9yIHJvb3QgZm9yIFwiYm90aFwiKVxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICBhY3RpdmVTb3VyY2VCcmVha2Rvd24gPSBjb21wdXRlZCgoKTogUmVjb3JkPHN0cmluZywgYW55PiB8IG51bGwgPT4ge1xuICAgIGNvbnN0IHNlbCA9IHRoaXMuc2VsZWN0ZWRMZWcoKTtcbiAgICBjb25zdCByb290ID0gdGhpcy5yZWZ1bmREYXRhKCk7XG4gICAgaWYgKCFyb290KSByZXR1cm4gbnVsbDtcbiAgICAvLyBBIGxlZy1zY29wZWQgdmlldyAoc2luZ2xlIGxlZywgb3IgYm90aCBsZWdzIHN1bW1lZCkgbXVzdCBub3QgZmFsbCBiYWNrXG4gICAgLy8gdG8gcm9vdC5zb3VyY2VCcmVha2Rvd24g4oCUIGl0cyB0b3RhbHMgYXJlIGZvciB0aGUgd2hvbGUvb3JpZ2luYWxcbiAgICAvLyBpdGluZXJhcnksIG5vdCBzY29wZWQgdG8gdGhlIGxlZyhzKSBhY3R1YWxseSBzaG93biwgYW5kIGFwcGx5aW5nIGl0XG4gICAgLy8gd291bGQgY2xvYmJlciB0aGUgY29ycmVjdGx5IGxlZy1zY29wZWQgdG90YWxzIGNvbXB1dGVkIGluXG4gICAgLy8gYGN1cnJlbnREYXRhKClgLlxuICAgIGlmIChzZWwgPT09ICdvbndhcmQnKSByZXR1cm4gcm9vdC5sZWdJbmZvPy5vbndhcmQ/LnNvdXJjZUJyZWFrZG93biA/PyBudWxsO1xuICAgIGlmIChzZWwgPT09ICdyZXR1cm4nKSByZXR1cm4gcm9vdC5sZWdJbmZvPy5yZXR1cm4/LnNvdXJjZUJyZWFrZG93biA/PyBudWxsO1xuICAgIGlmIChyb290LmxlZ0luZm8/Lm9ud2FyZCAmJiByb290LmxlZ0luZm8/LnJldHVybikgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHJvb3Quc291cmNlQnJlYWtkb3duID8/IG51bGw7XG4gIH0pO1xuXG4gIGF2YWlsYWJsZVNvdXJjZXMgPSBjb21wdXRlZCgoKTogc3RyaW5nW10gPT5cbiAgICBPYmplY3Qua2V5cyh0aGlzLmFjdGl2ZVNvdXJjZUJyZWFrZG93bigpID8/IHt9KVxuICApO1xuXG4gIGN1cnJlbnREYXRhID0gY29tcHV0ZWQ8UmVmdW5kRGF0YSB8IG51bGw+KCgpID0+IHtcbiAgICBjb25zdCByb290ID0gdGhpcy5yZWZ1bmREYXRhKCk7XG4gICAgaWYgKCFyb290KSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBzZWwgPSB0aGlzLnNlbGVjdGVkTGVnKCk7XG4gICAgaWYgKHNlbCA9PT0gJ29ud2FyZCcgJiYgcm9vdC5sZWdJbmZvPy5vbndhcmQpXG4gICAgICByZXR1cm4gdGhpcy5idWlsZExlZ0RhdGEocm9vdCwgcm9vdC5sZWdJbmZvLm9ud2FyZCwgJ29ud2FyZCcpO1xuICAgIGlmIChzZWwgPT09ICdyZXR1cm4nICYmIHJvb3QubGVnSW5mbz8ucmV0dXJuKVxuICAgICAgcmV0dXJuIHRoaXMuYnVpbGRMZWdEYXRhKHJvb3QsIHJvb3QubGVnSW5mby5yZXR1cm4sICdyZXR1cm4nKTtcbiAgICAvLyBQYXltZW50L3JlZnVuZCBmaWd1cmVzIGNvbWUgZnJvbSBgbGVnSW5mb2AsIG5ldmVyIHJvb3QgKHJvb3QgaXNuJ3RcbiAgICAvLyByZWxpYWJseSBzY29wZWQgdG8gd2hpY2hldmVyIGxlZyhzKSBlbmRlZCB1cCBzZWxlY3RlZCkg4oCUIGNvbWJpbmUgYm90aFxuICAgIC8vIGxlZ3Mgd2hlbiBib3RoIGFyZSBpbiBwbGF5LCBvdGhlcndpc2UgdXNlIHdoaWNoZXZlciBvbmUgZXhpc3RzLlxuICAgIGNvbnN0IG9ud2FyZCA9IHJvb3QubGVnSW5mbz8ub253YXJkO1xuICAgIGNvbnN0IHJldCA9IHJvb3QubGVnSW5mbz8ucmV0dXJuO1xuICAgIGlmIChvbndhcmQgJiYgcmV0KSByZXR1cm4gdGhpcy5idWlsZENvbWJpbmVkTGVnRGF0YShyb290LCBvbndhcmQsIHJldCk7XG4gICAgaWYgKG9ud2FyZCAmJiAhcmV0KSByZXR1cm4gdGhpcy5idWlsZExlZ0RhdGEocm9vdCwgb253YXJkLCAnb253YXJkJyk7XG4gICAgaWYgKHJldCAmJiAhb253YXJkKSByZXR1cm4gdGhpcy5idWlsZExlZ0RhdGEocm9vdCwgcmV0LCAncmV0dXJuJyk7XG4gICAgcmV0dXJuIHJvb3Q7XG4gIH0pO1xuXG4gIC8vIGN1cnJlbnREYXRhIHdpdGggc291cmNlLXNwZWNpZmljIHBlbmFsdHkvcmVmdW5kL3JlZnVuZGFiaWxpdHkgb3ZlcnJpZGVzIGFwcGxpZWRcbiAgYWRqdXN0ZWREYXRhID0gY29tcHV0ZWQ8UmVmdW5kRGF0YSB8IG51bGw+KCgpID0+IHtcbiAgICBjb25zdCBiYXNlID0gdGhpcy5jdXJyZW50RGF0YSgpO1xuICAgIGlmICghYmFzZSkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHRoaXMuYXBwbHlTb3VyY2VPdmVycmlkZShiYXNlLCB0aGlzLmFjdGl2ZVNvdXJjZUJyZWFrZG93bigpKTtcbiAgfSk7XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgcHJpdmF0ZSBhcHBseVNvdXJjZU92ZXJyaWRlKGJhc2U6IFJlZnVuZERhdGEsIGJyZWFrZG93bjogUmVjb3JkPHN0cmluZywgYW55PiB8IG51bGwpOiBSZWZ1bmREYXRhIHtcbiAgICBjb25zdCBzZWwgPSB0aGlzLnNlbGVjdGVkU291cmNlKCk7XG4gICAgaWYgKCFzZWwgfHwgIWJyZWFrZG93biB8fCAhYnJlYWtkb3duW3NlbF0pIHJldHVybiB0aGlzLnJlY29uY2lsZVNvbGVEZXN0aW5hdGlvbihiYXNlKTtcbiAgICBjb25zdCBzcmMgPSBicmVha2Rvd25bc2VsXTtcbiAgICBjb25zdCBzb3VyY2VSZWZ1bmRhYmxlID0gc3JjLmlzUmVmdW5kYWJsZSAhPT0gZmFsc2U7IC8vIGRlZmF1bHQgdHJ1ZSBpZiBub3Qgc2V0XG4gICAgaWYgKCFzb3VyY2VSZWZ1bmRhYmxlKSB7XG4gICAgICAvLyBTb3VyY2UgY2Fubm90IHByb2Nlc3MgcmVmdW5kIOKAlCB6ZXJvIG91dCBmaW5hbmNpYWwgZmllbGRzXG4gICAgICByZXR1cm4gdGhpcy5yZWNvbmNpbGVTb2xlRGVzdGluYXRpb24oe1xuICAgICAgICAuLi5iYXNlLFxuICAgICAgICBpc1JlZnVuZGFibGU6ICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgIHRvdGFsUGVuYWx0eVBvaW50czogICAgICAgICAwLFxuICAgICAgICB0b3RhbFN1cHBsaWVyUGVuYWx0eVBvaW50czogMCxcbiAgICAgICAgdG90YWxDYW5jZWxsYXRpb25GZWU6ICAgICAgIDAsXG4gICAgICAgIHRvdGFsUmVmdW5kQW1vdW50OiAgICAgICAgICAwLFxuICAgICAgICB0b3RhbENhcmRSZWZ1bmRBbW91bnQ6ICAgICAgMCxcbiAgICAgICAgaGFuZGxpbmdGZWU6ICAgICAgICAgICAgICAgIDAsXG4gICAgICB9KTtcbiAgICB9XG4gICAgLy8gUHJlZmVyIHRoZSBzb3VyY2UncyBvd24gd2FsbGV0UmVmdW5kQW1vdW50L3RvdGFsQ2FyZFJlZnVuZEFtb3VudCB3aGVuXG4gICAgLy8gdGhlIEFQSSBwcm92aWRlcyB0aGVtICh0aGV5J3JlIGFscmVhZHkgbmV0IG9mIGVhY2ggb3RoZXIgZm9yIHRoaXNcbiAgICAvLyBzb3VyY2UpIOKAlCBvbmx5IGZhbGwgYmFjayB0byBkZXJpdmluZyBjYXJkUmVmdW5kIHdoZW4gdGhlIEFQSSBkb2Vzbid0LlxuICAgIGNvbnN0IG5ld1RvdGFsICAgICAgPSBOdW1iZXIoc3JjLnRvdGFsUmVmdW5kQW1vdW50IHx8IDApO1xuICAgIGNvbnN0IHdhbGxldFJlZnVuZCAgPVxuICAgICAgc3JjLndhbGxldFJlZnVuZEFtb3VudCAhPT0gdW5kZWZpbmVkXG4gICAgICAgID8gTnVtYmVyKHNyYy53YWxsZXRSZWZ1bmRBbW91bnQgfHwgMClcbiAgICAgICAgOiBOdW1iZXIoYmFzZS53YWxsZXRSZWZ1bmRBbW91bnQgfHwgMCk7XG4gICAgY29uc3QgY2FyZFJlZnVuZCAgICA9XG4gICAgICBzcmMudG90YWxDYXJkUmVmdW5kQW1vdW50ICE9PSB1bmRlZmluZWRcbiAgICAgICAgPyBOdW1iZXIoc3JjLnRvdGFsQ2FyZFJlZnVuZEFtb3VudCB8fCAwKVxuICAgICAgICA6IE1hdGgubWF4KFxuICAgICAgICAgICAgMCxcbiAgICAgICAgICAgIG5ld1RvdGFsIC1cbiAgICAgICAgICAgICAgTnVtYmVyKGJhc2UudG90YWxDcmVkaXRSZWZ1bmRBbW91bnQgfHwgMCkgLVxuICAgICAgICAgICAgICB3YWxsZXRSZWZ1bmQgLVxuICAgICAgICAgICAgICBOdW1iZXIoYmFzZS50b3RhbExveWFsdHlQb2ludHNSZWZ1bmRBbW91bnQgfHwgMCksXG4gICAgICAgICAgKTtcbiAgICByZXR1cm4gdGhpcy5yZWNvbmNpbGVTb2xlRGVzdGluYXRpb24oe1xuICAgICAgLi4uYmFzZSxcbiAgICAgIGlzUmVmdW5kYWJsZTogICAgICAgICAgICAgICB0cnVlLFxuICAgICAgdG90YWxQZW5hbHR5UG9pbnRzOiAgICAgICAgIE51bWJlcihzcmMudG90YWxTdXBwbGllclBlbmFsdHlQb2ludHMgfHwgMCksXG4gICAgICB0b3RhbFN1cHBsaWVyUGVuYWx0eVBvaW50czogTnVtYmVyKHNyYy50b3RhbFN1cHBsaWVyUGVuYWx0eVBvaW50cyB8fCAwKSxcbiAgICAgIHRvdGFsQ2FuY2VsbGF0aW9uRmVlOiAgICAgICBOdW1iZXIoc3JjLnRvdGFsQ2FuY2VsbGF0aW9uRmVlIHx8IDApLFxuICAgICAgdG90YWxSZWZ1bmRBbW91bnQ6ICAgICAgICAgIG5ld1RvdGFsLFxuICAgICAgd2FsbGV0UmVmdW5kQW1vdW50OiAgICAgICAgIHdhbGxldFJlZnVuZCxcbiAgICAgIHRvdGFsQ2FyZFJlZnVuZEFtb3VudDogICAgICBjYXJkUmVmdW5kLFxuICAgICAgaGFuZGxpbmdGZWU6ICAgICAgICAgICAgICAgIE51bWJlcihzcmMuaGFuZGxpbmdGZWUgfHwgMCksXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogV2hlbiBleGFjdGx5IG9uZSBvZiB0aGUgZm91ciByZWZ1bmQtZGVzdGluYXRpb24gZmllbGRzICh3YWxsZXQgLyBjYXJkIC9cbiAgICogY3JlZGl0IC8gbG95YWx0eSkgaXMgbm9uLXplcm8sIHRoZSBiYWNrZW5kIGhhcyBvY2Nhc2lvbmFsbHkgc2VudCB0aGF0XG4gICAqIGZpZWxkIGFzIGEgcHJlLWRlZHVjdGlvbiB2YWx1ZSB0aGF0IGRpc2FncmVlcyB3aXRoIHRoZSBkZWNsYXJlZCB0b3RhbFxuICAgKiAoZS5nLiB3YWxsZXQgPSB0b3RhbCArIGNhbmNlbGxhdGlvbiBmZWUpIOKAlCB0aGVyZSdzIG5vIGFtYmlndWl0eSBhYm91dFxuICAgKiAqd2hlcmUqIHRoZSBtb25leSBnb2VzLCBvbmx5IGEgc3RhbGUgbnVtYmVyIGluIHRoYXQgb25lIGZpZWxkLCBzbyB0cnVzdFxuICAgKiB0aGUgZGVjbGFyZWQgdG90YWwgYW5kIGNvcnJlY3QgdGhlIHNvbGUgZGVzdGluYXRpb24gdG8gbWF0Y2ggcmF0aGVyXG4gICAqIHRoYW4gc3VyZmFjaW5nIGEgZmFsc2UgZGlzY3JlcGFuY3kuXG4gICAqL1xuICBwcml2YXRlIHJlY29uY2lsZVNvbGVEZXN0aW5hdGlvbihkOiBSZWZ1bmREYXRhKTogUmVmdW5kRGF0YSB7XG4gICAgaWYgKCFkPy5pc1JlZnVuZGFibGUpIHJldHVybiBkO1xuICAgIGNvbnN0IHdhbGxldCAgPSBOdW1iZXIoZC53YWxsZXRSZWZ1bmRBbW91bnQgPz8gMCk7XG4gICAgY29uc3QgY2FyZCAgICA9IE51bWJlcihkLnRvdGFsQ2FyZFJlZnVuZEFtb3VudCA/PyAwKTtcbiAgICBjb25zdCBjcmVkaXQgID0gTnVtYmVyKGQudG90YWxDcmVkaXRSZWZ1bmRBbW91bnQgPz8gMCk7XG4gICAgY29uc3QgbG95YWx0eSA9IE51bWJlcihkLnRvdGFsTG95YWx0eVBvaW50c1JlZnVuZEFtb3VudCA/PyAwKTtcbiAgICAvLyBBIGZvcmZlaXRlZC1wb2ludHMgZGVzdGluYXRpb24gKGUuZy4gUWl0YWYgcG9pbnRzIGZ1bmRlZCBzZXBhcmF0ZWx5XG4gICAgLy8gZnJvbSB0aGUgY2FyZCByZWZ1bmQpIGFsc28gY291bnRzIGFzIGEgcmVhbCBkZXN0aW5hdGlvbiBoZXJlIOKAlCB3aXRob3V0XG4gICAgLy8gdGhpcywgYSBsZWdpdGltYXRlbHkgc3BsaXQgY2FyZCtsb3lhbHR5LXBvaW50cyByZWZ1bmQgKGUuZy4gOTE4IGNhcmQgK1xuICAgIC8vIDUwIFFpdGFmIHBvaW50cyA9IDk2OCB0b3RhbCkgbG9va3MgbGlrZSBhIHNpbmdsZSBzdGFsZSBcImNhcmRcIiBmaWVsZCB0b1xuICAgIC8vIHRoaXMgaGV1cmlzdGljLCB3aGljaCB0aGVuIGZvcmNlLW92ZXJ3cml0ZXMgdGhlIGNvcnJlY3QgOTE4IHdpdGggdGhlXG4gICAgLy8gZnVsbCA5NjggdG90YWwgYW5kIHNpbGVudGx5IGVyYXNlcyB0aGUgc3BsaXQuXG4gICAgY29uc3QgZm9yZmVpdGVkTG95YWx0eSA9IHRoaXMuZm9yZmVpdGVkTG95YWx0eVBvaW50c0ZhbGxiYWNrKGQpO1xuICAgIGNvbnN0IG5vblplcm8gPSBbd2FsbGV0LCBjYXJkLCBjcmVkaXQsIGxveWFsdHksIGZvcmZlaXRlZExveWFsdHldLmZpbHRlcigodikgPT4gdiA+IDApO1xuICAgIGlmIChub25aZXJvLmxlbmd0aCAhPT0gMSkgcmV0dXJuIGQ7XG4gICAgY29uc3QgdG90YWwgPSBOdW1iZXIoZC50b3RhbFJlZnVuZEFtb3VudEJlZm9yZUNlaWwgPz8gZC50b3RhbFJlZnVuZEFtb3VudCA/PyAwKTtcbiAgICBpZiAod2FsbGV0ID4gMCAmJiBNYXRoLmFicyh3YWxsZXQgLSB0b3RhbCkgPj0gMC4wMSkgcmV0dXJuIHsgLi4uZCwgd2FsbGV0UmVmdW5kQW1vdW50OiB0b3RhbCB9O1xuICAgIGlmIChjYXJkID4gMCAmJiBNYXRoLmFicyhjYXJkIC0gdG90YWwpID49IDAuMDEpIHJldHVybiB7IC4uLmQsIHRvdGFsQ2FyZFJlZnVuZEFtb3VudDogdG90YWwgfTtcbiAgICBpZiAoY3JlZGl0ID4gMCAmJiBNYXRoLmFicyhjcmVkaXQgLSB0b3RhbCkgPj0gMC4wMSkgcmV0dXJuIHsgLi4uZCwgdG90YWxDcmVkaXRSZWZ1bmRBbW91bnQ6IHRvdGFsIH07XG4gICAgaWYgKGxveWFsdHkgPiAwICYmIE1hdGguYWJzKGxveWFsdHkgLSB0b3RhbCkgPj0gMC4wMSkgcmV0dXJuIHsgLi4uZCwgdG90YWxMb3lhbHR5UG9pbnRzUmVmdW5kQW1vdW50OiB0b3RhbCB9O1xuICAgIHJldHVybiBkO1xuICB9XG5cbiAgLyoqXG4gICAqIFBlci1sZWcgcmVmdW5kIHZpZXcgKGluZGVwZW5kZW50IG9mIHRoZSBjaGVja2JveCBpbmNsdXNpb24gc3RhdGUpIOKAlCB1c2VkXG4gICAqIHRvIHJlbmRlciBib3RoIGxlZ3MnIG93biBicmVha2Rvd24gY2FyZHMgc2ltdWx0YW5lb3VzbHkuXG4gICAqL1xuICBsZWdBZGp1c3RlZERhdGEobGVnVHlwZTogJ29ud2FyZCcgfCAncmV0dXJuJyk6IFJlZnVuZERhdGEgfCBudWxsIHtcbiAgICBjb25zdCByb290ID0gdGhpcy5yZWZ1bmREYXRhKCk7XG4gICAgY29uc3QgbGVnID0gcm9vdD8ubGVnSW5mbz8uW2xlZ1R5cGVdO1xuICAgIGlmICghcm9vdCB8fCAhbGVnKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBiYXNlID0gdGhpcy5idWlsZExlZ0RhdGEocm9vdCwgbGVnLCBsZWdUeXBlKTtcbiAgICByZXR1cm4gdGhpcy5hcHBseVNvdXJjZU92ZXJyaWRlKGJhc2UsIGxlZy5zb3VyY2VCcmVha2Rvd24gPz8gbnVsbCk7XG4gIH1cblxuICAvKiogRGVkdWN0aW9uIHJvd3MgZm9yIGEgc2luZ2xlIGxlZydzIGNhcmQuICovXG4gIGxlZ0RlZHVjdGlvbnMobGVnVHlwZTogJ29ud2FyZCcgfCAncmV0dXJuJykge1xuICAgIHJldHVybiB0aGlzLmRlZHVjdGlvblJvd3ModGhpcy5sZWdBZGp1c3RlZERhdGEobGVnVHlwZSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZnVuZGFibGUgcG9vbCAoXCJGYXJlXCIpIGZvciBhIGxlZyDigJQgdGhhdCBsZWcncyBvd24gcGFpZCBhbW91bnRcbiAgICogKGB0b3RhbFN1cHBsaWVyQm9va2luZ0Ftb3VudGApLiBgdG90YWxSZWZ1bmRBbW91bnQgKyB0b3RhbENhbmNlbGxhdGlvbkZlZWBcbiAgICogaXNuJ3QgcmVsaWFibGU6IGB0b3RhbENhbmNlbGxhdGlvbkZlZWAgZG9lc24ndCBpbmNsdWRlIGV2ZXJ5IGRlZHVjdGlvblxuICAgKiAoZS5nLiBgaGFuZGxpbmdGZWVgKSwgd2hpY2ggcHJvZHVjZWQgYSBGYXJlIHRoYXQgZGlkbid0IHJlY29uY2lsZSB3aXRoXG4gICAqIFRvdGFsIFJlZnVuZCArIHRoZSBzaG93biBkZWR1Y3Rpb25zLlxuICAgKi9cbiAgbGVnUmVmdW5kUG9vbChsZWdUeXBlOiAnb253YXJkJyB8ICdyZXR1cm4nKTogbnVtYmVyIHtcbiAgICBjb25zdCBkID0gdGhpcy5sZWdBZGp1c3RlZERhdGEobGVnVHlwZSk7XG4gICAgaWYgKCFkKSByZXR1cm4gMDtcbiAgICByZXR1cm4gTnVtYmVyKGQudG90YWxTdXBwbGllckJvb2tpbmdBbW91bnQgfHwgMCk7XG4gIH1cblxuICAvKiogVHJ1ZSBvbmNlIGEgbGVnJ3Mgb3duIGRlcGFydHVyZSB0aW1lIGhhcyBwYXNzZWQuICovXG4gIGxlZ0FscmVhZHlGbG93bihsZWdUeXBlOiAnb253YXJkJyB8ICdyZXR1cm4nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgZGVwVGltZSA9IHRoaXMuaXRpbmVyYXJ5TGVnKGxlZ1R5cGUpPy5kZXBUaW1lO1xuICAgIGlmICghZGVwVGltZSkgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IHQgPSBuZXcgRGF0ZShkZXBUaW1lKS5nZXRUaW1lKCk7XG4gICAgcmV0dXJuICFOdW1iZXIuaXNOYU4odCkgJiYgdCA8IERhdGUubm93KCk7XG4gIH1cblxuICAvKipcbiAgICogTm9uLUNyb3NzU2VsbGVyIGFpcmxpbmVzIHJlcXVpcmUgdGhlIHdob2xlIHJvdW5kLXRyaXAvbXVsdGljaXR5XG4gICAqIGl0aW5lcmFyeSB0byBiZSBjYW5jZWxsZWQgdG9nZXRoZXIg4oCUIGEgbGVnIGNhbid0IGJlIGV4Y2x1ZGVkIG9uIGl0cyBvd25cbiAgICogdW5sZXNzIGl0IGhhcyBhbHJlYWR5IGZsb3duICh3aGljaCBuYXR1cmFsbHkgZGVncmFkZXMgdG8gYSBvbmUtd2F5XG4gICAqIGNhbmNlbGxhdGlvbiBvZiBqdXN0IHRoZSByZW1haW5pbmcgbGVnKS4gU2V0IHdoZW4gYW4gdW5jaGVjayBhdHRlbXB0IHdhc1xuICAgKiBibG9ja2VkIGZvciB0aGlzIHJlYXNvbiwgc28gdGhlIGxlZydzIGNoZWNrYm94IGNhbiBiZSBmcm96ZW4gKGxvY2tlZClcbiAgICogYW5kIHRoZSBub3RlIHNob3duLlxuICAgKi9cbiAgZm9yY2VkTGVnVHlwZSA9IHNpZ25hbDwnb253YXJkJyB8ICdyZXR1cm4nIHwgbnVsbD4obnVsbCk7XG5cbiAgLyoqXG4gICAqIFRvZ2dsZSBhIGxlZydzIGluY2x1c2lvbi4gQSBub24tcmVmdW5kYWJsZSBsZWcgY2FuJ3QgYmUgY2hlY2tlZCwgYW5kIHRoZVxuICAgKiBsYXN0IGNoZWNrZWQgbGVnIGNhbid0IGJlIHVuY2hlY2tlZC4gVXNlZCBvbiBib3RoIHRoZSBzZWxlY3QtbGVnIHNjcmVlblxuICAgKiBhbmQgdGhlIHJvdW5kLXRyaXAgbGVnIGNhcmRzLlxuICAgKi9cbiAgdG9nZ2xlTGVnKGxlZ1R5cGU6ICdvbndhcmQnIHwgJ3JldHVybicpIHtcbiAgICBjb25zdCByZWZ1bmRhYmxlID0gbGVnVHlwZSA9PT0gJ29ud2FyZCcgPyB0aGlzLm9ud2FyZFJlZnVuZGFibGUoKSA6IHRoaXMucmV0dXJuUmVmdW5kYWJsZSgpO1xuICAgIGlmICghcmVmdW5kYWJsZSkgcmV0dXJuO1xuICAgIGNvbnN0IHNlbGYgPSBsZWdUeXBlID09PSAnb253YXJkJyA/IHRoaXMub253YXJkQ2hlY2tlZCA6IHRoaXMucmV0dXJuQ2hlY2tlZDtcbiAgICBjb25zdCBvdGhlciA9IGxlZ1R5cGUgPT09ICdvbndhcmQnID8gdGhpcy5yZXR1cm5DaGVja2VkIDogdGhpcy5vbndhcmRDaGVja2VkO1xuICAgIGlmIChzZWxmKCkgJiYgIW90aGVyKCkpIHJldHVybjtcblxuICAgIGNvbnN0IGlzVHVybmluZ09mZiA9IHNlbGYoKTtcbiAgICBpZiAoXG4gICAgICBpc1R1cm5pbmdPZmYgJiZcbiAgICAgIHRoaXMuaXNSb3VuZFRyaXAoKSAmJlxuICAgICAgIXRoaXMuaXNDcm9zc1NlbGxlcigpICYmXG4gICAgICAhdGhpcy5sZWdBbHJlYWR5Rmxvd24obGVnVHlwZSlcbiAgICApIHtcbiAgICAgIC8vIEFpcmxpbmUgZG9lc24ndCBhbGxvdyBjYW5jZWxsaW5nIHRoaXMgbGVnIG9uIGl0cyBvd24g4oCUIGJsb2NrIHRoZVxuICAgICAgLy8gdW5jaGVjaywga2VlcCBpdCBjaGVja2VkK2Zyb3plbiwgYW5kIHN1cmZhY2UgdGhlIG5vdGUuXG4gICAgICB0aGlzLmZvcmNlZExlZ1R5cGUuc2V0KGxlZ1R5cGUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmZvcmNlZExlZ1R5cGUuc2V0KG51bGwpO1xuICAgIHNlbGYuc2V0KCFzZWxmKCkpO1xuICAgIC8vIEEgbGVnIG1heSBjYXJyeSBpdHMgb3duIHNvdXJjZSBsaXN0IOKAlCByZS1yZXNvbHZlIHRoZSBzZWxlY3Rpb24uXG4gICAgY29uc3QgYnJlYWtkb3duID0gdGhpcy5hY3RpdmVTb3VyY2VCcmVha2Rvd24oKSA/PyB7fTtcbiAgICBjb25zdCBzb3VyY2VzID0gT2JqZWN0LmtleXMoYnJlYWtkb3duKTtcbiAgICBpZiAoc291cmNlcy5sZW5ndGggJiYgIWJyZWFrZG93blt0aGlzLnNlbGVjdGVkU291cmNlKCldKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkU291cmNlLnNldChzb3VyY2VzWzBdKTtcbiAgICB9XG4gIH1cblxuICAvKiogVG9nZ2xlIGEgbGVnIGNhcmQncyBleHBhbmRlZC9jb2xsYXBzZWQgc3RhdGUuICovXG4gIHRvZ2dsZUxlZ0V4cGFuZGVkKGxlZ1R5cGU6ICdvbndhcmQnIHwgJ3JldHVybicpIHtcbiAgICBjb25zdCBzaWcgPSBsZWdUeXBlID09PSAnb253YXJkJyA/IHRoaXMub253YXJkRXhwYW5kZWQgOiB0aGlzLnJldHVybkV4cGFuZGVkO1xuICAgIHNpZy5zZXQoIXNpZygpKTtcbiAgfVxuXG4gIHNvdXJjZU5vblJlZnVuZGFibGVIaW50ID0gY29tcHV0ZWQoKCk6IHN0cmluZyA9PiB7XG4gICAgY29uc3Qgc2VsID0gdGhpcy5zZWxlY3RlZFNvdXJjZSgpO1xuICAgIGlmICghc2VsKSByZXR1cm4gJyc7XG4gICAgY29uc3Qgc3JjID0gKHRoaXMuYWN0aXZlU291cmNlQnJlYWtkb3duKCkgPz8ge30pW3NlbF07XG4gICAgaWYgKCFzcmMgfHwgc3JjLmlzUmVmdW5kYWJsZSAhPT0gZmFsc2UpIHJldHVybiAnJztcbiAgICByZXR1cm4gYENhbmNlbGxhdGlvbiB2aWEgJHtzZWx9IGlzIG5vdCBlbGlnaWJsZSBmb3IgYSByZWZ1bmQuIFBsZWFzZSBzZWxlY3QgYSBkaWZmZXJlbnQgc291cmNlLmA7XG4gIH0pO1xuXG4gIGRlZHVjdGlvbnMgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmRlZHVjdGlvblJvd3ModGhpcy5hZGp1c3RlZERhdGEoKSkpO1xuXG4gIC8qKlxuICAgKiBJdGVtaXplZCByZWZ1bmRhYmxlIHJvd3MgKFwiRmFyZVwiICsgbmFtZWQgcmVmdW5kYWJsZSBhZGQtb25zL2FuY2lsbGFyaWVzKVxuICAgKiBmcm9tIGByZWZ1bmRCcmVha2Rvd24ucmVmdW5kYWJsZWAuIEVtcHR5IHdoZW4gdGhlIGJhY2tlbmQgaGFzbid0IHNlbnQgYVxuICAgKiBicmVha2Rvd24geWV0IOKAlCBjYWxsZXJzIGZhbGwgYmFjayB0byB0aGUgc2luZ2xlIGFnZ3JlZ2F0ZSBGYXJlIHJvdy5cbiAgICovXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gIHJlZnVuZGFibGVCcmVha2Rvd25Sb3dzKGQ6IGFueSk6IHsgbGFiZWw6IHN0cmluZzsgdmFsdWU6IG51bWJlciB9W10ge1xuICAgIGNvbnN0IGIgPSBkPy5yZWZ1bmRCcmVha2Rvd24/LnJlZnVuZGFibGU7XG4gICAgaWYgKCFiKSByZXR1cm4gW107XG4gICAgLy8gRmFyZSBhbHdheXMgc2hvd3MgZnJvbSByZWZ1bmRCcmVha2Rvd24ucmVmdW5kYWJsZS5mYXJlLCBldmVuIHdoZW4gMCDigJRcbiAgICAvLyBuZXZlciBmYWxscyBiYWNrIHRvIG9yaWdpbmFsQW1vdW50LlxuICAgIGNvbnN0IHJvd3M6IHsgbGFiZWw6IHN0cmluZzsgdmFsdWU6IG51bWJlciB9W10gPSBbeyBsYWJlbDogJ0ZhcmUnLCB2YWx1ZTogTnVtYmVyKGIuZmFyZSA/PyAwKSB9XTtcbiAgICBbLi4uKGIuYWRkT25zID8/IFtdKSwgLi4uKGIuYW5jaWxsYXJpZXMgPz8gW10pXVxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgIC5maWx0ZXIoKGl0ZW06IGFueSkgPT4gTnVtYmVyKGl0ZW0uYW1vdW50KSA+IDApXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgLmZvckVhY2goKGl0ZW06IGFueSkgPT4gcm93cy5wdXNoKHsgbGFiZWw6IGl0ZW0ubmFtZSwgdmFsdWU6IE51bWJlcihpdGVtLmFtb3VudCkgfSkpO1xuICAgIHJldHVybiByb3dzO1xuICB9XG5cbiAgLyoqIE5hbWVkIHJlZnVuZGFibGUgYWRkLW9ucy9hbmNpbGxhcmllcyBvbmx5IChleGNsdWRlcyBGYXJlKSDigJQgZHJpdmVzIHRoZSBcInByb2Nlc3NlZCBzZXBhcmF0ZWx5XCIgbm90ZS4gKi9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgcHJpdmF0ZSByZWZ1bmRhYmxlQWRkb25JdGVtcyhkOiBhbnkpOiBhbnlbXSB7XG4gICAgLy8gT25seSBgYWRkT25zYCBuZWVkIG1hbnVhbCBDdXN0b21lciBTZXJ2aWNlIHByb2Nlc3Npbmcg4oCUIGBhbmNpbGxhcmllc2BcbiAgICAvLyAoYmFnZ2FnZSwgc2VhdCwgYXV0byBjaGVjay1pbiwg4oCmKSBhcmUgYWxyZWFkeSBpdGVtaXplZC9yZWZ1bmRlZFxuICAgIC8vIGF1dG9tYXRpY2FsbHkgYXMgcGFydCBvZiB0aGUgdG90YWwsIG5vIHNlcGFyYXRlIG5vdGUgbmVlZGVkIGZvciB0aGVtLlxuICAgIGNvbnN0IGIgPSBkPy5yZWZ1bmRCcmVha2Rvd24/LnJlZnVuZGFibGU7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICByZXR1cm4gKGI/LmFkZE9ucyA/PyBbXSkuZmlsdGVyKChpdGVtOiBhbnkpID0+IE51bWJlcihpdGVtLmFtb3VudCkgPiAwKTtcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIHRvIHNob3cgdGhlIFwiYWRkLW9uIHJlZnVuZCBwcm9jZXNzZWQgc2VwYXJhdGVseSBieSBDdXN0b21lciBTZXJ2aWNlXCIgbm90ZS4gKi9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgaGFzUmVmdW5kYWJsZUFkZG9uTm90ZShkOiBhbnkpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5yZWZ1bmRhYmxlQWRkb25JdGVtcyhkKS5sZW5ndGggPiAwO1xuICB9XG5cbiAgLyoqXG4gICAqIERlZHVjdGlvbiByb3dzIGZvciB0aGUgXCJOb3QgUmVmdW5kZWRcIiBzZWN0aW9uLiBXaGVuIGFuIGl0ZW1pemVkXG4gICAqIGJyZWFrZG93biBpcyBwcmVzZW50LCBpdHMgbmFtZWQgYWRkLW9ucy9hbmNpbGxhcmllcyByZXBsYWNlIHRoZVxuICAgKiBhZ2dyZWdhdGUgYHRvdGFsQW5jaWxsYXJ5UmVmdW5kQW1vdW50YC9gdG90YWxHaWZ0QW1vdW50YCByb3dzIChzYW1lXG4gICAqIG1vbmV5LCBuYW1lZCBpbnN0ZWFkIG9mIGx1bXBlZCk7IHRoZSBvdGhlciBnZW5lcmljIHJvd3MgKGNhbmNlbGxhdGlvblxuICAgKiBmZWUsIGhhbmRsaW5nIGZlZSwgc2VydmljZSBjaGFyZ2UpIGFyZSB1bmFmZmVjdGVkLlxuICAgKi9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgcHJpdmF0ZSBkZWR1Y3Rpb25Sb3dzKGQ6IGFueSk6IHsgbGFiZWw6IHN0cmluZzsgdmFsdWU6IG51bWJlcjsgYmFkZ2U6IHN0cmluZyB9W10ge1xuICAgIGlmICghZCkgcmV0dXJuIFtdO1xuICAgIGNvbnN0IGIgPSBkLnJlZnVuZEJyZWFrZG93bj8ubm9uUmVmdW5kYWJsZTtcbiAgICBpZiAoIWIpIHtcbiAgICAgIHJldHVybiBERURVQ1RJT05fREVGU1xuICAgICAgICAuZmlsdGVyKGRlZiA9PiBOdW1iZXIoZFtkZWYua2V5XSkgPiAwKVxuICAgICAgICAubWFwKGRlZiA9PiAoeyBsYWJlbDogZGVmLmxhYmVsLCB2YWx1ZTogTnVtYmVyKGRbZGVmLmtleV0pLCBiYWRnZTogZGVmLmJhZGdlIH0pKTtcbiAgICB9XG4gICAgY29uc3QgaXRlbVJvd3MgPSBbLi4uKGIuYWRkT25zID8/IFtdKSwgLi4uKGIuYW5jaWxsYXJpZXMgPz8gW10pXVxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgIC5maWx0ZXIoKGl0ZW06IGFueSkgPT4gTnVtYmVyKGl0ZW0uYW1vdW50KSA+IDApXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgLm1hcCgoaXRlbTogYW55KSA9PiAoeyBsYWJlbDogaXRlbS5uYW1lLCB2YWx1ZTogTnVtYmVyKGl0ZW0uYW1vdW50KSwgYmFkZ2U6ICcnIH0pKTtcbiAgICBjb25zdCBhZ2dyZWdhdGVSb3dzID0gREVEVUNUSU9OX0RFRlNcbiAgICAgIC5maWx0ZXIoZGVmID0+IGRlZi5rZXkgIT09ICd0b3RhbEFuY2lsbGFyeVJlZnVuZEFtb3VudCcgJiYgZGVmLmtleSAhPT0gJ3RvdGFsR2lmdEFtb3VudCcpXG4gICAgICAuZmlsdGVyKGRlZiA9PiBOdW1iZXIoZFtkZWYua2V5XSkgPiAwKVxuICAgICAgLm1hcChkZWYgPT4gKHsgbGFiZWw6IGRlZi5sYWJlbCwgdmFsdWU6IE51bWJlcihkW2RlZi5rZXldKSwgYmFkZ2U6IGRlZi5iYWRnZSB9KSk7XG4gICAgcmV0dXJuIFsuLi5pdGVtUm93cywgLi4uYWdncmVnYXRlUm93c107XG4gIH1cblxuICByZWZ1bmRzID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGQgPSB0aGlzLmFkanVzdGVkRGF0YSgpO1xuICAgIGlmICghZCkgcmV0dXJuIFtdO1xuICAgIGNvbnN0IGlzTG95YWx0eSA9IHRoaXMuaXNMb3lhbHR5TWV0aG9kKCk7XG4gICAgY29uc3QgcGF5bWVudExhYmVsID0gdGhpcy5jdXN0b21lclBheW1lbnRMYWJlbCgpO1xuICAgIGNvbnN0IHJvd3MgPSBSRUZVTkRfREVGU1xuICAgICAgLmZpbHRlcihkZWYgPT4gTnVtYmVyKGRbZGVmLmtleV0pID4gMClcbiAgICAgIC5tYXAoZGVmID0+ICh7XG4gICAgICAgIC8vIFdhbGxldCByb3cgYWx3YXlzIHJlYWRzIFwiQWxtYXRhciBXYWxsZXRcIiAoZGVmLmxhYmVsKSDigJQgdGhlIGxveWFsdHlcbiAgICAgICAgLy8gcHJvZ3JhbSB0aGF0IGZ1bmRlZCBpdCBnZXRzIGl0cyBvd24gZGVkaWNhdGVkIHJvdyBiZWxvdyB2aWFcbiAgICAgICAgLy8gYGZvcmZlaXRlZExveWFsdHlQb2ludHNGYWxsYmFja2AsIHNvIHRoZSB0d28gc3RheSB2aXN1YWxseVxuICAgICAgICAvLyBkaXN0aW5jdCBpbnN0ZWFkIG9mIG1lcmdpbmcgaW50byBvbmUgbGFiZWwuXG4gICAgICAgIC8vIENhcmQgcm93OiBjYXJkL2xveWFsdHkgc3RheSBkaXN0aW5jdCDigJQgZG9uJ3QgcmVsYWJlbCB0aGUgY2FyZFxuICAgICAgICAvLyBwb3J0aW9uIHdpdGggdGhlIGxveWFsdHkgcHJvZ3JhbSBuYW1lIHRvbywgYW5kIG5ldmVyIHN1cmZhY2UgYW5cbiAgICAgICAgLy8gaW50ZXJuYWwgcHJvY2Vzc29yIG5hbWUgKGVtcHR5IGBwYXltZW50TGFiZWxgIGZhbGxzIGJhY2sgdG8gdGhlXG4gICAgICAgIC8vIGdlbmVyaWMgZGVmLmxhYmVsLCBlLmcuIFwiUmVmdW5kIEFtb3VudFwiKS5cbiAgICAgICAgbGFiZWw6XG4gICAgICAgICAgZGVmLmtleSA9PT0gJ3RvdGFsQ2FyZFJlZnVuZEFtb3VudCcgJiYgIWlzTG95YWx0eSAmJiBwYXltZW50TGFiZWxcbiAgICAgICAgICAgID8gYCR7ZGVmLmxhYmVsfSAke3BheW1lbnRMYWJlbH1gXG4gICAgICAgICAgICA6IGRlZi5sYWJlbCxcbiAgICAgICAgdmFsdWU6IE51bWJlcihkW2RlZi5rZXldKSxcbiAgICAgIH0pKTtcbiAgICBjb25zdCBmb3JmZWl0ZWRMb3lhbHR5ID0gdGhpcy5mb3JmZWl0ZWRMb3lhbHR5UG9pbnRzRmFsbGJhY2soZCk7XG4gICAgaWYgKGZvcmZlaXRlZExveWFsdHkgPiAwKSB7XG4gICAgICByb3dzLnB1c2goeyBsYWJlbDogdGhpcy53YWxsZXRPckxveWFsdHlMYWJlbChkKSwgdmFsdWU6IGZvcmZlaXRlZExveWFsdHkgfSk7XG4gICAgfVxuICAgIHJldHVybiByb3dzO1xuICB9KTtcblxuICBjcmVkaXRTaGVsbE5vdGUgPSBjb21wdXRlZCgoKTogc3RyaW5nID0+IHtcbiAgICAvLyBHb2xkZW4gR3VhcmFudGVlIG92ZXJyaWRlcyBjcmVkaXQtc2hlbGwgbWVzc2FnaW5nIGVudGlyZWx5IOKAlCB0aGVcbiAgICAvLyBkZWRpY2F0ZWQgc3VjY2VzcyBub3RpY2UgKGBnb2xkZW5HdWFyYW50ZWVOb3RlYCkgaXMgc2hvd24gaW5zdGVhZC5cbiAgICBpZiAodGhpcy5oYXNHb2xkZW5HdWFyYW50ZWVHaWZ0KCkpIHJldHVybiAnJztcbiAgICBjb25zdCBkID0gdGhpcy5jdXJyZW50RGF0YSgpO1xuICAgIGlmICghZCkgcmV0dXJuICcnO1xuICAgIGNvbnN0IGxlZ0luZm8gPSBkLmxlZ0luZm8gPz8ge307XG4gICAgY29uc3QgaGFzTyA9ICEhbGVnSW5mby5vbndhcmQ7XG4gICAgY29uc3QgaGFzUiA9ICEhbGVnSW5mby5yZXR1cm47XG4gICAgY29uc3Qgb1NoZWxsID0gbGVnSW5mby5vbndhcmQ/LmlzQ3JlZGl0U2hlbGwgPT09IHRydWU7XG4gICAgY29uc3QgclNoZWxsID0gbGVnSW5mby5yZXR1cm4/LmlzQ3JlZGl0U2hlbGwgPT09IHRydWU7XG4gICAgY29uc3QgaXNTaGVsbCA9XG4gICAgICAoaGFzTyAmJiBoYXNSICYmIG9TaGVsbCAmJiByU2hlbGwpIHx8XG4gICAgICAoaGFzTyAmJiAhaGFzUiAmJiBvU2hlbGwpIHx8XG4gICAgICAoIWhhc08gJiYgaGFzUiAmJiByU2hlbGwpIHx8XG4gICAgICAoaGFzTyAmJiBoYXNSICYmIChvU2hlbGwgfHwgclNoZWxsKSk7XG4gICAgaWYgKCFpc1NoZWxsKSByZXR1cm4gJyc7XG4gICAgY29uc3QgYW1vdW50ID0gdGhpcy5mbXQoTnVtYmVyKHRoaXMuYWRqdXN0ZWREYXRhKCk/LnRvdGFsUmVmdW5kQW1vdW50ID8/IGQudG90YWxSZWZ1bmRBbW91bnQgPz8gMCkpO1xuICAgIGNvbnN0IHBuciA9IHRoaXMucmVzb2x2ZVBucigpO1xuICAgIGNvbnN0IHBuclRleHQgPSBwbnIgPyBgdGhlIHNhbWUgUE5SICgke3Bucn0pYCA6ICd0aGUgc2FtZSBQTlInO1xuICAgIHJldHVybiBgVGhlIHJlZnVuZCBvZiAke2Ftb3VudH0gd2lsbCBiZSBpc3N1ZWQgYXMgYWlybGluZSBjcmVkaXQgdW5kZXIgJHtwbnJUZXh0fS4gJHtDUkVESVRfU0hFTExfU1VGRklYfWA7XG4gIH0pO1xuXG4gIC8vIFJlc29sdmUgdGhlIFBOUiBmb3IgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBsZWcgZnJvbSB0aGUgYm9va2luZydzIHBucl9pbmZvIGxpc3QuXG4gIHByaXZhdGUgcmVzb2x2ZVBucigpOiBzdHJpbmcge1xuICAgIGNvbnN0IGxpc3QgPSB0aGlzLnBuckluZm8oKSA/PyBbXTtcbiAgICBpZiAoIWxpc3QubGVuZ3RoKSByZXR1cm4gJyc7XG4gICAgY29uc3Qgc2VsID0gdGhpcy5zZWxlY3RlZExlZygpO1xuICAgIGNvbnN0IGJ5RGlyID0gKGRpcjogc3RyaW5nKSA9PiBsaXN0LmZpbmQocCA9PiBwLkxlZ0RpcmVjdGlvbmFsaXR5ID09PSBkaXIpPy5wbnI7XG4gICAgaWYgKHNlbCA9PT0gJ3JldHVybicpIHJldHVybiBieURpcignUmV0dXJuJykgPz8gbGlzdFswXT8ucG5yID8/ICcnO1xuICAgIGlmIChzZWwgPT09ICdvbndhcmQnKSByZXR1cm4gYnlEaXIoJ0RlcGFydHVyZScpID8/IGxpc3RbMF0/LnBuciA/PyAnJztcbiAgICByZXR1cm4gYnlEaXIoJ0RlcGFydHVyZScpID8/IGxpc3RbMF0/LnBuciA/PyAnJztcbiAgfVxuXG4gIC8qKlxuICAgKiBCb29raW5nIGluY2x1ZGVzIGEgR29sZGVuIEd1YXJhbnRlZSBnaWZ0IChcIkNhbmNlbCBmb3IgYW55IHJlYXNvblwiKSDigJRcbiAgICogb3ZlcnJpZGVzIGFsbCBjcmVkaXQtc2hlbGwgaGFuZGxpbmcgYmVsb3csIHNpbmNlIGEgR29sZGVuIEd1YXJhbnRlZVxuICAgKiBjYW5jZWxsYXRpb24gYWx3YXlzIHJlZnVuZHMgMTAwJSB0aHJvdWdoIHRoZSBzdGFuZGFyZCBwYXltZW50IG1ldGhvZFxuICAgKiByYXRoZXIgdGhhbiB0aGUgYWlybGluZSBjcmVkaXQgc2hlbGwuIE1heSBiZSBjYXJyaWVkIG9uIGVpdGhlciB0aGVcbiAgICogcHJldmlldyAoYHJlZnVuZERhdGFgKSBvciB0aGUgY29uZmlybSAoYGNhbmNlbFJlc3VsdGApIHJlc3BvbnNlIOKAlCBib3RoXG4gICAqIHNoYXJlIHRoZSBzYW1lIHNoYXBlLCBhbmQgZWl0aGVyIG9uZSBtYXkgc2V0IGl0IGluZGVwZW5kZW50bHkgb2YgdGhlXG4gICAqIG90aGVyLlxuICAgKi9cbiAgaGFzR29sZGVuR3VhcmFudGVlR2lmdCA9IGNvbXB1dGVkKCgpOiBib29sZWFuID0+XG4gICAgdGhpcy5yZWZ1bmREYXRhKCk/Lmhhc0dvbGRlbkd1YXJhbnRlZUdpZnQgPT09IHRydWUgfHxcbiAgICB0aGlzLmNhbmNlbFJlc3VsdCgpPy5oYXNHb2xkZW5HdWFyYW50ZWVHaWZ0ID09PSB0cnVlLFxuICApO1xuXG4gIC8vIFdoZXRoZXIgdGhlIHJlZnVuZCBpcyBhIGNyZWRpdC1zaGVsbCByZWZ1bmQgKHdob2xlIGJvb2tpbmcgb3IgZWl0aGVyIGxlZykuXG4gIC8vIFN1Y2ggcmVmdW5kcyBjYW4gb25seSByZXR1cm4gdG8gdGhlIGFpcmxpbmUgY3JlZGl0IHNoZWxsLCBzbyB0aGVcbiAgLy8gcmVmdW5kLW1ldGhvZCBwaWNrZXIgaXMgcmVwbGFjZWQgd2l0aCBhIHNpbmdsZSByZWFkLW9ubHkgY3JlZGl0IG5vdGljZS5cbiAgLy8gQSBHb2xkZW4gR3VhcmFudGVlIGdpZnQgb3ZlcnJpZGVzIHRoaXMgdG8gYGZhbHNlYCDigJQgdGhhdCBwb3J0aW9uIG5lZWRzIGFuXG4gIC8vIGFjdHVhbCBkZXN0aW5hdGlvbiBjaG9pY2UsIHNvIHRoZSBib29raW5nIGZhbGxzIGJhY2sgdG8gdGhlIHN0YW5kYXJkXG4gIC8vIHJlZnVuZC1tZXRob2QgZmxvdyBkZXNwaXRlIGJlaW5nIGZsYWdnZWQgY3JlZGl0LXNoZWxsLlxuICBpc0NyZWRpdFNoZWxsID0gY29tcHV0ZWQoKCk6IGJvb2xlYW4gPT4ge1xuICAgIGlmICh0aGlzLmhhc0dvbGRlbkd1YXJhbnRlZUdpZnQoKSkgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IGQgPSB0aGlzLnJlZnVuZERhdGEoKTtcbiAgICByZXR1cm4gKFxuICAgICAgZD8uaXNDcmVkaXRTaGVsbCA9PT0gdHJ1ZSB8fFxuICAgICAgZD8ubGVnSW5mbz8ub253YXJkPy5pc0NyZWRpdFNoZWxsID09PSB0cnVlIHx8XG4gICAgICBkPy5sZWdJbmZvPy5yZXR1cm4/LmlzQ3JlZGl0U2hlbGwgPT09IHRydWVcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogUmVmdW5kYWJsZSBhbmNpbGxhcmllcyAoYmFnZ2FnZSwgc2VhdHMsIOKApikgdGhhdCBjYXJyeSB0aGVpciBvd25cbiAgICogYGlzQ3JlZGl0U2hlbGxgIGZsYWcsIGluZGVwZW5kZW50IG9mIHRoZSBib29raW5nLWxldmVsIGZsYWcg4oCUIHJlbmRlcmVkXG4gICAqIGFzIGluZGl2aWR1YWwgY2FyZHMgb24gdGhlIGNyZWRpdC1zaGVsbCByZWZ1bmQtbWV0aG9kIHNjcmVlbiBzbyBlYWNoXG4gICAqIG9uZSBjYW4gc2hvdyBlaXRoZXIgdGhlIGNyZWRpdC1zaGVsbCBjYXJkIHN0eWxlIG9yIHRoZSBub3JtYWwgd2FsbGV0XG4gICAqIGNhcmQgc3R5bGUgKGJvdGggaW5jbHVkZSB0aGUgc2FtZSBuZXN0ZWQgY3JlZGl0LXNoZWxsIG5vdGUgd2hlbiB0cnVlKS5cbiAgICovXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gIGNyZWRpdFNoZWxsQW5jaWxsYXJ5SXRlbXMgPSBjb21wdXRlZCgoKTogYW55W10gPT5cbiAgICAodGhpcy5hZGp1c3RlZERhdGEoKT8ucmVmdW5kQnJlYWtkb3duPy5yZWZ1bmRhYmxlPy5hbmNpbGxhcmllcyA/PyBbXSlcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAuZmlsdGVyKChpdGVtOiBhbnkpID0+IE51bWJlcihpdGVtLmFtb3VudCkgPiAwKSxcbiAgKTtcblxuICAvLyBBaXJsaW5lIHRoYXQgaXNzdWVzIHRoZSBjcmVkaXQgc2hlbGwsIGZvciB0aGUgXCI8c3VwcGxpZXI+IHdlYnNpdGUgY3JlZGl0XCIgY2FyZC5cbiAgY3JlZGl0U2hlbGxTdXBwbGllck5hbWUgPSBjb21wdXRlZCgoKTogc3RyaW5nID0+IHtcbiAgICBjb25zdCBkID0gdGhpcy5yZWZ1bmREYXRhKCk7XG4gICAgcmV0dXJuIChcbiAgICAgIGQ/LmxlZ0luZm8/Lm9ud2FyZD8uc3VwcGxpZXJOYW1lID8/XG4gICAgICBkPy5sZWdJbmZvPy5yZXR1cm4/LnN1cHBsaWVyTmFtZSA/P1xuICAgICAgZD8uc3VwcGxpZXJOYW1lID8/XG4gICAgICBkPy5hcHBsaWVkU291cmNlID8/XG4gICAgICAnJ1xuICAgICk7XG4gIH0pO1xuXG4gIC8vIEhlYWRlciB0aXRsZSByZWZsZWN0aW5nIHRoZSByZWZ1bmQgdHlwZSBmb3IgdGhlIGFjdGl2ZSBzZWxlY3Rpb24uXG4gIHJlZnVuZFR5cGVMYWJlbCA9IGNvbXB1dGVkKCgpOiBzdHJpbmcgPT4ge1xuICAgIGlmICghdGhpcy5yZWZ1bmREYXRhKCk/LmlzUmVmdW5kYWJsZSkgcmV0dXJuICdSZWZ1bmQgRGV0YWlscyc7XG4gICAgcmV0dXJuIHRoaXMuY3JlZGl0U2hlbGxOb3RlKCkgPyAnQ3JlZGl0IFNoZWxsIFJlZnVuZCcgOiAnUmVmdW5kIERldGFpbHMnO1xuICB9KTtcblxuICBjdXJyZW5jeSA9IGNvbXB1dGVkKCgpOiBzdHJpbmcgPT4gdGhpcy5yZWZ1bmREYXRhKCk/LmN1cnJlbmN5ID8/ICdTQVInKTtcblxuICAvLyBTZWxmLWNvbnNpc3RlbmN5IGNoZWNrIGJldHdlZW4gdGhlIHBhaWQgYW1vdW50LCBkZWR1Y3Rpb25zIGFuZCB0aGUgc3lzdGVtIHJlZnVuZC5cbiAgLy8gU3VyZmFjZWQgdG8gdGhlIGFnZW50IHNvIG1pc21hdGNoZWQvb3Zlci1kZWR1Y3RlZCByZWZ1bmRzIGNhbiBiZSBjYXVnaHQgYmVmb3JlIGNvbmZpcm1pbmcuXG4gIGRpc2NyZXBhbmN5Tm90ZSA9IGNvbXB1dGVkKCgpOiBzdHJpbmcgPT4ge1xuICAgIGNvbnN0IGQgPSB0aGlzLmFkanVzdGVkRGF0YSgpO1xuICAgIGlmICghZCB8fCAhZC5pc1JlZnVuZGFibGUpIHJldHVybiAnJztcbiAgICBjb25zdCBwYWlkICAgICAgPSBOdW1iZXIoZC5vcmlnaW5hbEFtb3VudCB8fCAwKTtcbiAgICBjb25zdCBkZWR1Y3Rpb24gPSBOdW1iZXIoZC50b3RhbENhbmNlbGxhdGlvbkZlZSB8fCAwKTtcbiAgICBjb25zdCByZWZ1bmQgICAgPSBOdW1iZXIoZC50b3RhbFJlZnVuZEFtb3VudCB8fCAwKTtcbiAgICBjb25zdCBpc3N1ZXM6IHN0cmluZ1tdID0gW107XG4gICAgaWYgKGRlZHVjdGlvbiA+IHBhaWQgKyAwLjAxKVxuICAgICAgaXNzdWVzLnB1c2goYFRvdGFsIGRlZHVjdGlvbiAoJHt0aGlzLmZtdChkZWR1Y3Rpb24pfSkgZXhjZWVkcyB0aGUgcGFpZCBhbW91bnQgKCR7dGhpcy5mbXQocGFpZCl9KS5gKTtcbiAgICBpZiAoTWF0aC5hYnMoKHBhaWQgLSBkZWR1Y3Rpb24pIC0gcmVmdW5kKSA+IDAuMDEpXG4gICAgICBpc3N1ZXMucHVzaChgQ29tcHV0ZWQgcmVmdW5kICgke3RoaXMuZm10KHBhaWQgLSBkZWR1Y3Rpb24pfSkgZG9lc24ndCBtYXRjaCB0aGUgc3lzdGVtIHJlZnVuZCAoJHt0aGlzLmZtdChyZWZ1bmQpfSkuYCk7XG4gICAgcmV0dXJuIGlzc3Vlcy5qb2luKCcgJyk7XG4gIH0pO1xuXG4gIC8qKiBSZWFsIHBlci1ib29raW5nIENyb3NzU2VsbGVyIGZsYWcgZnJvbSB0aGUgcmVmdW5kIHByZXZpZXcg4oCUIENyb3NzU2VsbGVyIHN1cHBsaWVycyBhbGxvdyBjYW5jZWxsaW5nIGVpdGhlciBsZWcgaW5kZXBlbmRlbnRseS4gKi9cbiAgaXNDcm9zc1NlbGxlciA9IGNvbXB1dGVkKCgpID0+IHRoaXMucmVmdW5kRGF0YSgpPy5pc0Nyb3NzU2VsbGVyID09PSB0cnVlKTtcblxuICAvLyBOb24tQ3Jvc3NTZWxsZXIgcm91bmQgdHJpcHMgYXJlIG9uZSBpdGluZXJhcnkgc29sZCBhcyBhIHNpbmdsZSBmYXJlIOKAlFxuICAvLyBib3RoIGxlZ3Mgc2hhcmUgdGhlIHNhbWUgcmVmdW5kYWJpbGl0eSwgc291cmNlZCBmcm9tIHJvb3QsIGV2ZW4gd2hlblxuICAvLyB0aGUgYmFja2VuZCdzIGxlZ0luZm8gZW50cnkgZm9yIGEgbGVnIGlzIG1pc3Npbmcgb3IgaW5jb25zaXN0ZW50LlxuICAvLyBDcm9zc1NlbGxlciBsZWdzIGFyZSBpbmRlcGVuZGVudGx5IHNlbGxhYmxlLCBzbyBlYWNoIGxlZydzIG93biBmaWVsZFxuICAvLyBzdGlsbCBnb3Zlcm5zIHRoZXJlLlxuICBvbndhcmRSZWZ1bmRhYmxlICA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBpZiAoIXRoaXMuaGFzT253YXJkKCkpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gdGhpcy5pc0Nyb3NzU2VsbGVyKClcbiAgICAgID8gdGhpcy5yZWZ1bmREYXRhKCk/LmxlZ0luZm8/Lm9ud2FyZD8uaXNSZWZ1bmRhYmxlID09PSB0cnVlXG4gICAgICA6IHRoaXMucmVmdW5kRGF0YSgpPy5pc1JlZnVuZGFibGUgPT09IHRydWU7XG4gIH0pO1xuICByZXR1cm5SZWZ1bmRhYmxlICA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBpZiAoIXRoaXMuaGFzUmV0dXJuKCkpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gdGhpcy5pc0Nyb3NzU2VsbGVyKClcbiAgICAgID8gdGhpcy5yZWZ1bmREYXRhKCk/LmxlZ0luZm8/LnJldHVybj8uaXNSZWZ1bmRhYmxlID09PSB0cnVlXG4gICAgICA6IHRoaXMucmVmdW5kRGF0YSgpPy5pc1JlZnVuZGFibGUgPT09IHRydWU7XG4gIH0pO1xuICBpc01peGVkICAgICAgICAgICA9IGNvbXB1dGVkKCgpID0+IHRoaXMuaXNSb3VuZFRyaXAoKSAmJiB0aGlzLm9ud2FyZFJlZnVuZGFibGUoKSAhPT0gdGhpcy5yZXR1cm5SZWZ1bmRhYmxlKCkpO1xuXG4gIC8qKiBCb3RoIGxlZ3MgcHJlc2VudCBhbmQgQk9USCBub24tcmVmdW5kYWJsZSDigJQgbm90aGluZyBjYW4gYmUgcmVmdW5kZWQgZm9yIHRoaXMgYm9va2luZy4gKi9cbiAgYWxsTGVnc05vblJlZnVuZGFibGUgPSBjb21wdXRlZChcbiAgICAoKSA9PiB0aGlzLmlzUm91bmRUcmlwKCkgJiYgIXRoaXMub253YXJkUmVmdW5kYWJsZSgpICYmICF0aGlzLnJldHVyblJlZnVuZGFibGUoKSxcbiAgKTtcblxuICBtaXhlZEhpbnQgPSBjb21wdXRlZCgoKTogc3RyaW5nID0+IHtcbiAgICAvLyBPbmx5IHJlbGV2YW50IHdoZW4gYWdlbnQgaXMgYWJvdXQgdG8gY2FuY2VsIGJvdGggbGVncyB0b2dldGhlciDigJRcbiAgICAvLyBpbmRpdmlkdWFsIGxlZyB0YWJzIGFscmVhZHkgc2hvdyB0aGVpciBvd24gbm9uLXJlZnVuZGFibGUgbm90aWNlLlxuICAgIGlmICghdGhpcy5pc01peGVkKCkgfHwgdGhpcy5zZWxlY3RlZExlZygpICE9PSAnYm90aCcpIHJldHVybiAnJztcbiAgICBpZiAoIXRoaXMub253YXJkUmVmdW5kYWJsZSgpKSByZXR1cm4gJ+KaoO+4jyBPbndhcmQgbGVnIGlzIG5vdCBlbGlnaWJsZSBmb3IgcmVmdW5kLiBQbGVhc2UgY29udGFjdCBjdXN0b21lciBzZXJ2aWNlIGlmIHlvdSB3YW50IHRvIGNhbmNlbCBpdC4nO1xuICAgIGlmICghdGhpcy5yZXR1cm5SZWZ1bmRhYmxlKCkpIHJldHVybiAn4pqg77iPIFJldHVybiBsZWcgaXMgbm90IGVsaWdpYmxlIGZvciByZWZ1bmQuIFBsZWFzZSBjb250YWN0IGN1c3RvbWVyIHNlcnZpY2UgaWYgeW91IHdhbnQgdG8gY2FuY2VsIGl0Lic7XG4gICAgcmV0dXJuICcnO1xuICB9KTtcblxuICBnaWZ0SGludCA9IGNvbXB1dGVkKCgpOiBzdHJpbmcgPT4ge1xuICAgIGNvbnN0IHJvb3QgPSB0aGlzLnJlZnVuZERhdGEoKTtcbiAgICBpZiAoIXJvb3QgfHwgIXRoaXMuaXNSb3VuZFRyaXAoKSkgcmV0dXJuICcnO1xuICAgIGNvbnN0IGhhc0dpZnQgPSBOdW1iZXIocm9vdC50b3RhbEdpZnRBbW91bnQgfHwgMCkgPiAwIHx8XG4gICAgICBOdW1iZXIocm9vdC5sZWdJbmZvPy5vbndhcmQ/LnRvdGFsR2lmdEFtb3VudCB8fCAwKSA+IDAgfHxcbiAgICAgIE51bWJlcihyb290LmxlZ0luZm8/LnJldHVybj8udG90YWxHaWZ0QW1vdW50IHx8IDApID4gMDtcbiAgICByZXR1cm4gaGFzR2lmdCA/IEdJRlRfSElOVCA6ICcnO1xuICB9KTtcblxuICBzZWxlY3Rpb25IaW50ID0gY29tcHV0ZWQoKCk6IHN0cmluZyA9PiB7XG4gICAgaWYgKCF0aGlzLmlzUm91bmRUcmlwKCkpIHJldHVybiAnJztcbiAgICBjb25zdCBtYXA6IFJlY29yZDxMZWdTZWxlY3Rpb24sIHN0cmluZz4gPSB7XG4gICAgICBvbndhcmQ6ICdZb3UgYXJlIGFib3V0IHRvIGNhbmNlbDogT253YXJkIGxlZyBvbmx5JyxcbiAgICAgIHJldHVybjogJ1lvdSBhcmUgYWJvdXQgdG8gY2FuY2VsOiBSZXR1cm4gbGVnIG9ubHknLFxuICAgICAgYm90aDogICAnWW91IGFyZSBhYm91dCB0byBjYW5jZWw6IEJvdGggbGVncycsXG4gICAgfTtcbiAgICByZXR1cm4gbWFwW3RoaXMuc2VsZWN0ZWRMZWcoKV07XG4gIH0pO1xuXG4gIGNvbmZpcm1EZWR1Y3Rpb25zID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgY29uc3QgZDogYW55ID0gdGhpcy5jYW5jZWxSZXN1bHQoKTtcbiAgICBpZiAoIWQpIHJldHVybiBbXTtcbiAgICByZXR1cm4gREVEVUNUSU9OX0RFRlMuZmlsdGVyKGRlZiA9PiBOdW1iZXIoZFtkZWYua2V5XSkgPiAwKS5tYXAoZGVmID0+ICh7IGxhYmVsOiBkZWYubGFiZWwsIHZhbHVlOiBOdW1iZXIoZFtkZWYua2V5XSkgfSkpO1xuICB9KTtcblxuICBjb25maXJtUmVmdW5kcyA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIGNvbnN0IGQ6IGFueSA9IHRoaXMuY2FuY2VsUmVzdWx0KCk7XG4gICAgaWYgKCFkKSByZXR1cm4gW107XG4gICAgY29uc3QgY29kZSA9IHRoaXMubm9ybWFsaXplR2F0ZXdheUNvZGUoZC5wYXltZW50TWV0aG9kQ3VzdG9tZXJVc2VkKTtcbiAgICBjb25zdCBpc0xveWFsdHkgPSBMT1lBTFRZX0dBVEVXQVlfQ09ERVMuaW5jbHVkZXMoY29kZSk7XG4gICAgY29uc3QgaXNNYWRhID0gdGhpcy5jb25maXJtSXNNYWRhTWV0aG9kKCk7XG4gICAgY29uc3QgcGF5bWVudExhYmVsID0gY29kZSAmJiAhSU5URVJOQUxfR0FURVdBWV9DT0RFUy5pbmNsdWRlcyhjb2RlKSA/IFBBWU1FTlRfR0FURVdBWV9MQUJFTFNbY29kZV0gOiAnJztcbiAgICBjb25zdCByb3dzOiB7XG4gICAgICBrZXk6IHN0cmluZztcbiAgICAgIGxhYmVsOiBzdHJpbmc7XG4gICAgICB2YWx1ZTogbnVtYmVyO1xuICAgICAgc3ViUm93cz86IHsgbGFiZWw6IHN0cmluZzsgdmFsdWU6IG51bWJlciB9W107XG4gICAgICBoYXNMb3lhbHR5Tm90ZT86IGJvb2xlYW47XG4gICAgfVtdID0gW107XG4gICAgY29uc3QgeyB3YWxsZXQsIGZvcmZlaXRlZExveWFsdHkgfSA9IHRoaXMuY29ycmVjdGVkQ29uZmlybVdhbGxldEFuZExveWFsdHkoZCk7XG4gICAgLy8gR29sZGVuIEd1YXJhbnRlZSBvdmVycmlkZXMgY3JlZGl0LXNoZWxsIGhhbmRsaW5nIG9uIHRoZSByZXN1bHQgc2NyZWVuXG4gICAgLy8gdG9vIOKAlCB3aGF0ZXZlciBsYW5kZWQgYXMgYSBjcmVkaXQtc2hlbGwgYW1vdW50IGZvbGRzIGludG8gdGhlIG5vcm1hbFxuICAgIC8vIG9yaWdpbmFsLXBheW1lbnQtbWV0aG9kIHJvdyBpbnN0ZWFkIG9mIGdldHRpbmcgaXRzIG93biBcImFpcmxpbmVcbiAgICAvLyBjcmVkaXRcIiBjYXJkLCBzbyB0aGUgY29uZmlybWF0aW9uIHJlYWRzIGxpa2UgYW4gb3JkaW5hcnkgU2FicmUvQW1hZGV1c1xuICAgIC8vIHJlZnVuZC5cbiAgICBjb25zdCBnb2xkZW5HdWFyYW50ZWVPdmVycmlkZSA9IHRoaXMuaGFzR29sZGVuR3VhcmFudGVlR2lmdCgpO1xuICAgIC8vIENyZWRpdC1zaGVsbCByb3cgZ29lcyBmaXJzdCDigJQgbWF0Y2hlcyB0aGUgZGVzaWduIChhaXJsaW5lIGNyZWRpdCBhYm92ZVxuICAgIC8vIHRoZSB3YWxsZXQgcm93KSDigJQgYmVmb3JlIHRoZSBjYXJkIGFuZCB3YWxsZXQgcm93cyBiZWxvdy5cbiAgICBpZiAoIWdvbGRlbkd1YXJhbnRlZU92ZXJyaWRlKSB7XG4gICAgICBjb25zdCBjcmVkaXQgPSBOdW1iZXIoZC50b3RhbENyZWRpdFJlZnVuZEFtb3VudCA/PyAwKTtcbiAgICAgIGlmIChjcmVkaXQgPiAwKSB7XG4gICAgICAgIGNvbnN0IHN1cHBsaWVyID0gZC5hcHBsaWVkU291cmNlIHx8IHRoaXMuY3JlZGl0U2hlbGxTdXBwbGllck5hbWUoKTtcbiAgICAgICAgcm93cy5wdXNoKHtcbiAgICAgICAgICBrZXk6ICd0b3RhbENyZWRpdFJlZnVuZEFtb3VudCcsXG4gICAgICAgICAgbGFiZWw6IHN1cHBsaWVyID8gYCR7c3VwcGxpZXJ9IHdlYnNpdGUgY3JlZGl0YCA6ICdDcmVkaXQgU2hlbGwgUmVmdW5kJyxcbiAgICAgICAgICB2YWx1ZTogY3JlZGl0LFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgY2FyZEFtb3VudCA9XG4gICAgICBOdW1iZXIoZC50b3RhbENhcmRSZWZ1bmRBbW91bnQgPz8gMCkgK1xuICAgICAgKGdvbGRlbkd1YXJhbnRlZU92ZXJyaWRlID8gTnVtYmVyKGQudG90YWxDcmVkaXRSZWZ1bmRBbW91bnQgPz8gMCkgOiAwKTtcbiAgICBpZiAoY2FyZEFtb3VudCA+IDApIHtcbiAgICAgIHJvd3MucHVzaCh7XG4gICAgICAgIGtleTogJ3RvdGFsQ2FyZFJlZnVuZEFtb3VudCcsXG4gICAgICAgIGxhYmVsOiBpc01hZGFcbiAgICAgICAgICA/ICdNYWRhIENhcmQnXG4gICAgICAgICAgOiAhaXNMb3lhbHR5ICYmIHBheW1lbnRMYWJlbFxuICAgICAgICAgICAgPyBgUmVmdW5kIEFtb3VudCAke3BheW1lbnRMYWJlbH1gXG4gICAgICAgICAgICA6ICdSZWZ1bmQgQW1vdW50JyxcbiAgICAgICAgdmFsdWU6IGNhcmRBbW91bnQsXG4gICAgICB9KTtcbiAgICB9XG4gICAgaWYgKHdhbGxldCA+IDAgJiYgZm9yZmVpdGVkTG95YWx0eSA+IDApIHtcbiAgICAgIC8vIFdhbGxldCBjYXNoICsgYSBsb3lhbHR5IHByb2dyYW0ncyBwb2ludHMgYm90aCBsYW5kZWQgaW4gdGhlIHdhbGxldCDigJRcbiAgICAgIC8vIHNob3duIGFzIG9uZSBjb21iaW5lZCBjYXJkIHdpdGggdGhlIHR3byBzb3VyY2VzIGJyb2tlbiBvdXQgYXMgbmFtZWRcbiAgICAgIC8vIHN1Yi1yb3dzLCByYXRoZXIgdGhhbiB0d28gc2VwYXJhdGUgdG9wLWxldmVsIGNhcmRzLlxuICAgICAgcm93cy5wdXNoKHtcbiAgICAgICAga2V5OiAnd2FsbGV0UmVmdW5kQW1vdW50JyxcbiAgICAgICAgbGFiZWw6ICdBbG1hdGFyIFdhbGxldCcsXG4gICAgICAgIHZhbHVlOiB3YWxsZXQgKyBmb3JmZWl0ZWRMb3lhbHR5LFxuICAgICAgICBzdWJSb3dzOiBbXG4gICAgICAgICAgeyBsYWJlbDogJ0FsbWF0YXIgd2FsbGV0IHBvaW50cycsIHZhbHVlOiB3YWxsZXQgfSxcbiAgICAgICAgICB7IGxhYmVsOiBgJHt0aGlzLndhbGxldE9yTG95YWx0eUxhYmVsKGQpfSBwb2ludHNgLCB2YWx1ZTogZm9yZmVpdGVkTG95YWx0eSB9LFxuICAgICAgICBdLFxuICAgICAgICBoYXNMb3lhbHR5Tm90ZTogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAod2FsbGV0ID4gMCkge1xuICAgICAgcm93cy5wdXNoKHsga2V5OiAnd2FsbGV0UmVmdW5kQW1vdW50JywgbGFiZWw6ICdBbG1hdGFyIFdhbGxldCcsIHZhbHVlOiB3YWxsZXQgfSk7XG4gICAgfSBlbHNlIGlmIChmb3JmZWl0ZWRMb3lhbHR5ID4gMCkge1xuICAgICAgLy8gTG95YWx0eS1vbmx5IOKAlCBubyB3YWxsZXQgY2FzaCBpbnZvbHZlZCwgc3RpbGwgbGFuZHMgYXMgcGVybWFuZW50XG4gICAgICAvLyB3YWxsZXQgcG9pbnRzLCBzbyBpdCBrZWVwcyB0aGUgd2FsbGV0LXN0eWxlIGNhcmQgKyBub3RlLlxuICAgICAgcm93cy5wdXNoKHtcbiAgICAgICAga2V5OiAndG90YWxMb3lhbHR5UG9pbnRzJyxcbiAgICAgICAgbGFiZWw6IHRoaXMud2FsbGV0T3JMb3lhbHR5TGFiZWwoZCksXG4gICAgICAgIHZhbHVlOiBmb3JmZWl0ZWRMb3lhbHR5LFxuICAgICAgICBoYXNMb3lhbHR5Tm90ZTogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBSRUZVTkRfREVGU1xuICAgICAgLmZpbHRlcigoZGVmKSA9PlxuICAgICAgICBkZWYua2V5ICE9PSAnd2FsbGV0UmVmdW5kQW1vdW50JyAmJlxuICAgICAgICBkZWYua2V5ICE9PSAndG90YWxDYXJkUmVmdW5kQW1vdW50JyAmJlxuICAgICAgICBkZWYua2V5ICE9PSAndG90YWxDcmVkaXRSZWZ1bmRBbW91bnQnICYmXG4gICAgICAgIE51bWJlcihkW2RlZi5rZXldKSA+IDAsXG4gICAgICApXG4gICAgICAuZm9yRWFjaCgoZGVmKSA9PiB7XG4gICAgICAgIHJvd3MucHVzaCh7IGtleTogZGVmLmtleSwgbGFiZWw6IGRlZi5sYWJlbCwgdmFsdWU6IE51bWJlcihkW2RlZi5rZXldKSB9KTtcbiAgICAgIH0pO1xuICAgIHJldHVybiByb3dzO1xuICB9KTtcblxuICAvKiogUm93cyB0aGF0IGxhbmQgaW4gdGhlIHdhbGxldCDigJQgcGxhaW4gd2FsbGV0LCB3YWxsZXQrbG95YWx0eSBjb21iaW5lZCwgb3IgbG95YWx0eS1vbmx5IOKAlCBzaGFyZSB0aGUgd2FsbGV0IGljb24vbGF5b3V0IG9uIHRoZSByZXN1bHQgc2NyZWVuLiAqL1xuICBpc1dhbGxldERlc3RpbmF0aW9uUm93KHI6IHsga2V5OiBzdHJpbmcgfSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiByLmtleSA9PT0gJ3dhbGxldFJlZnVuZEFtb3VudCcgfHwgci5rZXkgPT09ICd0b3RhbExveWFsdHlQb2ludHMnO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSByZXN1bHQgc2NyZWVuJ3MgXCJpc3N1ZWQgYXMgYW4gQWlybGluZSBDcmVkaXQgU2hlbGxcIiBub3RlLiBHb2xkZW5cbiAgICogR3VhcmFudGVlIG92ZXJyaWRlcyB0aGlzIHRvICcnIOKAlCB0aGUgY29uZmlybWF0aW9uIHJlbmRlcnMgbGlrZSBhXG4gICAqIHN0YW5kYXJkIFNhYnJlL0FtYWRldXMgcmVmdW5kIGluc3RlYWQgKHNlZSBgY29uZmlybVJlZnVuZHNgJyBmb2xkaW5nXG4gICAqIG9mIGFueSBjcmVkaXQtc2hlbGwgYW1vdW50IGludG8gdGhlIG5vcm1hbCBwYXltZW50LW1ldGhvZCByb3cpLlxuICAgKi9cbiAgY29uZmlybUNyZWRpdFNoZWxsTm90ZSA9IGNvbXB1dGVkKCgpOiBzdHJpbmcgPT4ge1xuICAgIGlmICh0aGlzLmhhc0dvbGRlbkd1YXJhbnRlZUdpZnQoKSkgcmV0dXJuICcnO1xuICAgIGNvbnN0IGQgPSB0aGlzLmNhbmNlbFJlc3VsdCgpO1xuICAgIGlmICghZCkgcmV0dXJuICcnO1xuICAgIGNvbnN0IGxlZ0luZm8gPSBkLmxlZ0luZm8gPz8ge307XG4gICAgY29uc3QgaGFzTyA9ICEhbGVnSW5mby5vbndhcmQ7XG4gICAgY29uc3QgaGFzUiA9ICEhbGVnSW5mby5yZXR1cm47XG4gICAgY29uc3Qgb1NoZWxsID0gbGVnSW5mby5vbndhcmQ/LmlzQ3JlZGl0U2hlbGwgPT09IHRydWU7XG4gICAgY29uc3QgclNoZWxsID0gbGVnSW5mby5yZXR1cm4/LmlzQ3JlZGl0U2hlbGwgPT09IHRydWU7XG4gICAgY29uc3QgdG9wU2hlbGwgPSBkLmlzQ3JlZGl0U2hlbGwgPT09IHRydWU7XG4gICAgaWYgKChoYXNPICYmIGhhc1IgJiYgb1NoZWxsICYmIHJTaGVsbCkgfHwgKGhhc08gJiYgIWhhc1IgJiYgb1NoZWxsKSB8fCAoIWhhc08gJiYgaGFzUiAmJiByU2hlbGwpIHx8IHRvcFNoZWxsKVxuICAgICAgcmV0dXJuICdUaGUgcmVmdW5kIGhhcyBiZWVuIGlzc3VlZCBhcyBhbiBBaXJsaW5lIENyZWRpdCBTaGVsbCBhbmQgY2FuIGJlIHVzZWQgZm9yIGZ1dHVyZSBib29raW5ncyBvbiB0aGUgYWlybGluZSB3ZWJzaXRlLic7XG4gICAgaWYgKGhhc08gJiYgaGFzUikge1xuICAgICAgaWYgKG9TaGVsbCkgcmV0dXJuICdUaGUgcmVmdW5kIGZvciB0aGUgb253YXJkIGZsaWdodCBoYXMgYmVlbiBpc3N1ZWQgYXMgYW4gQWlybGluZSBDcmVkaXQgU2hlbGwuJztcbiAgICAgIGlmIChyU2hlbGwpIHJldHVybiAnVGhlIHJlZnVuZCBmb3IgdGhlIHJldHVybiBmbGlnaHQgaGFzIGJlZW4gaXNzdWVkIGFzIGFuIEFpcmxpbmUgQ3JlZGl0IFNoZWxsLic7XG4gICAgfVxuICAgIHJldHVybiAnJztcbiAgfSk7XG5cbiAgZm10UmVzdWx0KHZhbHVlOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGNvbnN0IGN1ciA9IHRoaXMuY2FuY2VsUmVzdWx0KCk/LmN1cnJlbmN5ID8/IHRoaXMucmVmdW5kRGF0YSgpPy5jdXJyZW5jeSA/PyAnU0FSJztcbiAgICByZXR1cm4gYCR7TnVtYmVyKHZhbHVlIHx8IDApLnRvTG9jYWxlU3RyaW5nKCdlbi1TQScsIHsgbWluaW11bUZyYWN0aW9uRGlnaXRzOiAyLCBtYXhpbXVtRnJhY3Rpb25EaWdpdHM6IDIgfSl9ICR7Y3VyfWA7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGN1c3RvbWVyLWZhY2luZyB0b3RhbCAoY2VpbGVkKSBtdXN0IG1hdGNoIHRoZSBwcmUtcm91bmRpbmcgdG90YWwgdGhlXG4gICAqIHJlZnVuZCBpcyBhY3R1YWxseSBjb21wdXRlZCBmcm9tIOKAlCBpLmUuIGB0b3RhbFJlZnVuZEFtb3VudGAgbXVzdCBiZVxuICAgKiBgdG90YWxSZWZ1bmRBbW91bnRCZWZvcmVDZWlsYCByb3VuZGVkIHVwIHRvIGEgd2hvbGUgY3VycmVuY3kgdW5pdCAoZS5nLlxuICAgKiAxNDU0LjUg4oaSIDE0NTUpLiBBIG1pc21hdGNoIGhlcmUgbWVhbnMgdGhlIHN1cHBsaWVyIHJlc3BvbnNlIGl0c2VsZiBpc1xuICAgKiBpbnRlcm5hbGx5IGluY29uc2lzdGVudCBhbmQgbXVzdCBibG9jayBjb25maXJtYXRpb24uXG4gICAqL1xuICByZWZ1bmRSZWNvbmNpbGVzID0gY29tcHV0ZWQoKCk6IGJvb2xlYW4gPT4ge1xuICAgIGNvbnN0IGQgPSB0aGlzLmFkanVzdGVkRGF0YSgpO1xuICAgIGlmICghZCB8fCAhZC5pc1JlZnVuZGFibGUpIHJldHVybiB0cnVlO1xuICAgIGNvbnN0IGJlZm9yZUNlaWwgPSBOdW1iZXIoZC50b3RhbFJlZnVuZEFtb3VudEJlZm9yZUNlaWwgPz8gZC50b3RhbFJlZnVuZEFtb3VudCA/PyAwKTtcbiAgICBjb25zdCB0b3RhbCA9IE51bWJlcihkLnRvdGFsUmVmdW5kQW1vdW50ID8/IGJlZm9yZUNlaWwpO1xuICAgIHJldHVybiBNYXRoLmFicyhNYXRoLmNlaWwoYmVmb3JlQ2VpbCkgLSB0b3RhbCkgPCAxO1xuICB9KTtcblxuICBjYW5Db25maXJtID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGQgPSB0aGlzLmFkanVzdGVkRGF0YSgpO1xuICAgIHJldHVybiAhIWQ/LmlzUmVmdW5kYWJsZSAmJiB0aGlzLnJlZnVuZFJlY29uY2lsZXMoKSAmJiAhdGhpcy5jYW5jZWxsaW5nKCk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBgdG90YWxMb3lhbHR5UG9pbnRzYCBpcyBub3JtYWxseSB0aGUgZm9yZmVpdGVkLWF0LWJvb2tpbmcgcG9pbnRzIGNvdW50XG4gICAqIChubyByZWZ1bmQgZGVzdGluYXRpb24gb2YgaXRzIG93bikuIEJ1dCB3aGVuIHRoZSBiYWNrZW5kIG5ldmVyXG4gICAqIHBvcHVsYXRlcyBgdG90YWxMb3lhbHR5UG9pbnRzUmVmdW5kQW1vdW50YCBmb3IgYSBgbG95YWx0eVBheW1lbnRUeXBlYFxuICAgKiBib29raW5nLCB0aGlzIGlzIHRoZSBvbmx5IHNpZ25hbCB0aGF0IGEgbG95YWx0eSBwcm9ncmFtIHdhcyBpbnZvbHZlZCxcbiAgICogc28gaXQgZG91YmxlcyBhcyBhIHNwbGl0LXJlZnVuZCByb3cgKGFsb25nc2lkZSBDYXJkL1dhbGxldCkgcmF0aGVyIHRoYW5cbiAgICogZGlzYXBwZWFyaW5nIGZyb20gdGhlIHJlZnVuZCBicmVha2Rvd24gZW50aXJlbHkuIEFsd2F5cyBzaG93biBhcyBpdHNcbiAgICogb3duIHJvdyB1bmRlciB0aGUgcHJvZ3JhbSBuYW1lIChlLmcuIFwiV2FsYVwiKSDigJQgbmV2ZXIgbWVyZ2VkIGludG8gdGhlXG4gICAqIGdlbmVyaWMgV2FsbGV0IHJvdywgZXZlbiB3aGVuIGB3YWxsZXRSZWZ1bmRBbW91bnRgIGlzIGFsc28gbm9uLXplcm8uXG4gICAqL1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICBwcml2YXRlIGZvcmZlaXRlZExveWFsdHlQb2ludHNGYWxsYmFjayhkOiBhbnkpOiBudW1iZXIge1xuICAgIGlmICghZD8ubG95YWx0eVBheW1lbnRUeXBlKSByZXR1cm4gMDtcbiAgICBpZiAoTnVtYmVyKGQudG90YWxMb3lhbHR5UG9pbnRzUmVmdW5kQW1vdW50ID8/IDApID4gMCkgcmV0dXJuIDA7XG4gICAgcmV0dXJuIE51bWJlcihkLnRvdGFsTG95YWx0eVBvaW50cyA/PyAwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTb21lIGAvY29uZmlybWAgcmVzcG9uc2VzIGZvciBhIHNpbmdsZS1sZWcgKG5vbi1jcm9zcy1zZWxsZXIpIGJvb2tpbmdcbiAgICogcHV0IGB3YWxsZXRSZWZ1bmRBbW91bnRgL2B0b3RhbExveWFsdHlQb2ludHNgIG9uIHRoZSB3cm9uZyBzaWRlIGF0IHRoZVxuICAgKiByb290IOKAlCBlLmcuIHJvb3QgcmVhZHMgYHdhbGxldFJlZnVuZEFtb3VudDogNDAsIHRvdGFsTG95YWx0eVBvaW50czogMGBcbiAgICogd2hpbGUgdGhlIHNpbmdsZSBsZWcgKHdoaWNoIHNob3VsZCBtaXJyb3Igcm9vdCBleGFjdGx5IGhlcmUpIHJlYWRzXG4gICAqIGB3YWxsZXRSZWZ1bmRBbW91bnQ6IDAsIHRvdGFsTG95YWx0eVBvaW50czogNDBgLiBEZXRlY3RlZCBuYXJyb3dseTogcm9vdFxuICAgKiBzaG93cyBubyBmb3JmZWl0ZWQgbG95YWx0eSBkZXNwaXRlIGBsb3lhbHR5UGF5bWVudFR5cGVgIGJlaW5nIHNldCwgdGhlXG4gICAqIHJvb3Qgd2FsbGV0IGFtb3VudCBleGFjdGx5IGVxdWFscyB0aGUgbGVnJ3MgbG95YWx0eSBwb2ludHMsIGFuZCB0aGVcbiAgICogbGVnJ3Mgb3duIHdhbGxldCBhbW91bnQgZGlzYWdyZWVzIOKAlCBpbiB0aGF0IHNwZWNpZmljIGNhc2UgdGhlIGxlZydzXG4gICAqIHZhbHVlcyBhcmUgdHJ1c3RlZCBpbnN0ZWFkLCBzaW5jZSB3aXRoIG9ubHkgb25lIGxlZyB0aGV5J3JlIHVuYW1iaWd1b3VzLlxuICAgKlxuICAgKiBBIHNlY29uZCwgbW9yZSBjb21tb24gc2hhcGU6IHJvb3QgZG9lc24ndCBzd2FwIGF0IGFsbCwgaXQgZm9sZHMgdGhlXG4gICAqIHBvaW50cyBzdHJhaWdodCBpbnRvIGB3YWxsZXRSZWZ1bmRBbW91bnRgIGFzIG9uZSBvcGFxdWUgbHVtcCBzdW0gKGUuZy5cbiAgICogcm9vdCB3YWxsZXQgMzQwID0gdGhlIGxlZydzIG93biBjYXNoIHdhbGxldCAzMDAgKyB0aGUgbGVnJ3MgZm9yZmVpdGVkXG4gICAqIGxveWFsdHkgcG9pbnRzIDQwKS4gU3BsaXQgdGhhdCBiYWNrIGludG8gdGhlIHR3byBwYXJ0cyB0aGUgbGVnIGFscmVhZHlcbiAgICogdGVsbHMgdXMgYWJvdXQgdG9vLCBzbyB0aGUgcmVzdWx0IHNjcmVlbiBjYW4gc2hvdyBhIGNvbWJpbmVkIHdhbGxldCBjYXJkXG4gICAqIHdpdGggdGhlIHByb2dyYW0gbmFtZWQgaW5zdGVhZCBvZiBvbmUgdW5leHBsYWluZWQgdG90YWwuXG4gICAqL1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICBwcml2YXRlIGNvcnJlY3RlZENvbmZpcm1XYWxsZXRBbmRMb3lhbHR5KGQ6IGFueSk6IHsgd2FsbGV0OiBudW1iZXI7IGZvcmZlaXRlZExveWFsdHk6IG51bWJlciB9IHtcbiAgICBjb25zdCByb290V2FsbGV0ID0gTnVtYmVyKGQud2FsbGV0UmVmdW5kQW1vdW50ID8/IDApO1xuICAgIGNvbnN0IGZvcmZlaXRlZEZyb21Sb290ID0gdGhpcy5mb3JmZWl0ZWRMb3lhbHR5UG9pbnRzRmFsbGJhY2soZCk7XG4gICAgaWYgKGZvcmZlaXRlZEZyb21Sb290ID4gMCB8fCAhZC5sb3lhbHR5UGF5bWVudFR5cGUpIHtcbiAgICAgIHJldHVybiB7IHdhbGxldDogcm9vdFdhbGxldCwgZm9yZmVpdGVkTG95YWx0eTogZm9yZmVpdGVkRnJvbVJvb3QgfTtcbiAgICB9XG4gICAgY29uc3Qgb253YXJkID0gZC5sZWdJbmZvPy5vbndhcmQ7XG4gICAgY29uc3QgcmV0ID0gZC5sZWdJbmZvPy5yZXR1cm47XG4gICAgY29uc3QgbGVnID0gb253YXJkICYmICFyZXQgPyBvbndhcmQgOiByZXQgJiYgIW9ud2FyZCA/IHJldCA6IG51bGw7XG4gICAgaWYgKCFsZWcpIHJldHVybiB7IHdhbGxldDogcm9vdFdhbGxldCwgZm9yZmVpdGVkTG95YWx0eTogMCB9O1xuICAgIGNvbnN0IGxlZ0xveWFsdHkgPSBOdW1iZXIobGVnLnRvdGFsTG95YWx0eVBvaW50cyA/PyAwKTtcbiAgICBjb25zdCBsZWdXYWxsZXQgPSBOdW1iZXIobGVnLndhbGxldFJlZnVuZEFtb3VudCA/PyAwKTtcbiAgICAvLyBGdWxsIHN3YXA6IHJvb3QgcmVhZHMgdGhlIGxlZydzIGxveWFsdHkgYW1vdW50IHdoZXJlIGl0cyB3YWxsZXQgc2hvdWxkIGJlLlxuICAgIGlmIChcbiAgICAgIGxlZ0xveWFsdHkgPiAwICYmXG4gICAgICByb290V2FsbGV0ID09PSBsZWdMb3lhbHR5ICYmXG4gICAgICBsZWdXYWxsZXQgIT09IHJvb3RXYWxsZXQgJiZcbiAgICAgIE51bWJlcihkLnRvdGFsTG95YWx0eVBvaW50c1JlZnVuZEFtb3VudCA/PyAwKSA9PT0gMFxuICAgICkge1xuICAgICAgcmV0dXJuIHsgd2FsbGV0OiBsZWdXYWxsZXQsIGZvcmZlaXRlZExveWFsdHk6IGxlZ0xveWFsdHkgfTtcbiAgICB9XG4gICAgLy8gTHVtcCBzdW06IHJvb3Qgd2FsbGV0ID0gbGVnJ3MgY2FzaCB3YWxsZXQgKyBsZWcncyBmb3JmZWl0ZWQgbG95YWx0eS5cbiAgICBpZiAoXG4gICAgICBsZWdMb3lhbHR5ID4gMCAmJlxuICAgICAgbGVnV2FsbGV0ID4gMCAmJlxuICAgICAgTWF0aC5hYnMocm9vdFdhbGxldCAtIChsZWdXYWxsZXQgKyBsZWdMb3lhbHR5KSkgPCAxICYmXG4gICAgICBOdW1iZXIoZC50b3RhbExveWFsdHlQb2ludHNSZWZ1bmRBbW91bnQgPz8gMCkgPT09IDBcbiAgICApIHtcbiAgICAgIHJldHVybiB7IHdhbGxldDogbGVnV2FsbGV0LCBmb3JmZWl0ZWRMb3lhbHR5OiBsZWdMb3lhbHR5IH07XG4gICAgfVxuICAgIC8vIE5ld2VyIGAvY29uZmlybWAgcmVzcG9uc2VzIGRyb3AgdGhlIGxveWFsdHkgcG9ydGlvbiBmcm9tIGJvdGggcm9vdCBhbmRcbiAgICAvLyBsZWcgdG90YWxzIOKAlCBgd2FsbGV0UmVmdW5kQW1vdW50YCBhcnJpdmVzIGFzIG9uZSBvcGFxdWUgbHVtcCB0aGF0J3MgdGhlXG4gICAgLy8gY2FzaC13YWxsZXQgcG9ydGlvbiAoYHRvdGFsV2FsbGV0QW1vdW50YCkgcGx1cyBhIGxveWFsdHktcHJvZ3JhbSBhbW91bnQuXG4gICAgLy8gV2hlbiBgbG95YWx0eVBheW1lbnRUeXBlYCBpcyBzZXQsIHRoZSBsdW1wIGV4Y2VlZHMgdGhlIGNhc2gtd2FsbGV0XG4gICAgLy8gcG9ydGlvbiwgYW5kIGl0J3MgYSBnZW51aW5lIGNhcmQrd2FsbGV0IHNwbGl0IChub3QgYSBcInNlbmQgZXZlcnl0aGluZyB0b1xuICAgIC8vIHRoZSB3YWxsZXRcIiByZWZ1bmQpLCB0aGUgZGlmZmVyZW5jZSBpcyB0aGF0IGxveWFsdHkgYW1vdW50LlxuICAgIGNvbnN0IGNhc2hXYWxsZXQgPSBOdW1iZXIoZC50b3RhbFdhbGxldEFtb3VudCA/PyAwKTtcbiAgICBjb25zdCBpbXBsaWVkTG95YWx0eSA9IHJvb3RXYWxsZXQgLSBjYXNoV2FsbGV0O1xuICAgIGlmIChcbiAgICAgIGltcGxpZWRMb3lhbHR5ID4gMC4wMSAmJlxuICAgICAgY2FzaFdhbGxldCA+IDAgJiZcbiAgICAgIE51bWJlcihkLnRvdGFsQ2FyZFJlZnVuZEFtb3VudCA/PyAwKSA+IDAgJiZcbiAgICAgIE51bWJlcihkLnRvdGFsTG95YWx0eVBvaW50c1JlZnVuZEFtb3VudCA/PyAwKSA9PT0gMFxuICAgICkge1xuICAgICAgcmV0dXJuIHsgd2FsbGV0OiBjYXNoV2FsbGV0LCBmb3JmZWl0ZWRMb3lhbHR5OiBpbXBsaWVkTG95YWx0eSB9O1xuICAgIH1cbiAgICAvLyBUaGUgd2hvbGUgd2FsbGV0IHJlZnVuZCBpcyB0aGUgbG95YWx0eS1wcm9ncmFtIGJhbGFuY2Ug4oCUIG5vIGNhc2gtd2FsbGV0XG4gICAgLy8gcG9ydGlvbiAoYHRvdGFsV2FsbGV0QW1vdW50YCAwKSBhbmQgbm8gY2FyZCBwb3J0aW9uLCBidXRcbiAgICAvLyBgbG95YWx0eVBheW1lbnRUeXBlYCBpcyBzZXQuIEF0dHJpYnV0ZSBhbGwgb2YgaXQgdG8gdGhlIHByb2dyYW0gc28gdGhlXG4gICAgLy8gcG9wdXAgbmFtZXMgaXQgKGUuZy4gXCJXYWxhXCIpIHdpdGggdGhlIHBlcm1hbmVudC1wb2ludHMgbm90ZS5cbiAgICBpZiAoXG4gICAgICBjYXNoV2FsbGV0ID09PSAwICYmXG4gICAgICByb290V2FsbGV0ID4gMCAmJlxuICAgICAgTnVtYmVyKGQudG90YWxDYXJkUmVmdW5kQW1vdW50ID8/IDApID09PSAwICYmXG4gICAgICBOdW1iZXIoZC50b3RhbExveWFsdHlQb2ludHNSZWZ1bmRBbW91bnQgPz8gMCkgPT09IDBcbiAgICApIHtcbiAgICAgIHJldHVybiB7IHdhbGxldDogMCwgZm9yZmVpdGVkTG95YWx0eTogcm9vdFdhbGxldCB9O1xuICAgIH1cbiAgICByZXR1cm4geyB3YWxsZXQ6IHJvb3RXYWxsZXQsIGZvcmZlaXRlZExveWFsdHk6IDAgfTtcbiAgfVxuXG4gIC8qKiBIb3cgbWFueSBvZiB7d2FsbGV0LCBjYXJkLCBsb3lhbHR5fSB0aGUgcmVmdW5kIGlzIGFjdHVhbGx5IHNwbGl0IGFjcm9zcy4gKi9cbiAgcHJpdmF0ZSBzcGxpdFBhcnRzQ291bnQgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3QgZCA9IHRoaXMuYWRqdXN0ZWREYXRhKCk7XG4gICAgaWYgKCFkKSByZXR1cm4gMDtcbiAgICByZXR1cm4gW1xuICAgICAgZC53YWxsZXRSZWZ1bmRBbW91bnQsXG4gICAgICBkLnRvdGFsQ2FyZFJlZnVuZEFtb3VudCxcbiAgICAgIGQudG90YWxMb3lhbHR5UG9pbnRzUmVmdW5kQW1vdW50LFxuICAgICAgdGhpcy5mb3JmZWl0ZWRMb3lhbHR5UG9pbnRzRmFsbGJhY2soZCksXG4gICAgXS5maWx0ZXIoKHYpID0+IE51bWJlcih2ID8/IDApID4gMCkubGVuZ3RoO1xuICB9KTtcblxuICAvKipcbiAgICogQSBwb3J0aW9uIG9mIHRoZSByZWZ1bmQgaXMgZm9yY2VkIHRvIHRoZSB3YWxsZXQgKGUuZy4gbG95YWx0eSBwb2ludHMgdXNlZClcbiAgICog4oCUIGluIHRoYXQgY2FzZSBvZmZlciBhIFwiU3BsaXQgUmVmdW5kXCIgb3B0aW9uIGluc3RlYWQgb2YgYSBwdXJlXG4gICAqIG9yaWdpbmFsLXBheW1lbnQtbWV0aG9kIG9wdGlvbiwgc2luY2UgdGhlIHdob2xlIGFtb3VudCBjYW4ndCBnbyB0byBjYXJkLlxuICAgKi9cbiAgaGFzU3BsaXRSZWZ1bmQgPSBjb21wdXRlZChcbiAgICAoKSA9PiBOdW1iZXIodGhpcy5hZGp1c3RlZERhdGEoKT8udG90YWxSZWZ1bmRBbW91bnQgPz8gMCkgPiAwICYmIHRoaXMuc3BsaXRQYXJ0c0NvdW50KCkgPj0gMixcbiAgKTtcblxuICAvKipcbiAgICogV2FsbGV0IGNvdmVycyB0aGUgd2hvbGUgcmVmdW5kIChubyBjYXJkIG9yIGxveWFsdHkgcG9ydGlvbiBhdCBhbGwpIOKAlCBzaG93XG4gICAqIHRoZSB3YWxsZXQgb3B0aW9uIGFsb25lIHJhdGhlciB0aGFuIGEgXCJzcGxpdFwiIHdpdGggZW1wdHkgb3RoZXIgc2lkZXMuXG4gICAqL1xuICBpc1dhbGxldE9ubHlSZWZ1bmQgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3QgZCA9IHRoaXMuYWRqdXN0ZWREYXRhKCk7XG4gICAgcmV0dXJuIChcbiAgICAgIE51bWJlcihkPy53YWxsZXRSZWZ1bmRBbW91bnQgPz8gMCkgPiAwICYmXG4gICAgICBOdW1iZXIoZD8udG90YWxDYXJkUmVmdW5kQW1vdW50ID8/IDApID09PSAwICYmXG4gICAgICBOdW1iZXIoZD8udG90YWxMb3lhbHR5UG9pbnRzUmVmdW5kQW1vdW50ID8/IDApID09PSAwICYmXG4gICAgICB0aGlzLmZvcmZlaXRlZExveWFsdHlQb2ludHNGYWxsYmFjayhkKSA9PT0gMFxuICAgICk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBUaGUgZW50aXJlIHJlZnVuZCBpcyBmb3JmZWl0ZWQgbG95YWx0eSBwb2ludHMgKGUuZy4gV2FsYSkgbGFuZGluZyBiYWNrIGFzXG4gICAqIHdhbGxldCBiYWxhbmNlIOKAlCBubyBjYXNoLXdhbGxldCwgY2FyZCwgY3JlZGl0IG9yIHJlYWxcbiAgICogbG95YWx0eS1wb2ludHMtcmVmdW5kIHBvcnRpb24gYXQgYWxsLiBXaXRob3V0IHRoaXMgdGhlIHBpY2tlciBmYWxsc1xuICAgKiB0aHJvdWdoIHRvIHRoZSBcIk9yaWdpbmFsIFBheW1lbnQgTWV0aG9kXCIgY2FyZCBhbmQgbWlzbGFiZWxzIHRoZVxuICAgKiBkZXN0aW5hdGlvbiBhcyB0aGUgb3JpZ2luYWwgZ2F0ZXdheSAoZS5nLiBcIlRhYmJ5XCIpLCBldmVuIHRob3VnaFxuICAgKiBgdG90YWxDYXJkUmVmdW5kQW1vdW50YCBpcyAwIGFuZCBub3RoaW5nIGdvZXMgYmFjayB0byB0aGF0IGNhcmQuXG4gICAqL1xuICBpc0xveWFsdHlPbmx5UmVmdW5kID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGQgPSB0aGlzLmFkanVzdGVkRGF0YSgpO1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmZvcmZlaXRlZExveWFsdHlQb2ludHNGYWxsYmFjayhkKSA+IDAgJiZcbiAgICAgIE51bWJlcihkPy53YWxsZXRSZWZ1bmRBbW91bnQgPz8gMCkgPT09IDAgJiZcbiAgICAgIE51bWJlcihkPy50b3RhbENhcmRSZWZ1bmRBbW91bnQgPz8gMCkgPT09IDAgJiZcbiAgICAgIE51bWJlcihkPy50b3RhbENyZWRpdFJlZnVuZEFtb3VudCA/PyAwKSA9PT0gMCAmJlxuICAgICAgTnVtYmVyKGQ/LnRvdGFsTG95YWx0eVBvaW50c1JlZnVuZEFtb3VudCA/PyAwKSA9PT0gMFxuICAgICk7XG4gIH0pO1xuXG4gIC8qKiBBIHJlYWwgY2FzaC13YWxsZXQgcG9ydGlvbiBpcyBwYXJ0IG9mIHRoZSByZWZ1bmQgKGRpc3RpbmN0IGZyb20gZm9yZmVpdGVkIGxveWFsdHkgcG9pbnRzIGxhbmRpbmcgaW4gdGhlIHdhbGxldCkuICovXG4gIGhhc0Nhc2hXYWxsZXRSZWZ1bmQgPSBjb21wdXRlZChcbiAgICAoKSA9PiBOdW1iZXIodGhpcy5hZGp1c3RlZERhdGEoKT8ud2FsbGV0UmVmdW5kQW1vdW50ID8/IDApID4gMCxcbiAgKTtcblxuICAvKipcbiAgICogV2FsbGV0IGNhcmQncyB0aXRsZSDigJQgbm9ybWFsbHkgXCJBbG1hdGFyIFdhbGxldFwiLCBidXQgdGhlIGxveWFsdHkgcHJvZ3JhbVxuICAgKiBuYW1lIChXYWxhLCBRaXRhZiwg4oCmKSB3aGVuIHRoZSB3aG9sZSByZWZ1bmQgaXMgdGhhdCBwcm9ncmFtJ3MgZm9yZmVpdGVkXG4gICAqIGJhbGFuY2UgbGFuZGluZyBiYWNrIGluIHRoZSB3YWxsZXQuXG4gICAqL1xuICB3YWxsZXRDYXJkTGFiZWwgPSBjb21wdXRlZCgoKSA9PlxuICAgIHRoaXMuaXNMb3lhbHR5T25seVJlZnVuZCgpXG4gICAgICA/IHRoaXMud2FsbGV0T3JMb3lhbHR5TGFiZWwodGhpcy5hZGp1c3RlZERhdGEoKSkgfHwgJ0FsbWF0YXIgV2FsbGV0J1xuICAgICAgOiAnQWxtYXRhciBXYWxsZXQnLFxuICApO1xuXG4gIC8qKlxuICAgKiBQYXJ0IG9mIHRoZSByZWZ1bmQgY2FtZSBmcm9tIGNvbnZlcnRpbmcgZXh0ZXJuYWwgbG95YWx0eSBwb2ludHMgaW50b1xuICAgKiB3YWxsZXQgZnVuZHMg4oCUIHN1cmZhY2VkIGFzIGEgbm90ZSB1bmRlciB0aGUgd2FsbGV0IGRlc3RpbmF0aW9uIHNvIHRoZVxuICAgKiBhZ2VudCBrbm93cyB0aG9zZSBwb2ludHMgbGFuZCBhcyBwZXJtYW5lbnQgd2FsbGV0IGJhbGFuY2UsIG5vdCBjYXNoLlxuICAgKi9cbiAgaGFzTG95YWx0eVBvaW50c1JlZnVuZCA9IGNvbXB1dGVkKFxuICAgICgpID0+IE51bWJlcih0aGlzLmFkanVzdGVkRGF0YSgpPy50b3RhbExveWFsdHlQb2ludHMgPz8gMCkgPiAwLFxuICApO1xuXG4gIC8qKlxuICAgKiBUaGUgYm9va2luZyBpcyByZWZ1bmRhYmxlIGJ1dCBuZXRzIHRvIDAuMDAgYWZ0ZXIgZGVkdWN0aW9ucyDigJQgYVxuICAgKiBkZWRpY2F0ZWQgTklMIFJlZnVuZCBzdGF0ZSwgZGlzdGluY3QgZnJvbSBcIm5vdCByZWZ1bmRhYmxlXCI6IG5vIHJlZnVuZFxuICAgKiBtZXRob2QgdG8gY2hvb3NlIGJldHdlZW4sIGp1c3QgY29uZmlybWF0aW9uIHRoYXQgbm90aGluZyBpcyBvd2VkIGJhY2suXG4gICAqL1xuICBpc05pbFJlZnVuZCA9IGNvbXB1dGVkKCgpOiBib29sZWFuID0+IHtcbiAgICBjb25zdCBkID0gdGhpcy5hZGp1c3RlZERhdGEoKTtcbiAgICByZXR1cm4gISFkPy5pc1JlZnVuZGFibGUgJiYgTnVtYmVyKGQudG90YWxSZWZ1bmRBbW91bnQgPz8gMCkgPT09IDA7XG4gIH0pO1xuXG4gIC8qKiBTYW1lIGFzIGBpc05pbFJlZnVuZGAsIHNjb3BlZCB0byB0aGUgY29uZmlybWVkIGNhbmNlbGxhdGlvbiByZXN1bHQg4oCUIGRyaXZlcyB0aGUgcmVzdWx0IHNjcmVlbidzIHRpdGxlLiAqL1xuICBjb25maXJtSXNOaWxSZWZ1bmQgPSBjb21wdXRlZCgoKTogYm9vbGVhbiA9PiB7XG4gICAgY29uc3QgZCA9IHRoaXMuY2FuY2VsUmVzdWx0KCk7XG4gICAgcmV0dXJuICEhZD8uaXNSZWZ1bmRhYmxlICYmIE51bWJlcihkLnRvdGFsUmVmdW5kQW1vdW50ID8/IDApID09PSAwO1xuICB9KTtcblxuICAvKiogV2hldGhlciB0aGUgY3VzdG9tZXIgbWF5IHNlbmQgdGhlIHdob2xlIHJlZnVuZCB0byB0aGVpciBBbG1hdGFyIFdhbGxldC4gKi9cbiAgaXNGdWxsV2FsbGV0UmVmdW5kQWxsb3dlZCA9IGNvbXB1dGVkKCgpID0+ICEhdGhpcy5hZGp1c3RlZERhdGEoKT8uaXNGdWxsV2FsbGV0UmVmdW5kQWxsb3dlZCk7XG5cbiAgLyoqIFdoZXRoZXIgdGhlIGN1c3RvbWVyIHBhaWQgdmlhIGFuIGluc3RhbGxtZW50IGdhdGV3YXkgKFRhbWFyYSwgVGFiYnksIOKApikuICovXG4gIGlzSW5zdGFsbG1lbnRNZXRob2QgPSBjb21wdXRlZCgoKSA9PlxuICAgIElOU1RBTExNRU5UX0dBVEVXQVlfQ09ERVMuaW5jbHVkZXMoXG4gICAgICB0aGlzLm5vcm1hbGl6ZUdhdGV3YXlDb2RlKHRoaXMuYWRqdXN0ZWREYXRhKCk/LnBheW1lbnRNZXRob2RDdXN0b21lclVzZWQpLFxuICAgICksXG4gICk7XG5cbiAgLyoqIFdoZXRoZXIgdGhlIGN1c3RvbWVyIHBhaWQgdmlhIGEgbG95YWx0eS1wcm9ncmFtIGdhdGV3YXkgKEFsIFJhamhpIE1va2FmYWEsIOKApikuICovXG4gIGlzTG95YWx0eU1ldGhvZCA9IGNvbXB1dGVkKCgpID0+XG4gICAgTE9ZQUxUWV9HQVRFV0FZX0NPREVTLmluY2x1ZGVzKFxuICAgICAgdGhpcy5ub3JtYWxpemVHYXRld2F5Q29kZSh0aGlzLmFkanVzdGVkRGF0YSgpPy5wYXltZW50TWV0aG9kQ3VzdG9tZXJVc2VkKSxcbiAgICApLFxuICApO1xuXG4gIC8qKiBBbnkgZ2F0ZXdheSB0aGF0IHJlZnVuZHMgc29tZXdoZXJlIG90aGVyIHRoYW4gYSBwbGFpbiBjYXJkIOKAlCB1c2VkIGZvciB0aGUgd2FsbGV0LXN0eWxlIGljb24uICovXG4gIGlzU3BlY2lhbEdhdGV3YXlNZXRob2QgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmlzSW5zdGFsbG1lbnRNZXRob2QoKSB8fCB0aGlzLmlzTG95YWx0eU1ldGhvZCgpKTtcblxuICAvKipcbiAgICogQ2FyZC1yZWZ1bmQgc2V0dGxlbWVudC10aW1lbGluZSBiYWRnZSDigJQgVGFiYnkgYW5kIFRhbWFyYSBlYWNoIGhhdmUgdGhlaXJcbiAgICogb3duIHByb2Nlc3Npbmcgd2luZG93LCBkaXN0aW5jdCBmcm9tIGEgcGxhaW4gY2FyZCdzIGdlbmVyaWMgYmFuayBwb2xpY3kuXG4gICAqL1xuICBjYXJkQmFkZ2VUZXh0ID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGNvZGUgPSB0aGlzLm5vcm1hbGl6ZUdhdGV3YXlDb2RlKHRoaXMuYWRqdXN0ZWREYXRhKCk/LnBheW1lbnRNZXRob2RDdXN0b21lclVzZWQpO1xuICAgIGlmIChjb2RlID09PSAnVEInKSByZXR1cm4gJ0Zyb20gNS03IGJ1c2luZXNzIGRheXMnO1xuICAgIGlmIChjb2RlID09PSAnVE0nKSByZXR1cm4gJ1VwIHRvIDEwIGJ1c2luZXNzIGRheXMnO1xuICAgIGlmICh0aGlzLmlzTG95YWx0eU1ldGhvZCgpKSByZXR1cm4gJ0xveWFsdHkgUHJvZ3JhbSBQb2xpY3knO1xuICAgIHJldHVybiAnVXAgdG8gMTUgYnVzaW5lc3MgZGF5cywgYmFuayBwb2xpY3knO1xuICB9KTtcblxuICAvKiogU2FtZSBhcyBgY2FyZEJhZGdlVGV4dGAsIHNjb3BlZCB0byB0aGUgY29uZmlybWVkIGNhbmNlbGxhdGlvbiByZXN1bHQuICovXG4gIGNvbmZpcm1DYXJkQmFkZ2VUZXh0ID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgY29uc3QgZDogYW55ID0gdGhpcy5jYW5jZWxSZXN1bHQoKTtcbiAgICBjb25zdCBjb2RlID0gdGhpcy5ub3JtYWxpemVHYXRld2F5Q29kZShkPy5wYXltZW50TWV0aG9kQ3VzdG9tZXJVc2VkKTtcbiAgICBpZiAoY29kZSA9PT0gJ1RCJykgcmV0dXJuICdGcm9tIDUtNyBidXNpbmVzcyBkYXlzJztcbiAgICBpZiAoY29kZSA9PT0gJ1RNJykgcmV0dXJuICdVcCB0byAxMCBidXNpbmVzcyBkYXlzJztcbiAgICBpZiAoTE9ZQUxUWV9HQVRFV0FZX0NPREVTLmluY2x1ZGVzKGNvZGUpKSByZXR1cm4gJ0xveWFsdHkgUHJvZ3JhbSBQb2xpY3knO1xuICAgIHJldHVybiAnVXAgdG8gMTUgYnVzaW5lc3MgZGF5cywgYmFuayBwb2xpY3knO1xuICB9KTtcblxuICAvKipcbiAgICogUGVyLW1ldGhvZCBicmVha2Rvd24gb2YgdGhlIFwiVG90YWwgcGFpZFwiIGFtb3VudC4gVGhlIGJhY2tlbmQgZG9lc24ndFxuICAgKiAoeWV0KSBleHBvc2UgYSBkZWRpY2F0ZWQgb3JpZ2luYWwtcGF5bWVudCBicmVha2Rvd24sIHNvIHRoZSBrbm93blxuICAgKiByZWZ1bmQtZGVzdGluYXRpb24gZmllbGRzIChjYXJkIC8gd2FsbGV0IC8gbG95YWx0eSkgYXJlIHVzZWQgYXMgYSBwcm94eVxuICAgKiBmb3IgaG93IHRoZSBib29raW5nIHdhcyBvcmlnaW5hbGx5IHBhaWQsIGFuZCB3aGF0ZXZlcidzIGxlZnQgb3ZlciBhZnRlclxuICAgKiB0aG9zZSAoZS5nLiBhIG5vbi1yZWZ1bmRhYmxlIGxlZy9mZWUgdGhhdCBuZXZlciBzaG93cyB1cCBpbiBhbnkgcmVmdW5kXG4gICAqIGZpZWxkKSBpcyBmb2xkZWQgaW50byB0aGUgcHJpbWFyeSBwYXltZW50IG1ldGhvZCDigJQgc28gdGhlIHJvd3MgYWx3YXlzXG4gICAqIGFkZCB1cCB0byB0aGUgZnVsbCBgb3JpZ2luYWxBbW91bnRgIHNob3duIGFib3ZlIHRoZW0sIGluc3RlYWQgb2Ygb25seVxuICAgKiBjb3ZlcmluZyB0aGUgcmVmdW5kYWJsZSBwb3J0aW9uLlxuICAgKi9cbiAgcGFpZEJyZWFrZG93blJvd3MgPSBjb21wdXRlZCgoKTogeyBsYWJlbDogc3RyaW5nOyB2YWx1ZTogbnVtYmVyIH1bXSA9PiB7XG4gICAgY29uc3QgZCA9IHRoaXMuYWRqdXN0ZWREYXRhKCk7XG4gICAgaWYgKCFkKSByZXR1cm4gW107XG4gICAgLy8gQ2FyZCBhbmQgbG95YWx0eSBzdGF5IGRpc3RpbmN0IGxhYmVscyAoc2FtZSBjYXRlZ29yaXphdGlvbiBhc1xuICAgIC8vIGByZWZ1bmRzYCkgc28gYSBnYXRld2F5IGxpa2UgQWwgUmFqaGkgTW9rYWZhYSBkb2Vzbid0IHN3YWxsb3cgYW5cbiAgICAvLyBhY3R1YWwgc2VwYXJhdGUgY2FyZCBwb3J0aW9uIHVuZGVyIG9uZSBsYWJlbC5cbiAgICBjb25zdCBjYXJkTGFiZWwgPVxuICAgICAgKCF0aGlzLmlzTG95YWx0eU1ldGhvZCgpICYmIHRoaXMuY3VzdG9tZXJQYXltZW50TGFiZWwoKSkgfHwgJ09yaWdpbmFsIFBheW1lbnQgTWV0aG9kJztcbiAgICAvLyBUaGUgd2FsbGV0IGRlc3RpbmF0aW9uIHJvdyBhbHdheXMgcmVhZHMgXCJBbG1hdGFyIFdhbGxldFwiIOKAlCB1bmxpa2VcbiAgICAvLyBgcmVmdW5kc2AvYGNvbmZpcm1SZWZ1bmRzYCwgdGhpcyByb3cgbmV2ZXIgc3dhcHMgdG8gdGhlIGxveWFsdHlcbiAgICAvLyBwcm9ncmFtIG5hbWUsIHNpbmNlIGBmb3JmZWl0ZWRMb3lhbHR5TGFiZWxgIGJlbG93IGlzIHRoYXQgcHJvZ3JhbSdzXG4gICAgLy8gb3duIGRlZGljYXRlZCByb3cgYW5kIHRoZSB0d28gbXVzdCBzdGF5IHZpc3VhbGx5IGRpc3RpbmN0IGhlcmUuXG4gICAgY29uc3Qgd2FsbGV0TGFiZWwgPSAnQWxtYXRhciBXYWxsZXQnO1xuICAgIGNvbnN0IGZvcmZlaXRlZExveWFsdHlMYWJlbCA9IHRoaXMud2FsbGV0T3JMb3lhbHR5TGFiZWwoZCkgfHwgJ0xveWFsdHkgUG9pbnRzJztcbiAgICBjb25zdCBsb3lhbHR5TGFiZWwgPSB0aGlzLmN1c3RvbWVyUGF5bWVudExhYmVsKCkgfHwgJ0xveWFsdHkgUG9pbnRzIFJlZnVuZCc7XG4gICAgY29uc3QgYW1vdW50cyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gICAgY29uc3QgYWRkID0gKGxhYmVsOiBzdHJpbmcsIHZhbHVlOiBudW1iZXIpID0+IHtcbiAgICAgIGlmICh2YWx1ZSA8PSAwKSByZXR1cm47XG4gICAgICBhbW91bnRzLnNldChsYWJlbCwgKGFtb3VudHMuZ2V0KGxhYmVsKSA/PyAwKSArIHZhbHVlKTtcbiAgICB9O1xuICAgIGFkZChjYXJkTGFiZWwsIE51bWJlcihkLnRvdGFsQ2FyZFJlZnVuZEFtb3VudCA/PyAwKSk7XG4gICAgLy8gVGhpcyByb3cgc2hvd3MgaG93IG11Y2ggb2YgdGhlICpvcmlnaW5hbCogcGF5bWVudCB3ZW50IHRocm91Z2ggdGhlXG4gICAgLy8gd2FsbGV0IOKAlCBgdG90YWxXYWxsZXRBbW91bnRgLCBub3QgYHdhbGxldFJlZnVuZEFtb3VudGAgKGEgcmVmdW5kXG4gICAgLy8gZGVzdGluYXRpb24gYW1vdW50IHRoYXQgY2FuIGRpZmZlciwgZS5nLiBvbmx5IHBhcnQgb2YgdGhlIHdhbGxldFxuICAgIC8vIHBheW1lbnQgaXMgcmVmdW5kYWJsZSBhZnRlciBkZWR1Y3Rpb25zKS5cbiAgICBhZGQod2FsbGV0TGFiZWwsIE51bWJlcihkLnRvdGFsV2FsbGV0QW1vdW50ID8/IDApKTtcbiAgICBhZGQobG95YWx0eUxhYmVsLCBOdW1iZXIoZC50b3RhbExveWFsdHlQb2ludHNSZWZ1bmRBbW91bnQgPz8gMCkpO1xuICAgIC8vIGB0b3RhbExveWFsdHlQb2ludHNgIGlzIHRoZSBwb3J0aW9uIG9mIHRoZSAqb3JpZ2luYWwqIHBheW1lbnQgbWFkZSB3aXRoXG4gICAgLy8gbG95YWx0eSBwb2ludHMgKG5vdyBmb3JmZWl0ZWQvZGVkdWN0ZWQsIG5vdCByZWZ1bmRlZCkg4oCUIGRpc3RpbmN0IGZyb21cbiAgICAvLyBgdG90YWxMb3lhbHR5UG9pbnRzUmVmdW5kQW1vdW50YCBhYm92ZSBhbmQgZnJvbSBgd2FsbGV0UmVmdW5kQW1vdW50YFxuICAgIC8vIChhbiB1bnJlbGF0ZWQgcmVmdW5kLWRlc3RpbmF0aW9uIGFtb3VudCkuIEFsd2F5cyBzaG93biBhcyBpdHMgb3duIHJvd1xuICAgIC8vIHVuZGVyIHRoZSBwcm9ncmFtIG5hbWUgKGUuZy4gXCJRaXRhZlwiL1wiV2FsYVwiKSByYXRoZXIgdGhhbiBtZXJnZWQgaW50b1xuICAgIC8vIHRoZSBnZW5lcmljIFdhbGxldCByb3cgb3Igc2lsZW50bHkgZm9sZGVkIGludG8gdGhlIGxlZnRvdmVyIHJlbWFpbmRlci5cbiAgICBhZGQoZm9yZmVpdGVkTG95YWx0eUxhYmVsLCBOdW1iZXIoZC50b3RhbExveWFsdHlQb2ludHMgPz8gMCkpO1xuXG4gICAgY29uc3QgdG90YWwgPSBOdW1iZXIoZC5vcmlnaW5hbEFtb3VudCA/PyAwKTtcbiAgICBjb25zdCBrbm93biA9IFsuLi5hbW91bnRzLnZhbHVlcygpXS5yZWR1Y2UoKGEsIGIpID0+IGEgKyBiLCAwKTtcbiAgICBjb25zdCByZW1haW5kZXIgPSB0b3RhbCAtIGtub3duO1xuICAgIGlmIChyZW1haW5kZXIgPiAwLjAxKSB7XG4gICAgICAvLyBVbmFjY291bnRlZCBsZWZ0b3ZlciAoZS5nLiBhIG5vbi1yZWZ1bmRhYmxlIHBvcnRpb24pIGlzIGZvbGRlZCBpbnRvXG4gICAgICAvLyB0aGUgcHJpbWFyeS9kZWZhdWx0IHBheW1lbnQgY2hhbm5lbCByYXRoZXIgdGhhbiBhIGZhYnJpY2F0ZWQgNHRoIHJvdy5cbiAgICAgIGFkZChjYXJkTGFiZWwsIHJlbWFpbmRlcik7XG4gICAgfVxuICAgIHJldHVybiBbLi4uYW1vdW50cy5lbnRyaWVzKCldLm1hcCgoW2xhYmVsLCB2YWx1ZV0pID0+ICh7IGxhYmVsLCB2YWx1ZSB9KSk7XG4gIH0pO1xuXG4gIC8qKiBUaGUgXCJUb3RhbCBwYWlkXCIgcm93IGFsd2F5cyBleHBhbmRzIOKAlCB0aGVyZSdzIGFsd2F5cyBhdCBsZWFzdCBvbmUgbWV0aG9kIHRvIHNob3cuICovXG4gIGhhc1BhaWRCcmVha2Rvd24gPSBjb21wdXRlZCgoKSA9PiB0aGlzLnBhaWRCcmVha2Rvd25Sb3dzKCkubGVuZ3RoID4gMCk7XG5cbiAgdG9nZ2xlUGFpZFN1bW1hcnkoKSB7XG4gICAgdGhpcy5wYWlkU3VtbWFyeUV4cGFuZGVkLnNldCghdGhpcy5wYWlkU3VtbWFyeUV4cGFuZGVkKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYWNrZW5kIGhhcyBzZW50IGBwYXltZW50TWV0aG9kQ3VzdG9tZXJVc2VkYCBhcyBib3RoIGEgc2hvcnQgY29kZVxuICAgKiAoYFwiQ0hcImApIGFuZCBhIGZ1bGwgZ2F0ZXdheSBuYW1lIChgXCJDYXJkXCJgKSBhdCBkaWZmZXJlbnQgdGltZXMg4oCUIG1hdGNoXG4gICAqIGVpdGhlciwgY2FzZS1pbnNlbnNpdGl2ZWx5LCBhZ2FpbnN0IHRoZSBrbm93biBjb2Rlcy9sYWJlbHMgcmF0aGVyIHRoYW5cbiAgICogYXNzdW1pbmcgb25lIGZvcm1hdC5cbiAgICovXG4gIHByaXZhdGUgbm9ybWFsaXplR2F0ZXdheUNvZGUocmF3Pzogc3RyaW5nIHwgbnVsbCk6IHN0cmluZyB7XG4gICAgaWYgKCFyYXcpIHJldHVybiAnJztcbiAgICBjb25zdCBuZWVkbGUgPSByYXcudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG4gICAgY29uc3QgY29kZXMgPSBPYmplY3Qua2V5cyhQQVlNRU5UX0dBVEVXQVlfTEFCRUxTKTtcbiAgICBjb25zdCBieUNvZGUgPSBjb2Rlcy5maW5kKChjb2RlKSA9PiBjb2RlLnRvTG93ZXJDYXNlKCkgPT09IG5lZWRsZSk7XG4gICAgaWYgKGJ5Q29kZSkgcmV0dXJuIGJ5Q29kZTtcbiAgICByZXR1cm4gY29kZXMuZmluZCgoY29kZSkgPT4gUEFZTUVOVF9HQVRFV0FZX0xBQkVMU1tjb2RlXS50b0xvd2VyQ2FzZSgpID09PSBuZWVkbGUpID8/ICcnO1xuICB9XG5cbiAgLyoqXG4gICAqIERpc3BsYXkgbGFiZWwgZm9yIGBwYXltZW50TWV0aG9kQ3VzdG9tZXJVc2VkYCwgb3IgJycgaWYgdW5rbm93bi9pbnRlcm5hbC5cbiAgICogTmV2ZXIgc3VyZmFjZXMgYW4gaW50ZXJuYWwgcHJvY2Vzc29yIG5hbWUgKGUuZy4gSHlwZXJwYXkpIHRvIHRoZSBhZ2VudCDigJRcbiAgICogY2FsbGVycyBmYWxsIGJhY2sgdG8gYSBnZW5lcmljIFwiT3JpZ2luYWwgUGF5bWVudCBNZXRob2RcIiBsYWJlbCB3aGVuZXZlclxuICAgKiB0aGlzIHJldHVybnMgJycuXG4gICAqL1xuICBjdXN0b21lclBheW1lbnRMYWJlbCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBjb2RlID0gdGhpcy5ub3JtYWxpemVHYXRld2F5Q29kZSh0aGlzLmFkanVzdGVkRGF0YSgpPy5wYXltZW50TWV0aG9kQ3VzdG9tZXJVc2VkKTtcbiAgICBpZiAoY29kZSAmJiBJTlRFUk5BTF9HQVRFV0FZX0NPREVTLmluY2x1ZGVzKGNvZGUpKSByZXR1cm4gJyc7XG4gICAgcmV0dXJuIGNvZGUgPyBQQVlNRU5UX0dBVEVXQVlfTEFCRUxTW2NvZGVdIDogJyc7XG4gIH0pO1xuXG4gIC8qKiBXaGV0aGVyIHRoZSBjb25maXJtZWQgY2FuY2VsbGF0aW9uJ3MgY2FyZCByZWZ1bmQgc2V0dGxlcyB2aWEgTWFkYS4gKi9cbiAgaXNNYWRhTWV0aG9kID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGNvZGUgPSB0aGlzLm5vcm1hbGl6ZUdhdGV3YXlDb2RlKHRoaXMuYWRqdXN0ZWREYXRhKCk/LnBheW1lbnRNZXRob2RDdXN0b21lclVzZWQpO1xuICAgIHJldHVybiAhIWNvZGUgJiYgTUFEQV9HQVRFV0FZX0NPREVTLmluY2x1ZGVzKGNvZGUpO1xuICB9KTtcblxuICAvKipcbiAgICogTGFiZWwgZm9yIHRoZSBzdGFuZGFsb25lIFwiT3JpZ2luYWwgUGF5bWVudCBNZXRob2RcIiBvcHRpb24gY2FyZCAoc2hvd25cbiAgICogd2hlbiB0aGUgd2hvbGUgcmVmdW5kIGdvZXMgdG8gb25lIGRlc3RpbmF0aW9uKS4gTWFkYSB3aW5zIG92ZXJcbiAgICogZXZlcnl0aGluZyBlbHNlLCByZWFkaW5nIFwiTWFkYSBDYXJkXCIgaW5zdGVhZCBvZiB0aGUgZ2VuZXJpYyBnYXRld2F5XG4gICAqIG5hbWUgb3IgdGhlIFwiT3JpZ2luYWwgUGF5bWVudCBNZXRob2RcIiBmYWxsYmFjay5cbiAgICovXG4gIG9yaWdpbmFsUGF5bWVudExhYmVsID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGlmICh0aGlzLmlzTWFkYU1ldGhvZCgpKSByZXR1cm4gJ01hZGEgQ2FyZCc7XG4gICAgcmV0dXJuIHRoaXMuY3VzdG9tZXJQYXltZW50TGFiZWwoKSB8fCAnT3JpZ2luYWwgUGF5bWVudCBNZXRob2QnO1xuICB9KTtcblxuICAvKiogU2FtZSBhcyBgaXNNYWRhTWV0aG9kYCwgc2NvcGVkIHRvIHRoZSBjb25maXJtZWQgY2FuY2VsbGF0aW9uIHJlc3VsdC4gKi9cbiAgY29uZmlybUlzTWFkYU1ldGhvZCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBjb2RlID0gdGhpcy5ub3JtYWxpemVHYXRld2F5Q29kZSh0aGlzLmNhbmNlbFJlc3VsdCgpPy5wYXltZW50TWV0aG9kQ3VzdG9tZXJVc2VkKTtcbiAgICByZXR1cm4gISFjb2RlICYmIE1BREFfR0FURVdBWV9DT0RFUy5pbmNsdWRlcyhjb2RlKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqIFNwbGl0LXJlZnVuZCBkZXN0aW5hdGlvbiByb3dzIOKAlCB1cCB0byBmb3VyOiBBbG1hdGFyIFdhbGxldCAoZ2VuZXJpY1xuICAgKiBsYWJlbCksIHRoZSBvcmlnaW5hbCBwYXltZW50IG1ldGhvZCAoY2FyZC9pbnN0YWxsbWVudCBnYXRld2F5KSwgYVxuICAgKiBzZXBhcmF0ZSBsb3lhbHR5LXBvaW50cy1yZWZ1bmQgcm93IHdoZW4gdGhlIGJhY2tlbmQgc2VuZHMgb25lLCBhbmQgYVxuICAgKiBkZWRpY2F0ZWQgbG95YWx0eS1wcm9ncmFtIHJvdyAoV2FsYSwgUWl0YWYsIOKApikgZm9yIGZvcmZlaXRlZCBwb2ludHNcbiAgICogKGBmb3JmZWl0ZWRMb3lhbHR5UG9pbnRzRmFsbGJhY2tgKSDigJQga2VwdCBkaXN0aW5jdCBmcm9tIHRoZSBXYWxsZXQgcm93XG4gICAqIGV2ZW4gd2hlbiBib3RoIGFyZSBub24temVyby5cbiAgICovXG4gIHNwbGl0UmVmdW5kUm93cyA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBkID0gdGhpcy5hZGp1c3RlZERhdGEoKTtcbiAgICBpZiAoIWQpIHJldHVybiBbXTtcbiAgICBjb25zdCByb3dzOiB7IGxhYmVsOiBzdHJpbmc7IHZhbHVlOiBudW1iZXI7IGluc3RhbnQ6IGJvb2xlYW47IGlzTG95YWx0eTogYm9vbGVhbjsgYmFkZ2VUZXh0OiBzdHJpbmc7IGlzTWFkYT86IGJvb2xlYW4gfVtdID0gW107XG4gICAgY29uc3Qgd2FsbGV0ID0gTnVtYmVyKGQud2FsbGV0UmVmdW5kQW1vdW50ID8/IDApO1xuICAgIGlmICh3YWxsZXQgPiAwKSB7XG4gICAgICByb3dzLnB1c2goeyBsYWJlbDogJ0FsbWF0YXIgV2FsbGV0JywgdmFsdWU6IHdhbGxldCwgaW5zdGFudDogdHJ1ZSwgaXNMb3lhbHR5OiBmYWxzZSwgYmFkZ2VUZXh0OiAnSW5zdGFudCcgfSk7XG4gICAgfVxuICAgIGNvbnN0IGNhcmQgPSBOdW1iZXIoZC50b3RhbENhcmRSZWZ1bmRBbW91bnQgPz8gMCk7XG4gICAgaWYgKGNhcmQgPiAwKSB7XG4gICAgICBjb25zdCBiYWRnZVRleHQgPSB0aGlzLmNhcmRCYWRnZVRleHQoKTtcbiAgICAgIHJvd3MucHVzaCh7XG4gICAgICAgIGxhYmVsOiB0aGlzLmlzTWFkYU1ldGhvZCgpXG4gICAgICAgICAgPyAnTWFkYSBDYXJkJ1xuICAgICAgICAgIDogKCF0aGlzLmlzTG95YWx0eU1ldGhvZCgpICYmIHRoaXMuY3VzdG9tZXJQYXltZW50TGFiZWwoKSkgfHwgJ09yaWdpbmFsIFBheW1lbnQgTWV0aG9kJyxcbiAgICAgICAgdmFsdWU6IGNhcmQsXG4gICAgICAgIGluc3RhbnQ6IGZhbHNlLFxuICAgICAgICBpc0xveWFsdHk6IGZhbHNlLFxuICAgICAgICBiYWRnZVRleHQsXG4gICAgICAgIGlzTWFkYTogdGhpcy5pc01hZGFNZXRob2QoKSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBjb25zdCBsb3lhbHR5ID0gTnVtYmVyKGQudG90YWxMb3lhbHR5UG9pbnRzUmVmdW5kQW1vdW50ID8/IDApO1xuICAgIGlmIChsb3lhbHR5ID4gMCkge1xuICAgICAgcm93cy5wdXNoKHtcbiAgICAgICAgbGFiZWw6IHRoaXMuY3VzdG9tZXJQYXltZW50TGFiZWwoKSB8fCAnTG95YWx0eSBQb2ludHMgUmVmdW5kJyxcbiAgICAgICAgdmFsdWU6IGxveWFsdHksXG4gICAgICAgIGluc3RhbnQ6IHRydWUsXG4gICAgICAgIGlzTG95YWx0eTogdHJ1ZSxcbiAgICAgICAgYmFkZ2VUZXh0OiAnSW5zdGFudCcsXG4gICAgICB9KTtcbiAgICB9XG4gICAgY29uc3QgZm9yZmVpdGVkTG95YWx0eSA9IHRoaXMuZm9yZmVpdGVkTG95YWx0eVBvaW50c0ZhbGxiYWNrKGQpO1xuICAgIGlmIChmb3JmZWl0ZWRMb3lhbHR5ID4gMCkge1xuICAgICAgcm93cy5wdXNoKHtcbiAgICAgICAgbGFiZWw6IHRoaXMud2FsbGV0T3JMb3lhbHR5TGFiZWwoZCkgfHwgJ0xveWFsdHkgUG9pbnRzJyxcbiAgICAgICAgdmFsdWU6IGZvcmZlaXRlZExveWFsdHksXG4gICAgICAgIGluc3RhbnQ6IHRydWUsXG4gICAgICAgIGlzTG95YWx0eTogdHJ1ZSxcbiAgICAgICAgYmFkZ2VUZXh0OiAnSW5zdGFudCcsXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHJvd3M7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBXYWxsZXQtcm93IGxhYmVsIGZvciBhIGxveWFsdHktcHJvZ3JhbSByZWRlbXB0aW9uIOKAlCBgbG95YWx0eVBheW1lbnRUeXBlYFxuICAgKiAoZS5nLiBXYWxhLCBRaXRhZikgbmFtZXMgdGhlIHByb2dyYW0gdGhhdCByZWRlZW1lZCBpbnRvIHRoZSB3YWxsZXRcbiAgICogYmFsYW5jZSBhbmQgYXBwbGllcyByZWdhcmRsZXNzIG9mIGBwYXltZW50TWV0aG9kQ3VzdG9tZXJVc2VkYDsgdGhlXG4gICAqIGJhY2tlbmQgY2FuIHJlcG9ydCBhbiB1bnJlbGF0ZWQgb3JpZ2luYWwgcGF5bWVudCBnYXRld2F5IChlLmcuIFRhYmJ5KVxuICAgKiBhbG9uZ3NpZGUgYSB3YWxsZXQgcG9ydGlvbiB0aGF0J3MgYWN0dWFsbHkgYSBsb3lhbHR5IHJlZGVtcHRpb24uXG4gICAqL1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICB3YWxsZXRPckxveWFsdHlMYWJlbChkOiBhbnkpOiBzdHJpbmcge1xuICAgIGNvbnN0IGxveWFsdHkgPSBkPy5sb3lhbHR5UGF5bWVudFR5cGUgPz8gJyc7XG4gICAgcmV0dXJuIFBBWU1FTlRfR0FURVdBWV9MQUJFTFNbbG95YWx0eV0gPz8gJyc7XG4gIH1cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBlZmZlY3QoKCkgPT4ge1xuICAgICAgaWYgKHRoaXMudmlzaWJsZSgpICYmIHRoaXMuYm9va2luZ0lkKCkpIHtcbiAgICAgICAgdGhpcy5sb2FkUmVmdW5kKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnN0b3BIaW50cygpO1xuICAgICAgICB0aGlzLnJlZnVuZERhdGEuc2V0KG51bGwpO1xuICAgICAgICB0aGlzLmNhbmNlbFJlc3VsdC5zZXQobnVsbCk7XG4gICAgICAgIHRoaXMub253YXJkQ2hlY2tlZC5zZXQodHJ1ZSk7XG4gICAgICAgIHRoaXMucmV0dXJuQ2hlY2tlZC5zZXQodHJ1ZSk7XG4gICAgICAgIHRoaXMuZm9yY2VkTGVnVHlwZS5zZXQobnVsbCk7XG4gICAgICAgIHRoaXMub253YXJkRXhwYW5kZWQuc2V0KHRydWUpO1xuICAgICAgICB0aGlzLnJldHVybkV4cGFuZGVkLnNldCh0cnVlKTtcbiAgICAgICAgdGhpcy5zZWxlY3RlZFNvdXJjZS5zZXQoJycpO1xuICAgICAgICB0aGlzLnByZWZlcnJlZFJlZnVuZE1ldGhvZC5zZXQoJ29yaWdpbmFsUGF5bWVudE1ldGhvZCcpO1xuICAgICAgICB0aGlzLmNvbmZpcm1pbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgdGhpcy5jYW5jZWxsaW5nLnNldChmYWxzZSk7XG4gICAgICAgIHRoaXMuc3RlcC5zZXQoJ2xvYWRpbmcnKTtcbiAgICAgIH1cbiAgICB9LCB7IGFsbG93U2lnbmFsV3JpdGVzOiB0cnVlIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBsb2FkUmVmdW5kKCk6IHZvaWQge1xuICAgIHRoaXMubG9hZGluZy5zZXQodHJ1ZSk7XG4gICAgdGhpcy5zdGFydEhpbnRzKCk7XG4gICAgdGhpcy5ib29raW5nU2VydmljZS5nZXRSZWZ1bmREZXRhaWxzKHRoaXMuYm9va2luZ0lkKCksIHRoaXMucHJvZHVjdCgpKS5zdWJzY3JpYmUoe1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgIG5leHQ6IChyYXc6IGFueSkgPT4ge1xuICAgICAgICBsZXQgZGF0YSA9IHJhdz8uZGF0YSA/PyByYXc7XG5cbiAgICAgICAgdGhpcy5zdG9wSGludHMoKTtcbiAgICAgICAgdGhpcy5yZWZ1bmREYXRhLnNldChkYXRhKTtcbiAgICAgICAgLy8gQXV0by1zZWxlY3Qgc291cmNlOiBwcmVmZXIgYXBwbGllZFNvdXJjZSwgb3RoZXJ3aXNlIHBpY2sgZmlyc3QgYXZhaWxhYmxlXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgIGNvbnN0IGJyZWFrZG93bjogUmVjb3JkPHN0cmluZywgYW55PiA9IGRhdGE/LnNvdXJjZUJyZWFrZG93biA/PyB7fTtcbiAgICAgICAgY29uc3Qgc291cmNlcyA9IE9iamVjdC5rZXlzKGJyZWFrZG93bik7XG4gICAgICAgIGlmIChzb3VyY2VzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBjb25zdCBhcHBsaWVkID0gZGF0YT8uYXBwbGllZFNvdXJjZTtcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkU291cmNlLnNldChhcHBsaWVkICYmIGJyZWFrZG93blthcHBsaWVkXSA/IGFwcGxpZWQgOiBzb3VyY2VzWzBdKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgLy8gT25seSBzaG93IHRoZSBsZWcgcGlja2VyIGZvciBhIGdlbnVpbmUgcm91bmQtdHJpcCB0aGUgYmFja2VuZCBoYXNuJ3RcbiAgICAgICAgLy8gYWxyZWFkeSByZXN0cmljdGVkIHRvIGEgc2luZ2xlIGxlZyDigJQgb3RoZXJ3aXNlIGdvIHN0cmFpZ2h0IHRvIGRldGFpbHMuXG4gICAgICAgIGlmICh0aGlzLnNob3dSb3VuZFRyaXBMZWdDYXJkcygpKSB7XG4gICAgICAgICAgLy8gUHJlLWNoZWNrIHdoaWNoZXZlciBsZWdzIGFyZSBhY3R1YWxseSByZWZ1bmRhYmxlLCBtYXRjaGluZyB0aGVcbiAgICAgICAgICAvLyBjb25zdW1lciBhcHAncyBcIm5vbi1yZWZ1bmRhYmxlIGxlZ3MgY2FuJ3QgYmUgc2VsZWN0ZWRcIiBiZWhhdmlvci5cbiAgICAgICAgICB0aGlzLm9ud2FyZENoZWNrZWQuc2V0KHRoaXMub253YXJkUmVmdW5kYWJsZSgpKTtcbiAgICAgICAgICB0aGlzLnJldHVybkNoZWNrZWQuc2V0KHRoaXMucmV0dXJuUmVmdW5kYWJsZSgpKTtcbiAgICAgICAgICB0aGlzLnN0ZXAuc2V0KCdzZWxlY3QtbGVnJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5zdGVwLnNldCgnZGV0YWlscycpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZXJyb3I6ICgpID0+IHsgdGhpcy5zdG9wSGludHMoKTsgdGhpcy5sb2FkaW5nLnNldChmYWxzZSk7IHRoaXMudG9hc3QuZXJyb3IoJ0NvdWxkIG5vdCBsb2FkIHJlZnVuZCBkZXRhaWxzLicpOyB9LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEJvdGggbGVncyBpbiBwbGF5IOKAlCBzdW0gZWFjaCBsZWcncyBvd24gZmlndXJlcyBpbnN0ZWFkIG9mIHRydXN0aW5nIHJvb3RcbiAgICogKHJvb3QgaXNuJ3QgcmVsaWFibHkgc2NvcGVkIHRvIHRoZSBwaWNrZWQgYWx0ZXJuYXRpdmVzLCBlLmcuIHJvdW5kaW5nXG4gICAqIGNhbiBkcmlmdCBiZXR3ZWVuIGxlZyB0b3RhbHMgYW5kIHRoZSBjb21iaW5lZCByb290IHRvdGFsKS5cbiAgICovXG4gIHByaXZhdGUgYnVpbGRDb21iaW5lZExlZ0RhdGEocm9vdDogUmVmdW5kRGF0YSwgb253YXJkOiBMZWdEZXRhaWxzLCByZXQ6IExlZ0RldGFpbHMpOiBSZWZ1bmREYXRhIHtcbiAgICBjb25zdCBvbndhcmREYXRhID0gdGhpcy5idWlsZExlZ0RhdGEocm9vdCwgb253YXJkLCAnb253YXJkJyk7XG4gICAgY29uc3QgcmV0dXJuRGF0YSA9IHRoaXMuYnVpbGRMZWdEYXRhKHJvb3QsIHJldCwgJ3JldHVybicpO1xuICAgIGNvbnN0IHN1bSA9IChrZXk6IHN0cmluZykgPT4gTnVtYmVyKG9ud2FyZERhdGFba2V5XSB8fCAwKSArIE51bWJlcihyZXR1cm5EYXRhW2tleV0gfHwgMCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnJvb3QsXG4gICAgICBpc1JlZnVuZGFibGU6ICAgICAgICAgICAgICAgICAgICBvbndhcmQuaXNSZWZ1bmRhYmxlID09PSB0cnVlICYmIHJldC5pc1JlZnVuZGFibGUgPT09IHRydWUsXG4gICAgICB0b3RhbFJlZnVuZEFtb3VudDogICAgICAgICAgICAgICBzdW0oJ3RvdGFsUmVmdW5kQW1vdW50JyksXG4gICAgICB0b3RhbFJlZnVuZEFtb3VudEJlZm9yZUNlaWw6ICAgICBzdW0oJ3RvdGFsUmVmdW5kQW1vdW50QmVmb3JlQ2VpbCcpLFxuICAgICAgdG90YWxDYXJkUmVmdW5kQW1vdW50OiAgICAgICAgICAgc3VtKCd0b3RhbENhcmRSZWZ1bmRBbW91bnQnKSxcbiAgICAgIHRvdGFsQ3JlZGl0UmVmdW5kQW1vdW50OiAgICAgICAgIHN1bSgndG90YWxDcmVkaXRSZWZ1bmRBbW91bnQnKSxcbiAgICAgIHRvdGFsTm9uUmVmdW5kYWJsZVNlcnZpY2VDaGFyZ2U6IHN1bSgndG90YWxOb25SZWZ1bmRhYmxlU2VydmljZUNoYXJnZScpLFxuICAgICAgdG90YWxDb3Vwb25BbW91bnQ6ICAgICAgICAgICAgICAgc3VtKCd0b3RhbENvdXBvbkFtb3VudCcpLFxuICAgICAgd2FsbGV0UmVmdW5kQW1vdW50OiAgICAgICAgICAgICAgc3VtKCd3YWxsZXRSZWZ1bmRBbW91bnQnKSxcbiAgICAgIHRvdGFsUGVuYWx0eVBvaW50czogICAgICAgICAgICAgIHN1bSgndG90YWxQZW5hbHR5UG9pbnRzJyksXG4gICAgICB0b3RhbFN1cHBsaWVyUGVuYWx0eVBvaW50czogICAgICBzdW0oJ3RvdGFsU3VwcGxpZXJQZW5hbHR5UG9pbnRzJyksXG4gICAgICB0b3RhbExveWFsdHlQb2ludHM6ICAgICAgICAgICAgICBzdW0oJ3RvdGFsTG95YWx0eVBvaW50cycpLFxuICAgICAgdG90YWxHaWZ0QW1vdW50OiAgICAgICAgICAgICAgICAgc3VtKCd0b3RhbEdpZnRBbW91bnQnKSxcbiAgICAgIHRvdGFsQW5jaWxsYXJ5UmVmdW5kQW1vdW50OiAgICAgIHN1bSgndG90YWxBbmNpbGxhcnlSZWZ1bmRBbW91bnQnKSxcbiAgICAgIHRvdGFsTG95YWx0eVBvaW50c1JlZnVuZEFtb3VudDogIHN1bSgndG90YWxMb3lhbHR5UG9pbnRzUmVmdW5kQW1vdW50JyksXG4gICAgICB0b3RhbENhbmNlbGxhdGlvbkZlZTogICAgICAgICAgICBzdW0oJ3RvdGFsQ2FuY2VsbGF0aW9uRmVlJyksXG4gICAgICB0b3RhbFN1cHBsaWVyQm9va2luZ0Ftb3VudDogICAgICBzdW0oJ3RvdGFsU3VwcGxpZXJCb29raW5nQW1vdW50JyksXG4gICAgICBvcmlnaW5hbEFtb3VudDogICAgICAgICAgICAgICAgICBOdW1iZXIocm9vdC5vcmlnaW5hbEFtb3VudCB8fCAwKSxcbiAgICAgIHJlZnVuZEJyZWFrZG93bjogdGhpcy5tZXJnZUJyZWFrZG93bnMob253YXJkRGF0YS5yZWZ1bmRCcmVha2Rvd24sIHJldHVybkRhdGEucmVmdW5kQnJlYWtkb3duKSxcbiAgICAgIGxlZ0luZm86IHsgb253YXJkLCByZXR1cm46IHJldCB9LFxuICAgIH07XG4gIH1cblxuICAvKiogQ29tYmluZSB0d28gbGVncycgaXRlbWl6ZWQgYnJlYWtkb3ducyBmb3IgdGhlIFwiYm90aCBsZWdzXCIgY29tYmluZWQgdmlldy4gKi9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgcHJpdmF0ZSBtZXJnZUJyZWFrZG93bnMoYTogYW55LCBiOiBhbnkpOiBhbnkge1xuICAgIGlmICghYSAmJiAhYikgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIGNvbnN0IG1lcmdlU2lkZSA9IChzYTogYW55LCBzYjogYW55KSA9PiAoe1xuICAgICAgZmFyZTogTnVtYmVyKHNhPy5mYXJlIHx8IDApICsgTnVtYmVyKHNiPy5mYXJlIHx8IDApIHx8IHVuZGVmaW5lZCxcbiAgICAgIGFkZE9uczogWy4uLihzYT8uYWRkT25zID8/IFtdKSwgLi4uKHNiPy5hZGRPbnMgPz8gW10pXSxcbiAgICAgIGFuY2lsbGFyaWVzOiBbLi4uKHNhPy5hbmNpbGxhcmllcyA/PyBbXSksIC4uLihzYj8uYW5jaWxsYXJpZXMgPz8gW10pXSxcbiAgICAgIHNlcnZpY2VGZWU6IE51bWJlcihzYT8uc2VydmljZUZlZSB8fCAwKSArIE51bWJlcihzYj8uc2VydmljZUZlZSB8fCAwKSB8fCB1bmRlZmluZWQsXG4gICAgICBoYW5kbGluZ0ZlZTogTnVtYmVyKHNhPy5oYW5kbGluZ0ZlZSB8fCAwKSArIE51bWJlcihzYj8uaGFuZGxpbmdGZWUgfHwgMCkgfHwgdW5kZWZpbmVkLFxuICAgICAgY2FuY2VsbGF0aW9uUGVuYWx0eTpcbiAgICAgICAgTnVtYmVyKHNhPy5jYW5jZWxsYXRpb25QZW5hbHR5IHx8IDApICsgTnVtYmVyKHNiPy5jYW5jZWxsYXRpb25QZW5hbHR5IHx8IDApIHx8IHVuZGVmaW5lZCxcbiAgICB9KTtcbiAgICByZXR1cm4ge1xuICAgICAgcmVmdW5kYWJsZTogbWVyZ2VTaWRlKGE/LnJlZnVuZGFibGUsIGI/LnJlZnVuZGFibGUpLFxuICAgICAgbm9uUmVmdW5kYWJsZTogbWVyZ2VTaWRlKGE/Lm5vblJlZnVuZGFibGUsIGI/Lm5vblJlZnVuZGFibGUpLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkTGVnRGF0YShyb290OiBSZWZ1bmREYXRhLCBsZWc6IExlZ0RldGFpbHMsIGxlZ1R5cGU6ICdvbndhcmQnIHwgJ3JldHVybicpOiBSZWZ1bmREYXRhIHtcbiAgICAvLyBXaGVuIHRoaXMgbGVnIGhhcyBubyBzaWJsaW5nIGluIGBsZWdJbmZvYCAoYSBnZW51aW5lIG9uZS13YXkgYm9va2luZyxcbiAgICAvLyBvciBhIG5hcnJvd2VkIENyb3NzU2VsbGVyIHNlbGVjdGlvbiB3aGVyZSB0aGUgQVBJIG9ubHkgZXZlciBzZW50IHRoZVxuICAgIC8vIG9uZSBsZWcpLCByb290IG5lY2Vzc2FyaWx5IGRlc2NyaWJlcyB0aGlzIHNhbWUgc2luZ2xlIGxlZyDigJQgc28gYVxuICAgIC8vIGRlc3RpbmF0aW9uIHRvdGFsIHRoZSBsZWcncyBvd24gb2JqZWN0IGxlZnQgYXQgMCBjYW4gc2FmZWx5IGZhbGwgYmFja1xuICAgIC8vIHRvIHJvb3QncyBmaWd1cmUgaW5zdGVhZCBvZiBzaWxlbnRseSB6ZXJvaW5nIG91dCBhIHJlYWwgcmVmdW5kXG4gICAgLy8gZGVzdGluYXRpb24uIFdpdGggYSBzaWJsaW5nIGxlZyBwcmVzZW50LCByb290IGFnZ3JlZ2F0ZXMgYm90aCBsZWdzIGFuZFxuICAgIC8vIGlzIG5vdCB0cnVzdHdvcnRoeSBwZXItbGVnLCBzbyB0aGUgbGVnJ3Mgb3duIHZhbHVlIChldmVuIDApIHdpbnMuXG4gICAgY29uc3QgaGFzU2libGluZ0xlZyA9XG4gICAgICBsZWdUeXBlID09PSAnb253YXJkJyA/ICEhcm9vdC5sZWdJbmZvPy5yZXR1cm4gOiAhIXJvb3QubGVnSW5mbz8ub253YXJkO1xuICAgIGNvbnN0IGZhbGxiYWNrID0gKHZhbHVlOiBudW1iZXIgfCB1bmRlZmluZWQsIHJvb3RWYWx1ZTogbnVtYmVyIHwgdW5kZWZpbmVkKSA9PlxuICAgICAgTnVtYmVyKHZhbHVlIHx8IChoYXNTaWJsaW5nTGVnID8gMCA6IHJvb3RWYWx1ZSkgfHwgMCk7XG5cbiAgICBjb25zdCBpc0NyZWRpdFNoZWxsID0gbGVnLmlzQ3JlZGl0U2hlbGwgPT09IHRydWU7XG4gICAgY29uc3QgbGVnUmVmdW5kICAgID0gTnVtYmVyKGxlZy50b3RhbFJlZnVuZEFtb3VudCA/PyAwKTtcbiAgICBjb25zdCBjYXJkUmVmdW5kICAgPSBpc0NyZWRpdFNoZWxsID8gMCA6IGZhbGxiYWNrKGxlZy50b3RhbENhcmRSZWZ1bmRBbW91bnQsIHJvb3QudG90YWxDYXJkUmVmdW5kQW1vdW50KTtcbiAgICBjb25zdCBjcmVkaXRSZWZ1bmQgPSBpc0NyZWRpdFNoZWxsID8gbGVnUmVmdW5kIDogZmFsbGJhY2sobGVnLnRvdGFsQ3JlZGl0UmVmdW5kQW1vdW50LCByb290LnRvdGFsQ3JlZGl0UmVmdW5kQW1vdW50KTtcbiAgICAvLyBUaGUgYmFja2VuZCBzb21ldGltZXMgb21pdHMgYGlzUmVmdW5kYWJsZWAgb24gYSBzaW5nbGUtbGVnIGJvb2tpbmcnc1xuICAgIC8vIGxlZyBvYmplY3QgZW50aXJlbHkgKG5vdCBgZmFsc2VgLCBqdXN0IGFic2VudCkgd2hpbGUgdGhlIHJvb3Qvc291cmNlXG4gICAgLy8gYnJlYWtkb3duIGJvdGggc2F5IHRoZSBib29raW5nIGlzIHJlZnVuZGFibGUg4oCUIHRydXN0IHRoZSByb290IGZsYWdcbiAgICAvLyByYXRoZXIgdGhhbiBkZWZhdWx0aW5nIGEgbWlzc2luZyBmaWVsZCB0byBcIm5vdCBlbGlnaWJsZSBmb3IgYSByZWZ1bmRcIi5cbiAgICBjb25zdCBsZWdJc1JlZnVuZGFibGUgPVxuICAgICAgbGVnLmlzUmVmdW5kYWJsZSA9PT0gdW5kZWZpbmVkID8gcm9vdC5pc1JlZnVuZGFibGUgPT09IHRydWUgOiBsZWcuaXNSZWZ1bmRhYmxlID09PSB0cnVlO1xuICAgIHJldHVybiB7XG4gICAgICAuLi5yb290LFxuICAgICAgaXNSZWZ1bmRhYmxlOiAgICAgICAgICAgICAgICAgICAgbGVnSXNSZWZ1bmRhYmxlLFxuICAgICAgdG90YWxSZWZ1bmRBbW91bnQ6ICAgICAgICAgICAgICAgbGVnUmVmdW5kLFxuICAgICAgLy8gUHJlLXJvdW5kaW5nIHRvdGFsIOKAlCB0aGUgYmFja2VuZCBjZWlscyBgdG90YWxSZWZ1bmRBbW91bnRgIHRvIGEgd2hvbGVcbiAgICAgIC8vIGN1cnJlbmN5IHVuaXQsIHNvIHdhbGxldCtjYXJkK2NyZWRpdCtsb3lhbHR5IGxlZ2l0aW1hdGVseSBmYWxsIGEgZmV3XG4gICAgICAvLyBjZW50cyBzaG9ydCBvZiBpdDsgcmVjb25jaWxpYXRpb24gbXVzdCBjb21wYXJlIGFnYWluc3QgdGhpcyBpbnN0ZWFkLlxuICAgICAgdG90YWxSZWZ1bmRBbW91bnRCZWZvcmVDZWlsOiAgICAgTnVtYmVyKGxlZy50b3RhbFJlZnVuZEFtb3VudEJlZm9yZUNlaWwgPz8gbGVnLnRvdGFsUmVmdW5kQW1vdW50ID8/IDApLFxuICAgICAgdG90YWxDYXJkUmVmdW5kQW1vdW50OiAgICAgICAgICAgY2FyZFJlZnVuZCxcbiAgICAgIHRvdGFsQ3JlZGl0UmVmdW5kQW1vdW50OiAgICAgICAgIGNyZWRpdFJlZnVuZCxcbiAgICAgIHRvdGFsTm9uUmVmdW5kYWJsZVNlcnZpY2VDaGFyZ2U6IE51bWJlcihsZWcudG90YWxOb25SZWZ1bmRhYmxlU2VydmljZUNoYXJnZSB8fCAwKSxcbiAgICAgIHRvdGFsQ291cG9uQW1vdW50OiAgICAgICAgICAgICAgIE51bWJlcihsZWcudG90YWxDb3Vwb25BbW91bnQgfHwgMCksXG4gICAgICB3YWxsZXRSZWZ1bmRBbW91bnQ6ICAgICAgICAgICAgICBmYWxsYmFjayhsZWcud2FsbGV0UmVmdW5kQW1vdW50LCByb290LndhbGxldFJlZnVuZEFtb3VudCksXG4gICAgICB0b3RhbFBlbmFsdHlQb2ludHM6ICAgICAgICAgICAgICBOdW1iZXIobGVnLnRvdGFsUGVuYWx0eVBvaW50cyB8fCAwKSxcbiAgICAgIHRvdGFsU3VwcGxpZXJQZW5hbHR5UG9pbnRzOiAgICAgIE51bWJlcihsZWcudG90YWxTdXBwbGllclBlbmFsdHlQb2ludHMgfHwgMCksXG4gICAgICB0b3RhbExveWFsdHlQb2ludHM6ICAgICAgICAgICAgICBOdW1iZXIobGVnLnRvdGFsTG95YWx0eVBvaW50cyB8fCAwKSxcbiAgICAgIHRvdGFsR2lmdEFtb3VudDogICAgICAgICAgICAgICAgIE51bWJlcihsZWcudG90YWxHaWZ0QW1vdW50IHx8IDApLFxuICAgICAgdG90YWxBbmNpbGxhcnlSZWZ1bmRBbW91bnQ6ICAgICAgTnVtYmVyKGxlZy50b3RhbEFuY2lsbGFyeVJlZnVuZEFtb3VudCB8fCAwKSxcbiAgICAgIHRvdGFsTG95YWx0eVBvaW50c1JlZnVuZEFtb3VudDogIGZhbGxiYWNrKGxlZy50b3RhbExveWFsdHlQb2ludHNSZWZ1bmRBbW91bnQsIHJvb3QudG90YWxMb3lhbHR5UG9pbnRzUmVmdW5kQW1vdW50KSxcbiAgICAgIHRvdGFsQ2FuY2VsbGF0aW9uRmVlOiAgICAgICAgICAgIE51bWJlcihsZWcudG90YWxDYW5jZWxsYXRpb25GZWUgPz8gbGVnLnRvdGFsUGVuYWx0eVBvaW50cyA/PyAwKSxcbiAgICAgIHRvdGFsU3VwcGxpZXJCb29raW5nQW1vdW50OiAgICAgIE51bWJlcihsZWcudG90YWxTdXBwbGllckJvb2tpbmdBbW91bnQgfHwgMCksXG4gICAgICBvcmlnaW5hbEFtb3VudDogICAgICAgICAgICAgICAgICBOdW1iZXIocm9vdC5vcmlnaW5hbEFtb3VudCB8fCAwKSxcbiAgICAgIC8vIExlZy1zY29wZWQgYnJlYWtkb3duIHdpbnMgd2hlbiB0aGUgYmFja2VuZCBzZW5kcyBvbmU7IGEgc2luZ2xlLWxlZ1xuICAgICAgLy8gYm9va2luZyBtYXkgb25seSBjYXJyeSBpdCBhdCB0aGUgcm9vdCBpbnN0ZWFkLlxuICAgICAgcmVmdW5kQnJlYWtkb3duOiAgICAgICAgICAgICAgICAgbGVnLnJlZnVuZEJyZWFrZG93biA/PyByb290LnJlZnVuZEJyZWFrZG93bixcbiAgICAgIGxlZ0luZm86IGxlZ1R5cGUgPT09ICdvbndhcmQnID8geyBvbndhcmQ6IGxlZyB9IDogeyByZXR1cm46IGxlZyB9LFxuICAgIH07XG4gIH1cblxuICBzdGFydEhpbnRzKCk6IHZvaWQge1xuICAgIGxldCBpID0gMDtcbiAgICB0aGlzLmNhbmNlbEhpbnQuc2V0KHRoaXMuQ0FOQ0VMX0hJTlRTWzBdKTtcbiAgICB0aGlzLmhpbnRUaW1lciA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgIGlmIChpIDwgdGhpcy5DQU5DRUxfSElOVFMubGVuZ3RoIC0gMSkge1xuICAgICAgICBpKys7XG4gICAgICAgIHRoaXMuY2FuY2VsSGludC5zZXQodGhpcy5DQU5DRUxfSElOVFNbaV0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLmhpbnRUaW1lcik7XG4gICAgICAgIHRoaXMuaGludFRpbWVyID0gbnVsbDtcbiAgICAgIH1cbiAgICB9LCAxODAwKTtcbiAgfVxuXG4gIHN0b3BIaW50cygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5oaW50VGltZXIpIHsgY2xlYXJJbnRlcnZhbCh0aGlzLmhpbnRUaW1lcik7IHRoaXMuaGludFRpbWVyID0gbnVsbDsgfVxuICAgIHRoaXMuY2FuY2VsSGludC5zZXQoJycpO1xuICB9XG5cbiAgZm10KHZhbHVlOiBudW1iZXIsIGN1cnJlbmN5Pzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBjdXIgPSBjdXJyZW5jeSA/PyB0aGlzLnJlZnVuZERhdGEoKT8uY3VycmVuY3kgPz8gJ1NBUic7XG4gICAgcmV0dXJuIGAke3RoaXMuZm10TnVtKHZhbHVlKX0gJHtjdXJ9YDtcbiAgfVxuXG4gIC8vIFBsYWluIGZvcm1hdHRlZCBudW1iZXIgd2l0aG91dCBhIGN1cnJlbmN5IHN1ZmZpeCAodXNlZCBieSB0aGUgY2FsYyBkaXZpZGVyIC8gZm9ybXVsYSBib3gpLlxuICBmbXROdW0odmFsdWU6IG51bWJlcik6IHN0cmluZyB7XG4gICAgcmV0dXJuIE51bWJlcih2YWx1ZSB8fCAwKS50b0xvY2FsZVN0cmluZygnZW4tU0EnLCB7IG1pbmltdW1GcmFjdGlvbkRpZ2l0czogMiwgbWF4aW11bUZyYWN0aW9uRGlnaXRzOiAyIH0pO1xuICB9XG5cbiAgZm10TmVnKHZhbHVlOiBudW1iZXIsIGN1cnJlbmN5Pzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBuID0gTnVtYmVyKHZhbHVlIHx8IDApO1xuICAgIGNvbnN0IHN0ciA9IHRoaXMuZm10KG4sIGN1cnJlbmN5KTtcbiAgICByZXR1cm4gbiA+IDAgPyBg4oiSICR7c3RyfWAgOiBzdHI7XG4gIH1cblxuICBmbXROZWdSZXN1bHQodmFsdWU6IG51bWJlcik6IHN0cmluZyB7XG4gICAgY29uc3QgbiA9IE51bWJlcih2YWx1ZSB8fCAwKTtcbiAgICBjb25zdCBzdHIgPSB0aGlzLmZtdFJlc3VsdChuKTtcbiAgICByZXR1cm4gbiA+IDAgPyBg4oiSICR7c3RyfWAgOiBzdHI7XG4gIH1cblxuICAvLyBFbnRyeSBwb2ludCBmcm9tIHRoZSBkZXRhaWxzIHNjcmVlbjogYWx3YXlzIGdvZXMgdG8gdGhlIHJlZnVuZC1tZXRob2RcbiAgLy8gc3RlcC4gRm9yIGNyZWRpdC1zaGVsbCByZWZ1bmRzIHRoYXQgc3RlcCBzaG93cyBhIHNpbmdsZSByZWFkLW9ubHkgY3JlZGl0XG4gIC8vIG5vdGljZSBpbnN0ZWFkIG9mIGEgcGlja2VyLCBzaW5jZSB0aGUgcmVmdW5kIGNhbiBvbmx5IGdvIHRvIHRoZSBzaGVsbCDigJRcbiAgLy8gYnV0IHRoZSBhZ2VudCBzdGlsbCBzZWVzIGl0IGJlZm9yZSBjb25maXJtaW5nLCBzYW1lIGFzIHRoZSBzdGFuZGFyZCBmbG93LlxuICByZXF1ZXN0Q2FuY2VsKCk6IHZvaWQge1xuICAgIC8vIE5JTCByZWZ1bmQ6IG5vdGhpbmcgdG8gcmVmdW5kIGF0IGFsbCDigJQgc2tpcCB0aGUgcmVmdW5kLW1ldGhvZCBwb3B1cFxuICAgIC8vIGFuZCBjYW5jZWwgZGlyZWN0bHkuXG4gICAgaWYgKHRoaXMuaXNOaWxSZWZ1bmQoKSkge1xuICAgICAgdGhpcy5jb25maXJtKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY29uZmlybWluZy5zZXQodHJ1ZSk7XG4gICAgfVxuICB9XG5cbiAgY29uZmlybSgpOiB2b2lkIHtcbiAgICBjb25zdCBzZWwgPSB0aGlzLnNlbGVjdGVkTGVnKCk7XG5cbiAgICAvLyBCdWlsZCBsZWdJbmZvIGFycmF5OiBvbWl0IHdoZW4gY2FuY2VsbGluZyBib3RoIChiYWNrZW5kIHRyZWF0cyBhYnNlbmNlIGFzIGJvdGgpXG4gICAgY29uc3QgbGVnSW5mbzogc3RyaW5nW10gfCB1bmRlZmluZWQgPVxuICAgICAgc2VsID09PSAnb253YXJkJyA/IFsnb253YXJkJ10gOlxuICAgICAgc2VsID09PSAncmV0dXJuJyA/IFsncmV0dXJuJ10gOlxuICAgICAgdW5kZWZpbmVkOyAvLyBib3RoIGxlZ3Mg4oCUIG9taXQgdGhlIGZpZWxkXG5cbiAgICBjb25zdCBzb3VyY2UgPSB0aGlzLnNlbGVjdGVkU291cmNlKCkgfHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IHByZWZlcnJlZFJlZnVuZE1ldGhvZCA9IHRoaXMucHJlZmVycmVkUmVmdW5kTWV0aG9kKCk7XG4gICAgY29uc3Qgc3BsaXRBbW91bnRzID1cbiAgICAgIHByZWZlcnJlZFJlZnVuZE1ldGhvZCA9PT0gJ3NwbGl0J1xuICAgICAgICA/IHtcbiAgICAgICAgICAgIHdhbGxldFJlZnVuZEFtb3VudDogTnVtYmVyKHRoaXMuYWRqdXN0ZWREYXRhKCk/LndhbGxldFJlZnVuZEFtb3VudCA/PyAwKSxcbiAgICAgICAgICAgIHRvdGFsQ2FyZFJlZnVuZEFtb3VudDogTnVtYmVyKHRoaXMuYWRqdXN0ZWREYXRhKCk/LnRvdGFsQ2FyZFJlZnVuZEFtb3VudCA/PyAwKSxcbiAgICAgICAgICB9XG4gICAgICAgIDogdW5kZWZpbmVkO1xuICAgIHRoaXMuY29uZmlybWluZy5zZXQoZmFsc2UpO1xuICAgIHRoaXMuc3RvcEhpbnRzKCk7XG4gICAgdGhpcy5jYW5jZWxsaW5nLnNldCh0cnVlKTtcbiAgICB0aGlzLmJvb2tpbmdTZXJ2aWNlLmNvbmZpcm1DYW5jZWwodGhpcy5ib29raW5nSWQoKSwgdGhpcy5wcm9kdWN0KCksIGxlZ0luZm8sIHNvdXJjZSwgcHJlZmVycmVkUmVmdW5kTWV0aG9kLCBzcGxpdEFtb3VudHMpLnN1YnNjcmliZSh7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgbmV4dDogKHJhdzogYW55KSA9PiB7XG4gICAgICAgIHRoaXMuc3RvcEhpbnRzKCk7XG4gICAgICAgIHRoaXMuY2FuY2VsbGluZy5zZXQoZmFsc2UpO1xuICAgICAgICB0aGlzLmNhbmNlbFJlc3VsdC5zZXQocmF3Py5kYXRhID8/IHJhdyk7XG4gICAgICAgIHRoaXMuY29uZmlybWVkLmVtaXQoc2VsKTtcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICB0aGlzLnN0b3BIaW50cygpO1xuICAgICAgICB0aGlzLmNhbmNlbGxpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgdGhpcy50b2FzdC5lcnJvcignQ2FuY2VsbGF0aW9uIGZhaWxlZC4gUGxlYXNlIHRyeSBhZ2Fpbi4nKTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cbn1cbiIsIjxwLWRpYWxvZyBbdmlzaWJsZV09XCJ2aXNpYmxlKClcIiAodmlzaWJsZUNoYW5nZSk9XCIkZXZlbnQgPyBudWxsIDogY2xvc2VkLmVtaXQoKVwiXG4gIFttb2RhbF09XCJ0cnVlXCIgW2Jsb2NrU2Nyb2xsXT1cInRydWVcIiBbZHJhZ2dhYmxlXT1cImZhbHNlXCIgW3Jlc2l6YWJsZV09XCJmYWxzZVwiXG4gIFtzaG93SGVhZGVyXT1cImZhbHNlXCIgW3N0eWxlXT1cInsgd2lkdGg6ICc1NjBweCcsIHBhZGRpbmc6ICcwJyB9XCIgc3R5bGVDbGFzcz1cInNiZC1jYW5jZWwtZGlhbG9nLXdyYXBwZXJcIj5cblxuICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbFwiPlxuXG4gICAgPCEtLSBMb2FkaW5nIHJlZnVuZCBkZXRhaWxzIOKAlCBzaG93cyBjeWNsaW5nIGhpbnRzIC0tPlxuICAgIEBpZiAobG9hZGluZygpKSB7XG4gICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fYXJlLXlvdS1zdXJlXCI+XG4gICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2JkLWNhbmNlbF9fY2xvc2UtYnRuIHNiZC1jYW5jZWxfX2Nsb3NlLWJ0bi0tZmxvYXRpbmdcIiAoY2xpY2spPVwiY2xvc2VkLmVtaXQoKVwiIGFyaWEtbGFiZWw9XCJDbG9zZVwiPlxuICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktdGltZXNcIj48L2k+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fYXlzLWljb25cIj5cbiAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLXNwaW4gcGktc3Bpbm5lclwiPjwvaT5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIEBmb3IgKGggb2YgW2NhbmNlbEhpbnQoKV07IHRyYWNrIGgpIHtcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fYXlzLWhpbnRcIj57eyBoIH19PC9kaXY+XG4gICAgICAgIH1cbiAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2F5cy1kb3RzXCI+XG4gICAgICAgICAgPHNwYW4+PC9zcGFuPjxzcGFuPjwvc3Bhbj48c3Bhbj48L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgfVxuXG4gICAgPCEtLSBTZWxlY3QgbGVnIOKAlCBzaG93biBvbmNlIHRoZSByZWZ1bmQgcHJldmlldyBoYXMgZnVsbHkgbG9hZGVkLCBiZWZvcmUgdGhlXG4gICAgICAgICByZWZ1bmQgYnJlYWtkb3duLCBmb3Igcm91bmQtdHJpcCBib29raW5ncyB0aGUgYmFja2VuZCBoYXNuJ3QgYWxyZWFkeVxuICAgICAgICAgcmVzdHJpY3RlZCB0byBhIHNpbmdsZSBsZWcuIFNhbWUgY2FyZCBkZXNpZ24gYXMgYWxtYXRhci1iMmMnc1xuICAgICAgICAgc2VsZWN0LWxlZyBzY3JlZW4gKGNoZWNrYm94IG92ZXJsYXksIHJlZnVuZGFibGUgYmFkZ2UsIGRpc2NsYWltZXIpLiAtLT5cbiAgICBAZWxzZSBpZiAoc3RlcCgpID09PSAnc2VsZWN0LWxlZycpIHtcbiAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtaGVhZGVyXCI+XG4gICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLWNsb3NlXCIgKGNsaWNrKT1cImNsb3NlZC5lbWl0KClcIiBhcmlhLWxhYmVsPVwiQ2xvc2VcIj5cbiAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLXRpbWVzXCI+PC9pPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1oZWFkZXItdGV4dFwiPlxuICAgICAgICAgIDxoMyBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC10aXRsZVwiPlNlbGVjdCBMZWcgdG8gQ2FuY2VsPC9oMz5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1zdWJcIj5Cb29raW5nIElEICN7eyBib29raW5nSWQoKSB9fTwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3NlbGVjdC1sZWctYm9keVwiPlxuICAgICAgICBAaWYgKGZvcmNlZExlZ1R5cGUoKTsgYXMgZm9yY2VkKSB7XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3NpbmdsZS1sZWctbm90ZVwiPlxuICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1pbmZvLWNpcmNsZVwiPjwvaT5cbiAgICAgICAgICAgIDxzcGFuPlRoaXMgYWlybGluZSBkb2Vzbid0IGFsbG93IGNhbmNlbGxpbmcgYSBzaW5nbGUgZmxpZ2h0IOKAlCB7eyBpdGluZXJhcnlMZWcoZm9yY2VkKT8uZnJvbSB9fSB0byB7eyBpdGluZXJhcnlMZWcoZm9yY2VkKT8udG8gfX0gd2lsbCBiZSBpbmNsdWRlZCBhdXRvbWF0aWNhbGx5Ljwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgICAgICBAaWYgKGFsbExlZ3NOb25SZWZ1bmRhYmxlKCkpIHtcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fYWxsLW5vbi1yZWZ1bmRhYmxlLW5vdGVcIj5cbiAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktZXhjbGFtYXRpb24tdHJpYW5nbGVcIj48L2k+XG4gICAgICAgICAgICA8c3Bhbj5Tb3JyeSwgd2UncmUgdW5hYmxlIHRvIHByb3ZpZGUgYSByZWZ1bmQgZm9yIHRoaXMgYm9va2luZywgYXMgYm90aCBmbGlnaHRzIGFyZSBub24tcmVmdW5kYWJsZSBiYXNlZCBvbiBhaXJsaW5lIHJ1bGVzLjwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgICAgICA8IS0tIE9ud2FyZCAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtY2FyZFwiXG4gICAgICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAgICAgJ3NiZC1jYW5jZWxfX2xlZy1zZWxlY3QtY2FyZC0tc2VsZWN0ZWQnOiBvbndhcmRDaGVja2VkKCkgJiYgb253YXJkUmVmdW5kYWJsZSgpLFxuICAgICAgICAgICAgJ3NiZC1jYW5jZWxfX2xlZy1zZWxlY3QtY2FyZC0tZGlzYWJsZWQnOiAhb253YXJkUmVmdW5kYWJsZSgpLFxuICAgICAgICAgICAgJ3NiZC1jYW5jZWxfX2xlZy1zZWxlY3QtY2FyZC0tZnJvemVuJzogZm9yY2VkTGVnVHlwZSgpID09PSAnb253YXJkJ1xuICAgICAgICAgIH1cIj5cbiAgICAgICAgICBAaWYgKGZvcmNlZExlZ1R5cGUoKSAhPT0gJ29ud2FyZCcpIHtcbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtY2hlY2tib3hcIj5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIFtjaGVja2VkXT1cIm9ud2FyZENoZWNrZWQoKVwiIFtkaXNhYmxlZF09XCIhb253YXJkUmVmdW5kYWJsZSgpXCJcbiAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInRvZ2dsZUxlZygnb253YXJkJylcIiAvPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtaWNvblwiPjxpIGNsYXNzPVwicGkgcGktY2hlY2tcIj48L2k+PC9zcGFuPlxuICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktbG9jayBzYmQtY2FuY2VsX19sZWctc2VsZWN0LWxvY2tcIj48L2k+XG4gICAgICAgICAgfVxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LWNvbnRlbnRcIj5cbiAgICAgICAgICAgIEBpZiAoaXRpbmVyYXJ5TGVnKCdvbndhcmQnKTsgYXMgbGVnKSB7XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LXRvcFwiPlxuICAgICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtbmFtZVwiPnt7IGxlZy5mcm9tIH19IHRvIHt7IGxlZy50byB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LWRhdGVcIj57eyBmbXRTaG9ydERhdGUobGVnLmRlcFRpbWUpIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19iYWRnZSBzYmQtY2FuY2VsX19iYWRnZS0tb3V0bGluZVwiXG4gICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJvbndhcmRSZWZ1bmRhYmxlKCkgJiYgZm9yY2VkTGVnVHlwZSgpICE9PSAnb253YXJkJyA/ICdzYmQtY2FuY2VsX19iYWRnZS0tZ3JlZW4nIDogJ3NiZC1jYW5jZWxfX2JhZGdlLS1tdXRlZCdcIj5cbiAgICAgICAgICAgICAgICAgIHt7IG9ud2FyZFJlZnVuZGFibGUoKSA/ICdSZWZ1bmRhYmxlJyA6ICdOb24tUmVmdW5kYWJsZScgfX1cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC10aW1lc1wiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC10aW1lXCI+e3sgZm10VGltZShsZWcuZGVwVGltZSkgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LWxpbmVcIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1saW5lLXN0b3BzXCI+e3sgbGVnLnN0b3BzLmxlbmd0aCA+IDAgPyAobGVnLnN0b3BzLmxlbmd0aCArICcgc3RvcCcgKyAobGVnLnN0b3BzLmxlbmd0aCA+IDEgPyAncycgOiAnJykpIDogJ0RpcmVjdCcgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICBAaWYgKGZtdE1pbnMobGVnLnRvdGFsTWludXRlcykpIHsgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LWxpbmUtZHVyXCI+e3sgZm10TWlucyhsZWcudG90YWxNaW51dGVzKSB9fTwvc3Bhbj4gfVxuICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1hcnJvdy1yaWdodCBzYmQtY2FuY2VsX19sZWctc2VsZWN0LWxpbmUtYXJyb3dcIj48L2k+XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC10aW1lXCI+e3sgZm10VGltZShsZWcuYXJyVGltZSkgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICBAaWYgKGxlZy5haXJsaW5lTmFtZSB8fCBsZWcuY2FiaW4pIHtcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtYWlybGluZVwiPlxuICAgICAgICAgICAgICAgICAge3sgbGVnLmFpcmxpbmVOYW1lIH19e3sgbGVnLmFpcmxpbmVOYW1lICYmIGxlZy5jYWJpbiA/ICcgwrcgJyA6ICcnIH19e3sgbGVnLmNhYmluIH19XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LWZvb3RlclwiPlxuICAgICAgICAgICAgICAgIEBpZiAobGVnLm9wZXJhdGVkQnkubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3Qtb3BlcmF0ZWQtYnlcIj5PcGVyYXRlZCBieSB7eyBsZWcub3BlcmF0ZWRCeS5qb2luKCcsICcpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8IS0tIDxpIGNsYXNzPVwicGkgcGktY2hldnJvbi1kb3duIHNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtY2hldnJvblwiPjwvaT4gLS0+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LXRvcFwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1uYW1lXCI+T253YXJkPC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fYmFkZ2Ugc2JkLWNhbmNlbF9fYmFkZ2UtLW91dGxpbmVcIlxuICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwib253YXJkUmVmdW5kYWJsZSgpICYmIGZvcmNlZExlZ1R5cGUoKSAhPT0gJ29ud2FyZCcgPyAnc2JkLWNhbmNlbF9fYmFkZ2UtLWdyZWVuJyA6ICdzYmQtY2FuY2VsX19iYWRnZS0tbXV0ZWQnXCI+XG4gICAgICAgICAgICAgICAgICB7eyBvbndhcmRSZWZ1bmRhYmxlKCkgPyAnUmVmdW5kYWJsZScgOiAnTm9uLVJlZnVuZGFibGUnIH19XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEBpZiAoIW9ud2FyZFJlZnVuZGFibGUoKSkge1xuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1ub3RpY2VcIj5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLWluZm8tY2lyY2xlXCI+PC9pPlxuICAgICAgICAgICAgICAgIDxzcGFuPlRoaXMgZmxpZ2h0IHR5cGUgZG9lc24ndCBhbGxvdyByZWZ1bmRzIG9uIGNhbmNlbGxhdGlvbiwgYmFzZWQgb24gdGhlIGFpcmxpbmUncyBmYXJlIHJ1bGVzLjwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gUmV0dXJuIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1jYXJkXCJcbiAgICAgICAgICBbbmdDbGFzc109XCJ7XG4gICAgICAgICAgICAnc2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1jYXJkLS1zZWxlY3RlZCc6IHJldHVybkNoZWNrZWQoKSAmJiByZXR1cm5SZWZ1bmRhYmxlKCksXG4gICAgICAgICAgICAnc2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1jYXJkLS1kaXNhYmxlZCc6ICFyZXR1cm5SZWZ1bmRhYmxlKCksXG4gICAgICAgICAgICAnc2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1jYXJkLS1mcm96ZW4nOiBmb3JjZWRMZWdUeXBlKCkgPT09ICdyZXR1cm4nXG4gICAgICAgICAgfVwiPlxuICAgICAgICAgIEBpZiAoZm9yY2VkTGVnVHlwZSgpICE9PSAncmV0dXJuJykge1xuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1jaGVja2JveFwiPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgW2NoZWNrZWRdPVwicmV0dXJuQ2hlY2tlZCgpXCIgW2Rpc2FibGVkXT1cIiFyZXR1cm5SZWZ1bmRhYmxlKClcIlxuICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwidG9nZ2xlTGVnKCdyZXR1cm4nKVwiIC8+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1pY29uXCI+PGkgY2xhc3M9XCJwaSBwaS1jaGVja1wiPjwvaT48L3NwYW4+XG4gICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1sb2NrIHNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtbG9ja1wiPjwvaT5cbiAgICAgICAgICB9XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtY29udGVudFwiPlxuICAgICAgICAgICAgQGlmIChpdGluZXJhcnlMZWcoJ3JldHVybicpOyBhcyBsZWcpIHtcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtdG9wXCI+XG4gICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1uYW1lXCI+e3sgbGVnLmZyb20gfX0gdG8ge3sgbGVnLnRvIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtZGF0ZVwiPnt7IGZtdFNob3J0RGF0ZShsZWcuZGVwVGltZSkgfX08L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX2JhZGdlIHNiZC1jYW5jZWxfX2JhZGdlLS1vdXRsaW5lXCJcbiAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInJldHVyblJlZnVuZGFibGUoKSAmJiBmb3JjZWRMZWdUeXBlKCkgIT09ICdyZXR1cm4nID8gJ3NiZC1jYW5jZWxfX2JhZGdlLS1ncmVlbicgOiAnc2JkLWNhbmNlbF9fYmFkZ2UtLW11dGVkJ1wiPlxuICAgICAgICAgICAgICAgICAge3sgcmV0dXJuUmVmdW5kYWJsZSgpID8gJ1JlZnVuZGFibGUnIDogJ05vbi1SZWZ1bmRhYmxlJyB9fVxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LXRpbWVzXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LXRpbWVcIj57eyBmbXRUaW1lKGxlZy5kZXBUaW1lKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtbGluZVwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LWxpbmUtc3RvcHNcIj57eyBsZWcuc3RvcHMubGVuZ3RoID4gMCA/IChsZWcuc3RvcHMubGVuZ3RoICsgJyBzdG9wJyArIChsZWcuc3RvcHMubGVuZ3RoID4gMSA/ICdzJyA6ICcnKSkgOiAnRGlyZWN0JyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIEBpZiAoZm10TWlucyhsZWcudG90YWxNaW51dGVzKSkgeyA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtbGluZS1kdXJcIj57eyBmbXRNaW5zKGxlZy50b3RhbE1pbnV0ZXMpIH19PC9zcGFuPiB9XG4gICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLWFycm93LXJpZ2h0IHNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtbGluZS1hcnJvd1wiPjwvaT5cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LXRpbWVcIj57eyBmbXRUaW1lKGxlZy5hcnJUaW1lKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIEBpZiAobGVnLmFpcmxpbmVOYW1lIHx8IGxlZy5jYWJpbikge1xuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1haXJsaW5lXCI+XG4gICAgICAgICAgICAgICAgICB7eyBsZWcuYWlybGluZU5hbWUgfX17eyBsZWcuYWlybGluZU5hbWUgJiYgbGVnLmNhYmluID8gJyDCtyAnIDogJycgfX17eyBsZWcuY2FiaW4gfX1cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtZm9vdGVyXCI+XG4gICAgICAgICAgICAgICAgQGlmIChsZWcub3BlcmF0ZWRCeS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1vcGVyYXRlZC1ieVwiPk9wZXJhdGVkIGJ5IHt7IGxlZy5vcGVyYXRlZEJ5LmpvaW4oJywgJykgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwhLS0gPGkgY2xhc3M9XCJwaSBwaS1jaGV2cm9uLWRvd24gc2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1jaGV2cm9uXCI+PC9pPiAtLT5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtdG9wXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LW5hbWVcIj5SZXR1cm48L3NwYW4+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19iYWRnZSBzYmQtY2FuY2VsX19iYWRnZS0tb3V0bGluZVwiXG4gICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJyZXR1cm5SZWZ1bmRhYmxlKCkgJiYgZm9yY2VkTGVnVHlwZSgpICE9PSAncmV0dXJuJyA/ICdzYmQtY2FuY2VsX19iYWRnZS0tZ3JlZW4nIDogJ3NiZC1jYW5jZWxfX2JhZGdlLS1tdXRlZCdcIj5cbiAgICAgICAgICAgICAgICAgIHt7IHJldHVyblJlZnVuZGFibGUoKSA/ICdSZWZ1bmRhYmxlJyA6ICdOb24tUmVmdW5kYWJsZScgfX1cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGlmICghcmV0dXJuUmVmdW5kYWJsZSgpKSB7XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LW5vdGljZVwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktaW5mby1jaXJjbGVcIj48L2k+XG4gICAgICAgICAgICAgICAgPHNwYW4+VGhpcyBmbGlnaHQgdHlwZSBkb2Vzbid0IGFsbG93IHJlZnVuZHMgb24gY2FuY2VsbGF0aW9uLCBiYXNlZCBvbiB0aGUgYWlybGluZSdzIGZhcmUgcnVsZXMuPC9zcGFuPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgQGlmICghYWxsTGVnc05vblJlZnVuZGFibGUoKSAmJiAhb253YXJkQ2hlY2tlZCgpICYmICFyZXR1cm5DaGVja2VkKCkpIHtcbiAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtaGludFwiPlNlbGVjdCBhdCBsZWFzdCBvbmUgZmxpZ2h0IHRvIGNvbnRpbnVlPC9kaXY+XG4gICAgICB9XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19mb290ZXJcIj5cbiAgICAgICAgPGJ1dHRvbiBwQnV0dG9uXG4gICAgICAgICAgc3R5bGVDbGFzcz1cInNiZC1jYW5jZWxfX2J0bi1wcmltYXJ5XCJcbiAgICAgICAgICBsYWJlbD1cIkNvbnRpbnVlXCJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiYWxsTGVnc05vblJlZnVuZGFibGUoKSB8fCAoIW9ud2FyZENoZWNrZWQoKSAmJiAhcmV0dXJuQ2hlY2tlZCgpKVwiXG4gICAgICAgICAgKGNsaWNrKT1cInN0ZXAuc2V0KCdkZXRhaWxzJylcIj48L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIH1cblxuICAgIDwhLS0gUmVmdW5kIG1ldGhvZCDigJQgcmVwbGFjZXMgdGhlIG9sZCBhcmUteW91LXN1cmUgKyByYWRpbyBwaWNrZXIuXG4gICAgICAgICBTdGF5cyBtb3VudGVkIChkaW1tZWQpIGJlaGluZCB0aGUgcmVzdWx0IG92ZXJsYXkgb25jZSBjb25maXJtZWQuIC0tPlxuICAgIEBlbHNlIGlmIChjb25maXJtaW5nKCkgfHwgY2FuY2VsUmVzdWx0KCkpIHtcbiAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtaGVhZGVyXCI+XG4gICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLWNsb3NlXCIgKGNsaWNrKT1cImNvbmZpcm1pbmcuc2V0KGZhbHNlKVwiIGFyaWEtbGFiZWw9XCJDbG9zZVwiPlxuICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktdGltZXNcIj48L2k+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLWhlYWRlci10ZXh0XCI+XG4gICAgICAgICAgPGgzIGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLXRpdGxlXCI+UmVmdW5kIE1ldGhvZDwvaDM+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2Qtc3ViXCI+Qm9va2luZyBJRCAje3sgYm9va2luZ0lkKCkgfX08L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtYm9keVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLWFtb3VudFwiPlxuICAgICAgICAgIDxzcGFuPllvdSB3aWxsIGdldCBiYWNrPC9zcGFuPlxuICAgICAgICAgIDxzdHJvbmc+e3sgZm10KGFkanVzdGVkRGF0YSgpPy50b3RhbFJlZnVuZEFtb3VudCkgfX08L3N0cm9uZz5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgQGlmIChpc0NyZWRpdFNoZWxsKCkpIHtcbiAgICAgICAgPCEtLSBDcmVkaXQtc2hlbGwgcmVmdW5kcyBoYXZlIGV4YWN0bHkgb25lIGRlc3RpbmF0aW9uIOKAlCB0aGUgYWlybGluZVxuICAgICAgICAgICAgIGNyZWRpdCBzaGVsbCDigJQgc28gc2hvdyBpdCBhcyBhIHJlYWQtb25seSBjYXJkLCBub3QgYSBwaWNrZXIuIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLW9wdGlvbiBzYmQtY2FuY2VsX19tZXRob2Qtb3B0aW9uLS1hY3RpdmVcIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1pY29uXCI+PGkgY2xhc3M9XCJwaSBwaS13YWxsZXRcIj48L2k+PC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLWJvZHktdGV4dFwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtbmFtZVwiPnt7IGNyZWRpdFNoZWxsU3VwcGxpZXJOYW1lKCkgfX0gd2Vic2l0ZSBjcmVkaXQ8L3NwYW4+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1kZXNjXCI+WW91ciByZWZ1bmQgd2lsbCBiZSBpc3N1ZWQgaW5zdGFudGx5IGJ5IHt7IGNyZWRpdFNoZWxsU3VwcGxpZXJOYW1lKCkgfX0uPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtYmFkZ2Ugc2JkLWNhbmNlbF9fbWV0aG9kLWJhZGdlLS1pbnN0YW50XCI+XG4gICAgICAgICAgICAgIDxzdmcgd2lkdGg9XCIxMlwiIGhlaWdodD1cIjlcIiB2aWV3Qm94PVwiMCAwIDEyIDlcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgICAgICAgICA8cGF0aFxuICAgICAgICAgICAgICAgICAgZD1cIk03LjMxODE4IDBDOC40MjcyNyAwIDkuNDkwOTMgMC40NDA1ODMgMTAuMjc1MiAxLjIyNDgzQzExLjA1OTQgMi4wMDkwNyAxMS41IDMuMDcyNzMgMTEuNSA0LjE4MTgyQzExLjUgNS4yOTA5IDExLjA1OTQgNi4zNTQ1NyAxMC4yNzUyIDcuMTM4ODFDOS40OTA5MyA3LjkyMzA1IDguNDI3MjcgOC4zNjM2NCA3LjMxODE4IDguMzYzNjRDNi4yMDkwOSA4LjM2MzY0IDUuMTQ1NDMgNy45MjMwNSA0LjM2MTE5IDcuMTM4ODFDMy41NzY5NSA2LjM1NDU3IDMuMTM2MzYgNS4yOTA5IDMuMTM2MzYgNC4xODE4MkMzLjEzNjM2IDMuMDcyNzMgMy41NzY5NSAyLjAwOTA3IDQuMzYxMTkgMS4yMjQ4M0M1LjE0NTQzIDAuNDQwNTgzIDYuMjA5MDkgMCA3LjMxODE4IDBaTTcuMzE4MTggMS4wNDU0NUM2LjQ4NjM3IDEuMDQ1NDUgNS42ODg2MiAxLjM3NTg5IDUuMTAwNDQgMS45NjQwN0M0LjUxMjI2IDIuNTUyMjYgNC4xODE4MiAzLjM1IDQuMTgxODIgNC4xODE4MkM0LjE4MTgyIDUuMDEzNjMgNC41MTIyNiA1LjgxMTM4IDUuMTAwNDQgNi4zOTk1NkM1LjY4ODYyIDYuOTg3NzQgNi40ODYzNyA3LjMxODE4IDcuMzE4MTggNy4zMTgxOEM4LjE1IDcuMzE4MTggOC45NDc3NCA2Ljk4Nzc0IDkuNTM1OTMgNi4zOTk1NkMxMC4xMjQxIDUuODExMzggMTAuNDU0NSA1LjAxMzYzIDEwLjQ1NDUgNC4xODE4MkMxMC40NTQ1IDMuMzUgMTAuMTI0MSAyLjU1MjI2IDkuNTM1OTMgMS45NjQwN0M4Ljk0Nzc0IDEuMzc1ODkgOC4xNSAxLjA0NTQ1IDcuMzE4MTggMS4wNDU0NVpNNi43OTU0NSAyLjA5MDkxSDcuNTc5NTVWNC4wNjY4Mkw4Ljc5NzUgNS4yODQ3N0w4LjI0MzQxIDUuODM4ODZMNi43OTU0NSA0LjM5MDkxVjIuMDkwOTFaTTAuNTIyNzI3IDcuMzE4MThDMC4zODQwOTEgNy4zMTgxOCAwLjI1MTEzNCA3LjI2MzExIDAuMTUzMTAzIDcuMTY1MDhDMC4wNTUwNzI5IDcuMDY3MDUgMCA2LjkzNDA5IDAgNi43OTU0NUMwIDYuNjU2ODIgMC4wNTUwNzI5IDYuNTIzODYgMC4xNTMxMDMgNi40MjU4M0MwLjI1MTEzNCA2LjMyNzggMC4zODQwOTEgNi4yNzI3MyAwLjUyMjcyNyA2LjI3MjczSDIuNTI0NzdDMi42ODY4MiA2LjY0Mzg2IDIuODk1OTEgNi45OTQwOSAzLjEzNjM2IDcuMzE4MThIMC41MjI3MjdaTTEuMDQ1NDUgNC43MDQ1NUMwLjkwNjgxOSA0LjcwNDU1IDAuNzczODYxIDQuNjQ5NDcgMC42NzU4MyA0LjU1MTQ0QzAuNTc3OCA0LjQ1MzQxIDAuNTIyNzI3IDQuMzIwNDUgMC41MjI3MjcgNC4xODE4MkMwLjUyMjcyNyA0LjA0MzE4IDAuNTc3OCAzLjkxMDIyIDAuNjc1ODMgMy44MTIxOUMwLjc3Mzg2MSAzLjcxNDE2IDAuOTA2ODE5IDMuNjU5MDkgMS4wNDU0NSAzLjY1OTA5SDIuMTE3MDVMMi4wOTA5MSA0LjE4MTgyTDIuMTE3MDUgNC43MDQ1NUgxLjA0NTQ1Wk0xLjU2ODE4IDIuMDkwOTFDMS40Mjk1NSAyLjA5MDkxIDEuMjk2NTkgMi4wMzU4NCAxLjE5ODU2IDEuOTM3ODFDMS4xMDA1MyAxLjgzOTc4IDEuMDQ1NDUgMS43MDY4MiAxLjA0NTQ1IDEuNTY4MThDMS4wNDU0NSAxLjQyOTU1IDEuMTAwNTMgMS4yOTY1OSAxLjE5ODU2IDEuMTk4NTZDMS4yOTY1OSAxLjEwMDUzIDEuNDI5NTUgMS4wNDU0NSAxLjU2ODE4IDEuMDQ1NDVIMy4xMzYzNkMyLjg5NTkxIDEuMzY5NTUgMi42ODY4MiAxLjcxOTc3IDIuNTI0NzcgMi4wOTA5MUgxLjU2ODE4WlwiXG4gICAgICAgICAgICAgICAgICBmaWxsPVwiIzE1ODAzQ1wiXG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgIEluc3RhbnRcbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19ub3RpY2Ugc2JkLWNhbmNlbF9fbm90aWNlLS1jcmVkaXRcIj5cbiAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLWluZm8tY2lyY2xlXCI+PC9pPlxuICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgWW91ciByZWZ1bmQgd2lsbCBiZSBpc3N1ZWQgYXMgYWlybGluZSBjcmVkaXQgdW5kZXIgdGhlIHNhbWUgUE5SLlxuICAgICAgICAgICAgSXQgY2FuIGJlIHVzZWQgb25seSBmb3IgZnV0dXJlIGJvb2tpbmcgb24ge3sgY3JlZGl0U2hlbGxTdXBwbGllck5hbWUoKSB9fSB3ZWJzaXRlLlxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBSZWZ1bmRhYmxlIGFuY2lsbGFyaWVzIChiYWdnYWdlLCBzZWF0cywg4oCmKSBjYW4gaW5kZXBlbmRlbnRseSBiZVxuICAgICAgICAgICAgIGZsYWdnZWQgY3JlZGl0LXNoZWxsIG9yIG5vdCDigJQgZWFjaCByZW5kZXJzIGFzIGl0cyBvd24gY2FyZCxcbiAgICAgICAgICAgICBtYXRjaGluZyBlaXRoZXIgdGhlIGNyZWRpdC1zaGVsbCBzdHlsZSBhYm92ZSBvciB0aGUgbm9ybWFsXG4gICAgICAgICAgICAgd2FsbGV0IHN0eWxlLCBib3RoIHdpdGggdGhlIHNhbWUgbmVzdGVkIG5vdGUgd2hlbiBjcmVkaXQtc2hlbGwuIC0tPlxuICAgICAgICBAZm9yIChpdGVtIG9mIGNyZWRpdFNoZWxsQW5jaWxsYXJ5SXRlbXMoKTsgdHJhY2sgaXRlbS5uYW1lKSB7XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1vcHRpb24gc2JkLWNhbmNlbF9fbWV0aG9kLW9wdGlvbi0tYWN0aXZlXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1pY29uXCI+PGkgY2xhc3M9XCJwaSBwaS13YWxsZXRcIj48L2k+PC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtYm9keS10ZXh0XCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLW5hbWVcIj5cbiAgICAgICAgICAgICAgICB7eyBpdGVtLmlzQ3JlZGl0U2hlbGwgPyAoY3JlZGl0U2hlbGxTdXBwbGllck5hbWUoKSArICcgd2Vic2l0ZSBjcmVkaXQnKSA6ICdBbG1hdGFyIFdhbGxldCcgfX1cbiAgICAgICAgICAgICAgICDigJQge3sgaXRlbS5uYW1lIH19XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtZGVzY1wiPlxuICAgICAgICAgICAgICAgIEBpZiAoaXRlbS5pc0NyZWRpdFNoZWxsKSB7XG4gICAgICAgICAgICAgICAgICBZb3VyIHJlZnVuZCB3aWxsIGJlIGlzc3VlZCBpbnN0YW50bHkgYnkge3sgY3JlZGl0U2hlbGxTdXBwbGllck5hbWUoKSB9fS5cbiAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIFVzYWJsZSBmb3IgZnV0dXJlIGJvb2tpbmdzXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLWJhZGdlIHNiZC1jYW5jZWxfX21ldGhvZC1iYWRnZS0taW5zdGFudFwiPlxuICAgICAgICAgICAgICAgIDxzdmcgd2lkdGg9XCIxMlwiIGhlaWdodD1cIjlcIiB2aWV3Qm94PVwiMCAwIDEyIDlcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgICAgICAgICAgIDxwYXRoXG4gICAgICAgICAgICAgICAgICAgIGQ9XCJNNy4zMTgxOCAwQzguNDI3MjcgMCA5LjQ5MDkzIDAuNDQwNTgzIDEwLjI3NTIgMS4yMjQ4M0MxMS4wNTk0IDIuMDA5MDcgMTEuNSAzLjA3MjczIDExLjUgNC4xODE4MkMxMS41IDUuMjkwOSAxMS4wNTk0IDYuMzU0NTcgMTAuMjc1MiA3LjEzODgxQzkuNDkwOTMgNy45MjMwNSA4LjQyNzI3IDguMzYzNjQgNy4zMTgxOCA4LjM2MzY0QzYuMjA5MDkgOC4zNjM2NCA1LjE0NTQzIDcuOTIzMDUgNC4zNjExOSA3LjEzODgxQzMuNTc2OTUgNi4zNTQ1NyAzLjEzNjM2IDUuMjkwOSAzLjEzNjM2IDQuMTgxODJDMy4xMzYzNiAzLjA3MjczIDMuNTc2OTUgMi4wMDkwNyA0LjM2MTE5IDEuMjI0ODNDNS4xNDU0MyAwLjQ0MDU4MyA2LjIwOTA5IDAgNy4zMTgxOCAwWk03LjMxODE4IDEuMDQ1NDVDNi40ODYzNyAxLjA0NTQ1IDUuNjg4NjIgMS4zNzU4OSA1LjEwMDQ0IDEuOTY0MDdDNC41MTIyNiAyLjU1MjI2IDQuMTgxODIgMy4zNSA0LjE4MTgyIDQuMTgxODJDNC4xODE4MiA1LjAxMzYzIDQuNTEyMjYgNS44MTEzOCA1LjEwMDQ0IDYuMzk5NTZDNS42ODg2MiA2Ljk4Nzc0IDYuNDg2MzcgNy4zMTgxOCA3LjMxODE4IDcuMzE4MThDOC4xNSA3LjMxODE4IDguOTQ3NzQgNi45ODc3NCA5LjUzNTkzIDYuMzk5NTZDMTAuMTI0MSA1LjgxMTM4IDEwLjQ1NDUgNS4wMTM2MyAxMC40NTQ1IDQuMTgxODJDMTAuNDU0NSAzLjM1IDEwLjEyNDEgMi41NTIyNiA5LjUzNTkzIDEuOTY0MDdDOC45NDc3NCAxLjM3NTg5IDguMTUgMS4wNDU0NSA3LjMxODE4IDEuMDQ1NDVaTTYuNzk1NDUgMi4wOTA5MUg3LjU3OTU1VjQuMDY2ODJMOC43OTc1IDUuMjg0NzdMOC4yNDM0MSA1LjgzODg2TDYuNzk1NDUgNC4zOTA5MVYyLjA5MDkxWk0wLjUyMjcyNyA3LjMxODE4QzAuMzg0MDkxIDcuMzE4MTggMC4yNTExMzQgNy4yNjMxMSAwLjE1MzEwMyA3LjE2NTA4QzAuMDU1MDcyOSA3LjA2NzA1IDAgNi45MzQwOSAwIDYuNzk1NDVDMCA2LjY1NjgyIDAuMDU1MDcyOSA2LjUyMzg2IDAuMTUzMTAzIDYuNDI1ODNDMC4yNTExMzQgNi4zMjc4IDAuMzg0MDkxIDYuMjcyNzMgMC41MjI3MjcgNi4yNzI3M0gyLjUyNDc3QzIuNjg2ODIgNi42NDM4NiAyLjg5NTkxIDYuOTk0MDkgMy4xMzYzNiA3LjMxODE4SDAuNTIyNzI3Wk0xLjA0NTQ1IDQuNzA0NTVDMC45MDY4MTkgNC43MDQ1NSAwLjc3Mzg2MSA0LjY0OTQ3IDAuNjc1ODMgNC41NTE0NEMwLjU3NzggNC40NTM0MSAwLjUyMjcyNyA0LjMyMDQ1IDAuNTIyNzI3IDQuMTgxODJDMC41MjI3MjcgNC4wNDMxOCAwLjU3NzggMy45MTAyMiAwLjY3NTgzIDMuODEyMTlDMC43NzM4NjEgMy43MTQxNiAwLjkwNjgxOSAzLjY1OTA5IDEuMDQ1NDUgMy42NTkwOUgyLjExNzA1TDIuMDkwOTEgNC4xODE4MkwyLjExNzA1IDQuNzA0NTVIMS4wNDU0NVpNMS41NjgxOCAyLjA5MDkxQzEuNDI5NTUgMi4wOTA5MSAxLjI5NjU5IDIuMDM1ODQgMS4xOTg1NiAxLjkzNzgxQzEuMTAwNTMgMS44Mzk3OCAxLjA0NTQ1IDEuNzA2ODIgMS4wNDU0NSAxLjU2ODE4QzEuMDQ1NDUgMS40Mjk1NSAxLjEwMDUzIDEuMjk2NTkgMS4xOTg1NiAxLjE5ODU2QzEuMjk2NTkgMS4xMDA1MyAxLjQyOTU1IDEuMDQ1NDUgMS41NjgxOCAxLjA0NTQ1SDMuMTM2MzZDMi44OTU5MSAxLjM2OTU1IDIuNjg2ODIgMS43MTk3NyAyLjUyNDc3IDIuMDkwOTFIMS41NjgxOFpcIlxuICAgICAgICAgICAgICAgICAgICBmaWxsPVwiIzE1ODAzQ1wiXG4gICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgIEluc3RhbnRcbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICBAaWYgKGl0ZW0uaXNDcmVkaXRTaGVsbCkge1xuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbm90aWNlIHNiZC1jYW5jZWxfX25vdGljZS0taW5mb1wiPlxuICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1pbmZvLWNpcmNsZVwiPjwvaT5cbiAgICAgICAgICAgICAgICAgIDxzcGFuPllvdXIgcmVmdW5kIHdpbGwgYmUgaXNzdWVkIGFzIGFpcmxpbmUgY3JlZGl0IHVuZGVyIHRoZSBzYW1lIFBOUi4gSXQgY2FuIGJlIHVzZWQgb25seSBmb3IgZnV0dXJlIGJvb2tpbmcgb24ge3sgY3JlZGl0U2hlbGxTdXBwbGllck5hbWUoKSB9fSB3ZWJzaXRlLjwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDxzdHJvbmc+e3sgZm10KGl0ZW0uYW1vdW50KSB9fTwvc3Ryb25nPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICAgIH0gQGVsc2Uge1xuXG4gICAgICAgIEBpZiAoaXNGdWxsV2FsbGV0UmVmdW5kQWxsb3dlZCgpIHx8IGlzV2FsbGV0T25seVJlZnVuZCgpIHx8IGlzTG95YWx0eU9ubHlSZWZ1bmQoKSkge1xuICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1vcHRpb25cIlxuICAgICAgICAgIFtuZ0NsYXNzXT1cInsgJ3NiZC1jYW5jZWxfX21ldGhvZC1vcHRpb24tLWFjdGl2ZSc6IHByZWZlcnJlZFJlZnVuZE1ldGhvZCgpID09PSAnd2FsbGV0JyB9XCJcbiAgICAgICAgICAoY2xpY2spPVwicHJlZmVycmVkUmVmdW5kTWV0aG9kLnNldCgnd2FsbGV0JylcIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1pY29uXCI+PGkgY2xhc3M9XCJwaSBwaS13YWxsZXRcIj48L2k+PC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLWJvZHktdGV4dFwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtbmFtZVwiPnt7IHdhbGxldENhcmRMYWJlbCgpIH19PC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtZGVzY1wiPlVzYWJsZSBmb3IgZnV0dXJlIGJvb2tpbmdzPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtYmFkZ2Ugc2JkLWNhbmNlbF9fbWV0aG9kLWJhZGdlLS1pbnN0YW50XCI+XG4gICAgICAgICAgICAgIDxzdmcgd2lkdGg9XCIxMlwiIGhlaWdodD1cIjlcIiB2aWV3Qm94PVwiMCAwIDEyIDlcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgICAgICAgICA8cGF0aFxuICAgICAgICAgICAgICAgICAgZD1cIk03LjMxODE4IDBDOC40MjcyNyAwIDkuNDkwOTMgMC40NDA1ODMgMTAuMjc1MiAxLjIyNDgzQzExLjA1OTQgMi4wMDkwNyAxMS41IDMuMDcyNzMgMTEuNSA0LjE4MTgyQzExLjUgNS4yOTA5IDExLjA1OTQgNi4zNTQ1NyAxMC4yNzUyIDcuMTM4ODFDOS40OTA5MyA3LjkyMzA1IDguNDI3MjcgOC4zNjM2NCA3LjMxODE4IDguMzYzNjRDNi4yMDkwOSA4LjM2MzY0IDUuMTQ1NDMgNy45MjMwNSA0LjM2MTE5IDcuMTM4ODFDMy41NzY5NSA2LjM1NDU3IDMuMTM2MzYgNS4yOTA5IDMuMTM2MzYgNC4xODE4MkMzLjEzNjM2IDMuMDcyNzMgMy41NzY5NSAyLjAwOTA3IDQuMzYxMTkgMS4yMjQ4M0M1LjE0NTQzIDAuNDQwNTgzIDYuMjA5MDkgMCA3LjMxODE4IDBaTTcuMzE4MTggMS4wNDU0NUM2LjQ4NjM3IDEuMDQ1NDUgNS42ODg2MiAxLjM3NTg5IDUuMTAwNDQgMS45NjQwN0M0LjUxMjI2IDIuNTUyMjYgNC4xODE4MiAzLjM1IDQuMTgxODIgNC4xODE4MkM0LjE4MTgyIDUuMDEzNjMgNC41MTIyNiA1LjgxMTM4IDUuMTAwNDQgNi4zOTk1NkM1LjY4ODYyIDYuOTg3NzQgNi40ODYzNyA3LjMxODE4IDcuMzE4MTggNy4zMTgxOEM4LjE1IDcuMzE4MTggOC45NDc3NCA2Ljk4Nzc0IDkuNTM1OTMgNi4zOTk1NkMxMC4xMjQxIDUuODExMzggMTAuNDU0NSA1LjAxMzYzIDEwLjQ1NDUgNC4xODE4MkMxMC40NTQ1IDMuMzUgMTAuMTI0MSAyLjU1MjI2IDkuNTM1OTMgMS45NjQwN0M4Ljk0Nzc0IDEuMzc1ODkgOC4xNSAxLjA0NTQ1IDcuMzE4MTggMS4wNDU0NVpNNi43OTU0NSAyLjA5MDkxSDcuNTc5NTVWNC4wNjY4Mkw4Ljc5NzUgNS4yODQ3N0w4LjI0MzQxIDUuODM4ODZMNi43OTU0NSA0LjM5MDkxVjIuMDkwOTFaTTAuNTIyNzI3IDcuMzE4MThDMC4zODQwOTEgNy4zMTgxOCAwLjI1MTEzNCA3LjI2MzExIDAuMTUzMTAzIDcuMTY1MDhDMC4wNTUwNzI5IDcuMDY3MDUgMCA2LjkzNDA5IDAgNi43OTU0NUMwIDYuNjU2ODIgMC4wNTUwNzI5IDYuNTIzODYgMC4xNTMxMDMgNi40MjU4M0MwLjI1MTEzNCA2LjMyNzggMC4zODQwOTEgNi4yNzI3MyAwLjUyMjcyNyA2LjI3MjczSDIuNTI0NzdDMi42ODY4MiA2LjY0Mzg2IDIuODk1OTEgNi45OTQwOSAzLjEzNjM2IDcuMzE4MThIMC41MjI3MjdaTTEuMDQ1NDUgNC43MDQ1NUMwLjkwNjgxOSA0LjcwNDU1IDAuNzczODYxIDQuNjQ5NDcgMC42NzU4MyA0LjU1MTQ0QzAuNTc3OCA0LjQ1MzQxIDAuNTIyNzI3IDQuMzIwNDUgMC41MjI3MjcgNC4xODE4MkMwLjUyMjcyNyA0LjA0MzE4IDAuNTc3OCAzLjkxMDIyIDAuNjc1ODMgMy44MTIxOUMwLjc3Mzg2MSAzLjcxNDE2IDAuOTA2ODE5IDMuNjU5MDkgMS4wNDU0NSAzLjY1OTA5SDIuMTE3MDVMMi4wOTA5MSA0LjE4MTgyTDIuMTE3MDUgNC43MDQ1NUgxLjA0NTQ1Wk0xLjU2ODE4IDIuMDkwOTFDMS40Mjk1NSAyLjA5MDkxIDEuMjk2NTkgMi4wMzU4NCAxLjE5ODU2IDEuOTM3ODFDMS4xMDA1MyAxLjgzOTc4IDEuMDQ1NDUgMS43MDY4MiAxLjA0NTQ1IDEuNTY4MThDMS4wNDU0NSAxLjQyOTU1IDEuMTAwNTMgMS4yOTY1OSAxLjE5ODU2IDEuMTk4NTZDMS4yOTY1OSAxLjEwMDUzIDEuNDI5NTUgMS4wNDU0NSAxLjU2ODE4IDEuMDQ1NDVIMy4xMzYzNkMyLjg5NTkxIDEuMzY5NTUgMi42ODY4MiAxLjcxOTc3IDIuNTI0NzcgMi4wOTA5MUgxLjU2ODE4WlwiXG4gICAgICAgICAgICAgICAgICBmaWxsPVwiIzE1ODAzQ1wiXG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgIEluc3RhbnQgUmVmdW5kXG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICBAaWYgKGhhc0xveWFsdHlQb2ludHNSZWZ1bmQoKSAmJiAhaGFzQ2FzaFdhbGxldFJlZnVuZCgpKSB7XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbm90aWNlIHNiZC1jYW5jZWxfX25vdGljZS0taW5mb1wiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktaW5mby1jaXJjbGVcIj48L2k+XG4gICAgICAgICAgICAgICAgPHNwYW4+RXh0ZXJuYWwgbG95YWx0eSBwb2ludHMgYXJlIHJlZnVuZGVkIHRvIHlvdXIgYWxtYXRhciBXYWxsZXQgYXMgcGVybWFuZW50IHBvaW50cyBhbmQgcmVhZHkgdG8gdXNlIGluIHlvdXIgbmV4dCBib29raW5nLjwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1yYWRpb1wiPjwvc3Bhbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIH1cblxuICAgICAgICA8IS0tIE9yaWdpbmFsIHBheW1lbnQgbWV0aG9kIOKAlCByZXBsYWNlZCB3aXRoIGEgXCJTcGxpdCBSZWZ1bmRcIiBjYXJkIHdoZW5ldmVyXG4gICAgICAgICAgICAgcGFydCBvZiB0aGUgcmVmdW5kIGlzIGZvcmNlZCB0byB0aGUgd2FsbGV0IChlLmcuIGxveWFsdHkgcG9pbnRzIHVzZWQpLFxuICAgICAgICAgICAgIHNpbmNlIHRoZSB0b3RhbCBjYW4ndCBnbyAxMDAlIHRvIHRoZSBvcmlnaW5hbCBwYXltZW50IG1ldGhvZC5cbiAgICAgICAgICAgICBOYW1lL2Rlc2MvYmFkZ2UvaWNvbiBiZWNvbWUgZ2F0ZXdheS1zcGVjaWZpYyBmb3IgaW5zdGFsbG1lbnQgKFRhbWFyYSxcbiAgICAgICAgICAgICBUYWJieSkgYW5kIGxveWFsdHkgKEFsIFJhamhpIE1va2FmYWEpIHBheW1lbnQgbWV0aG9kcy4gLS0+XG4gICAgICAgIEBpZiAoIWhhc1NwbGl0UmVmdW5kKCkgJiYgIWlzV2FsbGV0T25seVJlZnVuZCgpICYmICFpc0xveWFsdHlPbmx5UmVmdW5kKCkpIHtcbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2Qtb3B0aW9uXCJcbiAgICAgICAgICBbbmdDbGFzc109XCJ7ICdzYmQtY2FuY2VsX19tZXRob2Qtb3B0aW9uLS1hY3RpdmUnOiBwcmVmZXJyZWRSZWZ1bmRNZXRob2QoKSA9PT0gJ29yaWdpbmFsUGF5bWVudE1ldGhvZCcgfVwiXG4gICAgICAgICAgKGNsaWNrKT1cInByZWZlcnJlZFJlZnVuZE1ldGhvZC5zZXQoJ29yaWdpbmFsUGF5bWVudE1ldGhvZCcpXCI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtaWNvblwiPlxuICAgICAgICAgICAgPGkgY2xhc3M9XCJwaVwiIFtuZ0NsYXNzXT1cImlzU3BlY2lhbEdhdGV3YXlNZXRob2QoKSA/ICdwaS13YWxsZXQnIDogJ3BpLWNyZWRpdC1jYXJkJ1wiPjwvaT5cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtYm9keS10ZXh0XCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1uYW1lXCI+e3sgb3JpZ2luYWxQYXltZW50TGFiZWwoKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLWRlc2NcIj5cbiAgICAgICAgICAgICAgQGlmIChpc0luc3RhbGxtZW50TWV0aG9kKCkpIHtcbiAgICAgICAgICAgICAgICBSZXR1cm5lZCB0byB5b3VyIHt7IGN1c3RvbWVyUGF5bWVudExhYmVsKCkgfX0gaW5zdGFsbG1lbnQgcGxhblxuICAgICAgICAgICAgICB9IEBlbHNlIGlmIChpc0xveWFsdHlNZXRob2QoKSkge1xuICAgICAgICAgICAgICAgIFJlZnVuZGVkIHRvIHlvdXIge3sgY3VzdG9tZXJQYXltZW50TGFiZWwoKSB9fSBhY2NvdW50XG4gICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgIFJldHVybmVkIHRvIHlvdXIgb3JpZ2luYWwgcGF5bWVudCBtZXRob2RcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtYmFkZ2VcIiBbbmdDbGFzc109XCJpc0xveWFsdHlNZXRob2QoKSA/ICdzYmQtY2FuY2VsX19tZXRob2QtYmFkZ2UtLWxveWFsdHknIDogJ3NiZC1jYW5jZWxfX21ldGhvZC1iYWRnZS0tZGF5cydcIj5cbiAgICAgICAgICAgICAgQGlmICghaXNMb3lhbHR5TWV0aG9kKCkpIHtcbiAgICAgICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTJcIiBoZWlnaHQ9XCIxMlwiIHZpZXdCb3g9XCIwIDAgMTIgMTJcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgICAgICAgICAgIDxwYXRoXG4gICAgICAgICAgICAgICAgICAgIGQ9XCJNMy4zMDA3OCA2LjUwMTk1QzMuMjAzMTIgNi41MDE5NSAzLjEyMTc0IDYuNDY5NCAzLjA1NjY0IDYuNDA0M0MyLjk5MTU0IDYuMzM5MTkgMi45NTg5OCA2LjI1NzgxIDIuOTU4OTggNi4xNjAxNkMyLjk1ODk4IDYuMDY1NzYgMi45OTE1NCA1Ljk4NiAzLjA1NjY0IDUuOTIwOUMzLjEyMTc0IDUuODU1NzkgMy4yMDMxMiA1LjgyMzI0IDMuMzAwNzggNS44MjMyNEg1LjUxMjdWMi44NjkxNEM1LjUxMjcgMi43NzQ3NCA1LjU0NTI1IDIuNjk0OTkgNS42MTAzNSAyLjYyOTg4QzUuNjc1NDYgMi41NjQ3OCA1Ljc1NTIxIDIuNTMyMjMgNS44NDk2MSAyLjUzMjIzQzUuOTQ3MjcgMi41MzIyMyA2LjAyODY1IDIuNTY0NzggNi4wOTM3NSAyLjYyOTg4QzYuMTU4ODUgMi42OTQ5OSA2LjE5MTQxIDIuNzc0NzQgNi4xOTE0MSAyLjg2OTE0VjYuMTYwMTZDNi4xOTE0MSA2LjI1NzgxIDYuMTU4ODUgNi4zMzkxOSA2LjA5Mzc1IDYuNDA0M0M2LjAyODY1IDYuNDY5NCA1Ljk0NzI3IDYuNTAxOTUgNS44NDk2MSA2LjUwMTk1SDMuMzAwNzhaTTUuODU0NDkgMTAuOTU1MUM1LjE2NzY0IDEwLjk1NTEgNC41MjMxMSAxMC44MjQ5IDMuOTIwOSAxMC41NjQ1QzMuMzE4NjggMTAuMzA3MyAyLjc4OTcxIDkuOTUwODUgMi4zMzM5OCA5LjQ5NTEyQzEuODc4MjYgOS4wMzkzOSAxLjUyMDE4IDguNTEwNDIgMS4yNTk3NyA3LjkwODJDMS4wMDI2IDcuMzA1OTkgMC44NzQwMjMgNi42NjE0NiAwLjg3NDAyMyA1Ljk3NDYxQzAuODc0MDIzIDUuMjg3NzYgMS4wMDI2IDQuNjQzMjMgMS4yNTk3NyA0LjA0MTAyQzEuNTIwMTggMy40Mzg4IDEuODc4MjYgMi45MDk4MyAyLjMzMzk4IDIuNDU0MUMyLjc4OTcxIDEuOTk1MTIgMy4zMTg2OCAxLjYzNzA0IDMuOTIwOSAxLjM3OTg4QzQuNTIzMTEgMS4xMjI3MiA1LjE2NzY0IDAuOTk0MTQxIDUuODU0NDkgMC45OTQxNDFDNi41NDEzNCAwLjk5NDE0MSA3LjE4NTg3IDEuMTIyNzIgNy43ODgwOSAxLjM3OTg4QzguMzkwMyAxLjYzNzA0IDguOTE5MjcgMS45OTUxMiA5LjM3NSAyLjQ1NDFDOS44MzA3MyAyLjkwOTgzIDEwLjE4NzIgMy40Mzg4IDEwLjQ0NDMgNC4wNDEwMkMxMC43MDQ4IDQuNjQzMjMgMTAuODM1IDUuMjg3NzYgMTAuODM1IDUuOTc0NjFDMTAuODM1IDYuNjYxNDYgMTAuNzA0OCA3LjMwNTk5IDEwLjQ0NDMgNy45MDgyQzEwLjE4NzIgOC41MTA0MiA5LjgzMDczIDkuMDM5MzkgOS4zNzUgOS40OTUxMkM4LjkxOTI3IDkuOTUwODUgOC4zOTAzIDEwLjMwNzMgNy43ODgwOSAxMC41NjQ1QzcuMTg1ODcgMTAuODI0OSA2LjU0MTM0IDEwLjk1NTEgNS44NTQ0OSAxMC45NTUxWk01Ljg1NDQ5IDEwLjEyNUM2LjQyNzQxIDEwLjEyNSA2Ljk2NDUyIDEwLjAxNzYgNy40NjU4MiA5LjgwMjczQzcuOTY3MTIgOS41ODc4OSA4LjQwODIgOS4yOTAwNCA4Ljc4OTA2IDguOTA5MThDOS4xNjk5MiA4LjUyODMyIDkuNDY3NzcgOC4wODcyNCA5LjY4MjYyIDcuNTg1OTRDOS44OTc0NiA3LjA4NDY0IDEwLjAwNDkgNi41NDc1MyAxMC4wMDQ5IDUuOTc0NjFDMTAuMDA0OSA1LjQwMTY5IDkuODk3NDYgNC44NjQ1OCA5LjY4MjYyIDQuMzYzMjhDOS40Njc3NyAzLjg1ODcyIDkuMTY5OTIgMy40MTc2NCA4Ljc4OTA2IDMuMDQwMDRDOC40MDgyIDIuNjU5MTggNy45NjcxMiAyLjM2MTMzIDcuNDY1ODIgMi4xNDY0OEM2Ljk2NDUyIDEuOTMxNjQgNi40Mjc0MSAxLjgyNDIyIDUuODU0NDkgMS44MjQyMkM1LjI4MTU4IDEuODI0MjIgNC43NDQ0NyAxLjkzMTY0IDQuMjQzMTYgMi4xNDY0OEMzLjc0MTg2IDIuMzYxMzMgMy4zMDA3OCAyLjY1OTE4IDIuOTE5OTIgMy4wNDAwNEMyLjUzOTA2IDMuNDE3NjQgMi4yNDEyMSAzLjg1ODcyIDIuMDI2MzcgNC4zNjMyOEMxLjgxMTUyIDQuODY0NTggMS43MDQxIDUuNDAxNjkgMS43MDQxIDUuOTc0NjFDMS43MDQxIDYuNTQ3NTMgMS44MTE1MiA3LjA4NDY0IDIuMDI2MzcgNy41ODU5NEMyLjI0MTIxIDguMDg3MjQgMi41MzkwNiA4LjUyODMyIDIuOTE5OTIgOC45MDkxOEMzLjMwMDc4IDkuMjkwMDQgMy43NDE4NiA5LjU4Nzg5IDQuMjQzMTYgOS44MDI3M0M0Ljc0NDQ3IDEwLjAxNzYgNS4yODE1OCAxMC4xMjUgNS44NTQ0OSAxMC4xMjVaXCJcbiAgICAgICAgICAgICAgICAgICAgZmlsbD1cIiMwQjU0QzJcIlxuICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgPHN2ZyB3aWR0aD1cIjEyXCIgaGVpZ2h0PVwiMTJcIiB2aWV3Qm94PVwiMCAwIDEyIDEyXCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgICAgICAgICAgICAgICA8Y2lyY2xlIGN4PVwiNlwiIGN5PVwiNlwiIHI9XCI1XCIgc3Ryb2tlPVwiIzBCNTRDMlwiIHN0cm9rZS13aWR0aD1cIjEuMlwiIC8+XG4gICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTYgNS41djNNNiAzLjl2LjAxXCIgc3Ryb2tlPVwiIzBCNTRDMlwiIHN0cm9rZS13aWR0aD1cIjEuMlwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiAvPlxuICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHt7IGNhcmRCYWRnZVRleHQoKSB9fVxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX29wdGlvbi1lbmRcIj5cbiAgICAgICAgICAgIEBpZiAoaXNNYWRhTWV0aG9kKCkpIHtcbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tYWRhLWxvZ29cIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibWFkYUxvZ29cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtcmFkaW9cIj48L3NwYW4+XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgfVxuXG4gICAgICAgIDwhLS0gU3BsaXQgUmVmdW5kIC0tPlxuICAgICAgICBAaWYgKGhhc1NwbGl0UmVmdW5kKCkpIHtcbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2Qtb3B0aW9uIHNiZC1jYW5jZWxfX21ldGhvZC1vcHRpb24tLXNwbGl0XCJcbiAgICAgICAgICBbbmdDbGFzc109XCJ7ICdzYmQtY2FuY2VsX19tZXRob2Qtb3B0aW9uLS1hY3RpdmUnOiBwcmVmZXJyZWRSZWZ1bmRNZXRob2QoKSA9PT0gJ3NwbGl0JyB9XCJcbiAgICAgICAgICAoY2xpY2spPVwicHJlZmVycmVkUmVmdW5kTWV0aG9kLnNldCgnc3BsaXQnKVwiPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLWljb25cIj48aSBjbGFzcz1cInBpIHBpLXdhbGxldFwiPjwvaT48L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtYm9keS10ZXh0XCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1uYW1lXCI+U3BsaXQgUmVmdW5kPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtZGVzY1wiPlJldHVybmVkIHRvIHlvdXIgb3JpZ2luYWwgcGF5bWVudCBtZXRob2Q8L3NwYW4+XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDxzdHJvbmcgY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2Qtc3BsaXQtdG90YWxcIj57eyBmbXQoYWRqdXN0ZWREYXRhKCk/LnRvdGFsUmVmdW5kQW1vdW50KSB9fTwvc3Ryb25nPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLXJhZGlvXCI+PC9zcGFuPlxuXG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2Qtc3BsaXQtYnJlYWtkb3duXCI+XG4gICAgICAgICAgICBAZm9yIChyb3cgb2Ygc3BsaXRSZWZ1bmRSb3dzKCk7IHRyYWNrIHJvdy5sYWJlbCkge1xuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1zcGxpdC1yb3dcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1zcGxpdC1sYWJlbFwiPlxuICAgICAgICAgICAgICAgICAge3sgcm93LmxhYmVsIH19XG4gICAgICAgICAgICAgICAgICBAaWYgKHJvdy5pc01hZGEpIHtcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tYWRhLWxvZ29cIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibWFkYUxvZ29cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3Ryb25nPnt7IGZtdChyb3cudmFsdWUpIH19PC9zdHJvbmc+XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtYmFkZ2VcIlxuICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInJvdy5pbnN0YW50ID8gJ3NiZC1jYW5jZWxfX21ldGhvZC1iYWRnZS0taW5zdGFudCcgOiAoaXNMb3lhbHR5TWV0aG9kKCkgPyAnc2JkLWNhbmNlbF9fbWV0aG9kLWJhZGdlLS1sb3lhbHR5JyA6ICdzYmQtY2FuY2VsX19tZXRob2QtYmFkZ2UtLWRheXMnKVwiPlxuICAgICAgICAgICAgICAgIHt7IHJvdy5iYWRnZVRleHQgfX1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICBAaWYgKHJvdy5pc0xveWFsdHkpIHtcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX25vdGljZSBzYmQtY2FuY2VsX19ub3RpY2UtLWluZm9cIj5cbiAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktaW5mby1jaXJjbGVcIj48L2k+XG4gICAgICAgICAgICAgICAgICA8c3Bhbj5FeHRlcm5hbCBsb3lhbHR5IHBvaW50cyBhcmUgcmVmdW5kZWQgdG8geW91ciBhbG1hdGFyIFdhbGxldCBhcyBwZXJtYW5lbnQgcG9pbnRzIGFuZCByZWFkeSB0byB1c2UgaW4geW91ciBuZXh0IGJvb2tpbmcuPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19mb290ZXJcIj5cbiAgICAgICAgPGJ1dHRvbiBwQnV0dG9uXG4gICAgICAgICAgc3R5bGVDbGFzcz1cInNiZC1jYW5jZWxfX2J0bi1kYW5nZXItcGlsbFwiXG4gICAgICAgICAgW2xhYmVsXT1cImNhbmNlbGxpbmcoKSA/ICdDYW5jZWxsaW5nLi4uJyA6ICdDb25maXJtIENhbmNlbGxhdGlvbidcIlxuICAgICAgICAgIFtkaXNhYmxlZF09XCJjYW5jZWxsaW5nKClcIiAoY2xpY2spPVwiY29uZmlybSgpXCI+PC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICB9XG5cbiAgICA8IS0tIE1haW4gY2FyZCAtLT5cbiAgICBAZWxzZSBpZiAocmVmdW5kRGF0YSgpICYmIHN0ZXAoKSA9PT0gJ2RldGFpbHMnKSB7XG4gICAgICA8IS0tIENhcmQgaGVhZGVyIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2hlYWRlciBzYmQtY2FuY2VsX19oZWFkZXItLXN0YWNrXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19oZWFkZXItdGl0bGVzXCI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19oZWFkZXItdGl0bGVcIj5DYW5jZWwgQm9va2luZyBSZXF1ZXN0PC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9faGVhZGVyLXN1YlwiPiN7eyByZWZ1bmREYXRhKCk/LmJvb2tpbmdJZCA/PyBib29raW5nSWQoKSB9fTwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2JkLWNhbmNlbF9fY2xvc2UtYnRuXCIgKGNsaWNrKT1cImNsb3NlZC5lbWl0KClcIiBhcmlhLWxhYmVsPVwiQ2xvc2VcIj5cbiAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLXRpbWVzXCI+PC9pPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fYm9keVwiPlxuXG4gICAgICAgIDwhLS0gTm9uLXJlZnVuZGFibGUgLS0+XG4gICAgICAgIEBpZiAoIXJlZnVuZERhdGEoKT8uaXNSZWZ1bmRhYmxlKSB7XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX25vdGljZSBzYmQtY2FuY2VsX19ub3RpY2UtLXdhcm5pbmdcIj5cbiAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktZXhjbGFtYXRpb24tdHJpYW5nbGVcIj48L2k+XG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICA8c3Ryb25nPlRoaXMgYm9va2luZyBpcyBub3QgZWxpZ2libGUgZm9yIGEgcmVmdW5kLjwvc3Ryb25nPlxuICAgICAgICAgICAgICBAaWYgKHJlZnVuZERhdGEoKT8uY2F1c2UpIHtcbiAgICAgICAgICAgICAgICA8cD57eyByZWZ1bmREYXRhKCk/LmNhdXNlIH19PC9wPlxuICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICA8cD5QbGVhc2UgZXNjYWxhdGUgdG8gdGhlIHJlbGV2YW50IHRlYW0gZm9yIG1hbnVhbCBoYW5kbGluZy48L3A+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICB9XG5cbiAgICAgICAgPCEtLSBSZWZ1bmRhYmxlIGZsb3cgLS0+XG4gICAgICAgIEBlbHNlIHtcblxuICAgICAgICAgIDwhLS0gVG9wIHN1bW1hcnk6IHBhaWQgLyBnZXQgYmFjayAtLT5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fc3VtbWFyeVwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3N1bW1hcnktcm93XCJcbiAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyAnc2JkLWNhbmNlbF9fc3VtbWFyeS1yb3ctLXRvZ2dsZSc6IGhhc1BhaWRCcmVha2Rvd24oKSAmJiAhIWFkanVzdGVkRGF0YSgpPy50b3RhbFdhbGxldEFtb3VudCB9XCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cImhhc1BhaWRCcmVha2Rvd24oKSAmJiAhIWFkanVzdGVkRGF0YSgpPy50b3RhbFdhbGxldEFtb3VudCAmJiB0b2dnbGVQYWlkU3VtbWFyeSgpXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fc3VtbWFyeS1sYWJlbFwiPjxpIGNsYXNzPVwicGkgcGktd2FsbGV0XCI+PC9pPiBUb3RhbCBwYWlkPC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX3N1bW1hcnktdmFsdWVcIj5cbiAgICAgICAgICAgICAgICA8c3Ryb25nPnt7IGZtdChhZGp1c3RlZERhdGEoKT8ub3JpZ2luYWxBbW91bnQpIH19PC9zdHJvbmc+XG4gICAgICAgICAgICAgICAgQGlmIChoYXNQYWlkQnJlYWtkb3duKCkgJiYgISFhZGp1c3RlZERhdGEoKT8udG90YWxXYWxsZXRBbW91bnQpIHtcbiAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLWNoZXZyb25cIlxuICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7ICdzYmQtY2FuY2VsX19sZWctY2hldnJvbi0tY29sbGFwc2VkJzogIXBhaWRTdW1tYXJ5RXhwYW5kZWQoKSB9XCJcbiAgICAgICAgICAgICAgICAgICAgYXJpYS1sYWJlbD1cIlRvZ2dsZSBwYWlkIGJyZWFrZG93blwiPlxuICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLWNoZXZyb24tdXBcIj48L2k+XG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICBAaWYgKGhhc1BhaWRCcmVha2Rvd24oKSAmJiBwYWlkU3VtbWFyeUV4cGFuZGVkKCkgJiYgISFhZGp1c3RlZERhdGEoKT8udG90YWxXYWxsZXRBbW91bnQpIHtcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3N1bW1hcnktYnJlYWtkb3duXCI+XG4gICAgICAgICAgICAgICAgQGZvciAocm93IG9mIHBhaWRCcmVha2Rvd25Sb3dzKCk7IHRyYWNrIHJvdy5sYWJlbCkge1xuICAgICAgICAgICAgICAgICAgQGlmIChyb3cubGFiZWwgPT09ICdBbG1hdGFyIFdhbGxldCcpIHtcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3N1bW1hcnktYnJlYWtkb3duLXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7IHJvdy5sYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj57eyBmbXQocm93LnZhbHVlKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3N1bW1hcnktcm93IHNiZC1jYW5jZWxfX3N1bW1hcnktcm93LS1yZWZ1bmRcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19zdW1tYXJ5LWxhYmVsXCI+PGkgY2xhc3M9XCJwaSBwaS1kb2xsYXJcIj48L2k+IFlvdSB3aWxsIGdldCBiYWNrPC9zcGFuPlxuICAgICAgICAgICAgICA8c3Ryb25nPnt7IGZtdChhZGp1c3RlZERhdGEoKT8udG90YWxSZWZ1bmRBbW91bnQpIH19PC9zdHJvbmc+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDwhLS0gR29sZGVuIEd1YXJhbnRlZSBnaWZ0IOKAlCBvdmVycmlkZXMgY3JlZGl0LXNoZWxsIG1lc3NhZ2luZyBiZWxvdyAtLT5cbiAgICAgICAgICBAaWYgKGhhc0dvbGRlbkd1YXJhbnRlZUdpZnQoKSkge1xuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX25vdGljZSBzYmQtY2FuY2VsX19ub3RpY2UtLXN1Y2Nlc3NcIj5cbiAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1zaGllbGRcIj48L2k+XG4gICAgICAgICAgICAgIDxzcGFuPllvdSdyZSBjb3ZlcmVkIGJ5IENhbmNlbCBmb3IgYW55IHJlYXNvbiBzZXJ2aWNlLCB5b3UnbGwgZ2V0IDEwMCUgcmVmdW5kLCBtaW51cyBhbnkgYXBwbGljYWJsZSBmZWVzLiBTZWUgdGhlIGJyZWFrZG93biBiZWxvdy48L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICA8IS0tIE9uZS13YXkgKG9yIGEgcm91bmQtdHJpcCByZXN0cmljdGVkIHRvIGEgc2luZ2xlIGxlZyk6IHNpbmdsZSBjYXJkIC0tPlxuICAgICAgICAgIEBpZiAoIXNob3dSb3VuZFRyaXBMZWdDYXJkcygpKSB7XG4gICAgICAgICAgICA8IS0tIFNvdXJjZSBzZWxlY3RvciAobXVsdGlwbGUgc3VwcGxpZXJzKSAtLT5cbiAgICAgICAgICAgIEBpZiAoYXZhaWxhYmxlU291cmNlcygpLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3NvdXJjZS1zZWxlY3RvclwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fc291cmNlLWxhYmVsXCI+Q2FuY2VsIHZpYTwvc3Bhbj5cbiAgICAgICAgICAgICAgICBAZm9yIChzcmMgb2YgYXZhaWxhYmxlU291cmNlcygpOyB0cmFjayBzcmMpIHtcbiAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJzYmQtY2FuY2VsX19zb3VyY2UtY2hpcFwiXG4gICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIntcbiAgICAgICAgICAgICAgICAgICAgICAnc2JkLWNhbmNlbF9fc291cmNlLWNoaXAtLWFjdGl2ZSc6ICAgIHNlbGVjdGVkU291cmNlKCkgPT09IHNyYyxcbiAgICAgICAgICAgICAgICAgICAgICAnc2JkLWNhbmNlbF9fc291cmNlLWNoaXAtLW5vLXJlZnVuZCc6IGFjdGl2ZVNvdXJjZUJyZWFrZG93bigpPy5bc3JjXT8uaXNSZWZ1bmRhYmxlID09PSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICB9XCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdGVkU291cmNlLnNldChzcmMpXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7IHNyYyB9fVxuICAgICAgICAgICAgICAgICAgICBAaWYgKGFjdGl2ZVNvdXJjZUJyZWFrZG93bigpPy5bc3JjXT8uaXNSZWZ1bmRhYmxlID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktYmFuXCIgc3R5bGU9XCJmb250LXNpemU6MTBweDsgbWFyZ2luLWxlZnQ6NHB4O1wiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgQGlmIChzb3VyY2VOb25SZWZ1bmRhYmxlSGludCgpKSB7XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX25vdGljZSBzYmQtY2FuY2VsX19ub3RpY2UtLXdhcm5pbmdcIj5cbiAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktYmFuXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgc291cmNlTm9uUmVmdW5kYWJsZUhpbnQoKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICA8IS0tIE5vdCByZWZ1bmRhYmxlIC0tPlxuICAgICAgICAgICAgQGlmICghY3VycmVudERhdGEoKT8uaXNSZWZ1bmRhYmxlKSB7XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19ub3RpY2Ugc2JkLWNhbmNlbF9fbm90aWNlLS13YXJuaW5nXCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1iYW5cIj48L2k+XG4gICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgIDxzdHJvbmc+VGhpcyBsZWcgaXMgbm90IGVsaWdpYmxlIGZvciBhIHJlZnVuZC48L3N0cm9uZz5cbiAgICAgICAgICAgICAgICAgIDxwPlBsZWFzZSBlc2NhbGF0ZSB0byB0aGUgcmVsZXZhbnQgdGVhbSBmb3IgbWFudWFsIGhhbmRsaW5nLjwvcD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3NlY3Rpb24tdGl0bGVcIj5SZWZ1bmQgRGV0YWlsczwvZGl2PlxuXG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19yZWZ1bmQtY2FyZFwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fYmFkZ2Ugc2JkLWNhbmNlbF9fYmFkZ2UtLW91dGxpbmUgc2JkLWNhbmNlbF9fYmFkZ2UtLWdyZWVuXCI+UmVmdW5kYWJsZTwvc3Bhbj5cblxuICAgICAgICAgICAgICAgIEBpZiAocmVmdW5kYWJsZUJyZWFrZG93blJvd3MoYWRqdXN0ZWREYXRhKCkpLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgQGZvciAociBvZiByZWZ1bmRhYmxlQnJlYWtkb3duUm93cyhhZGp1c3RlZERhdGEoKSk7IHRyYWNrIHIubGFiZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3JlZnVuZC1jYXJkLXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7IHIubGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgPHN0cm9uZz57eyBmbXQoci52YWx1ZSkgfX08L3N0cm9uZz5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fcmVmdW5kLWNhcmQtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuPkZhcmU8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxzdHJvbmc+e3sgZm10KGFkanVzdGVkRGF0YSgpPy5vcmlnaW5hbEFtb3VudCkgfX08L3N0cm9uZz5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIDwhLS0gaGlkZSBhZGRvbiBub3RlIG5ldyBDUiBmcm9tIENYIC0tPlxuICAgICAgICAgICAgICAgIDwhLS0gQGlmIChoYXNSZWZ1bmRhYmxlQWRkb25Ob3RlKGFkanVzdGVkRGF0YSgpKSkge1xuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX25vdGljZSBzYmQtY2FuY2VsX19ub3RpY2UtLW5ldXRyYWxcIj5cbiAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1pbmZvLWNpcmNsZVwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+WW91ciBhZGQtb24gc2VydmljZS9zIHJlZnVuZCB3aWxsIGJlIHByb2Nlc3NlZCBzZXBhcmF0ZWx5IGJ5IG91ciBDdXN0b21lciBTZXJ2aWNlIHRlYW0gc2hvcnRseS48L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB9IC0tPlxuXG4gICAgICAgICAgICAgICAgPCEtLSBEZWR1Y3Rpb25zIC0tPlxuICAgICAgICAgICAgICAgIEBpZiAoZGVkdWN0aW9ucygpLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3JlZnVuZC1jYXJkLWRpdmlkZXJcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fYmFkZ2Ugc2JkLWNhbmNlbF9fYmFkZ2UtLW91dGxpbmUgc2JkLWNhbmNlbF9fYmFkZ2UtLW11dGVkXCI+Tm90IFJlZnVuZGVkIC0gRGVkdWN0aW9uczwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIEBmb3IgKGQgb2YgZGVkdWN0aW9ucygpOyB0cmFjayBkLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19yZWZ1bmQtY2FyZC1saW5lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICB7eyBkLmxhYmVsIH19XG4gICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGQuYmFkZ2UpIHsgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX190YWdcIj57eyBkLmJhZGdlIH19PC9zcGFuPiB9XG4gICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fcmVmdW5kLWNhcmQtbGluZS0tbmVnXCI+e3sgZm10TmVnKGQudmFsdWUpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fcmVmdW5kLWNhcmQtZGl2aWRlciBzYmQtY2FuY2VsX19yZWZ1bmQtY2FyZC1kaXZpZGVyLS1kYXNoZWRcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fcmVmdW5kLWNhcmQtdG90YWxcIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuPlRvdGFsIFJlZnVuZDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxzdHJvbmc+e3sgZm10KGFkanVzdGVkRGF0YSgpPy50b3RhbFJlZnVuZEFtb3VudCkgfX08L3N0cm9uZz5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgPCEtLSBDcmVkaXQgc2hlbGwgLS0+XG4gICAgICAgICAgICAgIEBpZiAoY3JlZGl0U2hlbGxOb3RlKCkpIHtcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbm90aWNlIHNiZC1jYW5jZWxfX25vdGljZS0tY3JlZGl0XCI+XG4gICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLXdhbGxldFwiPjwvaT5cbiAgICAgICAgICAgICAgICAgIDxzcGFuPuKEue+4jyB7eyBjcmVkaXRTaGVsbE5vdGUoKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIDwhLS0gUm91bmQgdHJpcDogb25lIGNvbGxhcHNpYmxlIGNhcmQgcGVyIGxlZyAob25seSB3aGVuIGJvdGggbGVncyBhcmUgY2FuY2VsbGFibGUpIC0tPlxuICAgICAgICAgIEBpZiAoc2hvd1JvdW5kVHJpcExlZ0NhcmRzKCkpIHtcbiAgICAgICAgICAgIDwhLS0gR2lmdCBoaW50IC0tPlxuICAgICAgICAgICAgQGlmIChnaWZ0SGludCgpKSB7XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19ub3RpY2Ugc2JkLWNhbmNlbF9fbm90aWNlLS10aXBcIj5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLWluZm8tY2lyY2xlXCI+PC9pPlxuICAgICAgICAgICAgICAgIDxzcGFuPnt7IGdpZnRIaW50KCkgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICA8IS0tIE1peGVkIGhpbnQgLS0+XG4gICAgICAgICAgICBAaWYgKG1peGVkSGludCgpKSB7XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19ub3RpY2Ugc2JkLWNhbmNlbF9fbm90aWNlLS13YXJuaW5nXCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1leGNsYW1hdGlvbi10cmlhbmdsZVwiPjwvaT5cbiAgICAgICAgICAgICAgICA8c3Bhbj57eyBtaXhlZEhpbnQoKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIDwhLS0gU291cmNlIHNlbGVjdG9yIChtdWx0aXBsZSBzdXBwbGllcnMpIC0tPlxuICAgICAgICAgICAgQGlmIChhdmFpbGFibGVTb3VyY2VzKCkubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fc291cmNlLXNlbGVjdG9yXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19zb3VyY2UtbGFiZWxcIj5DYW5jZWwgdmlhPC9zcGFuPlxuICAgICAgICAgICAgICAgIEBmb3IgKHNyYyBvZiBhdmFpbGFibGVTb3VyY2VzKCk7IHRyYWNrIHNyYykge1xuICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInNiZC1jYW5jZWxfX3NvdXJjZS1jaGlwXCJcbiAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAgICAgICAgICAgICAgICdzYmQtY2FuY2VsX19zb3VyY2UtY2hpcC0tYWN0aXZlJzogICAgc2VsZWN0ZWRTb3VyY2UoKSA9PT0gc3JjLFxuICAgICAgICAgICAgICAgICAgICAgICdzYmQtY2FuY2VsX19zb3VyY2UtY2hpcC0tbm8tcmVmdW5kJzogYWN0aXZlU291cmNlQnJlYWtkb3duKCk/LltzcmNdPy5pc1JlZnVuZGFibGUgPT09IGZhbHNlXG4gICAgICAgICAgICAgICAgICAgIH1cIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwic2VsZWN0ZWRTb3VyY2Uuc2V0KHNyYylcIj5cbiAgICAgICAgICAgICAgICAgICAge3sgc3JjIH19XG4gICAgICAgICAgICAgICAgICAgIEBpZiAoYWN0aXZlU291cmNlQnJlYWtkb3duKCk/LltzcmNdPy5pc1JlZnVuZGFibGUgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1iYW5cIiBzdHlsZT1cImZvbnQtc2l6ZToxMHB4OyBtYXJnaW4tbGVmdDo0cHg7XCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICBAaWYgKHNvdXJjZU5vblJlZnVuZGFibGVIaW50KCkpIHtcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbm90aWNlIHNiZC1jYW5jZWxfX25vdGljZS0td2FybmluZ1wiPlxuICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1iYW5cIj48L2k+XG4gICAgICAgICAgICAgICAgICA8c3Bhbj57eyBzb3VyY2VOb25SZWZ1bmRhYmxlSGludCgpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIDwhLS0gT253YXJkIGxlZyBjYXJkIC0tPlxuICAgICAgICAgICAgQGlmIChvbndhcmRDaGVja2VkKCkpIHtcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1jYXJkXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1jYXJkLWhlYWRlclwiIChjbGljayk9XCJ0b2dnbGVMZWdFeHBhbmRlZCgnb253YXJkJylcIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLWNoZWNrYm94XCI+T253YXJkPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctY2hldnJvblwiXG4gICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsgJ3NiZC1jYW5jZWxfX2xlZy1jaGV2cm9uLS1jb2xsYXBzZWQnOiAhb253YXJkRXhwYW5kZWQoKSB9XCJcbiAgICAgICAgICAgICAgICAgICAgYXJpYS1sYWJlbD1cIlRvZ2dsZVwiPlxuICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLWNoZXZyb24tdXBcIj48L2k+XG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIEBpZiAob253YXJkRXhwYW5kZWQoKSkge1xuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1jYXJkLWJvZHlcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19iYWRnZSBzYmQtY2FuY2VsX19iYWRnZS0tb3V0bGluZVwiXG4gICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwibGVnQWRqdXN0ZWREYXRhKCdvbndhcmQnKT8uaXNSZWZ1bmRhYmxlID8gJ3NiZC1jYW5jZWxfX2JhZGdlLS1ncmVlbicgOiAnc2JkLWNhbmNlbF9fYmFkZ2UtLXJlZCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICB7eyBsZWdBZGp1c3RlZERhdGEoJ29ud2FyZCcpPy5pc1JlZnVuZGFibGUgPyAnUmVmdW5kYWJsZScgOiAnTm9uLVJlZnVuZGFibGUnIH19XG4gICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cblxuICAgICAgICAgICAgICAgICAgICBAaWYgKGxlZ0FkanVzdGVkRGF0YSgnb253YXJkJyk/LmlzUmVmdW5kYWJsZSkge1xuICAgICAgICAgICAgICAgICAgICAgIEBpZiAocmVmdW5kYWJsZUJyZWFrZG93blJvd3MobGVnQWRqdXN0ZWREYXRhKCdvbndhcmQnKSkubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBAZm9yIChyIG9mIHJlZnVuZGFibGVCcmVha2Rvd25Sb3dzKGxlZ0FkanVzdGVkRGF0YSgnb253YXJkJykpOyB0cmFjayByLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19yZWZ1bmQtY2FyZC1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj57eyByLmxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdHJvbmc+e3sgZm10KHIudmFsdWUpIH19PC9zdHJvbmc+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3JlZnVuZC1jYXJkLXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj5GYXJlPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Ryb25nPnt7IGZtdChsZWdSZWZ1bmRQb29sKCdvbndhcmQnKSkgfX08L3N0cm9uZz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgIDwhLS0gaGlkZSBhZGRvbiBub3RlIG5ldyBDUiBmcm9tIENYIC0tPlxuICAgICAgICAgICAgICAgICAgICAgIDwhLS0gQGlmIChoYXNSZWZ1bmRhYmxlQWRkb25Ob3RlKGxlZ0FkanVzdGVkRGF0YSgnb253YXJkJykpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbm90aWNlIHNiZC1jYW5jZWxfX25vdGljZS0tbmV1dHJhbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLWluZm8tY2lyY2xlXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj5Zb3VyIGFkZC1vbiBzZXJ2aWNlL3MgcmVmdW5kIHdpbGwgYmUgcHJvY2Vzc2VkIHNlcGFyYXRlbHkgYnkgb3VyIEN1c3RvbWVyIFNlcnZpY2UgdGVhbSBzaG9ydGx5Ljwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgIH0gLS0+XG5cbiAgICAgICAgICAgICAgICAgICAgICBAaWYgKGxlZ0RlZHVjdGlvbnMoJ29ud2FyZCcpLmxlbmd0aCAmJiAhaXNDcmVkaXRTaGVsbCgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fcmVmdW5kLWNhcmQtZGl2aWRlclwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19iYWRnZSBzYmQtY2FuY2VsX19iYWRnZS0tb3V0bGluZSBzYmQtY2FuY2VsX19iYWRnZS0tbXV0ZWRcIj5Ob3QgUmVmdW5kZWQgLSBEZWR1Y3Rpb25zPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgQGZvciAoZCBvZiBsZWdEZWR1Y3Rpb25zKCdvbndhcmQnKTsgdHJhY2sgZC5sYWJlbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fcmVmdW5kLWNhcmQtbGluZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgZC5sYWJlbCB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChkLmJhZGdlKSB7IDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fdGFnXCI+e3sgZC5iYWRnZSB9fTwvc3Bhbj4gfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX3JlZnVuZC1jYXJkLWxpbmUtLW5lZ1wiPnt7IGZtdE5lZyhkLnZhbHVlKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3JlZnVuZC1jYXJkLWRpdmlkZXIgc2JkLWNhbmNlbF9fcmVmdW5kLWNhcmQtZGl2aWRlci0tZGFzaGVkXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3JlZnVuZC1jYXJkLXRvdGFsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj5EZXBhcnR1cmUgVG90YWwgUmVmdW5kPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHN0cm9uZz57eyBmbXQobGVnQWRqdXN0ZWREYXRhKCdvbndhcmQnKT8udG90YWxSZWZ1bmRBbW91bnQpIH19PC9zdHJvbmc+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICBAaWYgKHJlZnVuZERhdGEoKT8ubGVnSW5mbz8ub253YXJkPy5pc0NyZWRpdFNoZWxsICYmICFoYXNHb2xkZW5HdWFyYW50ZWVHaWZ0KCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19ub3RpY2Ugc2JkLWNhbmNlbF9fbm90aWNlLS1jcmVkaXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS13YWxsZXRcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPuKEue+4jyBUaGUgcmVmdW5kIGZvciB0aGUgb253YXJkIGZsaWdodCBoYXMgYmVlbiBpc3N1ZWQgYXMgYW4gQWlybGluZSBDcmVkaXQgU2hlbGwuPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbm90aWNlIHNiZC1jYW5jZWxfX25vdGljZS0td2FybmluZ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1iYW5cIj48L2k+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj5UaGlzIGxlZyBpcyBub3QgZWxpZ2libGUgZm9yIGEgcmVmdW5kLjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgPCEtLSBSZXR1cm4gbGVnIGNhcmQgLS0+XG4gICAgICAgICAgICBAaWYgKHJldHVybkNoZWNrZWQoKSkge1xuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLWNhcmRcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLWNhcmQtaGVhZGVyXCIgKGNsaWNrKT1cInRvZ2dsZUxlZ0V4cGFuZGVkKCdyZXR1cm4nKVwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctY2hlY2tib3hcIj5SZXR1cm48L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1jaGV2cm9uXCJcbiAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyAnc2JkLWNhbmNlbF9fbGVnLWNoZXZyb24tLWNvbGxhcHNlZCc6ICFyZXR1cm5FeHBhbmRlZCgpIH1cIlxuICAgICAgICAgICAgICAgICAgICBhcmlhLWxhYmVsPVwiVG9nZ2xlXCI+XG4gICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktY2hldnJvbi11cFwiPjwvaT5cbiAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgQGlmIChyZXR1cm5FeHBhbmRlZCgpKSB7XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLWNhcmQtYm9keVwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX2JhZGdlIHNiZC1jYW5jZWxfX2JhZGdlLS1vdXRsaW5lXCJcbiAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJsZWdBZGp1c3RlZERhdGEoJ3JldHVybicpPy5pc1JlZnVuZGFibGUgPyAnc2JkLWNhbmNlbF9fYmFkZ2UtLWdyZWVuJyA6ICdzYmQtY2FuY2VsX19iYWRnZS0tcmVkJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgIHt7IGxlZ0FkanVzdGVkRGF0YSgncmV0dXJuJyk/LmlzUmVmdW5kYWJsZSA/ICdSZWZ1bmRhYmxlJyA6ICdOb24tUmVmdW5kYWJsZScgfX1cbiAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuXG4gICAgICAgICAgICAgICAgICAgIEBpZiAobGVnQWRqdXN0ZWREYXRhKCdyZXR1cm4nKT8uaXNSZWZ1bmRhYmxlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgQGlmIChyZWZ1bmRhYmxlQnJlYWtkb3duUm93cyhsZWdBZGp1c3RlZERhdGEoJ3JldHVybicpKS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEBmb3IgKHIgb2YgcmVmdW5kYWJsZUJyZWFrZG93blJvd3MobGVnQWRqdXN0ZWREYXRhKCdyZXR1cm4nKSk7IHRyYWNrIHIubGFiZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3JlZnVuZC1jYXJkLXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7IHIubGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN0cm9uZz57eyBmbXQoci52YWx1ZSkgfX08L3N0cm9uZz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fcmVmdW5kLWNhcmQtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPkZhcmU8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzdHJvbmc+e3sgZm10KGxlZ1JlZnVuZFBvb2woJ3JldHVybicpKSB9fTwvc3Ryb25nPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgPCEtLSBoaWRlIGFkZG9uIG5vdGUgbmV3IENSIGZyb20gQ1ggLS0+XG4gICAgICAgICAgICAgICAgICAgICAgPCEtLSBAaWYgKGhhc1JlZnVuZGFibGVBZGRvbk5vdGUobGVnQWRqdXN0ZWREYXRhKCdyZXR1cm4nKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19ub3RpY2Ugc2JkLWNhbmNlbF9fbm90aWNlLS1uZXV0cmFsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktaW5mby1jaXJjbGVcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPllvdXIgYWRkLW9uIHNlcnZpY2UvcyByZWZ1bmQgd2lsbCBiZSBwcm9jZXNzZWQgc2VwYXJhdGVseSBieSBvdXIgQ3VzdG9tZXIgU2VydmljZSB0ZWFtIHNob3J0bHkuPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgfSAtLT5cblxuICAgICAgICAgICAgICAgICAgICAgIEBpZiAobGVnRGVkdWN0aW9ucygncmV0dXJuJykubGVuZ3RoICYmICFpc0NyZWRpdFNoZWxsKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19yZWZ1bmQtY2FyZC1kaXZpZGVyXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX2JhZGdlIHNiZC1jYW5jZWxfX2JhZGdlLS1vdXRsaW5lIHNiZC1jYW5jZWxfX2JhZGdlLS1tdXRlZFwiPk5vdCBSZWZ1bmRlZCAtIERlZHVjdGlvbnM8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICBAZm9yIChkIG9mIGxlZ0RlZHVjdGlvbnMoJ3JldHVybicpOyB0cmFjayBkLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19yZWZ1bmQtY2FyZC1saW5lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBkLmxhYmVsIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGQuYmFkZ2UpIHsgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX190YWdcIj57eyBkLmJhZGdlIH19PC9zcGFuPiB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fcmVmdW5kLWNhcmQtbGluZS0tbmVnXCI+e3sgZm10TmVnKGQudmFsdWUpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fcmVmdW5kLWNhcmQtZGl2aWRlciBzYmQtY2FuY2VsX19yZWZ1bmQtY2FyZC1kaXZpZGVyLS1kYXNoZWRcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fcmVmdW5kLWNhcmQtdG90YWxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPlJldHVybiBUb3RhbCBSZWZ1bmQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3Ryb25nPnt7IGZtdChsZWdBZGp1c3RlZERhdGEoJ3JldHVybicpPy50b3RhbFJlZnVuZEFtb3VudCkgfX08L3N0cm9uZz5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgIEBpZiAocmVmdW5kRGF0YSgpPy5sZWdJbmZvPy5yZXR1cm4/LmlzQ3JlZGl0U2hlbGwgJiYgIWhhc0dvbGRlbkd1YXJhbnRlZUdpZnQoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX25vdGljZSBzYmQtY2FuY2VsX19ub3RpY2UtLWNyZWRpdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLXdhbGxldFwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+4oS577iPIFRoZSByZWZ1bmQgZm9yIHRoZSByZXR1cm4gZmxpZ2h0IGhhcyBiZWVuIGlzc3VlZCBhcyBhbiBBaXJsaW5lIENyZWRpdCBTaGVsbC48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19ub3RpY2Ugc2JkLWNhbmNlbF9fbm90aWNlLS13YXJuaW5nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLWJhblwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPlRoaXMgbGVnIGlzIG5vdCBlbGlnaWJsZSBmb3IgYSByZWZ1bmQuPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIDwhLS0gSW5zdGFudCByZWZ1bmQgbm90aWNlIC0tPlxuICAgICAgICAgIEBpZiAoY3VycmVudERhdGEoKT8uaXNSZWZ1bmRhYmxlKSB7XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbm90aWNlIHNiZC1jYW5jZWxfX25vdGljZS0tc2hpZWxkXCI+XG4gICAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktc2hpZWxkXCI+PC9pPlxuICAgICAgICAgICAgICA8c3Bhbj5cbiAgICAgICAgICAgICAgICBAaWYgKGlzTmlsUmVmdW5kKCkpIHtcbiAgICAgICAgICAgICAgICAgIFdlJ3JlIHNvcnJ5LCBhcyBwZXIgYWlybGluZSBwb2xpY3ksIG5vIHJlZnVuZCBhcHBsaWVzIGJlY2F1c2UgdGhlIGNhbmNlbGxhdGlvbiBmZWVzIGVxdWFsIG9yIGV4Y2VlZCB5b3VyIHJlZnVuZGFibGUgZmFyZSBhbW91bnQuXG4gICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICBAaWYgKGlzV2FsbGV0T25seVJlZnVuZCgpIHx8IGlzTG95YWx0eU9ubHlSZWZ1bmQoKSkge1xuICAgICAgICAgICAgICAgICAgICBZb3VyIHJlZnVuZCBpcyBpbnN0YW50IHRvIHRoZSBjdXN0b21lcidzIGFsbWF0YXIgV2FsbGV0LlxuICAgICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIFlvdXIgcmVmdW5kIGlzIGluc3RhbnQgZnJvbSBvdXIgc2lkZSwgeW91ciBiYW5rIG1heSB0YWtlIHVwIHRvIDE1IGJ1c2luZXNzIGRheXMgdG8gcmVmbGVjdCBpdC5cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgQGlmICghaXNOaWxSZWZ1bmQoKSAmJiAhaXNDcmVkaXRTaGVsbCgpKSB7XG4gICAgICAgICAgICAgICAgICA8c3Ryb25nPllvdSBjYW4gc2VsZWN0IHJlZnVuZCBvcHRpb24gaW4gdGhlIG5leHQgc3RlcDwvc3Ryb25nPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIEZvb3RlciAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19mb290ZXJcIj5cbiAgICAgICAgQGlmIChyZWZ1bmREYXRhKCk/LmlzUmVmdW5kYWJsZSkge1xuICAgICAgICAgIDxidXR0b24gcEJ1dHRvbiBsYWJlbD1cIktlZXAgYm9va2luZ1wiIHN0eWxlQ2xhc3M9XCJwLWJ1dHRvbi1vdXRsaW5lZCBwLWJ1dHRvbi1zZWNvbmRhcnkgc2JkLWNhbmNlbF9fYnRuLWtlZXBcIiAoY2xpY2spPVwiY2xvc2VkLmVtaXQoKVwiPjwvYnV0dG9uPlxuICAgICAgICAgIEBpZiAoY3VycmVudERhdGEoKT8uaXNSZWZ1bmRhYmxlKSB7XG4gICAgICAgICAgICA8YnV0dG9uIHBCdXR0b25cbiAgICAgICAgICAgICAgc3R5bGVDbGFzcz1cInNiZC1jYW5jZWxfX2J0bi1wcmltYXJ5XCJcbiAgICAgICAgICAgICAgW2xhYmVsXT1cImlzQ3JlZGl0U2hlbGwoKSA/ICdDb250aW51ZSBDYW5jZWxsYXRpb24nIDogJ1NlbGVjdCByZWZ1bmQgb3B0aW9uJ1wiXG4gICAgICAgICAgICAgIFtkaXNhYmxlZF09XCIhY2FuQ29uZmlybSgpXCIgKGNsaWNrKT1cInJlcXVlc3RDYW5jZWwoKVwiPjwvYnV0dG9uPlxuICAgICAgICAgIH1cbiAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgPGJ1dHRvbiBwQnV0dG9uIGxhYmVsPVwiQ2xvc2VcIiBzdHlsZUNsYXNzPVwicC1idXR0b24tb3V0bGluZWQgcC1idXR0b24tc2Vjb25kYXJ5XCIgKGNsaWNrKT1cImNsb3NlZC5lbWl0KClcIj48L2J1dHRvbj5cbiAgICAgICAgfVxuICAgICAgPC9kaXY+XG4gICAgfVxuXG4gICAgPCEtLSDilIDilIAgUmVzdWx0IG92ZXJsYXk6IGZsb2F0aW5nIG1vZGFsIG92ZXIgdGhlIGRpbW1lZCByZWZ1bmQtbWV0aG9kIHNjcmVlbiAoc2NvcGVkIHRvIHRoaXMgZGlhbG9nLCBub3QgdGhlIHdob2xlIHZpZXdwb3J0KSDilIDilIAgLS0+XG4gICAgQGlmIChjYW5jZWxSZXN1bHQoKSkge1xuICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3Jlc3VsdC1vdmVybGF5XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19yZXN1bHQtYmFja2Ryb3BcIj48L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3Jlc3VsdC1tb2RhbFwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19yZXN1bHQtaGVyb1wiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19yZXN1bHQtaWNvbiBzYmQtY2FuY2VsX19yZXN1bHQtaWNvbi0tZ3JlZW5cIj5cbiAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1jaGVja1wiPjwvaT5cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDxoMyBjbGFzcz1cInNiZC1jYW5jZWxfX3Jlc3VsdC10aXRsZVwiPnt7IGNvbmZpcm1Jc05pbFJlZnVuZCgpID8gJ0NhbmNlbCBDb25maXJtZWQnIDogJ1JlZnVuZCBDb25maXJtZWQnIH19PC9oMz5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIEBmb3IgKHIgb2YgY29uZmlybVJlZnVuZHMoKTsgdHJhY2sgci5sYWJlbCkge1xuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3Jlc3VsdC1yb3dcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtaWNvblwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwicGlcIiBbbmdDbGFzc109XCJpc1dhbGxldERlc3RpbmF0aW9uUm93KHIpID8gJ3BpLXdhbGxldCcgOiAncGktY3JlZGl0LWNhcmQnXCI+PC9pPlxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fcmVzdWx0LWJvZHktdGV4dFwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLW5hbWVcIj57eyByLmxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIEBpZiAoci5zdWJSb3dzPy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fcmVzdWx0LXN1Yi1yb3dzXCI+XG4gICAgICAgICAgICAgICAgICAgIEBmb3IgKHN1YiBvZiByLnN1YlJvd3M7IHRyYWNrIHN1Yi5sYWJlbCkge1xuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fcmVzdWx0LXN1Yi1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7IHN1Yi5sYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzdHJvbmc+e3sgZm10UmVzdWx0KHN1Yi52YWx1ZSkgfX08L3N0cm9uZz5cbiAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtYmFkZ2VcIlxuICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiaXNXYWxsZXREZXN0aW5hdGlvblJvdyhyKSA/ICdzYmQtY2FuY2VsX19tZXRob2QtYmFkZ2UtLWluc3RhbnQnIDogJ3NiZC1jYW5jZWxfX21ldGhvZC1iYWRnZS0tZGF5cydcIj5cbiAgICAgICAgICAgICAgICAgIHt7IGlzV2FsbGV0RGVzdGluYXRpb25Sb3cocikgPyAnUmVhZHkgTm93JyA6IChyLmtleSA9PT0gJ3RvdGFsQ2FyZFJlZnVuZEFtb3VudCcgPyBjb25maXJtQ2FyZEJhZGdlVGV4dCgpIDogJ1VwIHRvIDE1IGJ1c2luZXNzIGRheXMsIGJhbmsgcG9saWN5JykgfX1cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgQGlmIChyLmhhc0xveWFsdHlOb3RlKSB7XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX25vdGljZSBzYmQtY2FuY2VsX19ub3RpY2UtLWluZm9cIj5cbiAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1pbmZvLWNpcmNsZVwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+RXh0ZXJuYWwgbG95YWx0eSBwb2ludHMgYXJlIHJlZnVuZGVkIHRvIHlvdXIgYWxtYXRhciBXYWxsZXQgYXMgcGVybWFuZW50IHBvaW50cyBhbmQgcmVhZHkgdG8gdXNlIGluIHlvdXIgbmV4dCBib29raW5nLjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgPHN0cm9uZyBjbGFzcz1cInNiZC1jYW5jZWxfX3Jlc3VsdC1hbW91bnRcIj57eyBmbXRSZXN1bHQoci52YWx1ZSkgfX08L3N0cm9uZz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIH1cblxuICAgICAgICAgIEBpZiAoY29uZmlybUNyZWRpdFNoZWxsTm90ZSgpKSB7XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbm90aWNlIHNiZC1jYW5jZWxfX25vdGljZS0tY3JlZGl0XCI+XG4gICAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktd2FsbGV0XCI+PC9pPlxuICAgICAgICAgICAgICA8c3Bhbj7ihLnvuI8ge3sgY29uZmlybUNyZWRpdFNoZWxsTm90ZSgpIH19PC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgPGJ1dHRvbiBwQnV0dG9uIHN0eWxlQ2xhc3M9XCJzYmQtY2FuY2VsX19idG4tcHJpbWFyeSBzYmQtY2FuY2VsX19yZXN1bHQtZG9uZVwiIGxhYmVsPVwiQ2xvc2VcIiAoY2xpY2spPVwiY2xvc2VkLmVtaXQoKVwiPjwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIH1cblxuICA8L2Rpdj5cblxuPC9wLWRpYWxvZz5cblxuPG5nLXRlbXBsYXRlICNtYWRhTG9nbz5cbiAgPHN2ZyB3aWR0aD1cIjQzXCIgaGVpZ2h0PVwiMTVcIiB2aWV3Qm94PVwiMCAwIDQzIDE1XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgPGcgY2xpcC1wYXRoPVwidXJsKCNjbGlwMF9zYmRfbWFkYSlcIj5cbiAgICAgIDxwYXRoIGQ9XCJNMTguMTg5NCA4LjY1NDNIMFYxNC45OTMzSDE4LjE4OTRWOC42NTQzWlwiIGZpbGw9XCIjODRCNzQwXCIgLz5cbiAgICAgIDxwYXRoIGQ9XCJNMTguMTg5NCAwSDBWNi4zNDQ2M0gxOC4xODk0VjBaXCIgZmlsbD1cIiMyNTlCRDZcIiAvPlxuICAgICAgPHBhdGhcbiAgICAgICAgZD1cIk0zNi4zNzc5IDEzLjcwMzRMMzYuMjk2OSAxMy43MjAzQzM2LjAxNiAxMy43NzY4IDM1LjkxMzQgMTMuNzk5NCAzNS43MDgyIDEzLjc5OTRDMzUuMjMzIDEzLjc5OTQgMzQuNjcxMyAxMy41NDUyIDM0LjY3MTMgMTIuMzQ3NUMzNC42NzEzIDExLjczMTYgMzQuNzY4NSAxMC45MTI0IDM1LjY1NDIgMTAuOTEyNEgzNS42NTk2QzM1LjgxMDggMTAuOTIzNyAzNS45ODM2IDEwLjk0MDcgMzYuMzA3NyAxMS4wNDI0TDM2LjM3NzkgMTEuMDY1VjEzLjcwMzRaTTM2LjUyMzcgNy43MzE2NEwzNi4zNzc5IDcuNzU5ODlWOS45NzQ1OEwzNi4yNDgzIDkuOTM1MDNMMzYuMjEwNSA5LjkyMzczQzM2LjA2NDcgOS44Nzg1MyAzNS43Mjk4IDkuNzc2ODQgMzUuNDA1OCA5Ljc3Njg0QzMzLjYzNDQgOS43NzY4NCAzMy4yNjE3IDExLjE3OCAzMy4yNjE3IDEyLjM1MzFDMzMuMjYxNyAxMy45NjMzIDM0LjEyNTggMTQuODg5OCAzNS42MzI2IDE0Ljg4OThDMzYuMjY5OSAxNC44ODk4IDM2LjczOTcgMTQuODIyIDM3LjIxNSAxNC42NTgyQzM3LjY1MjQgMTQuNTExMyAzNy44MDkxIDE0LjMwMjMgMzcuODA5MSAxMy44NTU5VjcuNUMzNy4zODc4IDcuNTc5MSAzNi45NTA0IDcuNjU4MTkgMzYuNTIzNyA3LjczMTY0WlwiXG4gICAgICAgIGZpbGw9XCIjNzQ3NTgzXCJcbiAgICAgIC8+XG4gICAgICA8cGF0aFxuICAgICAgICBkPVwiTTQxLjY1MSAxMy43Mzg1TDQxLjU3NTQgMTMuNzYxMUw0MS4zMDUzIDEzLjgzNDVDNDEuMDUxNSAxMy45MDIzIDQwLjgyNDcgMTMuOTQxOSA0MC42NTE5IDEzLjk0MTlDNDAuMjM2IDEzLjk0MTkgMzkuOTg3NiAxMy43MjcyIDM5Ljk4NzYgMTMuMzZDMzkuOTg3NiAxMy4xMjI3IDQwLjA5MDIgMTIuNzIxNSA0MC43NzA3IDEyLjcyMTVINDEuNjUxVjEzLjczODVaTTQxLjAyOTkgOS43NDQxNEM0MC40ODQ0IDkuNzQ0MTQgMzkuOTIyOCA5Ljg0NTg0IDM5LjIyNjEgMTAuMDcxOEwzOC43NzI0IDEwLjIxMzFMMzguOTIzNiAxMS4yODY1TDM5LjM2NjUgMTEuMTM0QzM5LjgzMSAxMC45NzU4IDQwLjQwODggMTAuODc0MSA0MC44NDA5IDEwLjg3NDFDNDEuMDM1MyAxMC44NzQxIDQxLjYyOTQgMTAuODc0MSA0MS42Mjk0IDExLjU0NjRWMTEuODQwMkg0MC44MDMxQzM5LjI5NjMgMTEuODQwMiAzOC41OTk2IDEyLjM0MyAzOC41OTk2IDEzLjQyMjFDMzguNTk5NiAxNC4zNDMgMzkuMjQyMyAxNC44OTY3IDQwLjMyMjQgMTQuODk2N0M0MC42NTczIDE0Ljg5NjcgNDEuMTIxNyAxNC44Mjg5IDQxLjUyMTQgMTQuNzI3Mkw0MS41NDMgMTQuNzIxNUw0MS41NjQ2IDE0LjcyNzJMNDEuNjk5NiAxNC43NDk4QzQyLjEyMDggMTQuODI4OSA0Mi41NTgzIDE0LjkwOCA0Mi45ODQ5IDE0Ljk5MjdWMTEuNDY3M0M0Mi45ODQ5IDEwLjMyNjEgNDIuMzI2MSA5Ljc0NDE0IDQxLjAyOTkgOS43NDQxNFpcIlxuICAgICAgICBmaWxsPVwiIzc0NzU4M1wiXG4gICAgICAvPlxuICAgICAgPHBhdGhcbiAgICAgICAgZD1cIk0zMS4xNTI3IDEzLjczODVMMzEuMDc3MSAxMy43NjExTDMwLjgwNyAxMy44MzQ1QzMwLjU1MzIgMTMuOTAyMyAzMC4zMzE4IDEzLjk0MTkgMzAuMTUzNiAxMy45NDE5QzI5LjczNzcgMTMuOTQxOSAyOS40ODkzIDEzLjcyNzIgMjkuNDg5MyAxMy4zNkMyOS40ODkzIDEzLjEyMjcgMjkuNTkxOSAxMi43MjE1IDMwLjI2NyAxMi43MjE1SDMxLjE0NzNMMzEuMTUyNyAxMy43Mzg1Wk0zMC41MzcgOS43NDQxNEMyOS45ODYxIDkuNzQ0MTQgMjkuNDI5OSA5Ljg0NTg0IDI4LjczMzIgMTAuMDcxOEwyOC4yNzk1IDEwLjIxMzFMMjguNDMwOCAxMS4yODY1TDI4Ljg3MzYgMTEuMTM0QzI5LjMzODEgMTAuOTc1OCAyOS45MTU5IDEwLjg3NDEgMzAuMzQ4IDEwLjg3NDFDMzAuNTQyNCAxMC44NzQxIDMxLjEzNjUgMTAuODc0MSAzMS4xMzY1IDExLjU0NjRWMTEuODQwMkgzMC4zMTAyQzI4LjgwMzQgMTEuODQwMiAyOC4xMDEzIDEyLjM0MyAyOC4xMDEzIDEzLjQyMjFDMjguMTAxMyAxNC4zNDMgMjguNzQ0IDE0Ljg5NjcgMjkuODI5NSAxNC44OTY3QzMwLjE2NDQgMTQuODk2NyAzMC42Mjg4IDE0LjgyODkgMzEuMDI4NSAxNC43MjcyTDMxLjA1MDEgMTQuNzIxNUwzMS4wNzE3IDE0LjcyNzJMMzEuMjAxMyAxNC43NDk4QzMxLjYyNzkgMTQuODI4OSAzMi4wNiAxNC45MDggMzIuNDg2NiAxNC45OTg0VjExLjQ3M0MzMi40OTIgMTAuMzIwNCAzMS44MzMyIDkuNzQ0MTQgMzAuNTM3IDkuNzQ0MTRaXCJcbiAgICAgICAgZmlsbD1cIiM3NDc1ODNcIlxuICAgICAgLz5cbiAgICAgIDxwYXRoXG4gICAgICAgIGQ9XCJNMjUuNDcwMSA5Ljc1NzZDMjQuNzg0MiA5Ljc1NzYgMjQuMjE3MiA5Ljk5NDg5IDI0LjAwNjUgMTAuMDk2NkwyMy45NTI1IDEwLjEyNDhMMjMuOTAzOSAxMC4wODUzQzIzLjYxMjMgOS44NjQ5NSAyMy4xODU2IDkuNzUxOTUgMjIuNTkxNiA5Ljc1MTk1QzIyLjA2NzcgOS43NTE5NSAyMS41NzYyIDkuODMxMDUgMjEuMDQxNiA5Ljk5NDg5QzIwLjU4MjUgMTAuMTQxOCAyMC40MDQzIDEwLjM3MzQgMjAuNDA0MyAxMC44MDg1VjE0LjgzNjdIMjEuODQwOVYxMS4xMTM1TDIxLjkxMTEgMTEuMDkwOUMyMi4yMDI3IDEwLjk4OTIgMjIuMzc1NSAxMC45NzIzIDIyLjU0MyAxMC45NzIzQzIyLjk1ODggMTAuOTcyMyAyMy4xNjk0IDExLjIwMzkgMjMuMTY5NCAxMS42NTU5VjE0Ljg0MjNIMjQuNTg0NFYxMS41OTM4QzI0LjU4NDQgMTEuNDAxNyAyNC41NDY2IDExLjI4ODcgMjQuNTQxMiAxMS4yNjYxTDI0LjQ5MjYgMTEuMTdMMjQuNTg5OCAxMS4xMjQ4QzI0LjgwNTggMTEuMDIzMSAyNS4wNDM1IDEwLjk3MjMgMjUuMjkxOSAxMC45NzIzQzI1LjU3ODEgMTAuOTcyMyAyNS45MTg0IDExLjA5MDkgMjUuOTE4NCAxMS42NTU5VjE0Ljg0MjNIMjcuMzI3OVYxMS41MDlDMjcuMzI3OSAxMC4zMjgyIDI2LjcyMzEgOS43NTc2IDI1LjQ3MDEgOS43NTc2WlwiXG4gICAgICAgIGZpbGw9XCIjNzQ3NTgzXCJcbiAgICAgIC8+XG4gICAgICA8cGF0aFxuICAgICAgICBkPVwiTTQwLjU4NjYgNC4xMzU1OUM0MC4zNzU5IDQuMTM1NTkgNDAuMDI0OSA0LjExMyAzOS43NDk1IDQuMDU2NUwzOS42Njg0IDQuMDM5NTVWMS44NjQ0MUMzOS42Njg0IDEuNjgzNjIgMzkuNjM2IDEuNTcwNjIgMzkuNjMwNiAxLjU1MzY3TDM5LjU4NzQgMS40NjMyOEwzOS42NzkzIDEuNDIzNzNDMzkuNzAwOSAxLjQxMjQzIDM5LjcyMjUgMS40MDY3OCAzOS43NDk1IDEuMzk1NDhMMzkuNzY1NyAxLjM4NDE4QzM5Ljc5ODEgMS4zNzI4OCAzOS44MzA1IDEuMzYxNTggMzkuODYyOSAxLjM1MDI4QzM5Ljg3OTEgMS4zNDQ2MyAzOS44ODk5IDEuMzM4OTggMzkuOTAwNyAxLjMzODk4QzQwLjIxOTMgMS4yNDg1OSA0MC41MTEgMS4yNTk4OSA0MC42NDA2IDEuMjQ4NTlINDAuNjQ2QzQxLjUyNjMgMS4yNDg1OSA0MS42Mjg5IDIuMDY3OCA0MS42Mjg5IDIuNjgzNjJDNDEuNjIzNSAzLjg4MTM2IDQxLjA1NjQgNC4xMzU1OSA0MC41ODY2IDQuMTM1NTlaTTQwLjU4MTIgMEM0MC41NzA0IDAgNDAuNTU0MiAwIDQwLjU0MzQgMEMzOS43MTcxIDAgMzguODY5MiAwLjIzNzI4OCAzOC41NjY3IDAuNzAwNTY1QzM4LjQwNDcgMC45MjY1NTQgMzguMzEyOSAxLjIwOTA0IDM4LjMwNzUgMS41NDIzN1YzLjc4NTMxQzM4LjMwNzUgMy45Nzc0IDM4LjI2OTcgNC4wNTA4NSAzOC4yNjQzIDQuMDY3OEwzOC4yMTU3IDQuMTYzODRIMzUuNjA3MlYyLjYwNDUySDM1LjYwMThDMzUuNTY5NCAwLjk2MDQ1MiAzNC42NDA0IDAuMDU2NDk3MiAzMy4yOTU3IDAuMDU2NDk3MkgzMy4xMzkxSDMxLjk4MzNDMzEuOTI5MyAwLjQ1NzYyNyAzMS44ODYxIDAuNzQwMTEzIDMxLjgzMjEgMS4xNDEyNEgzMy4xMzkxQzMzLjgyNDkgMS4xNDEyNCAzNC4xODY4IDEuNzUxNDEgMzQuMTg2OCAyLjY4OTI3VjQuMjU5ODlMMzQuMDk1IDQuMjA5MDRDMzQuMDc4OCA0LjIwMzM5IDMzLjk2NTQgNC4xNjM4NCAzMy43ODcxIDQuMTYzODRIMzEuNTI5N0MzMS40ODY1IDQuNDYzMjggMzEuNDMyNSA0Ljg1MzExIDMxLjM3MyA1LjI0Mjk0SDM4LjMxMjlDMzguNTUwNSA1LjE5MjA5IDM4LjgyNTkgNS4xNDY4OSAzOS4wNjM2IDUuMTA3MzVDMzkuNDE0NiA1LjI4ODE0IDQwLjA2ODEgNS4zODQxOCA0MC41MTY0IDUuMzg0MThDNDIuMDIzMSA1LjM4NDE4IDQzLjAwMDcgNC4zMjc2OCA0My4wMDA3IDIuNzAwNTdDNDIuOTk1MyAxLjA5MDQgNDIuMDUwMSAwLjAzMzg5ODMgNDAuNTgxMiAwWlwiXG4gICAgICAgIGZpbGw9XCIjNzQ3NTgzXCJcbiAgICAgIC8+XG4gICAgICA8cGF0aFxuICAgICAgICBkPVwiTTI4LjQxODkgNS45MDgyMUgyOC40ODM3QzI5Ljk5MDUgNS45MDgyMSAzMC42OTI1IDUuMzg4NDQgMzAuNjkyNSA0LjEwNTk1QzMwLjY5MjUgMy4xODUwNSAzMC4wNDk5IDIuNDUwNTkgMjguOTY5NyAyLjQ1MDU5SDI3LjU4MThDMjcuMTY1OSAyLjQ1MDU5IDI2LjkxNzUgMi4yMDIgMjYuOTE3NSAxLjc4MzkyQzI2LjkxNzUgMS41MDE0MyAyNy4wMjAxIDEuMTUxMTUgMjcuNzAwNiAxLjE1MTE1SDMwLjczNTdDMzAuODAwNiAwLjczODcyMyAzMC44MzMgMC40Nzg4MzYgMzAuODkyNCAwLjA2NjQwNjJIMjcuNzM4NEMyNi4yNjk0IDAuMDY2NDA2MiAyNS41Mjk1IDAuNzEwNDc0IDI1LjUyOTUgMS43ODM5MkMyNS41Mjk1IDIuODQ2MDcgMjYuMTcyMiAzLjM5OTc0IDI3LjI1MjMgMy4zOTk3NEgyOC42NDAzQzI5LjA1NjEgMy4zOTk3NCAyOS4zMDQ2IDMuNzQ0MzcgMjkuMzA0NiA0LjEwNTk1QzI5LjMwNDYgNC4zNDMyNCAyOS4yMDIgNC44MzQ3NyAyOC41MjY5IDQuODM0NzdIMjguMjk0N0wyMy44NDk5IDQuODIzNDdIMjMuMDM5OEMyMi4zNTM5IDQuODIzNDcgMjEuODczMyA0LjQxNjY5IDIxLjg3MzMgMy40NzMxOVYyLjgyMzQ3QzIxLjg3MzMgMS44NDA0MiAyMi4yNDU5IDEuMjMwMjUgMjMuMDM5OCAxLjIzMDI1SDI0LjM1NzZDMjQuNDE3IDAuODEyMTY5IDI0LjQ1NDggMC41NDY2MzIgMjQuNTA4OCAwLjE1MTE1MkgyMi44NjdIMjIuNzEwNEMyMS4zNjU2IDAuMTUxMTUyIDIwLjQzNjcgMS4wOTQ2NiAyMC40MDQzIDIuNzM4NzJWMi44MDA4N1YzLjQ3MzE5QzIwLjQzNjcgNS4xMTcyNSAyMS4zNjU2IDUuOTAyNTYgMjIuNzEwNCA1LjkwMjU2SDIyLjg2N0gyNC4wMjI3TDI2LjQzMTQgNS45MDgyMUgyNy44NjhIMjguNDE4OVpcIlxuICAgICAgICBmaWxsPVwiIzc0NzU4M1wiXG4gICAgICAvPlxuICAgIDwvZz5cbiAgICA8ZGVmcz5cbiAgICAgIDxjbGlwUGF0aCBpZD1cImNsaXAwX3NiZF9tYWRhXCI+XG4gICAgICAgIDxyZWN0IHdpZHRoPVwiNDNcIiBoZWlnaHQ9XCIxNVwiIGZpbGw9XCJ3aGl0ZVwiIC8+XG4gICAgICA8L2NsaXBQYXRoPlxuICAgIDwvZGVmcz5cbiAgPC9zdmc+XG48L25nLXRlbXBsYXRlPlxuIl19