iamcal 1.0.1 → 1.0.3

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.
package/src/index.ts CHANGED
@@ -1,18 +1,14 @@
1
- export interface Property {
2
- name: string
3
- params: string[]
4
- value: string
5
- }
1
+ import { Property } from './types'
6
2
 
7
3
  // Max line length as defined by RFC 5545 3.1.
8
4
  const MAX_LINE_LENGTH = 75
9
5
 
10
6
  export class Component {
11
7
  name: string
12
- properties: Array<Property>
13
- components: Array<Component>
8
+ properties: Property[]
9
+ components: Component[]
14
10
 
15
- constructor(name: string, properties?: Array<Property>, components?: Array<Component>) {
11
+ constructor(name: string, properties?: Property[], components?: Component[]) {
16
12
  this.name = name
17
13
  if (properties) {
18
14
  this.properties = properties
@@ -40,7 +36,7 @@ export class Component {
40
36
  // Wrap lines
41
37
  while (line.length > MAX_LINE_LENGTH) {
42
38
  lines.push(line.substring(0, MAX_LINE_LENGTH))
43
- line = " " + line.substring(MAX_LINE_LENGTH)
39
+ line = ' ' + line.substring(MAX_LINE_LENGTH)
44
40
  }
45
41
  lines.push(line)
46
42
  }
@@ -80,6 +76,13 @@ export class Component {
80
76
  })
81
77
  }
82
78
 
79
+ removePropertiesWithName(name: string) {
80
+ const index = this.properties.findIndex(p => p.name === name)
81
+ if (index === -1) return
82
+ // Remove property at index
83
+ this.properties.splice(index, 1)
84
+ }
85
+
83
86
  getPropertyParams(name: string): string[] | null {
84
87
  for (const property of this.properties) {
85
88
  if (property.name === name) {
@@ -96,41 +99,355 @@ export class Component {
96
99
  }
97
100
  }
98
101
  }
102
+
103
+ addComponent(component: Component) {
104
+ this.components.push(component)
105
+ }
106
+
107
+ removeComponent(component: Component): boolean {
108
+ const index = this.components.indexOf(component)
109
+ if (index === -1) return false
110
+
111
+ // Remove element at index from list
112
+ this.components.splice(index, 1)
113
+
114
+ return true
115
+ }
116
+
117
+ getComponents(name: string): Component[] {
118
+ const components: Component[] = []
119
+
120
+ for (let component of this.components) {
121
+ if (component.name === name) {
122
+ components.push(component)
123
+ }
124
+ }
125
+
126
+ return components
127
+ }
99
128
  }
100
129
 
130
+ /**
131
+ * Represents a VCALENDAR component, the root component of an iCalendar file.
132
+ */
101
133
  export class Calendar extends Component {
102
134
  name = 'VCALENDAR'
103
135
 
104
- constructor(component: Component) {
136
+ /**
137
+ * @param prodid A unique identifier of the program creating the calendar.
138
+ *
139
+ * Example: `-//Google Inc//Google Calendar 70.9054//EN`
140
+ */
141
+ constructor(prodid: string)
142
+ /**
143
+ * @param prodid A unique identifier of the program creating the calendar.
144
+ *
145
+ * Example: `-//Google Inc//Google Calendar 70.9054//EN`
146
+ * @param version The version of the iCalendar specification that this calendar uses.
147
+ */
148
+ constructor(prodid: string, version: string)
149
+ /**
150
+ * @param component A VCALENDAR component.
151
+ */
152
+ constructor(component: Component)
153
+ constructor(a?: string | Component, b?: string) {
154
+ var component: Component
155
+ if (a instanceof Component) {
156
+ component = a as Component
157
+ } else {
158
+ const prodid = a as string
159
+ const version = (b as string) ?? '2.0'
160
+ component = new Component('VCALENDAR')
161
+ component.setProperty('PRODID', prodid)
162
+ component.setProperty('VERSION', version)
163
+ }
105
164
  super(component.name, component.properties, component.components)
106
165
  }
107
166
 
108
- events(): Array<CalendarEvent> {
109
- const events = new Array<CalendarEvent>()
167
+ events(): CalendarEvent[] {
168
+ return this.getComponents('VEVENT').map(c => new CalendarEvent(c))
169
+ }
110
170
 
111
- for (let component of this.components) {
112
- if (component.name === 'VEVENT') {
113
- events.push(new CalendarEvent(component))
171
+ removeEvent(event: CalendarEvent): boolean
172
+ removeEvent(uid: string): boolean
173
+ removeEvent(a: CalendarEvent | string): boolean {
174
+ if (a instanceof CalendarEvent) {
175
+ const event = a as CalendarEvent
176
+ return this.removeComponent(event)
177
+ } else {
178
+ const uid = a as string
179
+ for (const event of this.events()) {
180
+ if (event.uid() !== uid) continue
181
+ return this.removeComponent(event)
114
182
  }
115
183
  }
184
+ return false
185
+ }
186
+
187
+ prodId(): string {
188
+ return this.getProperty('PRODID')!.value
189
+ }
190
+
191
+ setProdId(value: string) {
192
+ this.setProperty('PRODID', value)
193
+ }
194
+
195
+ version(): string {
196
+ return this.getProperty('VERSION')!.value
197
+ }
198
+
199
+ setVersion(value: string) {
200
+ this.setProperty('VERSION', value)
201
+ }
202
+
203
+ calScale(): string | undefined {
204
+ return this.getProperty('CALSCALE')?.value
205
+ }
206
+
207
+ setCalScale(value: string) {
208
+ this.setProperty('CALSCALE', value)
209
+ }
210
+
211
+ removeCalScale() {
212
+ this.removePropertiesWithName('CALSCALE')
213
+ }
116
214
 
117
- return events
215
+ method(): string | undefined {
216
+ return this.getProperty('METHOD')?.value
217
+ }
218
+
219
+ setMethod(value: string) {
220
+ this.setProperty('METHOD', value)
221
+ }
222
+
223
+ removeMethod() {
224
+ this.removePropertiesWithName('METHOD')
225
+ }
226
+
227
+ calendarName(): string | undefined {
228
+ return this.getProperty('X-WR-CALNAME')?.value
229
+ }
230
+
231
+ setCalendarName(value: string) {
232
+ this.setProperty('X-WR-CALNAME', value)
233
+ }
234
+
235
+ removeCalendarName() {
236
+ this.removePropertiesWithName('X-WR-CALNAME')
237
+ }
238
+
239
+ calendarDescription(): string | undefined {
240
+ return this.getProperty('X-WR-CALDESC')?.value
241
+ }
242
+
243
+ setCalendarDescription(value: string) {
244
+ this.setProperty('X-WR-CALDESC', value)
245
+ }
246
+
247
+ removeCalendarDescription() {
248
+ this.removePropertiesWithName('X-WR-CALDESC')
249
+ }
250
+ }
251
+
252
+ /**
253
+ * Represents a VTIMEZONE component, containing time zone definitions.
254
+ */
255
+ export class TimeZone extends Component {
256
+ constructor(id: string)
257
+ constructor(component: Component)
258
+ constructor(a: string | Component) {
259
+ var component: Component
260
+ if (a instanceof Component) {
261
+ component = a as Component
262
+ } else {
263
+ const tzid = a as string
264
+ component = new Component('VTIMEZONE')
265
+ component.setProperty('TZID', tzid)
266
+ }
267
+ super(component.name, component.properties, component.components)
268
+ }
269
+
270
+ id(): string {
271
+ return this.getProperty('TZID')!.value
272
+ }
273
+
274
+ setId(value: string) {
275
+ this.setProperty('TZID', value)
276
+ }
277
+
278
+ lastMod(): Date | undefined {
279
+ const text = this.getProperty('LAST-MOD')
280
+ if (!text) return
281
+ return new Date(text.value)
282
+ }
283
+
284
+ setLastMod(value: Date) {
285
+ this.setProperty('LAST-MOD', value.toISOString())
286
+ }
287
+
288
+ removeLastMod() {
289
+ this.removePropertiesWithName('LAST-MOD')
290
+ }
291
+
292
+ url(): string | undefined {
293
+ return this.getProperty('TZURL')?.value
294
+ }
295
+
296
+ setUrl(value: string) {
297
+ this.setProperty('TZURL', value)
298
+ }
299
+
300
+ removeUrl() {
301
+ this.removePropertiesWithName('TZURL')
302
+ }
303
+
304
+ /** Get all time offsets. */
305
+ offsets(): TimeZoneOffset[] {
306
+ const offsets: TimeZoneOffset[] = []
307
+ this.components.forEach(component => {
308
+ if (component.name === 'STANDARD' || component.name === 'DAYLIGHT') {
309
+ offsets.push(new TimeZoneOffset(component))
310
+ }
311
+ })
312
+ return offsets
313
+ }
314
+
315
+ /** Get standard/winter time offsets. */
316
+ standardOffsets(): TimeZoneOffset[] {
317
+ return this.getComponents('STANDARD').map(c => new TimeZoneOffset(c))
318
+ }
319
+
320
+ /** Get daylight savings time offsets. */
321
+ daylightOffsets(): TimeZoneOffset[] {
322
+ return this.getComponents('DAYLIGHT').map(c => new TimeZoneOffset(c))
323
+ }
324
+ }
325
+
326
+ export type OffsetType = 'DAYLIGHT' | 'STANDARD'
327
+ type Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
328
+ export type Offset = `${'-' | '+'}${Digit}${Digit}${Digit}${Digit}`
329
+ /** Represents a STANDARD or DAYLIGHT component, defining a time zone offset. */
330
+ class TimeZoneOffset extends Component {
331
+ /**
332
+ *
333
+ * @param type If this is a STANDARD or DAYLIGHT component.
334
+ * @param start From when this offset is active.
335
+ * @param offsetFrom The offset that is in use prior to this time zone observance.
336
+ * @param offsetTo The offset that is in use during this time zone observance.
337
+ */
338
+ constructor(type: OffsetType, start: Date, offsetFrom: Offset, offsetTo: Offset)
339
+ constructor(component: Component)
340
+ constructor(a: OffsetType | Component, b?: Date, c?: Offset, d?: Offset) {
341
+ var component: Component
342
+ if (a instanceof Component) {
343
+ component = a as Component
344
+ } else {
345
+ const name = a as OffsetType
346
+ const start = b as Date
347
+ const offsetFrom = c as Offset
348
+ const offsetTo = d as Offset
349
+ component = new Component(name)
350
+ component.setProperty('DTSTART', start.toISOString())
351
+ component.setProperty('TZOFFSETFROM', offsetFrom)
352
+ component.setProperty('TZOFFSETTO', offsetTo)
353
+ }
354
+ super(component.name, component.properties, component.components)
355
+ }
356
+
357
+ start(): Date {
358
+ return new Date(this.getProperty('DTSTART')!.value)
359
+ }
360
+
361
+ setStart(value: Date) {
362
+ this.setProperty('DTSTART', value.toISOString())
363
+ }
364
+
365
+ offsetFrom(): Offset {
366
+ return this.getProperty('TZOFFSETFROM')!.value as Offset
367
+ }
368
+
369
+ setOffsetFrom(value: Offset) {
370
+ this.setProperty('TZOFFSETFROM', value)
371
+ }
372
+
373
+ offsetTo(): Offset {
374
+ return this.getProperty('TZOFFSETTO')!.value as Offset
375
+ }
376
+
377
+ setOffsetTo(value: Offset) {
378
+ this.setProperty('TZOFFSETTO', value)
379
+ }
380
+
381
+ comment(): string | undefined {
382
+ return this.getProperty('COMMENT')?.value
383
+ }
384
+
385
+ setComment(value: string) {
386
+ this.setProperty('COMMENT', value)
387
+ }
388
+
389
+ removeComment() {
390
+ this.removePropertiesWithName('COMMENT')
391
+ }
392
+
393
+ timeZoneName(): string | undefined {
394
+ return this.getProperty('TZNAME')?.value
395
+ }
396
+
397
+ setTimeZoneName(value: string) {
398
+ this.setProperty('TZNAME', value)
399
+ }
400
+
401
+ removeTimeZoneName() {
402
+ this.removePropertiesWithName('TZNAME')
118
403
  }
119
404
  }
120
405
 
121
406
  export class CalendarEvent extends Component {
122
407
  name = 'VEVENT'
123
408
 
124
- constructor(component: Component) {
409
+ constructor(uid: string, dtstamp: Date)
410
+ constructor(component: Component)
411
+ constructor(a: string | Component, b?: Date) {
412
+ var component: Component
413
+ if (b) {
414
+ const uid = a as string
415
+ const dtstamp = b as Date
416
+ component = new Component('VEVENT')
417
+ component.setProperty('UID', uid)
418
+ component.setProperty('DTSTAMP', dtstamp.toISOString())
419
+ } else {
420
+ component = a as Component
421
+ }
125
422
  super(component.name, component.properties, component.components)
126
423
  }
127
424
 
425
+ stamp(): Date {
426
+ return new Date(this.getProperty('DTSTAMP')!.value)
427
+ }
428
+
429
+ setStamp(value: Date) {
430
+ this.setProperty('DTSTAMP', value.toISOString())
431
+ }
432
+
433
+ uid(): string {
434
+ return this.getProperty('UID')!.value
435
+ }
436
+
437
+ setUid(value: string) {
438
+ this.setProperty('UID', value)
439
+ }
440
+
128
441
  summary(): string {
129
442
  return this.getProperty('SUMMARY')!.value
130
443
  }
131
444
 
132
445
  setSummary(value: string) {
133
- this.setProperty("SUMMARY", value)
446
+ this.setProperty('SUMMARY', value)
447
+ }
448
+
449
+ removeSummary() {
450
+ this.removePropertiesWithName('SUMMARY')
134
451
  }
135
452
 
136
453
  description(): string {
@@ -138,7 +455,11 @@ export class CalendarEvent extends Component {
138
455
  }
139
456
 
140
457
  setDescription(value: string) {
141
- this.setProperty("DESCRIPTION", value)
458
+ this.setProperty('DESCRIPTION', value)
459
+ }
460
+
461
+ removeDescription() {
462
+ this.removePropertiesWithName('DESCRIPTION')
142
463
  }
143
464
 
144
465
  location(): string | undefined {
@@ -146,7 +467,11 @@ export class CalendarEvent extends Component {
146
467
  }
147
468
 
148
469
  setLocation(value: string) {
149
- this.setProperty("LOCATION", value)
470
+ this.setProperty('LOCATION', value)
471
+ }
472
+
473
+ removeLocation() {
474
+ this.removePropertiesWithName('LOCATION')
150
475
  }
151
476
 
152
477
  start(): Date {
@@ -154,14 +479,49 @@ export class CalendarEvent extends Component {
154
479
  }
155
480
 
156
481
  setStart(value: Date) {
157
- this.setProperty("DTSTART", value.toISOString())
482
+ this.setProperty('DTSTART', value.toISOString())
483
+ }
484
+
485
+ removeStart() {
486
+ this.removePropertiesWithName('DTSTART')
158
487
  }
159
488
 
160
489
  end(): Date {
161
490
  return new Date(this.getProperty('DTEND')!.value)
162
491
  }
163
-
492
+
164
493
  setEnd(value: Date) {
165
- this.setProperty("DTEND", value.toISOString())
494
+ this.setProperty('DTEND', value.toISOString())
495
+ }
496
+
497
+ removeEnd() {
498
+ this.removePropertiesWithName('DTEND')
499
+ }
500
+
501
+ created(): Date | undefined {
502
+ const text = this.getProperty('CREATED')?.value
503
+ if (!text) return
504
+ return new Date(text)
505
+ }
506
+
507
+ setCreated(value: Date) {
508
+ this.setProperty('CREATED', value.toISOString())
509
+ }
510
+
511
+ removeCreated() {
512
+ this.removePropertiesWithName('CREATED')
513
+ }
514
+
515
+ geo(): [number, number] | undefined {
516
+ const text = this.getProperty('GEO')?.value
517
+ if (!text) return
518
+ const pattern = /^[+-]?\d+(\.\d+)?,[+-]?\d+(\.\d+)?$/
519
+ if (!pattern.test(text)) throw new Error(`Failed to parse GEO property: ${text}`)
520
+ const [longitude, latitude] = text.split(',')
521
+ return [parseFloat(longitude), parseFloat(latitude)]
522
+ }
523
+
524
+ setGeo(latitude: number, longitude: number) {
525
+ const text = `${latitude},${longitude}`
166
526
  }
167
527
  }
package/src/types.ts ADDED
@@ -0,0 +1,5 @@
1
+ export interface Property {
2
+ name: string
3
+ params: string[]
4
+ value: string
5
+ }
package/lib/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"names":["MAX_LINE_LENGTH","Component","name","properties","components","constructor","this","Array","serialize","lines","property","line","params","map","p","join","length","push","substring","component","getProperty","setProperty","value","getPropertyParams","setPropertyParams","exports","Calendar","super","events","CalendarEvent","summary","setSummary","description","setDescription","location","setLocation","start","Date","setStart","toISOString","end","setEnd"],"sources":["../src/index.ts"],"mappings":";;AAOA,MAAMA,gBAAkB,GAExB,MAAaC,UACTC,KACAC,WACAC,WAEAC,YAAYH,EAAcC,EAA8BC,GACpDE,KAAKJ,KAAOA,EAERI,KAAKH,WADLA,GAGkB,IAAII,MAGtBD,KAAKF,WADLA,GAGkB,IAAIG,KAE9B,CAEAC;;AAEI,MAAMC,EAAQ,CAAC,SAASH,KAAKJ,QAE7B,IAAK,IAAIQ,KAAYJ,KAAKH,WAAY,CAClC,IAAIQ,EACAD,EAAe,KACfA,EAASE,OAAOC,KAAIC,GAAK,IAAMA,IAAGC,KAAK,IACvC,IACAL,EAAgB;aAGpB;KAAOC,EAAKK,OAjCA,IAkCRP,EAAMQ,KAAKN,EAAKO,UAAU,EAlClB,KAmCRP,EAAO,IAAMA,EAAKO,UAnCV,IAqCZT,EAAMQ,KAAKN,EACf,CAEA,IAAK,IAAIQ,KAAab,KAAKF,WACvBK,EAAMQ,KAAKE,EAAUX,aAGzBC,EAAMQ,KAAK,OAAOX,KAAKJ,QAKvB,OAFmBO,EAAMM,KAAK,KAGlC,CAEAK,YAAYlB,GACR,IAAK,MAAMQ,KAAYJ,KAAKH,WACxB,GAAIO,EAASR,OAASA,EAClB,OAAOQ,EAGf,OAAO,IACX,CAEAW,YAAYnB,EAAcoB,GACtB,IAAK,MAAMZ,KAAYJ,KAAKH,WACxB,GAAIO,EAASR,OAASA,EAElB,YADAQ,EAASY,MAAQA,GAIzBhB,KAAKH,WAAWc,KAAK,CACjBf,KAAMA,EACNU,OAAQ,GACRU,MAAOA,GAEf,CAEAC,kBAAkBrB,GACd,IAAK,MAAMQ,KAAYJ,KAAKH,WACxB,GAAIO,EAASR,OAASA,EAClB,OAAOQ,EAASE,OAGxB,OAAO,IACX,CAEAY,kBAAkBtB,EAAcU,GAC5B,IAAK,MAAMF,KAAYJ,KAAKH,WACpBO,EAASR,OAASA,IAClBQ,EAASE,OAASA,EAG9B,EAxFJa,QAAAxB,oBA2FA,MAAayB,iBAAiBzB,UAC1BC,KAAO,YAEPG,YAAYc,GACRQ,MAAMR,EAAUjB,KAAMiB,EAAUhB,WAAYgB,EAAUf,WAC1D,CAEAwB,SACI,MAAMA,EAAS,IAAIrB,MAEnB,IAAK,IAAIY,KAAab,KAAKF,WACA,WAAnBe,EAAUjB,MACV0B,EAAOX,KAAK,IAAIY,cAAcV,IAItC,OAAOS,CACX,EAjBJH,QAAAC,kBAoBA,MAAaG,sBAAsB5B,UAC/BC,KAAO,SAEPG,YAAYc,GACRQ,MAAMR,EAAUjB,KAAMiB,EAAUhB,WAAYgB,EAAUf,WAC1D,CAEA0B,UACI,OAAOxB,KAAKc,YAAY,WAAYE,KACxC,CAEAS,WAAWT,GACPhB,KAAKe,YAAY,UAAWC,EAChC,CAEAU,cACI,OAAO1B,KAAKc,YAAY,eAAgBE,KAC5C,CAEAW,eAAeX,GACXhB,KAAKe,YAAY,cAAeC,EACpC,CAEAY,WACI,OAAO5B,KAAKc,YAAY,aAAaE,KACzC,CAEAa,YAAYb,GACRhB,KAAKe,YAAY,WAAYC,EACjC,CAEAc,QACI,OAAO,IAAIC,KAAK/B,KAAKc,YAAY,WAAYE,MACjD,CAEAgB,SAAShB,GACLhB,KAAKe,YAAY,UAAWC,EAAMiB,cACtC,CAEAC,MACI,OAAO,IAAIH,KAAK/B,KAAKc,YAAY,SAAUE,MAC/C,CAEAmB,OAAOnB,GACHhB,KAAKe,YAAY,QAASC,EAAMiB,cACpC,EA7CJd,QAAAI","ignoreList":[]}
package/lib/io.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"names":["exports","load","dump","fs_1","__importDefault","require","readline_1","_1","parse_1","async","path","stream","default","createReadStream","lines","createInterface","input","crlfDelay","Infinity","component","deserialize","name","TypeError","Calendar","calendar","Promise","resolve","writeFile","serialize"],"sources":["../src/io.ts"],"mappings":"sKAYAA,QAAAC,UAkBAD,QAAAE,UA9BA,MAAAC,KAAAC,gBAAAC,QAAA,OACAC,WAAAF,gBAAAC,QAAA,aACAE,GAAAF,QAAA,KACAG,QAAAH,QAAA;;;;;;;AASOI,eAAeR,KAAKS,GACvB,MAAMC,EAASR,KAAAS,QAAGC,iBAAiBH,GAC7BI,EAAQR,WAAAM,QAASG,gBAAgB,CAAEC,MAAOL,EAAQM,UAAWC,MAE7DC,QAAkB,EAAAX,QAAAY,aAAYN,GAEpC,GAAsB,aAAlBK,EAAUE,KACV,MAAMC,UAAU,+BAGpB,OAAO,IAAIf,GAAAgB,SAASJ,EACxB;;;;;GAOA,SAAgBjB,KAAKsB,EAAoBd,GACrC,OAAO,IAAIe,SAAQC,IACfvB,KAAAS,QAAGe,UAAUjB,EAAMc,EAASI,aAAa,KACrCF,GAAS,GACX,GAEV","ignoreList":[]}
package/lib/parse.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"names":["exports","deserialize","deserializeString","parseCalendar","parseEvent","readline_1","__importDefault","require","stream_1","_1","DeserializationError","Error","name","async","lines","component","Component","done","stack","Array","subcomponentLines","processLine","line","trim","startsWith","slice","indexOf","push","length","pop","subcomponent","join","components","colon","value","params","split","property","properties","unfoldedLine","replace","text","stream","Readable","from","default","createInterface","input","crlfDelay","Infinity","Calendar","CalendarEvent"],"sources":["../src/parse.ts"],"mappings":"0MAYAA,QAAAC,wBA4HAD,QAAAE,oCAWAF,QAAAG,4BAYAH,QAAAI,sBA/JA,MAAAC,WAAAC,gBAAAC,QAAA,aACAC,SAAAD,QAAA,UACAE,GAAAF,QAAA,KAEA,MAAaG,6BAA6BC,MACtCC,KAAO;;;;;AAOJC,eAAeZ,YAAYa,GAC9B,MAAMC,EAAY,IAAIN,GAAAO,UAAU,IAChC,IAAIC,GAAO;oDAGX;MAAMC,EAAQ,IAAIC,MAEZC,EAAoB,IAAID,MAE9BN,eAAeQ,EAAYC,GACvB,GAAoB,KAAhBA,EAAKC,OAAT,CAEA,GAAIN,EACA,MAAM,IAAIP,qBAAqB,qCAGnC,GAAIY,EAAKE,WAAW,UAAW;;AAE3B,MAAMZ,EAAOU,EAAKG,MAAMH,EAAKI,QAAQ,KAAO,GAC5CR,EAAMS,KAAKf,GAES,GAAhBM,EAAMU,OACNb,EAAUH,KAAOA,EAEjBQ,EAAkBO,KAAKL,EAE/B,MAAO,GAAIA,EAAKE,WAAW,QAAS;;AAEhC,GAAoB,GAAhBN,EAAMU,OACN,MAAM,IAAIlB,qBAAqB,8BAKnC,GAFkBQ,EAAMW,QACXP,EAAKG,MAAMH,EAAKI,QAAQ,KAAO,GAExC,MAAM,IAAIhB,qBAAqB;mDAInC;GAAoB,GAAhBQ,EAAMU,OAAa,CACnBR,EAAkBO,KAAKL,GACvB,MAAMQ,QAAqB5B,kBAAkBkB,EAAkBW,KAAK,SACpEX,EAAkBQ,OAAS,EAE3Bb,EAAUiB,WAAWL,KAAKG,EAC9B,MAAWZ,EAAMU,OAAS,EACtBR,EAAkBO,KAAKL,GACA,GAAhBJ,EAAMU,SACbX,GAAO,EAEf,KAAO,CACH,GAAoB,GAAhBC,EAAMU,OAAa,MAAM,IAAIlB,qBAAqB,kCAEtD,GAAIQ,EAAMU,OAAS;;AAEfR,EAAkBO,KAAKL,OACpB;;AAEH,MAAMW,EAAQX,EAAKI,QAAQ,KAC3B,IAAe,IAAXO,EACA,MAAM,IAAIvB,qBAAqB,yBAAyBY,KAE5D,MAAMV,EAAOU,EAAKG,MAAM,EAAGQ,GACrBC,EAAQZ,EAAKG,MAAMQ,EAAQ,GAE3BE,EAASvB,EAAKwB,MAAM,KACpBC,EAAW,CACbzB,KAAMuB,EAAO,GACbA,OAAQA,EAAOV,MAAM,GACrBS,MAAOA,GAGXnB,EAAUuB,WAAWX,KAAKU,EAC9B,CACJ,CAhEwB,CAiE5B;;;;;;;;;;;;;;;;;MAmBA,IAAIE,EAAe,GACnB,UAAW,MAAMjB,KAAQR,EACjBQ,EAAKE,WAAW,MAAQF,EAAKE,WAAW;;AAExCe,GAAgBjB,EAAKkB,QAAQ,SAAU,IAAIf,MAAM,IAE7Cc;;MAEMlB,EAAYkB;;AAGtBA,EAAejB;;;AAQvB,SAHMD,EAAYkB,IAGbtB,EACD,MAAM,IAAIP,qBAAqB,oBAGnC,OAAOK,CACX;;;;GAMOF,eAAeX,kBAAkBuC,GACpC,MAAMC,EAASlC,SAAAmC,SAASC,KAAKH,GAE7B,OAAOxC,YADOI,WAAAwC,QAASC,gBAAgB,CAAEC,MAAOL,EAAQM,UAAWC,MAEvE;;;;;GAOOpC,eAAeV,cAAcsC,GAChC,MAAM1B,QAAkBb,kBAAkBuC,GAC1C,GAAuB,cAAnB1B,EAAUH,KACV,MAAM,IAAIF,qBAAqB,kBACnC,OAAO,IAAID,GAAAyC,SAASnC,EACxB;;;;;GAOOF,eAAeT,WAAWqC,GAC7B,MAAM1B,QAAkBb,kBAAkBuC,GAC1C,GAAuB,WAAnB1B,EAAUH,KACV,MAAM,IAAIF,qBAAqB,gBACnC,OAAO,IAAID,GAAA0C,cAAcpC,EAC7B;0yKAhKAf;QAAAU","ignoreList":[]}