@tiba-spark/client-shared-lib 25.4.1-204 → 25.4.1-212

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.
@@ -4,6 +4,7 @@ import { Store } from '@ngxs/store';
4
4
  import moment from 'moment';
5
5
  import { CommandNotificationService } from '../components/notification/command-notification/command-notification.service';
6
6
  import { NotificationClass } from '../components/notification/notification-config';
7
+ import { DEFAULT_SMART_PARK_DATE_TIME } from '../constants/global-constants';
7
8
  import { BarcodeTypeLength } from '../enums/barcode-type.enum';
8
9
  import { FacilityState } from '../modules/facility/facility.state';
9
10
  import { ParkerState } from '../modules/parker/parker.state';
@@ -39,47 +40,52 @@ export class TicketService {
39
40
  return this.sendCommand(commandType, options, analyticsPayload)
40
41
  .pipe(this.commandNotificationService.display(config));
41
42
  }
42
- extractTicketInfo(content) {
43
+ extractTicketInfo(content, timezone) {
43
44
  let ticketNum;
44
- let ticketDateTime;
45
+ let ticketDateTimeInSeconds;
45
46
  try {
46
47
  // To determine what type, check content length
47
48
  switch (content.length) {
48
49
  case BarcodeTypeLength.QR1:
49
50
  case BarcodeTypeLength.QR2:
50
- ticketNum = content.slice(6, 14); // Location of ticket number; from 7 to 14
51
- // Location of ticket date; from 14 to 20
52
- // Location of ticket time; from 20 to 24
53
- ticketDateTime = this.getTicketDateTimeByContent(content, { start: 14, end: 20 }, { start: 20, end: 24 });
51
+ {
52
+ ticketNum = content.slice(6, 14); // Location of ticket number; from 7 to 14
53
+ // Location of ticket date; from 14 to 20
54
+ // Location of ticket time; from 20 to 24
55
+ const ticketDateTime = this.getTicketDateTimeByQRContent(content, { start: 14, end: 20 }, { start: 20, end: 24 });
56
+ ticketDateTimeInSeconds = parseDateTimeToSparkParkTime(ticketDateTime?.toDate());
57
+ }
54
58
  break;
55
59
  case BarcodeTypeLength.QR4:
56
- ticketNum = content.slice(7, 16); // Location of ticket number; from 8 to 16.
57
- // Location of ticket date; from 16 to 22
58
- // Location of ticket time; from 22 to 28
59
- ticketDateTime = this.getTicketDateTimeByContent(content, { start: 16, end: 22 }, { start: 22, end: 28 });
60
+ {
61
+ ticketNum = content.slice(7, 16); // Location of ticket number; from 8 to 16.
62
+ // Location of ticket date; from 16 to 22
63
+ // Location of ticket time; from 22 to 28
64
+ const ticketDateTime = this.getTicketDateTimeByQRContent(content, { start: 16, end: 22 }, { start: 22, end: 28 });
65
+ ticketDateTimeInSeconds = parseDateTimeToSparkParkTime(ticketDateTime?.toDate());
66
+ }
60
67
  break;
61
68
  case BarcodeTypeLength.Barcode1:
62
69
  ticketNum = content.slice(7, 14); // Location of ticket number; from 7 to 14
63
70
  // Location of ticket time info; from 1 to 7
64
- ticketDateTime = this.getTicketDateTimeByTicketTime(content, { start: 1, end: 7 });
71
+ ticketDateTimeInSeconds = this.getTicketDateTimeInSecondsByBarcodeContent(content, { start: 1, end: 7 }, timezone);
65
72
  break;
66
73
  case BarcodeTypeLength.Barcode2:
67
74
  ticketNum = content.slice(13, 22); // Location of ticket number; from 14 to 22
68
75
  // Location of ticket time info; from 7 to 13
69
- ticketDateTime = this.getTicketDateTimeByTicketTime(content, { start: 7, end: 13 });
76
+ ticketDateTimeInSeconds = this.getTicketDateTimeInSecondsByBarcodeContent(content, { start: 7, end: 13 }, timezone);
70
77
  break;
71
78
  default:
72
79
  {
73
80
  const qValue = this.extractQueryParam(content, 'q');
74
- if (qValue !== null) {
75
- return this.extractTicketInfo(qValue);
81
+ if (qValue !== null && qValue !== content) {
82
+ return this.extractTicketInfo(qValue, timezone);
76
83
  }
77
84
  }
78
85
  break;
79
86
  }
80
87
  }
81
88
  catch (_) { }
82
- const ticketDateTimeInSeconds = parseDateTimeToSparkParkTime(ticketDateTime?.toDate());
83
89
  return { ticketNum, ticketDateTimeInSeconds };
84
90
  }
85
91
  extractQueryParam(url, param) {
@@ -95,7 +101,7 @@ export class TicketService {
95
101
  return null;
96
102
  }
97
103
  }
98
- getTicketDateTimeByContent(content, date, time) {
104
+ getTicketDateTimeByQRContent(content, date, time) {
99
105
  const _date = content.slice(date.start, date.end);
100
106
  const _time = content.slice(time.start, time.end);
101
107
  return moment({
@@ -107,27 +113,36 @@ export class TicketService {
107
113
  second: _time.length === 6 ? +_time.slice(4, 6) : 0
108
114
  });
109
115
  }
110
- getTicketDateTimeByTicketTime(content, location) {
111
- // multiple 60000:
112
- // getTime method return date in miliseconds
113
- // to convert to seconds multiple by 10000
114
- // to convert seconds to minutes multiple by 60
115
- const ticketTime = +content.slice(location.start, location.end);
116
- var curTimeDateTime = new Date();
117
- curTimeDateTime.setSeconds(0);
118
- let defaultSmartParkDateTime = new Date(2000, 0, 1, 0, 0, 0).getTime();
119
- // The default smart park date time is always: Sat Jan 01 2000 00:00:00 GMT+0200 (Israel Standard Time)
120
- // If the current time date is in DST (GMT+0300) then to avoid incorrect results we need to remove 1 hour
121
- if (moment(curTimeDateTime).isDST()) {
122
- // 60 Minutes ( 1 hour ) in miliseconds equal 3600000
123
- defaultSmartParkDateTime -= 3600000;
116
+ getTicketDateTimeInSecondsByBarcodeContent(content, location, timezone) {
117
+ // Barcode time encoding (based on SQL Date2Number / Number2Date):
118
+ // The original datetime is converted in SQL to total seconds since ~2000-01-01,
119
+ // then effectively to total minutes. The barcode stores only the LAST 6 digits
120
+ // of those minutes (totalMinutes % 1,000,000).
121
+ //
122
+ // Because of this truncation, the value wraps every 1,000,000 minutes (~694 days),
123
+ // so the same value can represent multiple dates.
124
+ //
125
+ // To reconstruct the correct datetime, we rebuild possible full values and
126
+ // select the one closest to "now".
127
+ const MINUTE_CYCLE = 1_000_000;
128
+ const CYCLE_SEARCH_RADIUS = 1;
129
+ const truncatedMinutesFromBarcode = Number(content.slice(location.start, location.end));
130
+ const now = moment.tz(timezone).seconds(0).milliseconds(0);
131
+ const barcodeBaseDate = moment.tz(DEFAULT_SMART_PARK_DATE_TIME, 'YYYY-MM-DD HH:mm:ss', timezone);
132
+ const currentTotalMinutesFromBase = now.diff(barcodeBaseDate, 'minutes');
133
+ const estimatedCycleIndex = Math.floor(currentTotalMinutesFromBase / MINUTE_CYCLE);
134
+ let resolvedTicketDateTime = barcodeBaseDate.clone();
135
+ let smallestDifferenceFromNow = Number.MAX_SAFE_INTEGER;
136
+ for (let cycleIndex = estimatedCycleIndex - CYCLE_SEARCH_RADIUS; cycleIndex <= estimatedCycleIndex + CYCLE_SEARCH_RADIUS; cycleIndex++) {
137
+ const fullMinutesFromBase = cycleIndex * MINUTE_CYCLE + truncatedMinutesFromBarcode;
138
+ const candidateDateTime = barcodeBaseDate.clone().add(fullMinutesFromBase, 'minutes');
139
+ const differenceFromNow = Math.abs(candidateDateTime.diff(now));
140
+ if (differenceFromNow < smallestDifferenceFromNow) {
141
+ smallestDifferenceFromNow = differenceFromNow;
142
+ resolvedTicketDateTime = candidateDateTime;
143
+ }
124
144
  }
125
- var curTimeInMinutes = (curTimeDateTime.getTime() - defaultSmartParkDateTime) / 60000;
126
- var curTimeTicketFormat = curTimeInMinutes % 1000000;
127
- if (ticketTime > curTimeTicketFormat)
128
- curTimeTicketFormat += 1000000;
129
- const ticketDateTimeInMinutes = (defaultSmartParkDateTime / 60000) + curTimeInMinutes - (curTimeTicketFormat - ticketTime);
130
- return moment(new Date(ticketDateTimeInMinutes * 60000));
145
+ return resolvedTicketDateTime.diff(barcodeBaseDate, 'seconds');
131
146
  }
132
147
  navigateToTicket(ticketNum, guid, parkId, activatedRoute, ticketDateTimeInSeconds = null) {
133
148
  const tibaKeys = this.store.selectSnapshot(FacilityState.tibaKeys);
@@ -150,4 +165,4 @@ export class TicketService {
150
165
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TicketService, decorators: [{
151
166
  type: Injectable
152
167
  }], ctorParameters: () => [{ type: i0.Injector }] });
153
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGlja2V0LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jbGllbnQtc2hhcmVkLWxpYi9zcmMvbGlicmFyaWVzL3NlcnZpY2VzL3RpY2tldC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQVksTUFBTSxlQUFlLENBQUM7QUFDckQsT0FBTyxFQUFrQixNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3BDLE9BQU8sTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUc1QixPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSw4RUFBOEUsQ0FBQztBQUMxSCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnREFBZ0QsQ0FBQztBQUNuRixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUsvRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDbkUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBRzdELE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDOztBQUdoRSxNQUFNLE9BQWdCLGFBQWE7SUFPakMsWUFBbUIsUUFBa0I7UUFBbEIsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUNuQyxJQUFJLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDakMsSUFBSSxDQUFDLDBCQUEwQixHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsMEJBQTBCLENBQUMsQ0FBQztRQUMzRSxJQUFJLENBQUMsb0JBQW9CLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQy9ELElBQUksQ0FBQyxNQUFNLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQsV0FBVyxDQUFDLFdBQStCLEVBQUUsVUFBZSxJQUFJLEVBQUUsbUJBQWlDLEVBQUU7UUFDbkcsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzNELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDakYsTUFBTSxJQUFJLEdBQWUsRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUsT0FBTyxFQUFFLENBQUM7UUFDcEUsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLDBCQUEwQixDQUFDLFdBQVcsRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDbEcsT0FBTyxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixDQUFDLENBQUM7SUFDbkYsQ0FBQztJQUVELHdCQUF3QixDQUFDLFdBQStCLEVBQUUsVUFBZSxJQUFJLEVBQUUsbUJBQWlDLEVBQUU7UUFDaEgsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUNqRixNQUFNLG1CQUFtQixHQUFHLE9BQU8sRUFBRSxtQkFBbUIsSUFBSSxnQkFBZ0IsRUFBRSxtQkFBbUIsQ0FBQztRQUNsRyxNQUFNLGlCQUFpQixHQUFHLE9BQU8sRUFBRSxpQkFBaUIsSUFBSSxnQkFBZ0IsRUFBRSxpQkFBaUIsQ0FBQztRQUU1RixNQUFNLE1BQU0sR0FBOEI7WUFDeEMsUUFBUSxFQUFFLENBQUM7b0JBQ1QsS0FBSyxFQUFFLEdBQUcsbUJBQW1CLElBQUksaUJBQWlCLEVBQUU7b0JBQ3BELEtBQUssRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJO2lCQUMvRSxDQUFDO1lBQ0YsT0FBTyxFQUFFLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxvQkFBb0IsQ0FBQyxXQUFXLENBQUM7U0FDckUsQ0FBQztRQUVGLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixDQUFDO2FBQzVELElBQUksQ0FBQyxJQUFJLENBQUMsMEJBQTBCLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDM0QsQ0FBQztJQUlELGlCQUFpQixDQUFDLE9BQWU7UUFDL0IsSUFBSSxTQUFpQixDQUFDO1FBQ3RCLElBQUksY0FBNkIsQ0FBQztRQUNsQyxJQUFJLENBQUM7WUFDSCwrQ0FBK0M7WUFDL0MsUUFBUSxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ3ZCLEtBQUssaUJBQWlCLENBQUMsR0FBRyxDQUFDO2dCQUMzQixLQUFLLGlCQUFpQixDQUFDLEdBQUc7b0JBQ3hCLFNBQVMsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLDBDQUEwQztvQkFDNUUseUNBQXlDO29CQUN6Qyx5Q0FBeUM7b0JBQ3pDLGNBQWMsR0FBRyxJQUFJLENBQUMsMEJBQTBCLENBQUMsT0FBTyxFQUFFLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO29CQUMxRyxNQUFNO2dCQUNSLEtBQUssaUJBQWlCLENBQUMsR0FBRztvQkFDeEIsU0FBUyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsMkNBQTJDO29CQUM3RSx5Q0FBeUM7b0JBQ3pDLHlDQUF5QztvQkFDekMsY0FBYyxHQUFHLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxPQUFPLEVBQUUsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7b0JBQzFHLE1BQU07Z0JBQ1IsS0FBSyxpQkFBaUIsQ0FBQyxRQUFRO29CQUM3QixTQUFTLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQywwQ0FBMEM7b0JBQzVFLDRDQUE0QztvQkFDNUMsY0FBYyxHQUFHLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxPQUFPLEVBQUUsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO29CQUNuRixNQUFNO2dCQUNSLEtBQUssaUJBQWlCLENBQUMsUUFBUTtvQkFDN0IsU0FBUyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsMkNBQTJDO29CQUM5RSw2Q0FBNkM7b0JBQzdDLGNBQWMsR0FBRyxJQUFJLENBQUMsNkJBQTZCLENBQUMsT0FBTyxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztvQkFDcEYsTUFBTTtnQkFDUjtvQkFDRSxDQUFDO3dCQUNDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQUM7d0JBQ3BELElBQUksTUFBTSxLQUFLLElBQUksRUFBRSxDQUFDOzRCQUNwQixPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQzt3QkFDeEMsQ0FBQztvQkFDSCxDQUFDO29CQUNELE1BQU07WUFDVixDQUFDO1FBQ0gsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRWYsTUFBTSx1QkFBdUIsR0FBRyw0QkFBNEIsQ0FBQyxjQUFjLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUN2RixPQUFPLEVBQUUsU0FBUyxFQUFFLHVCQUF1QixFQUFFLENBQUM7SUFDaEQsQ0FBQztJQUVPLGlCQUFpQixDQUFDLEdBQVcsRUFBRSxLQUFhO1FBQ2xELElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNuQixPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFFRCxJQUFJLENBQUM7WUFDSCxNQUFNLFNBQVMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUMvQixPQUFPLFNBQVMsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzNDLENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCx3Q0FBd0M7WUFDeEMsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQztJQUVPLDBCQUEwQixDQUFDLE9BQWUsRUFBRSxJQUFvQyxFQUFFLElBQW9DO1FBQzVILE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDbEQsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNsRCxPQUFPLE1BQU0sQ0FBQztZQUNaLElBQUksRUFBRSxJQUFJLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDL0IsS0FBSyxFQUFFLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQztZQUM3QixHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDdkIsSUFBSSxFQUFFLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3hCLE1BQU0sRUFBRSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUMxQixNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDcEQsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLDZCQUE2QixDQUFDLE9BQWUsRUFBRSxRQUF3QztRQUM3RixrQkFBa0I7UUFDbEIsNENBQTRDO1FBQzVDLDBDQUEwQztRQUMxQywrQ0FBK0M7UUFFL0MsTUFBTSxVQUFVLEdBQUcsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2hFLElBQUksZUFBZSxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7UUFDakMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUU5QixJQUFJLHdCQUF3QixHQUFHLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDdkUsdUdBQXVHO1FBQ3ZHLHlHQUF5RztRQUN6RyxJQUFJLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDO1lBQ3BDLHFEQUFxRDtZQUNyRCx3QkFBd0IsSUFBSSxPQUFPLENBQUM7UUFDdEMsQ0FBQztRQUVELElBQUksZ0JBQWdCLEdBQUcsQ0FBQyxlQUFlLENBQUMsT0FBTyxFQUFFLEdBQUcsd0JBQXdCLENBQUMsR0FBRyxLQUFLLENBQUM7UUFDdEYsSUFBSSxtQkFBbUIsR0FBRyxnQkFBZ0IsR0FBRyxPQUFPLENBQUM7UUFDckQsSUFBSSxVQUFVLEdBQUcsbUJBQW1CO1lBQUUsbUJBQW1CLElBQUksT0FBTyxDQUFDO1FBRXJFLE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyx3QkFBd0IsR0FBRyxLQUFLLENBQUMsR0FBRyxnQkFBZ0IsR0FBRyxDQUFDLG1CQUFtQixHQUFHLFVBQVUsQ0FBQyxDQUFDO1FBQzNILE9BQU8sTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLHVCQUF1QixHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFDM0QsQ0FBQztJQUVELGdCQUFnQixDQUFDLFNBQWlCLEVBQUUsSUFBWSxFQUFFLE1BQWMsRUFBRSxjQUE4QixFQUFFLDBCQUFrQyxJQUFJO1FBQ3RJLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNuRSxNQUFNLFFBQVEsR0FBVTtZQUN0QixRQUFRLENBQUMsSUFBSSxDQUFDO1lBQ2QsTUFBTTtZQUNOLFNBQVM7U0FDVixDQUFDO1FBQ0YsSUFBSSx1QkFBdUIsRUFBRSxDQUFDO1lBQzVCLFFBQVEsQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQztRQUN6QyxDQUFDO1FBQ0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRSxDQUFDLENBQUM7SUFDakUsQ0FBQztJQUVELFVBQVUsQ0FBQyxTQUFpQixFQUFFLElBQVksRUFBRSxNQUFjLEVBQUUsY0FBOEIsRUFBRSx1QkFBK0I7UUFDekgsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO0lBQzFGLENBQUM7K0dBekptQixhQUFhO21IQUFiLGFBQWE7OzRGQUFiLGFBQWE7a0JBRGxDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBJbmplY3RvciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUsIFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBTdG9yZSB9IGZyb20gJ0BuZ3hzL3N0b3JlJztcbmltcG9ydCBtb21lbnQgZnJvbSAnbW9tZW50JztcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IENvbW1hbmROb3RpZmljYXRpb25Db25maWcgfSBmcm9tICcuLi9jb21wb25lbnRzL25vdGlmaWNhdGlvbi9jb21tYW5kLW5vdGlmaWNhdGlvbi9jb21tYW5kLW5vdGlmaWNhdGlvbi1jb25maWcnO1xuaW1wb3J0IHsgQ29tbWFuZE5vdGlmaWNhdGlvblNlcnZpY2UgfSBmcm9tICcuLi9jb21wb25lbnRzL25vdGlmaWNhdGlvbi9jb21tYW5kLW5vdGlmaWNhdGlvbi9jb21tYW5kLW5vdGlmaWNhdGlvbi5zZXJ2aWNlJztcbmltcG9ydCB7IE5vdGlmaWNhdGlvbkNsYXNzIH0gZnJvbSAnLi4vY29tcG9uZW50cy9ub3RpZmljYXRpb24vbm90aWZpY2F0aW9uLWNvbmZpZyc7XG5pbXBvcnQgeyBCYXJjb2RlVHlwZUxlbmd0aCB9IGZyb20gJy4uL2VudW1zL2JhcmNvZGUtdHlwZS5lbnVtJztcbmltcG9ydCB7IFRyYWNlUGF5bG9hZCB9IGZyb20gJy4uL2ludGVyZmFjZXMvYW5hbHl0aWNzLmludGVyZmFjZSc7XG5pbXBvcnQgeyBDbWREYXRhRHRvIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9jbWQtZGF0YS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgQ29uZmlnRGF0YSB9IGZyb20gJy4uL2ludGVyZmFjZXMvY29uZmlnLWRhdGEuaW50ZXJmYWNlJztcbmltcG9ydCB7IFRpY2tldElkZW50aWZpZXIgfSBmcm9tICcuLi9pbnRlcmZhY2VzL3RpY2tldC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgRmFjaWxpdHlTdGF0ZSB9IGZyb20gJy4uL21vZHVsZXMvZmFjaWxpdHkvZmFjaWxpdHkuc3RhdGUnO1xuaW1wb3J0IHsgUGFya2VyU3RhdGUgfSBmcm9tICcuLi9tb2R1bGVzL3Bhcmtlci9wYXJrZXIuc3RhdGUnO1xuaW1wb3J0IHsgUmVtb3RlQ29tbWFuZFR5cGVzIH0gZnJvbSAnLi4vc2VydmljZS1wcm94eS9jbG91ZC1zZXJ2aWNlLXByb3hpZXMnO1xuaW1wb3J0IHsgUmVtb3RlQ29tbWFuZEJhc2UgfSBmcm9tICcuLi9zZXJ2aWNlLXByb3h5L3JwYy1zZXJ2aWNlLXByb3hpZXMnO1xuaW1wb3J0IHsgcGFyc2VEYXRlVGltZVRvU3BhcmtQYXJrVGltZSB9IGZyb20gJy4uL3V0aWxzL2RhdGUudXRpbCc7XG5pbXBvcnQgeyBSZW1vdGVDb21tYW5kU2VydmljZSB9IGZyb20gJy4vcmVtb3RlLWNvbW1hbmQuc2VydmljZSc7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBUaWNrZXRTZXJ2aWNlIHtcblxuICBwcm90ZWN0ZWQgc3RvcmU6IFN0b3JlO1xuICBwcm90ZWN0ZWQgY29tbWFuZE5vdGlmaWNhdGlvblNlcnZpY2U6IENvbW1hbmROb3RpZmljYXRpb25TZXJ2aWNlO1xuICBwcm90ZWN0ZWQgcmVtb3RlQ29tbWFuZFNlcnZpY2U6IFJlbW90ZUNvbW1hbmRTZXJ2aWNlO1xuICBwcm90ZWN0ZWQgcm91dGVyOiBSb3V0ZXI7XG5cbiAgY29uc3RydWN0b3IocHVibGljIGluamVjdG9yOiBJbmplY3Rvcikge1xuICAgIHRoaXMuc3RvcmUgPSBpbmplY3Rvci5nZXQoU3RvcmUpO1xuICAgIHRoaXMuY29tbWFuZE5vdGlmaWNhdGlvblNlcnZpY2UgPSBpbmplY3Rvci5nZXQoQ29tbWFuZE5vdGlmaWNhdGlvblNlcnZpY2UpO1xuICAgIHRoaXMucmVtb3RlQ29tbWFuZFNlcnZpY2UgPSBpbmplY3Rvci5nZXQoUmVtb3RlQ29tbWFuZFNlcnZpY2UpO1xuICAgIHRoaXMucm91dGVyID0gaW5qZWN0b3IuZ2V0KFJvdXRlcik7XG4gIH1cblxuICBzZW5kQ29tbWFuZChjb21tYW5kVHlwZTogUmVtb3RlQ29tbWFuZFR5cGVzLCBvcHRpb25zOiBhbnkgPSBudWxsLCBhbmFseXRpY3NQYXlsb2FkOiBUcmFjZVBheWxvYWQgPSB7fSk6IE9ic2VydmFibGU8eyBwYXlsb2FkRGF0YTogUmVtb3RlQ29tbWFuZEJhc2UsIHJlc3BvbnNlOiBhbnkgfT4ge1xuICAgIGNvbnN0IGd1aWQgPSB0aGlzLnN0b3JlLnNlbGVjdFNuYXBzaG90KEZhY2lsaXR5U3RhdGUuZ3VpZCk7XG4gICAgY29uc3QgdGlja2V0SWRlbnRpZmllciA9IHRoaXMuc3RvcmUuc2VsZWN0U25hcHNob3QoUGFya2VyU3RhdGUudGlja2V0SWRlbnRpZmllcik7XG4gICAgY29uc3QgZGF0YTogQ29uZmlnRGF0YSA9IHsgY29tbWFuZFR5cGUsIHRpY2tldElkZW50aWZpZXIsIG9wdGlvbnMgfTtcbiAgICBjb25zdCBjbWREYXRhRHRvJCA9IHRoaXMuZ2V0VGlja2V0UmVtb3RlQ29tbWFuZERhdGEoY29tbWFuZFR5cGUsIGRhdGEsIHRpY2tldElkZW50aWZpZXIsIG9wdGlvbnMpO1xuICAgIHJldHVybiB0aGlzLnJlbW90ZUNvbW1hbmRTZXJ2aWNlLnNlbmQoY21kRGF0YUR0byQsIGd1aWQsIG51bGwsIGFuYWx5dGljc1BheWxvYWQpO1xuICB9XG5cbiAgc2VuZENvbW1hbmRXaXRoU25hY2tEYXRhKGNvbW1hbmRUeXBlOiBSZW1vdGVDb21tYW5kVHlwZXMsIG9wdGlvbnM6IGFueSA9IG51bGwsIGFuYWx5dGljc1BheWxvYWQ6IFRyYWNlUGF5bG9hZCA9IHt9KTogT2JzZXJ2YWJsZTx7IHBheWxvYWREYXRhOiBSZW1vdGVDb21tYW5kQmFzZSwgcmVzcG9uc2U6IGFueSB9PiB7XG4gICAgY29uc3QgdGlja2V0SWRlbnRpZmllciA9IHRoaXMuc3RvcmUuc2VsZWN0U25hcHNob3QoUGFya2VyU3RhdGUudGlja2V0SWRlbnRpZmllcik7XG4gICAgY29uc3QgZW50aXR5VHlwZVRyYW5zbGF0ZSA9IG9wdGlvbnM/LmVudGl0eVR5cGVUcmFuc2xhdGUgfHwgdGlja2V0SWRlbnRpZmllcj8uZW50aXR5VHlwZVRyYW5zbGF0ZTtcbiAgICBjb25zdCBlbnRpdHlEaXNwbGF5TmFtZSA9IG9wdGlvbnM/LmVudGl0eURpc3BsYXlOYW1lIHx8IHRpY2tldElkZW50aWZpZXI/LmVudGl0eURpc3BsYXlOYW1lO1xuXG4gICAgY29uc3QgY29uZmlnOiBDb21tYW5kTm90aWZpY2F0aW9uQ29uZmlnID0ge1xuICAgICAgbWVzc2FnZXM6IFt7XG4gICAgICAgIHZhbHVlOiBgJHtlbnRpdHlUeXBlVHJhbnNsYXRlfSAke2VudGl0eURpc3BsYXlOYW1lfWAsXG4gICAgICAgIGNsYXNzOiBlbnRpdHlEaXNwbGF5TmFtZSA/IE5vdGlmaWNhdGlvbkNsYXNzLnN1YlRpdGxlIDogTm90aWZpY2F0aW9uQ2xhc3Mubm9uZSxcbiAgICAgIH1dLFxuICAgICAgY29tbWFuZDogdGhpcy5yZW1vdGVDb21tYW5kU2VydmljZS5nZXRSZW1vdGVDb21tYW5kVGV4dChjb21tYW5kVHlwZSksXG4gICAgfTtcblxuICAgIHJldHVybiB0aGlzLnNlbmRDb21tYW5kKGNvbW1hbmRUeXBlLCBvcHRpb25zLCBhbmFseXRpY3NQYXlsb2FkKVxuICAgICAgLnBpcGUodGhpcy5jb21tYW5kTm90aWZpY2F0aW9uU2VydmljZS5kaXNwbGF5KGNvbmZpZykpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFic3RyYWN0IGdldFRpY2tldFJlbW90ZUNvbW1hbmREYXRhKGNvbW1hbmRUeXBlOiBSZW1vdGVDb21tYW5kVHlwZXMsIGRhdGE6IENvbmZpZ0RhdGEsIHRpY2tldElkZW50aWZpZXI/OiBUaWNrZXRJZGVudGlmaWVyLCBvcHRpb25zPzogYW55KTogT2JzZXJ2YWJsZTxDbWREYXRhRHRvPjtcblxuICBleHRyYWN0VGlja2V0SW5mbyhjb250ZW50OiBzdHJpbmcpOiB7IHRpY2tldE51bTogc3RyaW5nLCB0aWNrZXREYXRlVGltZUluU2Vjb25kczogbnVtYmVyIH0ge1xuICAgIGxldCB0aWNrZXROdW06IHN0cmluZztcbiAgICBsZXQgdGlja2V0RGF0ZVRpbWU6IG1vbWVudC5Nb21lbnQ7XG4gICAgdHJ5IHtcbiAgICAgIC8vIFRvIGRldGVybWluZSB3aGF0IHR5cGUsIGNoZWNrIGNvbnRlbnQgbGVuZ3RoXG4gICAgICBzd2l0Y2ggKGNvbnRlbnQubGVuZ3RoKSB7XG4gICAgICAgIGNhc2UgQmFyY29kZVR5cGVMZW5ndGguUVIxOlxuICAgICAgICBjYXNlIEJhcmNvZGVUeXBlTGVuZ3RoLlFSMjpcbiAgICAgICAgICB0aWNrZXROdW0gPSBjb250ZW50LnNsaWNlKDYsIDE0KTsgLy8gTG9jYXRpb24gb2YgdGlja2V0IG51bWJlcjsgZnJvbSA3IHRvIDE0XG4gICAgICAgICAgLy8gTG9jYXRpb24gb2YgdGlja2V0IGRhdGU7IGZyb20gMTQgdG8gMjBcbiAgICAgICAgICAvLyBMb2NhdGlvbiBvZiB0aWNrZXQgdGltZTsgZnJvbSAyMCB0byAyNFxuICAgICAgICAgIHRpY2tldERhdGVUaW1lID0gdGhpcy5nZXRUaWNrZXREYXRlVGltZUJ5Q29udGVudChjb250ZW50LCB7IHN0YXJ0OiAxNCwgZW5kOiAyMCB9LCB7IHN0YXJ0OiAyMCwgZW5kOiAyNCB9KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBCYXJjb2RlVHlwZUxlbmd0aC5RUjQ6XG4gICAgICAgICAgdGlja2V0TnVtID0gY29udGVudC5zbGljZSg3LCAxNik7IC8vIExvY2F0aW9uIG9mIHRpY2tldCBudW1iZXI7IGZyb20gOCB0byAxNi5cbiAgICAgICAgICAvLyBMb2NhdGlvbiBvZiB0aWNrZXQgZGF0ZTsgZnJvbSAxNiB0byAyMlxuICAgICAgICAgIC8vIExvY2F0aW9uIG9mIHRpY2tldCB0aW1lOyBmcm9tIDIyIHRvIDI4XG4gICAgICAgICAgdGlja2V0RGF0ZVRpbWUgPSB0aGlzLmdldFRpY2tldERhdGVUaW1lQnlDb250ZW50KGNvbnRlbnQsIHsgc3RhcnQ6IDE2LCBlbmQ6IDIyIH0sIHsgc3RhcnQ6IDIyLCBlbmQ6IDI4IH0pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIEJhcmNvZGVUeXBlTGVuZ3RoLkJhcmNvZGUxOlxuICAgICAgICAgIHRpY2tldE51bSA9IGNvbnRlbnQuc2xpY2UoNywgMTQpOyAvLyBMb2NhdGlvbiBvZiB0aWNrZXQgbnVtYmVyOyBmcm9tIDcgdG8gMTRcbiAgICAgICAgICAvLyBMb2NhdGlvbiBvZiB0aWNrZXQgdGltZSBpbmZvOyBmcm9tIDEgdG8gN1xuICAgICAgICAgIHRpY2tldERhdGVUaW1lID0gdGhpcy5nZXRUaWNrZXREYXRlVGltZUJ5VGlja2V0VGltZShjb250ZW50LCB7IHN0YXJ0OiAxLCBlbmQ6IDcgfSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgQmFyY29kZVR5cGVMZW5ndGguQmFyY29kZTI6XG4gICAgICAgICAgdGlja2V0TnVtID0gY29udGVudC5zbGljZSgxMywgMjIpOyAvLyBMb2NhdGlvbiBvZiB0aWNrZXQgbnVtYmVyOyBmcm9tIDE0IHRvIDIyXG4gICAgICAgICAgLy8gTG9jYXRpb24gb2YgdGlja2V0IHRpbWUgaW5mbzsgZnJvbSA3IHRvIDEzXG4gICAgICAgICAgdGlja2V0RGF0ZVRpbWUgPSB0aGlzLmdldFRpY2tldERhdGVUaW1lQnlUaWNrZXRUaW1lKGNvbnRlbnQsIHsgc3RhcnQ6IDcsIGVuZDogMTMgfSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAge1xuICAgICAgICAgICAgY29uc3QgcVZhbHVlID0gdGhpcy5leHRyYWN0UXVlcnlQYXJhbShjb250ZW50LCAncScpO1xuICAgICAgICAgICAgaWYgKHFWYWx1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5leHRyYWN0VGlja2V0SW5mbyhxVmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9IGNhdGNoIChfKSB7IH1cblxuICAgIGNvbnN0IHRpY2tldERhdGVUaW1lSW5TZWNvbmRzID0gcGFyc2VEYXRlVGltZVRvU3BhcmtQYXJrVGltZSh0aWNrZXREYXRlVGltZT8udG9EYXRlKCkpO1xuICAgIHJldHVybiB7IHRpY2tldE51bSwgdGlja2V0RGF0ZVRpbWVJblNlY29uZHMgfTtcbiAgfVxuXG4gIHByaXZhdGUgZXh0cmFjdFF1ZXJ5UGFyYW0odXJsOiBzdHJpbmcsIHBhcmFtOiBzdHJpbmcpOiBzdHJpbmcgfCBudWxsIHtcbiAgICBpZiAoIXVybCB8fCAhcGFyYW0pIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhcnNlZFVybCA9IG5ldyBVUkwodXJsKTtcbiAgICAgIHJldHVybiBwYXJzZWRVcmwuc2VhcmNoUGFyYW1zLmdldChwYXJhbSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBJbiBjYXNlIHRoZSBzdHJpbmcgaXMgbm90IGEgdmFsaWQgVVJMXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldFRpY2tldERhdGVUaW1lQnlDb250ZW50KGNvbnRlbnQ6IHN0cmluZywgZGF0ZTogeyBzdGFydDogbnVtYmVyLCBlbmQ6IG51bWJlciB9LCB0aW1lOiB7IHN0YXJ0OiBudW1iZXIsIGVuZDogbnVtYmVyIH0pOiBtb21lbnQuTW9tZW50IHtcbiAgICBjb25zdCBfZGF0ZSA9IGNvbnRlbnQuc2xpY2UoZGF0ZS5zdGFydCwgZGF0ZS5lbmQpO1xuICAgIGNvbnN0IF90aW1lID0gY29udGVudC5zbGljZSh0aW1lLnN0YXJ0LCB0aW1lLmVuZCk7XG4gICAgcmV0dXJuIG1vbWVudCh7XG4gICAgICB5ZWFyOiAyMDAwICsgK19kYXRlLnNsaWNlKDQsIDYpLFxuICAgICAgbW9udGg6ICtfZGF0ZS5zbGljZSgyLCA0KSAtIDEsXG4gICAgICBkYXk6ICtfZGF0ZS5zbGljZSgwLCAyKSxcbiAgICAgIGhvdXI6ICtfdGltZS5zbGljZSgwLCAyKSxcbiAgICAgIG1pbnV0ZTogK190aW1lLnNsaWNlKDIsIDQpLFxuICAgICAgc2Vjb25kOiBfdGltZS5sZW5ndGggPT09IDYgPyArX3RpbWUuc2xpY2UoNCwgNikgOiAwXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGdldFRpY2tldERhdGVUaW1lQnlUaWNrZXRUaW1lKGNvbnRlbnQ6IHN0cmluZywgbG9jYXRpb246IHsgc3RhcnQ6IG51bWJlciwgZW5kOiBudW1iZXIgfSk6IG1vbWVudC5Nb21lbnQge1xuICAgIC8vIG11bHRpcGxlIDYwMDAwOlxuICAgIC8vIGdldFRpbWUgbWV0aG9kIHJldHVybiBkYXRlIGluIG1pbGlzZWNvbmRzXG4gICAgLy8gdG8gY29udmVydCB0byBzZWNvbmRzIG11bHRpcGxlIGJ5IDEwMDAwXG4gICAgLy8gdG8gY29udmVydCBzZWNvbmRzIHRvIG1pbnV0ZXMgbXVsdGlwbGUgYnkgNjBcblxuICAgIGNvbnN0IHRpY2tldFRpbWUgPSArY29udGVudC5zbGljZShsb2NhdGlvbi5zdGFydCwgbG9jYXRpb24uZW5kKTtcbiAgICB2YXIgY3VyVGltZURhdGVUaW1lID0gbmV3IERhdGUoKTtcbiAgICBjdXJUaW1lRGF0ZVRpbWUuc2V0U2Vjb25kcygwKTtcblxuICAgIGxldCBkZWZhdWx0U21hcnRQYXJrRGF0ZVRpbWUgPSBuZXcgRGF0ZSgyMDAwLCAwLCAxLCAwLCAwLCAwKS5nZXRUaW1lKCk7XG4gICAgLy8gVGhlIGRlZmF1bHQgc21hcnQgcGFyayBkYXRlIHRpbWUgaXMgYWx3YXlzOiBTYXQgSmFuIDAxIDIwMDAgMDA6MDA6MDAgR01UKzAyMDAgKElzcmFlbCBTdGFuZGFyZCBUaW1lKVxuICAgIC8vIElmIHRoZSBjdXJyZW50IHRpbWUgZGF0ZSBpcyBpbiBEU1QgKEdNVCswMzAwKSB0aGVuIHRvIGF2b2lkIGluY29ycmVjdCByZXN1bHRzIHdlIG5lZWQgdG8gcmVtb3ZlIDEgaG91clxuICAgIGlmIChtb21lbnQoY3VyVGltZURhdGVUaW1lKS5pc0RTVCgpKSB7XG4gICAgICAvLyA2MCBNaW51dGVzICggMSBob3VyICkgaW4gbWlsaXNlY29uZHMgZXF1YWwgMzYwMDAwMFxuICAgICAgZGVmYXVsdFNtYXJ0UGFya0RhdGVUaW1lIC09IDM2MDAwMDA7XG4gICAgfVxuXG4gICAgdmFyIGN1clRpbWVJbk1pbnV0ZXMgPSAoY3VyVGltZURhdGVUaW1lLmdldFRpbWUoKSAtIGRlZmF1bHRTbWFydFBhcmtEYXRlVGltZSkgLyA2MDAwMDtcbiAgICB2YXIgY3VyVGltZVRpY2tldEZvcm1hdCA9IGN1clRpbWVJbk1pbnV0ZXMgJSAxMDAwMDAwO1xuICAgIGlmICh0aWNrZXRUaW1lID4gY3VyVGltZVRpY2tldEZvcm1hdCkgY3VyVGltZVRpY2tldEZvcm1hdCArPSAxMDAwMDAwO1xuXG4gICAgY29uc3QgdGlja2V0RGF0ZVRpbWVJbk1pbnV0ZXMgPSAoZGVmYXVsdFNtYXJ0UGFya0RhdGVUaW1lIC8gNjAwMDApICsgY3VyVGltZUluTWludXRlcyAtIChjdXJUaW1lVGlja2V0Rm9ybWF0IC0gdGlja2V0VGltZSk7XG4gICAgcmV0dXJuIG1vbWVudChuZXcgRGF0ZSh0aWNrZXREYXRlVGltZUluTWludXRlcyAqIDYwMDAwKSk7XG4gIH1cblxuICBuYXZpZ2F0ZVRvVGlja2V0KHRpY2tldE51bTogc3RyaW5nLCBndWlkOiBzdHJpbmcsIHBhcmtJZDogbnVtYmVyLCBhY3RpdmF0ZWRSb3V0ZTogQWN0aXZhdGVkUm91dGUsIHRpY2tldERhdGVUaW1lSW5TZWNvbmRzOiBudW1iZXIgPSBudWxsKSB7XG4gICAgY29uc3QgdGliYUtleXMgPSB0aGlzLnN0b3JlLnNlbGVjdFNuYXBzaG90KEZhY2lsaXR5U3RhdGUudGliYUtleXMpO1xuICAgIGNvbnN0IGNvbW1hbmRzOiBhbnlbXSA9IFtcbiAgICAgIHRpYmFLZXlzW2d1aWRdLFxuICAgICAgcGFya0lkLFxuICAgICAgdGlja2V0TnVtLFxuICAgIF07XG4gICAgaWYgKHRpY2tldERhdGVUaW1lSW5TZWNvbmRzKSB7XG4gICAgICBjb21tYW5kcy5wdXNoKHRpY2tldERhdGVUaW1lSW5TZWNvbmRzKTtcbiAgICB9XG4gICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoY29tbWFuZHMsIHsgcmVsYXRpdmVUbzogYWN0aXZhdGVkUm91dGUgfSk7XG4gIH1cblxuICBzY2FuVGlja2V0KHRpY2tldE51bTogc3RyaW5nLCBndWlkOiBzdHJpbmcsIHBhcmtJZDogbnVtYmVyLCBhY3RpdmF0ZWRSb3V0ZTogQWN0aXZhdGVkUm91dGUsIHRpY2tldERhdGVUaW1lSW5TZWNvbmRzOiBudW1iZXIpIHtcbiAgICB0aGlzLm5hdmlnYXRlVG9UaWNrZXQodGlja2V0TnVtLCBndWlkLCBwYXJrSWQsIGFjdGl2YXRlZFJvdXRlLCB0aWNrZXREYXRlVGltZUluU2Vjb25kcyk7XG4gIH1cbn1cbiJdfQ==
168
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGlja2V0LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jbGllbnQtc2hhcmVkLWxpYi9zcmMvbGlicmFyaWVzL3NlcnZpY2VzL3RpY2tldC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQVksTUFBTSxlQUFlLENBQUM7QUFDckQsT0FBTyxFQUFrQixNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3BDLE9BQU8sTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUc1QixPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSw4RUFBOEUsQ0FBQztBQUMxSCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnREFBZ0QsQ0FBQztBQUNuRixPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUM3RSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUsvRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDbkUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBRzdELE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDOztBQUdoRSxNQUFNLE9BQWdCLGFBQWE7SUFPakMsWUFBbUIsUUFBa0I7UUFBbEIsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUNuQyxJQUFJLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDakMsSUFBSSxDQUFDLDBCQUEwQixHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsMEJBQTBCLENBQUMsQ0FBQztRQUMzRSxJQUFJLENBQUMsb0JB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UUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNuRSxNQUFNLFFBQVEsR0FBVTtZQUN0QixRQUFRLENBQUMsSUFBSSxDQUFDO1lBQ2QsTUFBTTtZQUNOLFNBQVM7U0FDVixDQUFDO1FBQ0YsSUFBSSx1QkFBdUIsRUFBRSxDQUFDO1lBQzVCLFFBQVEsQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQztRQUN6QyxDQUFDO1FBQ0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRSxDQUFDLENBQUM7SUFDakUsQ0FBQztJQUVELFVBQVUsQ0FBQyxTQUFpQixFQUFFLElBQVksRUFBRSxNQUFjLEVBQUUsY0FBOEIsRUFBRSx1QkFBK0I7UUFDekgsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO0lBQzFGLENBQUM7K0dBNUttQixhQUFhO21IQUFiLGFBQWE7OzRGQUFiLGFBQWE7a0JBRGxDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBJbmplY3RvciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUsIFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBTdG9yZSB9IGZyb20gJ0BuZ3hzL3N0b3JlJztcbmltcG9ydCBtb21lbnQgZnJvbSAnbW9tZW50JztcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IENvbW1hbmROb3RpZmljYXRpb25Db25maWcgfSBmcm9tICcuLi9jb21wb25lbnRzL25vdGlmaWNhdGlvbi9jb21tYW5kLW5vdGlmaWNhdGlvbi9jb21tYW5kLW5vdGlmaWNhdGlvbi1jb25maWcnO1xuaW1wb3J0IHsgQ29tbWFuZE5vdGlmaWNhdGlvblNlcnZpY2UgfSBmcm9tICcuLi9jb21wb25lbnRzL25vdGlmaWNhdGlvbi9jb21tYW5kLW5vdGlmaWNhdGlvbi9jb21tYW5kLW5vdGlmaWNhdGlvbi5zZXJ2aWNlJztcbmltcG9ydCB7IE5vdGlmaWNhdGlvbkNsYXNzIH0gZnJvbSAnLi4vY29tcG9uZW50cy9ub3RpZmljYXRpb24vbm90aWZpY2F0aW9uLWNvbmZpZyc7XG5pbXBvcnQgeyBERUZBVUxUX1NNQVJUX1BBUktfREFURV9USU1FIH0gZnJvbSAnLi4vY29uc3RhbnRzL2dsb2JhbC1jb25zdGFudHMnO1xuaW1wb3J0IHsgQmFyY29kZVR5cGVMZW5ndGggfSBmcm9tICcuLi9lbnVtcy9iYXJjb2RlLXR5cGUuZW51bSc7XG5pbXBvcnQgeyBUcmFjZVBheWxvYWQgfSBmcm9tICcuLi9pbnRlcmZhY2VzL2FuYWx5dGljcy5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgQ21kRGF0YUR0byB9IGZyb20gJy4uL2ludGVyZmFjZXMvY21kLWRhdGEuaW50ZXJmYWNlJztcbmltcG9ydCB7IENvbmZpZ0RhdGEgfSBmcm9tICcuLi9pbnRlcmZhY2VzL2NvbmZpZy1kYXRhLmludGVyZmFjZSc7XG5pbXBvcnQgeyBUaWNrZXRJZGVudGlmaWVyIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy90aWNrZXQuaW50ZXJmYWNlJztcbmltcG9ydCB7IEZhY2lsaXR5U3RhdGUgfSBmcm9tICcuLi9tb2R1bGVzL2ZhY2lsaXR5L2ZhY2lsaXR5LnN0YXRlJztcbmltcG9ydCB7IFBhcmtlclN0YXRlIH0gZnJvbSAnLi4vbW9kdWxlcy9wYXJrZXIvcGFya2VyLnN0YXRlJztcbmltcG9ydCB7IFJlbW90ZUNvbW1hbmRUeXBlcyB9IGZyb20gJy4uL3NlcnZpY2UtcHJveHkvY2xvdWQtc2VydmljZS1wcm94aWVzJztcbmltcG9ydCB7IFJlbW90ZUNvbW1hbmRCYXNlIH0gZnJvbSAnLi4vc2VydmljZS1wcm94eS9ycGMtc2VydmljZS1wcm94aWVzJztcbmltcG9ydCB7IHBhcnNlRGF0ZVRpbWVUb1NwYXJrUGFya1RpbWUgfSBmcm9tICcuLi91dGlscy9kYXRlLnV0aWwnO1xuaW1wb3J0IHsgUmVtb3RlQ29tbWFuZFNlcnZpY2UgfSBmcm9tICcuL3JlbW90ZS1jb21tYW5kLnNlcnZpY2UnO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgVGlja2V0U2VydmljZSB7XG5cbiAgcHJvdGVjdGVkIHN0b3JlOiBTdG9yZTtcbiAgcHJvdGVjdGVkIGNvbW1hbmROb3RpZmljYXRpb25TZXJ2aWNlOiBDb21tYW5kTm90aWZpY2F0aW9uU2VydmljZTtcbiAgcHJvdGVjdGVkIHJlbW90ZUNvbW1hbmRTZXJ2aWNlOiBSZW1vdGVDb21tYW5kU2VydmljZTtcbiAgcHJvdGVjdGVkIHJvdXRlcjogUm91dGVyO1xuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBpbmplY3RvcjogSW5qZWN0b3IpIHtcbiAgICB0aGlzLnN0b3JlID0gaW5qZWN0b3IuZ2V0KFN0b3JlKTtcbiAgICB0aGlzLmNvbW1hbmROb3RpZmljYXRpb25TZXJ2aWNlID0gaW5qZWN0b3IuZ2V0KENvbW1hbmROb3RpZmljYXRpb25TZXJ2aWNlKTtcbiAgICB0aGlzLnJlbW90ZUNvbW1hbmRTZXJ2aWNlID0gaW5qZWN0b3IuZ2V0KFJlbW90ZUNvbW1hbmRTZXJ2aWNlKTtcbiAgICB0aGlzLnJvdXRlciA9IGluamVjdG9yLmdldChSb3V0ZXIpO1xuICB9XG5cbiAgc2VuZENvbW1hbmQoY29tbWFuZFR5cGU6IFJlbW90ZUNvbW1hbmRUeXBlcywgb3B0aW9uczogYW55ID0gbnVsbCwgYW5hbHl0aWNzUGF5bG9hZDogVHJhY2VQYXlsb2FkID0ge30pOiBPYnNlcnZhYmxlPHsgcGF5bG9hZERhdGE6IFJlbW90ZUNvbW1hbmRCYXNlLCByZXNwb25zZTogYW55IH0+IHtcbiAgICBjb25zdCBndWlkID0gdGhpcy5zdG9yZS5zZWxlY3RTbmFwc2hvdChGYWNpbGl0eVN0YXRlLmd1aWQpO1xuICAgIGNvbnN0IHRpY2tldElkZW50aWZpZXIgPSB0aGlzLnN0b3JlLnNlbGVjdFNuYXBzaG90KFBhcmtlclN0YXRlLnRpY2tldElkZW50aWZpZXIpO1xuICAgIGNvbnN0IGRhdGE6IENvbmZpZ0RhdGEgPSB7IGNvbW1hbmRUeXBlLCB0aWNrZXRJZGVudGlmaWVyLCBvcHRpb25zIH07XG4gICAgY29uc3QgY21kRGF0YUR0byQgPSB0aGlzLmdldFRpY2tldFJlbW90ZUNvbW1hbmREYXRhKGNvbW1hbmRUeXBlLCBkYXRhLCB0aWNrZXRJZGVudGlmaWVyLCBvcHRpb25zKTtcbiAgICByZXR1cm4gdGhpcy5yZW1vdGVDb21tYW5kU2VydmljZS5zZW5kKGNtZERhdGFEdG8kLCBndWlkLCBudWxsLCBhbmFseXRpY3NQYXlsb2FkKTtcbiAgfVxuXG4gIHNlbmRDb21tYW5kV2l0aFNuYWNrRGF0YShjb21tYW5kVHlwZTogUmVtb3RlQ29tbWFuZFR5cGVzLCBvcHRpb25zOiBhbnkgPSBudWxsLCBhbmFseXRpY3NQYXlsb2FkOiBUcmFjZVBheWxvYWQgPSB7fSk6IE9ic2VydmFibGU8eyBwYXlsb2FkRGF0YTogUmVtb3RlQ29tbWFuZEJhc2UsIHJlc3BvbnNlOiBhbnkgfT4ge1xuICAgIGNvbnN0IHRpY2tldElkZW50aWZpZXIgPSB0aGlzLnN0b3JlLnNlbGVjdFNuYXBzaG90KFBhcmtlclN0YXRlLnRpY2tldElkZW50aWZpZXIpO1xuICAgIGNvbnN0IGVudGl0eVR5cGVUcmFuc2xhdGUgPSBvcHRpb25zPy5lbnRpdHlUeXBlVHJhbnNsYXRlIHx8IHRpY2tldElkZW50aWZpZXI/LmVudGl0eVR5cGVUcmFuc2xhdGU7XG4gICAgY29uc3QgZW50aXR5RGlzcGxheU5hbWUgPSBvcHRpb25zPy5lbnRpdHlEaXNwbGF5TmFtZSB8fCB0aWNrZXRJZGVudGlmaWVyPy5lbnRpdHlEaXNwbGF5TmFtZTtcblxuICAgIGNvbnN0IGNvbmZpZzogQ29tbWFuZE5vdGlmaWNhdGlvbkNvbmZpZyA9IHtcbiAgICAgIG1lc3NhZ2VzOiBbe1xuICAgICAgICB2YWx1ZTogYCR7ZW50aXR5VHlwZVRyYW5zbGF0ZX0gJHtlbnRpdHlEaXNwbGF5TmFtZX1gLFxuICAgICAgICBjbGFzczogZW50aXR5RGlzcGxheU5hbWUgPyBOb3RpZmljYXRpb25DbGFzcy5zdWJUaXRsZSA6IE5vdGlmaWNhdGlvbkNsYXNzLm5vbmUsXG4gICAgICB9XSxcbiAgICAgIGNvbW1hbmQ6IHRoaXMucmVtb3RlQ29tbWFuZFNlcnZpY2UuZ2V0UmVtb3RlQ29tbWFuZFRleHQoY29tbWFuZFR5cGUpLFxuICAgIH07XG5cbiAgICByZXR1cm4gdGhpcy5zZW5kQ29tbWFuZChjb21tYW5kVHlwZSwgb3B0aW9ucywgYW5hbHl0aWNzUGF5bG9hZClcbiAgICAgIC5waXBlKHRoaXMuY29tbWFuZE5vdGlmaWNhdGlvblNlcnZpY2UuZGlzcGxheShjb25maWcpKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBnZXRUaWNrZXRSZW1vdGVDb21tYW5kRGF0YShjb21tYW5kVHlwZTogUmVtb3RlQ29tbWFuZFR5cGVzLCBkYXRhOiBDb25maWdEYXRhLCB0aWNrZXRJZGVudGlmaWVyPzogVGlja2V0SWRlbnRpZmllciwgb3B0aW9ucz86IGFueSk6IE9ic2VydmFibGU8Q21kRGF0YUR0bz47XG5cbiAgZXh0cmFjdFRpY2tldEluZm8oY29udGVudDogc3RyaW5nLCB0aW1lem9uZTogc3RyaW5nKTogeyB0aWNrZXROdW06IHN0cmluZywgdGlja2V0RGF0ZVRpbWVJblNlY29uZHM6IG51bWJlciB9IHtcbiAgICBsZXQgdGlja2V0TnVtOiBzdHJpbmc7XG4gICAgbGV0IHRpY2tldERhdGVUaW1lSW5TZWNvbmRzOiBudW1iZXI7XG4gICAgdHJ5IHtcbiAgICAgIC8vIFRvIGRldGVybWluZSB3aGF0IHR5cGUsIGNoZWNrIGNvbnRlbnQgbGVuZ3RoXG4gICAgICBzd2l0Y2ggKGNvbnRlbnQubGVuZ3RoKSB7XG4gICAgICAgIGNhc2UgQmFyY29kZVR5cGVMZW5ndGguUVIxOlxuICAgICAgICBjYXNlIEJhcmNvZGVUeXBlTGVuZ3RoLlFSMjpcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0aWNrZXROdW0gPSBjb250ZW50LnNsaWNlKDYsIDE0KTsgLy8gTG9jYXRpb24gb2YgdGlja2V0IG51bWJlcjsgZnJvbSA3IHRvIDE0XG4gICAgICAgICAgICAvLyBMb2NhdGlvbiBvZiB0aWNrZXQgZGF0ZTsgZnJvbSAxNCB0byAyMFxuICAgICAgICAgICAgLy8gTG9jYXRpb24gb2YgdGlja2V0IHRpbWU7IGZyb20gMjAgdG8gMjRcbiAgICAgICAgICAgIGNvbnN0IHRpY2tldERhdGVUaW1lID0gdGhpcy5nZXRUaWNrZXREYXRlVGltZUJ5UVJDb250ZW50KGNvbnRlbnQsIHsgc3RhcnQ6IDE0LCBlbmQ6IDIwIH0sIHsgc3RhcnQ6IDIwLCBlbmQ6IDI0IH0pO1xuICAgICAgICAgICAgdGlja2V0RGF0ZVRpbWVJblNlY29uZHMgPSBwYXJzZURhdGVUaW1lVG9TcGFya1BhcmtUaW1lKHRpY2tldERhdGVUaW1lPy50b0RhdGUoKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIEJhcmNvZGVUeXBlTGVuZ3RoLlFSNDpcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0aWNrZXROdW0gPSBjb250ZW50LnNsaWNlKDcsIDE2KTsgLy8gTG9jYXRpb24gb2YgdGlja2V0IG51bWJlcjsgZnJvbSA4IHRvIDE2LlxuICAgICAgICAgICAgLy8gTG9jYXRpb24gb2YgdGlja2V0IGRhdGU7IGZyb20gMTYgdG8gMjJcbiAgICAgICAgICAgIC8vIExvY2F0aW9uIG9mIHRpY2tldCB0aW1lOyBmcm9tIDIyIHRvIDI4XG4gICAgICAgICAgICBjb25zdCB0aWNrZXREYXRlVGltZSA9IHRoaXMuZ2V0VGlja2V0RGF0ZVRpbWVCeVFSQ29udGVudChjb250ZW50LCB7IHN0YXJ0OiAxNiwgZW5kOiAyMiB9LCB7IHN0YXJ0OiAyMiwgZW5kOiAyOCB9KTtcbiAgICAgICAgICAgIHRpY2tldERhdGVUaW1lSW5TZWNvbmRzID0gcGFyc2VEYXRlVGltZVRvU3BhcmtQYXJrVGltZSh0aWNrZXREYXRlVGltZT8udG9EYXRlKCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBCYXJjb2RlVHlwZUxlbmd0aC5CYXJjb2RlMTpcbiAgICAgICAgICB0aWNrZXROdW0gPSBjb250ZW50LnNsaWNlKDcsIDE0KTsgLy8gTG9jYXRpb24gb2YgdGlja2V0IG51bWJlcjsgZnJvbSA3IHRvIDE0XG4gICAgICAgICAgLy8gTG9jYXRpb24gb2YgdGlja2V0IHRpbWUgaW5mbzsgZnJvbSAxIHRvIDdcbiAgICAgICAgICB0aWNrZXREYXRlVGltZUluU2Vjb25kcyA9IHRoaXMuZ2V0VGlja2V0RGF0ZVRpbWVJblNlY29uZHNCeUJhcmNvZGVDb250ZW50KGNvbnRlbnQsIHsgc3RhcnQ6IDEsIGVuZDogNyB9LCB0aW1lem9uZSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgQmFyY29kZVR5cGVMZW5ndGguQmFyY29kZTI6XG4gICAgICAgICAgdGlja2V0TnVtID0gY29udGVudC5zbGljZSgxMywgMjIpOyAvLyBMb2NhdGlvbiBvZiB0aWNrZXQgbnVtYmVyOyBmcm9tIDE0IHRvIDIyXG4gICAgICAgICAgLy8gTG9jYXRpb24gb2YgdGlja2V0IHRpbWUgaW5mbzsgZnJvbSA3IHRvIDEzXG4gICAgICAgICAgdGlja2V0RGF0ZVRpbWVJblNlY29uZHMgPSB0aGlzLmdldFRpY2tldERhdGVUaW1lSW5TZWNvbmRzQnlCYXJjb2RlQ29udGVudChjb250ZW50LCB7IHN0YXJ0OiA3LCBlbmQ6IDEzIH0sIHRpbWV6b25lKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBjb25zdCBxVmFsdWUgPSB0aGlzLmV4dHJhY3RRdWVyeVBhcmFtKGNvbnRlbnQsICdxJyk7XG4gICAgICAgICAgICBpZiAocVZhbHVlICE9PSBudWxsICYmIHFWYWx1ZSAhPT0gY29udGVudCkge1xuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5leHRyYWN0VGlja2V0SW5mbyhxVmFsdWUsIHRpbWV6b25lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoXykgeyB9XG5cbiAgICByZXR1cm4geyB0aWNrZXROdW0sIHRpY2tldERhdGVUaW1lSW5TZWNvbmRzIH07XG4gIH1cblxuICBwcml2YXRlIGV4dHJhY3RRdWVyeVBhcmFtKHVybDogc3RyaW5nLCBwYXJhbTogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgaWYgKCF1cmwgfHwgIXBhcmFtKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIFxuICAgIHRyeSB7XG4gICAgICBjb25zdCBwYXJzZWRVcmwgPSBuZXcgVVJMKHVybCk7XG4gICAgICByZXR1cm4gcGFyc2VkVXJsLnNlYXJjaFBhcmFtcy5nZXQocGFyYW0pO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gSW4gY2FzZSB0aGUgc3RyaW5nIGlzIG5vdCBhIHZhbGlkIFVSTFxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRUaWNrZXREYXRlVGltZUJ5UVJDb250ZW50KGNvbnRlbnQ6IHN0cmluZywgZGF0ZTogeyBzdGFydDogbnVtYmVyLCBlbmQ6IG51bWJlciB9LCB0aW1lOiB7IHN0YXJ0OiBudW1iZXIsIGVuZDogbnVtYmVyIH0pOiBtb21lbnQuTW9tZW50IHtcbiAgICBjb25zdCBfZGF0ZSA9IGNvbnRlbnQuc2xpY2UoZGF0ZS5zdGFydCwgZGF0ZS5lbmQpO1xuICAgIGNvbnN0IF90aW1lID0gY29udGVudC5zbGljZSh0aW1lLnN0YXJ0LCB0aW1lLmVuZCk7XG4gICAgcmV0dXJuIG1vbWVudCh7XG4gICAgICB5ZWFyOiAyMDAwICsgK19kYXRlLnNsaWNlKDQsIDYpLFxuICAgICAgbW9udGg6ICtfZGF0ZS5zbGljZSgyLCA0KSAtIDEsXG4gICAgICBkYXk6ICtfZGF0ZS5zbGljZSgwLCAyKSxcbiAgICAgIGhvdXI6ICtfdGltZS5zbGljZSgwLCAyKSxcbiAgICAgIG1pbnV0ZTogK190aW1lLnNsaWNlKDIsIDQpLFxuICAgICAgc2Vjb25kOiBfdGltZS5sZW5ndGggPT09IDYgPyArX3RpbWUuc2xpY2UoNCwgNikgOiAwXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGdldFRpY2tldERhdGVUaW1lSW5TZWNvbmRzQnlCYXJjb2RlQ29udGVudChjb250ZW50OiBzdHJpbmcsIGxvY2F0aW9uOiB7IHN0YXJ0OiBudW1iZXIsIGVuZDogbnVtYmVyOyB9LCB0aW1lem9uZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICAvLyBCYXJjb2RlIHRpbWUgZW5jb2RpbmcgKGJhc2VkIG9uIFNRTCBEYXRlMk51bWJlciAvIE51bWJlcjJEYXRlKTpcbiAgICAvLyBUaGUgb3JpZ2luYWwgZGF0ZXRpbWUgaXMgY29udmVydGVkIGluIFNRTCB0byB0b3RhbCBzZWNvbmRzIHNpbmNlIH4yMDAwLTAxLTAxLFxuICAgIC8vIHRoZW4gZWZmZWN0aXZlbHkgdG8gdG90YWwgbWludXRlcy4gVGhlIGJhcmNvZGUgc3RvcmVzIG9ubHkgdGhlIExBU1QgNiBkaWdpdHNcbiAgICAvLyBvZiB0aG9zZSBtaW51dGVzICh0b3RhbE1pbnV0ZXMgJSAxLDAwMCwwMDApLlxuICAgIC8vXG4gICAgLy8gQmVjYXVzZSBvZiB0aGlzIHRydW5jYXRpb24sIHRoZSB2YWx1ZSB3cmFwcyBldmVyeSAxLDAwMCwwMDAgbWludXRlcyAofjY5NCBkYXlzKSxcbiAgICAvLyBzbyB0aGUgc2FtZSB2YWx1ZSBjYW4gcmVwcmVzZW50IG11bHRpcGxlIGRhdGVzLlxuICAgIC8vXG4gICAgLy8gVG8gcmVjb25zdHJ1Y3QgdGhlIGNvcnJlY3QgZGF0ZXRpbWUsIHdlIHJlYnVpbGQgcG9zc2libGUgZnVsbCB2YWx1ZXMgYW5kXG4gICAgLy8gc2VsZWN0IHRoZSBvbmUgY2xvc2VzdCB0byBcIm5vd1wiLlxuXG4gICAgY29uc3QgTUlOVVRFX0NZQ0xFICA9IDFfMDAwXzAwMDtcbiAgICBjb25zdCBDWUNMRV9TRUFSQ0hfUkFESVVTID0gMTtcblxuICAgIGNvbnN0IHRydW5jYXRlZE1pbnV0ZXNGcm9tQmFyY29kZSA9IE51bWJlcihjb250ZW50LnNsaWNlKGxvY2F0aW9uLnN0YXJ0LCBsb2NhdGlvbi5lbmQpKTtcbiAgICBcbiAgICBjb25zdCBub3cgPSBtb21lbnQudHoodGltZXpvbmUpLnNlY29uZHMoMCkubWlsbGlzZWNvbmRzKDApO1xuICAgIGNvbnN0IGJhcmNvZGVCYXNlRGF0ZSA9IG1vbWVudC50eihERUZBVUxUX1NNQVJUX1BBUktfREFURV9USU1FLCAnWVlZWS1NTS1ERCBISDptbTpzcycsIHRpbWV6b25lKTtcbiAgICBcbiAgICBjb25zdCBjdXJyZW50VG90YWxNaW51dGVzRnJvbUJhc2UgPSBub3cuZGlmZihiYXJjb2RlQmFzZURhdGUsICdtaW51dGVzJyk7XG4gICAgY29uc3QgZXN0aW1hdGVkQ3ljbGVJbmRleCA9IE1hdGguZmxvb3IoY3VycmVudFRvdGFsTWludXRlc0Zyb21CYXNlIC8gTUlOVVRFX0NZQ0xFICk7XG4gICAgXG4gICAgbGV0IHJlc29sdmVkVGlja2V0RGF0ZVRpbWUgPSBiYXJjb2RlQmFzZURhdGUuY2xvbmUoKTtcbiAgICBsZXQgc21hbGxlc3REaWZmZXJlbmNlRnJvbU5vdyA9IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSO1xuICAgIFxuICAgIGZvciAobGV0IGN5Y2xlSW5kZXggPSBlc3RpbWF0ZWRDeWNsZUluZGV4IC0gQ1lDTEVfU0VBUkNIX1JBRElVUzsgY3ljbGVJbmRleCA8PSBlc3RpbWF0ZWRDeWNsZUluZGV4ICsgQ1lDTEVfU0VBUkNIX1JBRElVUzsgY3ljbGVJbmRleCsrKSB7XG4gICAgICBjb25zdCBmdWxsTWludXRlc0Zyb21CYXNlID0gY3ljbGVJbmRleCAqIE1JTlVURV9DWUNMRSAgKyB0cnVuY2F0ZWRNaW51dGVzRnJvbUJhcmNvZGUgO1xuICAgICAgY29uc3QgY2FuZGlkYXRlRGF0ZVRpbWUgPSBiYXJjb2RlQmFzZURhdGUuY2xvbmUoKS5hZGQoZnVsbE1pbnV0ZXNGcm9tQmFzZSwgJ21pbnV0ZXMnKTtcbiAgICAgIGNvbnN0IGRpZmZlcmVuY2VGcm9tTm93ICA9IE1hdGguYWJzKGNhbmRpZGF0ZURhdGVUaW1lLmRpZmYobm93KSk7XG4gICAgXG4gICAgICBpZiAoZGlmZmVyZW5jZUZyb21Ob3cgIDwgc21hbGxlc3REaWZmZXJlbmNlRnJvbU5vdykge1xuICAgICAgICBzbWFsbGVzdERpZmZlcmVuY2VGcm9tTm93ID0gZGlmZmVyZW5jZUZyb21Ob3cgO1xuICAgICAgICByZXNvbHZlZFRpY2tldERhdGVUaW1lID0gY2FuZGlkYXRlRGF0ZVRpbWU7XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIHJldHVybiByZXNvbHZlZFRpY2tldERhdGVUaW1lLmRpZmYoYmFyY29kZUJhc2VEYXRlLCAnc2Vjb25kcycpO1xuICB9XG5cbiAgbmF2aWdhdGVUb1RpY2tldCh0aWNrZXROdW06IHN0cmluZywgZ3VpZDogc3RyaW5nLCBwYXJrSWQ6IG51bWJlciwgYWN0aXZhdGVkUm91dGU6IEFjdGl2YXRlZFJvdXRlLCB0aWNrZXREYXRlVGltZUluU2Vjb25kczogbnVtYmVyID0gbnVsbCkge1xuICAgIGNvbnN0IHRpYmFLZXlzID0gdGhpcy5zdG9yZS5zZWxlY3RTbmFwc2hvdChGYWNpbGl0eVN0YXRlLnRpYmFLZXlzKTtcbiAgICBjb25zdCBjb21tYW5kczogYW55W10gPSBbXG4gICAgICB0aWJhS2V5c1tndWlkXSxcbiAgICAgIHBhcmtJZCxcbiAgICAgIHRpY2tldE51bSxcbiAgICBdO1xuICAgIGlmICh0aWNrZXREYXRlVGltZUluU2Vjb25kcykge1xuICAgICAgY29tbWFuZHMucHVzaCh0aWNrZXREYXRlVGltZUluU2Vjb25kcyk7XG4gICAgfVxuICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKGNvbW1hbmRzLCB7IHJlbGF0aXZlVG86IGFjdGl2YXRlZFJvdXRlIH0pO1xuICB9XG5cbiAgc2NhblRpY2tldCh0aWNrZXROdW06IHN0cmluZywgZ3VpZDogc3RyaW5nLCBwYXJrSWQ6IG51bWJlciwgYWN0aXZhdGVkUm91dGU6IEFjdGl2YXRlZFJvdXRlLCB0aWNrZXREYXRlVGltZUluU2Vjb25kczogbnVtYmVyKSB7XG4gICAgdGhpcy5uYXZpZ2F0ZVRvVGlja2V0KHRpY2tldE51bSwgZ3VpZCwgcGFya0lkLCBhY3RpdmF0ZWRSb3V0ZSwgdGlja2V0RGF0ZVRpbWVJblNlY29uZHMpO1xuICB9XG59XG4iXX0=
@@ -113920,47 +113920,52 @@ class TicketService {
113920
113920
  return this.sendCommand(commandType, options, analyticsPayload)
113921
113921
  .pipe(this.commandNotificationService.display(config));
113922
113922
  }
113923
- extractTicketInfo(content) {
113923
+ extractTicketInfo(content, timezone) {
113924
113924
  let ticketNum;
113925
- let ticketDateTime;
113925
+ let ticketDateTimeInSeconds;
113926
113926
  try {
113927
113927
  // To determine what type, check content length
113928
113928
  switch (content.length) {
113929
113929
  case BarcodeTypeLength.QR1:
113930
113930
  case BarcodeTypeLength.QR2:
113931
- ticketNum = content.slice(6, 14); // Location of ticket number; from 7 to 14
113932
- // Location of ticket date; from 14 to 20
113933
- // Location of ticket time; from 20 to 24
113934
- ticketDateTime = this.getTicketDateTimeByContent(content, { start: 14, end: 20 }, { start: 20, end: 24 });
113931
+ {
113932
+ ticketNum = content.slice(6, 14); // Location of ticket number; from 7 to 14
113933
+ // Location of ticket date; from 14 to 20
113934
+ // Location of ticket time; from 20 to 24
113935
+ const ticketDateTime = this.getTicketDateTimeByQRContent(content, { start: 14, end: 20 }, { start: 20, end: 24 });
113936
+ ticketDateTimeInSeconds = parseDateTimeToSparkParkTime(ticketDateTime?.toDate());
113937
+ }
113935
113938
  break;
113936
113939
  case BarcodeTypeLength.QR4:
113937
- ticketNum = content.slice(7, 16); // Location of ticket number; from 8 to 16.
113938
- // Location of ticket date; from 16 to 22
113939
- // Location of ticket time; from 22 to 28
113940
- ticketDateTime = this.getTicketDateTimeByContent(content, { start: 16, end: 22 }, { start: 22, end: 28 });
113940
+ {
113941
+ ticketNum = content.slice(7, 16); // Location of ticket number; from 8 to 16.
113942
+ // Location of ticket date; from 16 to 22
113943
+ // Location of ticket time; from 22 to 28
113944
+ const ticketDateTime = this.getTicketDateTimeByQRContent(content, { start: 16, end: 22 }, { start: 22, end: 28 });
113945
+ ticketDateTimeInSeconds = parseDateTimeToSparkParkTime(ticketDateTime?.toDate());
113946
+ }
113941
113947
  break;
113942
113948
  case BarcodeTypeLength.Barcode1:
113943
113949
  ticketNum = content.slice(7, 14); // Location of ticket number; from 7 to 14
113944
113950
  // Location of ticket time info; from 1 to 7
113945
- ticketDateTime = this.getTicketDateTimeByTicketTime(content, { start: 1, end: 7 });
113951
+ ticketDateTimeInSeconds = this.getTicketDateTimeInSecondsByBarcodeContent(content, { start: 1, end: 7 }, timezone);
113946
113952
  break;
113947
113953
  case BarcodeTypeLength.Barcode2:
113948
113954
  ticketNum = content.slice(13, 22); // Location of ticket number; from 14 to 22
113949
113955
  // Location of ticket time info; from 7 to 13
113950
- ticketDateTime = this.getTicketDateTimeByTicketTime(content, { start: 7, end: 13 });
113956
+ ticketDateTimeInSeconds = this.getTicketDateTimeInSecondsByBarcodeContent(content, { start: 7, end: 13 }, timezone);
113951
113957
  break;
113952
113958
  default:
113953
113959
  {
113954
113960
  const qValue = this.extractQueryParam(content, 'q');
113955
- if (qValue !== null) {
113956
- return this.extractTicketInfo(qValue);
113961
+ if (qValue !== null && qValue !== content) {
113962
+ return this.extractTicketInfo(qValue, timezone);
113957
113963
  }
113958
113964
  }
113959
113965
  break;
113960
113966
  }
113961
113967
  }
113962
113968
  catch (_) { }
113963
- const ticketDateTimeInSeconds = parseDateTimeToSparkParkTime(ticketDateTime?.toDate());
113964
113969
  return { ticketNum, ticketDateTimeInSeconds };
113965
113970
  }
113966
113971
  extractQueryParam(url, param) {
@@ -113976,7 +113981,7 @@ class TicketService {
113976
113981
  return null;
113977
113982
  }
113978
113983
  }
113979
- getTicketDateTimeByContent(content, date, time) {
113984
+ getTicketDateTimeByQRContent(content, date, time) {
113980
113985
  const _date = content.slice(date.start, date.end);
113981
113986
  const _time = content.slice(time.start, time.end);
113982
113987
  return moment({
@@ -113988,27 +113993,36 @@ class TicketService {
113988
113993
  second: _time.length === 6 ? +_time.slice(4, 6) : 0
113989
113994
  });
113990
113995
  }
113991
- getTicketDateTimeByTicketTime(content, location) {
113992
- // multiple 60000:
113993
- // getTime method return date in miliseconds
113994
- // to convert to seconds multiple by 10000
113995
- // to convert seconds to minutes multiple by 60
113996
- const ticketTime = +content.slice(location.start, location.end);
113997
- var curTimeDateTime = new Date();
113998
- curTimeDateTime.setSeconds(0);
113999
- let defaultSmartParkDateTime = new Date(2000, 0, 1, 0, 0, 0).getTime();
114000
- // The default smart park date time is always: Sat Jan 01 2000 00:00:00 GMT+0200 (Israel Standard Time)
114001
- // If the current time date is in DST (GMT+0300) then to avoid incorrect results we need to remove 1 hour
114002
- if (moment(curTimeDateTime).isDST()) {
114003
- // 60 Minutes ( 1 hour ) in miliseconds equal 3600000
114004
- defaultSmartParkDateTime -= 3600000;
114005
- }
114006
- var curTimeInMinutes = (curTimeDateTime.getTime() - defaultSmartParkDateTime) / 60000;
114007
- var curTimeTicketFormat = curTimeInMinutes % 1000000;
114008
- if (ticketTime > curTimeTicketFormat)
114009
- curTimeTicketFormat += 1000000;
114010
- const ticketDateTimeInMinutes = (defaultSmartParkDateTime / 60000) + curTimeInMinutes - (curTimeTicketFormat - ticketTime);
114011
- return moment(new Date(ticketDateTimeInMinutes * 60000));
113996
+ getTicketDateTimeInSecondsByBarcodeContent(content, location, timezone) {
113997
+ // Barcode time encoding (based on SQL Date2Number / Number2Date):
113998
+ // The original datetime is converted in SQL to total seconds since ~2000-01-01,
113999
+ // then effectively to total minutes. The barcode stores only the LAST 6 digits
114000
+ // of those minutes (totalMinutes % 1,000,000).
114001
+ //
114002
+ // Because of this truncation, the value wraps every 1,000,000 minutes (~694 days),
114003
+ // so the same value can represent multiple dates.
114004
+ //
114005
+ // To reconstruct the correct datetime, we rebuild possible full values and
114006
+ // select the one closest to "now".
114007
+ const MINUTE_CYCLE = 1_000_000;
114008
+ const CYCLE_SEARCH_RADIUS = 1;
114009
+ const truncatedMinutesFromBarcode = Number(content.slice(location.start, location.end));
114010
+ const now = moment.tz(timezone).seconds(0).milliseconds(0);
114011
+ const barcodeBaseDate = moment.tz(DEFAULT_SMART_PARK_DATE_TIME, 'YYYY-MM-DD HH:mm:ss', timezone);
114012
+ const currentTotalMinutesFromBase = now.diff(barcodeBaseDate, 'minutes');
114013
+ const estimatedCycleIndex = Math.floor(currentTotalMinutesFromBase / MINUTE_CYCLE);
114014
+ let resolvedTicketDateTime = barcodeBaseDate.clone();
114015
+ let smallestDifferenceFromNow = Number.MAX_SAFE_INTEGER;
114016
+ for (let cycleIndex = estimatedCycleIndex - CYCLE_SEARCH_RADIUS; cycleIndex <= estimatedCycleIndex + CYCLE_SEARCH_RADIUS; cycleIndex++) {
114017
+ const fullMinutesFromBase = cycleIndex * MINUTE_CYCLE + truncatedMinutesFromBarcode;
114018
+ const candidateDateTime = barcodeBaseDate.clone().add(fullMinutesFromBase, 'minutes');
114019
+ const differenceFromNow = Math.abs(candidateDateTime.diff(now));
114020
+ if (differenceFromNow < smallestDifferenceFromNow) {
114021
+ smallestDifferenceFromNow = differenceFromNow;
114022
+ resolvedTicketDateTime = candidateDateTime;
114023
+ }
114024
+ }
114025
+ return resolvedTicketDateTime.diff(barcodeBaseDate, 'seconds');
114012
114026
  }
114013
114027
  navigateToTicket(ticketNum, guid, parkId, activatedRoute, ticketDateTimeInSeconds = null) {
114014
114028
  const tibaKeys = this.store.selectSnapshot(FacilityState.tibaKeys);