@ultimat3/time 1.0.0 → 1.1.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ultimat3/time",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "UTC instants, DST-correct zone math, cron, durations and Intl formatting with an explicit timezone",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -30,6 +30,6 @@
30
30
  "test": "bun test"
31
31
  },
32
32
  "dependencies": {
33
- "@ultimat3/core": "1.0.0"
33
+ "@ultimat3/core": "1.1.0"
34
34
  }
35
35
  }
package/src/business.d.ts DELETED
@@ -1,37 +0,0 @@
1
- /**
2
- * Business-day math. The weekend is configuration, not a constant: Friday/Saturday in
3
- * much of the Gulf, Sunday-only in parts of Asia, Saturday/Sunday in the West.
4
- */
5
- import type { Instant } from './instant';
6
- import type { TimeZone } from './zones';
7
- /** ISO weekday numbers: 1 = Monday … 7 = Sunday. */
8
- export type IsoWeekday = 1 | 2 | 3 | 4 | 5 | 6 | 7;
9
- export declare const WEEKEND_SAT_SUN: readonly IsoWeekday[];
10
- /** Gulf states, and the default in Israel (Fri/Sat). */
11
- export declare const WEEKEND_FRI_SAT: readonly IsoWeekday[];
12
- export declare const WEEKEND_SUN_ONLY: readonly IsoWeekday[];
13
- export interface BusinessCalendar {
14
- zone: TimeZone;
15
- /** Defaults to Saturday + Sunday, which is a choice, not a law. */
16
- weekendDays?: readonly IsoWeekday[];
17
- /** Local `YYYY-MM-DD` dates that are holidays in this calendar. */
18
- holidays?: readonly string[];
19
- }
20
- export declare function isWeekend(at: Instant, zone: TimeZone, weekendDays?: readonly IsoWeekday[]): boolean;
21
- export declare function isHoliday(at: Instant, calendar: BusinessCalendar): boolean;
22
- /** A business day is a non-weekend, non-holiday local day. */
23
- export declare function isBusinessDay(at: Instant, calendar: BusinessCalendar): boolean;
24
- /**
25
- * Move `days` business days forward (or back, if negative), keeping the local wall-clock
26
- * time. `days === 0` returns the input untouched, even on a weekend — callers that want
27
- * "the next business day" should ask for 1.
28
- */
29
- export declare function addBusinessDays(at: Instant, days: number, calendar: BusinessCalendar): Instant;
30
- /** The next business day at the same local time; today if it already qualifies. */
31
- export declare function nextBusinessDay(at: Instant, calendar: BusinessCalendar): Instant;
32
- /**
33
- * Business days in `[from, to)`, counted on local calendar days. Order-independent:
34
- * a reversed range returns a negative count.
35
- */
36
- export declare function businessDaysBetween(from: Instant, to: Instant, calendar: BusinessCalendar): number;
37
- //# sourceMappingURL=business.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"business.d.ts","sourceRoot":"","sources":["business.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,oDAAoD;AACpD,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEnD,eAAO,MAAM,eAAe,EAAE,SAAS,UAAU,EAAW,CAAC;AAC7D,wDAAwD;AACxD,eAAO,MAAM,eAAe,EAAE,SAAS,UAAU,EAAW,CAAC;AAC7D,eAAO,MAAM,gBAAgB,EAAE,SAAS,UAAU,EAAQ,CAAC;AAE3D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,QAAQ,CAAC;IACf,mEAAmE;IACnE,WAAW,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACpC,mEAAmE;IACnE,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,wBAAkB,GAAG,OAAO,CAE7F;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAG1E;AAED,8DAA8D;AAC9D,wBAAgB,aAAa,CAAC,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAK9E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAe9F;AAED,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAEhF;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,OAAO,EACb,EAAE,EAAE,OAAO,EACX,QAAQ,EAAE,gBAAgB,GACzB,MAAM,CAYR"}
package/src/business.js DELETED
@@ -1,68 +0,0 @@
1
- /**
2
- * Business-day math. The weekend is configuration, not a constant: Friday/Saturday in
3
- * much of the Gulf, Sunday-only in parts of Asia, Saturday/Sunday in the West.
4
- */
5
- import { addDaysInZone, isoDateInZone, toZoned } from './zoned';
6
- export const WEEKEND_SAT_SUN = [6, 7];
7
- /** Gulf states, and the default in Israel (Fri/Sat). */
8
- export const WEEKEND_FRI_SAT = [5, 6];
9
- export const WEEKEND_SUN_ONLY = [7];
10
- export function isWeekend(at, zone, weekendDays = WEEKEND_SAT_SUN) {
11
- return weekendDays.includes(toZoned(at, zone).weekday);
12
- }
13
- export function isHoliday(at, calendar) {
14
- const holidays = calendar.holidays ?? [];
15
- return holidays.includes(isoDateInZone(at, calendar.zone));
16
- }
17
- /** A business day is a non-weekend, non-holiday local day. */
18
- export function isBusinessDay(at, calendar) {
19
- return (!isWeekend(at, calendar.zone, calendar.weekendDays ?? WEEKEND_SAT_SUN) &&
20
- !isHoliday(at, calendar));
21
- }
22
- /**
23
- * Move `days` business days forward (or back, if negative), keeping the local wall-clock
24
- * time. `days === 0` returns the input untouched, even on a weekend — callers that want
25
- * "the next business day" should ask for 1.
26
- */
27
- export function addBusinessDays(at, days, calendar) {
28
- if (days === 0)
29
- return at;
30
- const step = days > 0 ? 1 : -1;
31
- let remaining = Math.abs(days);
32
- let cursor = at;
33
- let guard = 0;
34
- while (remaining > 0) {
35
- cursor = addDaysInZone(cursor, step, calendar.zone);
36
- if (isBusinessDay(cursor, calendar))
37
- remaining -= 1;
38
- guard += 1;
39
- // A calendar with every day marked as a holiday would otherwise loop forever.
40
- if (guard > Math.abs(days) * 7 + 3650)
41
- return cursor;
42
- }
43
- return cursor;
44
- }
45
- /** The next business day at the same local time; today if it already qualifies. */
46
- export function nextBusinessDay(at, calendar) {
47
- return isBusinessDay(at, calendar) ? at : addBusinessDays(at, 1, calendar);
48
- }
49
- /**
50
- * Business days in `[from, to)`, counted on local calendar days. Order-independent:
51
- * a reversed range returns a negative count.
52
- */
53
- export function businessDaysBetween(from, to, calendar) {
54
- const sign = to.getTime() < from.getTime() ? -1 : 1;
55
- const start = sign === 1 ? from : to;
56
- const end = sign === 1 ? to : from;
57
- let cursor = start;
58
- let count = 0;
59
- while (isoDateInZone(cursor, calendar.zone) !== isoDateInZone(end, calendar.zone)) {
60
- cursor = addDaysInZone(cursor, 1, calendar.zone);
61
- if (cursor.getTime() > end.getTime())
62
- break;
63
- if (isBusinessDay(cursor, calendar))
64
- count += 1;
65
- }
66
- return sign * count;
67
- }
68
- //# sourceMappingURL=business.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"business.js","sourceRoot":"","sources":["business.ts"],"names":[],"mappings":"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"}
package/src/context.d.ts DELETED
@@ -1,40 +0,0 @@
1
- /**
2
- * Resolve the request timezone once, then read it from the ALS context.
3
- * User record → header → config default. Every formatter still takes the zone
4
- * explicitly; this is where call sites get the value from, not a hidden default.
5
- */
6
- import { type Ctx } from '@ultimat3/core';
7
- import { type TimeZone } from './zones';
8
- /** Header a client sets from `Intl.DateTimeFormat().resolvedOptions().timeZone`. */
9
- export declare const TIMEZONE_HEADER = "x-timezone";
10
- export interface TimeZoneSources {
11
- /** `user.timeZone` — an explicit preference beats a browser guess. */
12
- user?: string | null;
13
- /** `x-timezone` request header. */
14
- header?: string | null;
15
- /** `?tz=Europe/Berlin`, for share links and email previews. */
16
- query?: string | null;
17
- }
18
- export type TimeZoneSourceName = keyof TimeZoneSources;
19
- export interface TimeZoneResolution {
20
- zone: TimeZone;
21
- source: TimeZoneSourceName | 'default';
22
- }
23
- export interface TimeConfig {
24
- /** The zone used when nothing else resolves. UTC unless the app says otherwise. */
25
- defaultZone: TimeZone;
26
- order: readonly TimeZoneSourceName[];
27
- }
28
- export declare function configureTime(partial: Partial<TimeConfig>): TimeConfig;
29
- export declare function timeConfig(): TimeConfig;
30
- /**
31
- * First valid IANA name wins. An invalid value is skipped, never thrown: a stale
32
- * `x-timezone` header from an old client must not fail the request.
33
- */
34
- export declare function resolveTimeZone(sources: TimeZoneSources, overrides?: Partial<TimeConfig>): TimeZoneResolution;
35
- /** Called once per request by the HTTP layer. */
36
- export declare function attachTimeZone(ctx: Ctx, zone: TimeZone): TimeZone;
37
- export declare function timeZoneOf(ctx: Ctx): TimeZone;
38
- /** Ambient zone for the in-flight request; the configured default outside one. */
39
- export declare function currentTimeZone(): TimeZone;
40
- //# sourceMappingURL=context.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["context.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,GAAG,EAAc,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAmB,KAAK,QAAQ,EAAO,MAAM,SAAS,CAAC;AAE9D,oFAAoF;AACpF,eAAO,MAAM,eAAe,eAAe,CAAC;AAI5C,MAAM,WAAW,eAAe;IAC9B,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,MAAM,kBAAkB,GAAG,MAAM,eAAe,CAAC;AAEvD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,kBAAkB,GAAG,SAAS,CAAC;CACxC;AAED,MAAM,WAAW,UAAU;IACzB,mFAAmF;IACnF,WAAW,EAAE,QAAQ,CAAC;IACtB,KAAK,EAAE,SAAS,kBAAkB,EAAE,CAAC;CACtC;AAID,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,UAAU,CAGtE;AAED,wBAAgB,UAAU,IAAI,UAAU,CAEvC;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,eAAe,EACxB,SAAS,GAAE,OAAO,CAAC,UAAU,CAAM,GAClC,kBAAkB,CAQpB;AAED,iDAAiD;AACjD,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAGjE;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,GAAG,GAAG,QAAQ,CAE7C;AAED,kFAAkF;AAClF,wBAAgB,eAAe,IAAI,QAAQ,CAG1C"}
package/src/context.js DELETED
@@ -1,61 +0,0 @@
1
- /**
2
- * Resolve the request timezone once, then read it from the ALS context.
3
- * User record → header → config default. Every formatter still takes the zone
4
- * explicitly; this is where call sites get the value from, not a hidden default.
5
- */
6
- import { useContext } from '@ultimat3/core';
7
- import { isValidTimeZone, UTC } from './zones';
8
- /** Header a client sets from `Intl.DateTimeFormat().resolvedOptions().timeZone`. */
9
- export const TIMEZONE_HEADER = 'x-timezone';
10
- const CTX_TIMEZONE = 'timeZone';
11
- let config = { defaultZone: UTC, order: ['user', 'header', 'query'] };
12
- export function configureTime(partial) {
13
- config = { ...config, ...partial };
14
- return config;
15
- }
16
- export function timeConfig() {
17
- return config;
18
- }
19
- /**
20
- * First valid IANA name wins. An invalid value is skipped, never thrown: a stale
21
- * `x-timezone` header from an old client must not fail the request.
22
- */
23
- export function resolveTimeZone(sources, overrides = {}) {
24
- const { defaultZone, order } = { ...config, ...overrides };
25
- for (const name of order) {
26
- const candidate = sources[name];
27
- if (candidate === undefined || candidate === null || candidate === '')
28
- continue;
29
- if (isValidTimeZone(candidate))
30
- return { zone: candidate, source: name };
31
- }
32
- return { zone: defaultZone, source: 'default' };
33
- }
34
- /** Called once per request by the HTTP layer. */
35
- export function attachTimeZone(ctx, zone) {
36
- ctx[CTX_TIMEZONE] = zone;
37
- return zone;
38
- }
39
- export function timeZoneOf(ctx) {
40
- return readField(ctx, CTX_TIMEZONE) ?? config.defaultZone;
41
- }
42
- /** Ambient zone for the in-flight request; the configured default outside one. */
43
- export function currentTimeZone() {
44
- const ctx = tryContext();
45
- return (ctx === undefined ? undefined : readField(ctx, CTX_TIMEZONE)) ?? config.defaultZone;
46
- }
47
- function tryContext() {
48
- try {
49
- return useContext();
50
- }
51
- catch {
52
- // Outside a request scope (boot, worker tick, CLI) — fall back to the configured zone.
53
- return undefined;
54
- }
55
- }
56
- /** `Ctx` belongs to core (tier 0) and cannot import `TimeZone`; read the field structurally. */
57
- function readField(ctx, field) {
58
- const value = ctx[field];
59
- return typeof value === 'string' && value !== '' ? value : undefined;
60
- }
61
- //# sourceMappingURL=context.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["context.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAY,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAiB,GAAG,EAAE,MAAM,SAAS,CAAC;AAE9D,oFAAoF;AACpF,MAAM,CAAC,MAAM,eAAe,GAAG,YAAY,CAAC;AAE5C,MAAM,YAAY,GAAG,UAAU,CAAC;AAwBhC,IAAI,MAAM,GAAe,EAAE,WAAW,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC;AAElF,MAAM,UAAU,aAAa,CAAC,OAA4B;IACxD,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC;IACnC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAwB,EACxB,SAAS,GAAwB,EAAE;IAEnC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC;IAC3D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAChC,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,EAAE;YAAE,SAAS;QAChF,IAAI,eAAe,CAAC,SAAS,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC3E,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AAClD,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,cAAc,CAAC,GAAQ,EAAE,IAAc;IACpD,GAA0C,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC;IACjE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAQ;IACjC,OAAO,SAAS,CAAC,GAAG,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,WAAW,CAAC;AAC5D,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,eAAe;IAC7B,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,OAAO,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,IAAI,MAAM,CAAC,WAAW,CAAC;AAC9F,CAAC;AAED,SAAS,UAAU;IACjB,IAAI,CAAC;QACH,OAAO,UAAU,EAAE,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,uFAAuF;QACvF,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,gGAAgG;AAChG,SAAS,SAAS,CAAC,GAAQ,EAAE,KAAa;IACxC,MAAM,KAAK,GAAI,GAA0C,CAAC,KAAK,CAAC,CAAC;IACjE,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACvE,CAAC"}
package/src/cron.d.ts DELETED
@@ -1,60 +0,0 @@
1
- /**
2
- * A real cron parser and occurrence calculator. Timezone-aware through `fromZoned`, so
3
- * `0 3 * * *` in `Europe/Berlin` fires at 03:00 local on both sides of a DST change
4
- * instead of drifting to 02:00 or 04:00 for half the year.
5
- */
6
- import { type Instant } from './instant';
7
- import { type TimeZone } from './zones';
8
- export interface CronExpression {
9
- /** The normalized source text. */
10
- source: string;
11
- seconds: readonly number[];
12
- minutes: readonly number[];
13
- hours: readonly number[];
14
- daysOfMonth: readonly number[];
15
- months: readonly number[];
16
- /** ISO weekdays, 1 = Monday … 7 = Sunday (cron's 0 and 7 both mean Sunday). */
17
- daysOfWeek: readonly number[];
18
- /** Vixie semantics: when both day fields are restricted, either one matching is a hit. */
19
- dayOfMonthRestricted: boolean;
20
- dayOfWeekRestricted: boolean;
21
- }
22
- /** Parse 5 fields (`m h dom mon dow`) or 6 with a leading seconds field. */
23
- export declare function parseCron(expression: string): CronExpression;
24
- export declare function isValidCron(expression: string): boolean;
25
- /** True when `at` matches the expression in `zone`, to the second. */
26
- export declare function matchesCron(expression: string | CronExpression, at: Instant, zone: TimeZone): boolean;
27
- /**
28
- * The next instant strictly after `after` that matches, computed on the zone's wall clock
29
- * and converted with `fromZoned({ gap: 'next', overlap: 'first' })`:
30
- * - spring forward: a 02:30 daily job runs once, at the first existing local time after
31
- * the gap, instead of being silently skipped;
32
- * - fall back: a repeated local time runs once, on its first occurrence.
33
- */
34
- export declare function nextCronOccurrence(expression: string | CronExpression, zone: TimeZone, after: Instant): Instant;
35
- /** The next `count` occurrences, each strictly after the previous one. */
36
- export declare function nextCronOccurrences(expression: string | CronExpression, zone: TimeZone, after: Instant, count: number): Instant[];
37
- export interface CronPhrases {
38
- everyMinute: string;
39
- everyNMinutes: string;
40
- everyHour: string;
41
- everyNHours: string;
42
- at: string;
43
- onDaysOfMonth: string;
44
- onWeekdays: string;
45
- inMonths: string;
46
- everyDay: string;
47
- }
48
- /** English defaults; the admin dashboard passes `t('time.cron.*')` instead. */
49
- export declare const DEFAULT_CRON_PHRASES: CronPhrases;
50
- /**
51
- * `describeCron('0 3 * * MON-FRI', 'en')` → `at 03:00 on Monday–Friday`.
52
- * Month and weekday names come from `Intl`; the connective phrases are injected so this
53
- * package never hardcodes a user-facing English string.
54
- */
55
- export declare function describeCron(expression: string | CronExpression, locale: string, phrases?: Partial<CronPhrases>): string;
56
- /** Exported for the scheduler's leader loop: has this expression fired since `since`? */
57
- export declare function firedSince(expression: string | CronExpression, zone: TimeZone, since: Instant, until: Instant): boolean;
58
- /** Epoch-ms helper used by the jobs package when it only has a number. */
59
- export declare function nextCronOccurrenceMs(expression: string | CronExpression, zone: TimeZone, afterMs: number): number;
60
- //# sourceMappingURL=cron.d.ts.map
package/src/cron.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"cron.d.ts","sourceRoot":"","sources":["cron.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAe,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAEtD,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExD,MAAM,WAAW,cAAc;IAC7B,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,+EAA+E;IAC/E,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,0FAA0F;IAC1F,oBAAoB,EAAE,OAAO,CAAC;IAC9B,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AA4BD,4EAA4E;AAC5E,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAkC5D;AAED,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAOvD;AAED,sEAAsE;AACtE,wBAAgB,WAAW,CACzB,UAAU,EAAE,MAAM,GAAG,cAAc,EACnC,EAAE,EAAE,OAAO,EACX,IAAI,EAAE,QAAQ,GACb,OAAO,CAUT;AAKD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,GAAG,cAAc,EACnC,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,OAAO,GACb,OAAO,CAkET;AAED,0EAA0E;AAC1E,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,GAAG,cAAc,EACnC,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,MAAM,GACZ,OAAO,EAAE,CASX;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,+EAA+E;AAC/E,eAAO,MAAM,oBAAoB,EAAE,WAUlC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,MAAM,GAAG,cAAc,EACnC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,OAAO,CAAC,WAAW,CAAM,GACjC,MAAM,CAuCR;AAyLD,yFAAyF;AACzF,wBAAgB,UAAU,CACxB,UAAU,EAAE,MAAM,GAAG,cAAc,EACnC,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,OAAO,GACb,OAAO,CAIT;AAED,0EAA0E;AAC1E,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,GAAG,cAAc,EACnC,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,MAAM,GACd,MAAM,CAER"}