@weaver-apps/calendar 0.1.3 → 0.3.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/README.md +42 -18
- package/fesm2022/weaver-apps-calendar-calendar-gateway-DUo797bn.mjs +35 -0
- package/fesm2022/weaver-apps-calendar-calendar-gateway-DUo797bn.mjs.map +1 -0
- package/fesm2022/weaver-apps-calendar-calendar-list-page-dgF-nnQF.mjs +74 -0
- package/fesm2022/weaver-apps-calendar-calendar-list-page-dgF-nnQF.mjs.map +1 -0
- package/fesm2022/weaver-apps-calendar-calendar-page-DpdU_Vfy.mjs +722 -0
- package/fesm2022/weaver-apps-calendar-calendar-page-DpdU_Vfy.mjs.map +1 -0
- package/fesm2022/weaver-apps-calendar-calendar-paths-qzIR-lDU.mjs +19 -0
- package/fesm2022/weaver-apps-calendar-calendar-paths-qzIR-lDU.mjs.map +1 -0
- package/fesm2022/weaver-apps-calendar.mjs +19 -640
- package/fesm2022/weaver-apps-calendar.mjs.map +1 -1
- package/package.json +10 -6
- package/types/weaver-apps-calendar.d.ts +7 -1
- /package/i18n/{calendar → weaver-apps-calendar}/de.json +0 -0
- /package/i18n/{calendar → weaver-apps-calendar}/en.json +0 -0
package/README.md
CHANGED
|
@@ -7,10 +7,15 @@ and holds no key.
|
|
|
7
7
|
## Compose it
|
|
8
8
|
|
|
9
9
|
```ts
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
import {
|
|
11
|
+
calendarPluginId,
|
|
12
|
+
createCalendarPlugin,
|
|
13
|
+
createHttpCalendarGateway,
|
|
14
|
+
provideCalendarGateway,
|
|
15
|
+
} from '@weaver-apps/calendar';
|
|
16
|
+
|
|
17
|
+
provideTranslationNamespaces(calendarPluginId),
|
|
18
|
+
provideCapabilityGrants({ [calendarPluginId]: ['contributions', 'navigation', 'ui'] }),
|
|
14
19
|
...providePlugins(createCalendarPlugin({ railItem: true })),
|
|
15
20
|
provideCalendarGateway(createHttpCalendarGateway({ baseUrl: '/weaver-apps' })),
|
|
16
21
|
```
|
|
@@ -18,17 +23,36 @@ provideCalendarGateway(createHttpCalendarGateway({ baseUrl: '/weaver-apps' })),
|
|
|
18
23
|
- `baseUrl` is a same-origin path the host's backend forwards to the server, adding the forwarding key and
|
|
19
24
|
the signed-in person's tenant (`X-API-Key`, `X-Act-For-Tenant`). The gateway appends the server's own
|
|
20
25
|
routes, such as `/calendar/calendars/{id}/appointments`.
|
|
21
|
-
- Serve the translations: the package carries them under `i18n/calendar`; add an assets glob
|
|
22
|
-
`node_modules/@weaver-apps/calendar/i18n/calendar` to `i18n/calendar`.
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
26
|
+
- Serve the translations: the package carries them under `i18n/weaver-apps-calendar`; add an assets glob
|
|
27
|
+
that copies `node_modules/@weaver-apps/calendar/i18n/weaver-apps-calendar` to `i18n/weaver-apps-calendar`.
|
|
28
|
+
- Install AG Grid, a peer dependency the list is drawn with: `npm i ag-grid-community@^36.2 ag-grid-angular@^36.2
|
|
29
|
+
@ag-grid-community/locale@^36.2`. `@weaver-apps/data-grid`, the grid both Weaver Apps weavers share, comes along as a
|
|
30
|
+
dependency; the host composes nothing for it.
|
|
31
|
+
- If the host compiles the shell's theme with Tailwind, add the package and `@weaver-apps/data-grid` as an `@source`.
|
|
32
|
+
|
|
33
|
+
## Names in the host
|
|
34
|
+
|
|
35
|
+
The plugin id is `weaver-apps-calendar` (`calendarPluginId`). Every id the plugin registers and every icon
|
|
36
|
+
it contributes starts with `weaver-apps-calendar.`, its routes live under `weaver-apps-calendar/`, and its
|
|
37
|
+
translations are the namespace `weaver-apps-calendar`. The ids are exported as `calendarContributionIds`.
|
|
38
|
+
|
|
39
|
+
| Id | Path | What it shows |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| `weaver-apps-calendar.calendars` | `weaver-apps-calendar` | the tenant's calendars |
|
|
42
|
+
| `weaver-apps-calendar.calendar` | `weaver-apps-calendar/:calendarId` | one calendar's appointments, a week at a time |
|
|
43
|
+
| `weaver-apps-calendar.rail` | | the rail item, only with `railItem: true` |
|
|
44
|
+
|
|
45
|
+
A calendar's week is a grid: a click on a column header sorts it (earliest first by default), and the status
|
|
46
|
+
column filters by any number of statuses.
|
|
47
|
+
|
|
48
|
+
`calendarPath(id)` builds the address of one calendar; a host that shows one entry per calendar navigates
|
|
49
|
+
there. `createCalendarPlugin({ railItem: true })` adds a rail item that opens the list; without it the host
|
|
50
|
+
decides where the calendar is reached from.
|
|
51
|
+
|
|
52
|
+
## Moving from 0.1.x
|
|
53
|
+
|
|
54
|
+
0.2.0 draws the list with AG Grid, so a host installs it (see above). It also renamed everything the plugin puts
|
|
55
|
+
into a host; a host composing it changes three places: the key of
|
|
56
|
+
its capability grant (`calendar` becomes `weaver-apps-calendar`), the translation namespace it declares, and
|
|
57
|
+
the folder it serves the translations from (`i18n/calendar` becomes `i18n/weaver-apps-calendar`). Addresses
|
|
58
|
+
saved under `calendar/...` no longer resolve; build them with `calendarPath`.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { InjectionToken } from "@angular/core";
|
|
2
|
+
var CalendarHost = class {
|
|
3
|
+
ctx;
|
|
4
|
+
bind(ctx) {
|
|
5
|
+
this.ctx = ctx;
|
|
6
|
+
}
|
|
7
|
+
unbind() {
|
|
8
|
+
this.ctx = void 0;
|
|
9
|
+
}
|
|
10
|
+
get ui() {
|
|
11
|
+
if (!this.ctx) throw new Error("The calendar plugin is not active.");
|
|
12
|
+
return this.ctx.ui;
|
|
13
|
+
}
|
|
14
|
+
navigate(path) {
|
|
15
|
+
this.ctx?.navigateContent(path);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
const calendarHost = new CalendarHost();
|
|
19
|
+
var CalendarGatewayError = class extends Error {
|
|
20
|
+
status;
|
|
21
|
+
constructor(status) {
|
|
22
|
+
super(`The calendar answered ${status}.`);
|
|
23
|
+
this.status = status;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
const CALENDAR_GATEWAY = new InjectionToken("weaver-apps.calendar.gateway");
|
|
27
|
+
function provideCalendarGateway(gateway) {
|
|
28
|
+
return {
|
|
29
|
+
provide: CALENDAR_GATEWAY,
|
|
30
|
+
useValue: gateway
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export { calendarHost as i, CalendarGatewayError as n, provideCalendarGateway as r, CALENDAR_GATEWAY as t };
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=weaver-apps-calendar-calendar-gateway-DUo797bn.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"weaver-apps-calendar-calendar-gateway-DUo797bn.mjs","names":[],"sources":["../../../../libs/calendar/src/lib/plugin/calendar-host.ts","../../../../libs/calendar/src/lib/gateway/calendar-gateway.ts"],"sourcesContent":["import type { PluginContext } from '@loomweaver/plugin-sdk';\n\ntype HostContext = Pick<PluginContext, 'ui' | 'navigateContent'>;\n\nclass CalendarHost {\n private ctx?: HostContext;\n\n bind(ctx: HostContext): void {\n this.ctx = ctx;\n }\n\n unbind(): void {\n this.ctx = undefined;\n }\n\n get ui(): HostContext['ui'] {\n if (!this.ctx) {\n throw new Error('The calendar plugin is not active.');\n }\n return this.ctx.ui;\n }\n\n navigate(path: string): void {\n this.ctx?.navigateContent(path);\n }\n}\n\nexport const calendarHost = new CalendarHost();\n","import { InjectionToken, Provider } from '@angular/core';\nimport type { AppointmentRequest, AppointmentResponse, AppointmentStatus, CalendarResponse } from '../api/models';\n\nexport interface CalendarRange {\n readonly from: Date;\n readonly until: Date;\n}\n\nexport interface ConflictingAppointment {\n readonly id: string;\n readonly start: string;\n readonly end: string;\n}\n\nexport type AppointmentOutcome =\n | { readonly kind: 'saved'; readonly appointment: AppointmentResponse }\n | { readonly kind: 'conflict'; readonly conflicts: readonly ConflictingAppointment[] }\n | { readonly kind: 'closed' }\n | { readonly kind: 'changed' }\n | { readonly kind: 'invalid' }\n | { readonly kind: 'missing' };\n\nexport interface CalendarGateway {\n calendars(): Promise<readonly CalendarResponse[]>;\n calendar(calendarId: string): Promise<CalendarResponse | null>;\n saveCalendar(calendarId: string, name: string): Promise<CalendarResponse>;\n appointments(calendarId: string, range: CalendarRange, contact?: string, signal?: AbortSignal): Promise<readonly AppointmentResponse[]>;\n book(calendarId: string, request: AppointmentRequest): Promise<AppointmentOutcome>;\n update(calendarId: string, appointmentId: string, request: AppointmentRequest): Promise<AppointmentOutcome>;\n cancel(calendarId: string, appointmentId: string, reason: string | null): Promise<AppointmentOutcome>;\n setStatus(calendarId: string, appointmentId: string, status: AppointmentStatus): Promise<AppointmentOutcome>;\n remove(calendarId: string, appointmentId: string): Promise<void>;\n}\n\nexport class CalendarGatewayError extends Error {\n constructor(readonly status: number) {\n super(`The calendar answered ${status}.`);\n }\n}\n\nexport const CALENDAR_GATEWAY = new InjectionToken<CalendarGateway>('weaver-apps.calendar.gateway');\n\nexport function provideCalendarGateway(gateway: CalendarGateway): Provider {\n return { provide: CALENDAR_GATEWAY, useValue: gateway };\n}\n"],"mappings":";AAIA,IAAM,eAAN,MAAkB;CACR;CAER,KAAK,KAAgB;EACnB,KAAK,MAAM;CACb;CAEA,SAAM;EACJ,KAAK,MAAM;CACb;CAEA,IAAI,KAAE;EACJ,IAAI,CAAC,KAAK,KACR,MAAM,IAAI,MAAM,oCAAoC;EAEtD,OAAO,KAAK,IAAI;CAClB;CAEA,SAAS,MAAY;EACnB,KAAK,KAAK,gBAAgB,IAAI;CAChC;AACD;AAED,MAAa,eAAe,IAAI,aAAY;ACO5C,IAAa,uBAAb,cAA0C,MAAK;CACxB;CAArB,YAAqB,QAAc;EACjC,MAAM,yBAAyB,OAAM,EAAG;EADrB,KAAA,SAAA;CAErB;AACD;AAED,MAAa,mBAAmB,IAAI,eAAgC,8BAA8B;AAElG,SAAgB,uBAAuB,SAAwB;CAC7D,OAAO;EAAE,SAAS;EAAkB,UAAU;CAAO;AACvD"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { i as calendarHost, t as CALENDAR_GATEWAY } from "./weaver-apps-calendar-calendar-gateway-DUo797bn.mjs";
|
|
2
|
+
import { n as calendarPath } from "./weaver-apps-calendar-calendar-paths-qzIR-lDU.mjs";
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, inject, resource } from "@angular/core";
|
|
5
|
+
import { TranslocoPipe } from "@jsverse/transloco";
|
|
6
|
+
var CalendarListPage = class CalendarListPage {
|
|
7
|
+
gateway = inject(CALENDAR_GATEWAY);
|
|
8
|
+
calendars = resource({
|
|
9
|
+
...ngDevMode ? { debugName: "calendars" } : /* istanbul ignore next */ {},
|
|
10
|
+
loader: () => this.gateway.calendars()
|
|
11
|
+
});
|
|
12
|
+
open(calendarId) {
|
|
13
|
+
calendarHost.navigate(calendarPath(calendarId));
|
|
14
|
+
}
|
|
15
|
+
async create() {
|
|
16
|
+
const name = await calendarHost.ui.prompt({
|
|
17
|
+
title: "weaver-apps-calendar.calendars.create",
|
|
18
|
+
message: "weaver-apps-calendar.calendars.createMessage",
|
|
19
|
+
confirmLabel: "weaver-apps-calendar.calendars.createConfirm"
|
|
20
|
+
});
|
|
21
|
+
if (!name?.trim()) return;
|
|
22
|
+
try {
|
|
23
|
+
const calendar = await this.gateway.saveCalendar(crypto.randomUUID(), name.trim());
|
|
24
|
+
this.open(calendar.id);
|
|
25
|
+
} catch {
|
|
26
|
+
calendarHost.ui.toast({
|
|
27
|
+
message: "weaver-apps-calendar.errors.create",
|
|
28
|
+
kind: "error"
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
33
|
+
minVersion: "12.0.0",
|
|
34
|
+
version: "22.2.3",
|
|
35
|
+
ngImport: i0,
|
|
36
|
+
type: CalendarListPage,
|
|
37
|
+
deps: [],
|
|
38
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
39
|
+
});
|
|
40
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
41
|
+
minVersion: "17.0.0",
|
|
42
|
+
version: "22.2.3",
|
|
43
|
+
type: CalendarListPage,
|
|
44
|
+
isStandalone: true,
|
|
45
|
+
selector: "wa-calendar-list-page",
|
|
46
|
+
ngImport: i0,
|
|
47
|
+
template: "<div class=\"flex h-full flex-col gap-4 overflow-auto p-6\">\n <div class=\"flex items-center justify-between gap-4\">\n <h2 class=\"text-lg font-semibold text-content\">{{ 'weaver-apps-calendar.calendars.title' | transloco }}</h2>\n <button type=\"button\" class=\"lw-btn lw-btn--primary\" (click)=\"create()\">{{ 'weaver-apps-calendar.calendars.create' | transloco }}</button>\n </div>\n @if (calendars.error()) {\n <p class=\"text-sm text-negative\" role=\"alert\">{{ 'weaver-apps-calendar.errors.load' | transloco }}</p>\n } @else if (calendars.hasValue()) {\n <ul role=\"list\" class=\"divide-y divide-border rounded-xl border border-border bg-surface\">\n @for (calendar of calendars.value(); track calendar.id) {\n <li>\n <button type=\"button\" class=\"flex w-full items-center gap-3 px-4 py-3 text-left text-sm text-content hover:bg-surface-overlay\" (click)=\"open(calendar.id)\">\n <lw-icon name=\"weaver-apps-calendar.calendar\" size=\"1.25rem\"></lw-icon>\n <span>{{ calendar.name }}</span>\n </button>\n </li>\n } @empty {\n <li class=\"px-4 py-8 text-center text-sm text-content-faint\">{{ 'weaver-apps-calendar.calendars.empty' | transloco }}</li>\n }\n </ul>\n }\n</div>\n",
|
|
48
|
+
dependencies: [{
|
|
49
|
+
kind: "pipe",
|
|
50
|
+
type: TranslocoPipe,
|
|
51
|
+
name: "transloco"
|
|
52
|
+
}],
|
|
53
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
57
|
+
minVersion: "12.0.0",
|
|
58
|
+
version: "22.2.3",
|
|
59
|
+
ngImport: i0,
|
|
60
|
+
type: CalendarListPage,
|
|
61
|
+
decorators: [{
|
|
62
|
+
type: Component,
|
|
63
|
+
args: [{
|
|
64
|
+
selector: "wa-calendar-list-page",
|
|
65
|
+
imports: [TranslocoPipe],
|
|
66
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
67
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
68
|
+
template: "<div class=\"flex h-full flex-col gap-4 overflow-auto p-6\">\n <div class=\"flex items-center justify-between gap-4\">\n <h2 class=\"text-lg font-semibold text-content\">{{ 'weaver-apps-calendar.calendars.title' | transloco }}</h2>\n <button type=\"button\" class=\"lw-btn lw-btn--primary\" (click)=\"create()\">{{ 'weaver-apps-calendar.calendars.create' | transloco }}</button>\n </div>\n @if (calendars.error()) {\n <p class=\"text-sm text-negative\" role=\"alert\">{{ 'weaver-apps-calendar.errors.load' | transloco }}</p>\n } @else if (calendars.hasValue()) {\n <ul role=\"list\" class=\"divide-y divide-border rounded-xl border border-border bg-surface\">\n @for (calendar of calendars.value(); track calendar.id) {\n <li>\n <button type=\"button\" class=\"flex w-full items-center gap-3 px-4 py-3 text-left text-sm text-content hover:bg-surface-overlay\" (click)=\"open(calendar.id)\">\n <lw-icon name=\"weaver-apps-calendar.calendar\" size=\"1.25rem\"></lw-icon>\n <span>{{ calendar.name }}</span>\n </button>\n </li>\n } @empty {\n <li class=\"px-4 py-8 text-center text-sm text-content-faint\">{{ 'weaver-apps-calendar.calendars.empty' | transloco }}</li>\n }\n </ul>\n }\n</div>\n"
|
|
69
|
+
}]
|
|
70
|
+
}]
|
|
71
|
+
});
|
|
72
|
+
export { CalendarListPage };
|
|
73
|
+
|
|
74
|
+
//# sourceMappingURL=weaver-apps-calendar-calendar-list-page-dgF-nnQF.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"weaver-apps-calendar-calendar-list-page-dgF-nnQF.mjs","names":[],"sources":["../../../../libs/calendar/src/lib/views/calendar-list-page.ts","../../../../libs/calendar/src/lib/views/calendar-list-page.html"],"sourcesContent":["import { ChangeDetectionStrategy, Component, CUSTOM_ELEMENTS_SCHEMA, inject, resource } from '@angular/core';\nimport { TranslocoPipe } from '@jsverse/transloco';\nimport { CALENDAR_GATEWAY } from '../gateway/calendar-gateway';\nimport { calendarHost } from '../plugin/calendar-host';\nimport { calendarPath } from '../plugin/calendar-paths';\n\n@Component({\n selector: 'wa-calendar-list-page',\n imports: [TranslocoPipe],\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\n templateUrl: './calendar-list-page.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class CalendarListPage {\n private readonly gateway = inject(CALENDAR_GATEWAY);\n\n protected readonly calendars = resource({ loader: () => this.gateway.calendars() });\n\n protected open(calendarId: string): void {\n calendarHost.navigate(calendarPath(calendarId));\n }\n\n protected async create(): Promise<void> {\n const name = await calendarHost.ui.prompt({\n title: 'weaver-apps-calendar.calendars.create',\n message: 'weaver-apps-calendar.calendars.createMessage',\n confirmLabel: 'weaver-apps-calendar.calendars.createConfirm',\n });\n if (!name?.trim()) {\n return;\n }\n try {\n const calendar = await this.gateway.saveCalendar(crypto.randomUUID(), name.trim());\n this.open(calendar.id);\n } catch {\n calendarHost.ui.toast({ message: 'weaver-apps-calendar.errors.create', kind: 'error' });\n }\n }\n}\n","<div class=\"flex h-full flex-col gap-4 overflow-auto p-6\">\n <div class=\"flex items-center justify-between gap-4\">\n <h2 class=\"text-lg font-semibold text-content\">{{ 'weaver-apps-calendar.calendars.title' | transloco }}</h2>\n <button type=\"button\" class=\"lw-btn lw-btn--primary\" (click)=\"create()\">{{ 'weaver-apps-calendar.calendars.create' | transloco }}</button>\n </div>\n @if (calendars.error()) {\n <p class=\"text-sm text-negative\" role=\"alert\">{{ 'weaver-apps-calendar.errors.load' | transloco }}</p>\n } @else if (calendars.hasValue()) {\n <ul role=\"list\" class=\"divide-y divide-border rounded-xl border border-border bg-surface\">\n @for (calendar of calendars.value(); track calendar.id) {\n <li>\n <button type=\"button\" class=\"flex w-full items-center gap-3 px-4 py-3 text-left text-sm text-content hover:bg-surface-overlay\" (click)=\"open(calendar.id)\">\n <lw-icon name=\"weaver-apps-calendar.calendar\" size=\"1.25rem\"></lw-icon>\n <span>{{ calendar.name }}</span>\n </button>\n </li>\n } @empty {\n <li class=\"px-4 py-8 text-center text-sm text-content-faint\">{{ 'weaver-apps-calendar.calendars.empty' | transloco }}</li>\n }\n </ul>\n }\n</div>\n"],"mappings":";;;;;AAaA,IAAa,mBAAb,MAAa,iBAAgB;CACV,UAAU,OAAO,gBAAgB;CAE/B,YAAY,SAAQ;EAAA,GAAA,YAAA,EAAA,WAAA,YAAA,+BAAA,CAAA;EAAG,cAAc,KAAK,QAAQ,UAAS;CAAE,CAAA;CAEtE,KAAK,YAAkB;EAC/B,aAAa,SAAS,aAAa,UAAU,CAAC;CAChD;CAEU,MAAM,SAAM;EACpB,MAAM,OAAO,MAAM,aAAa,GAAG,OAAO;GACxC,OAAO;GACP,SAAS;GACT,cAAc;EACf,CAAA;EACD,IAAI,CAAC,MAAM,KAAI,GACb;EAEF,IAAI;GACF,MAAM,WAAW,MAAM,KAAK,QAAQ,aAAa,OAAO,WAAU,GAAI,KAAK,KAAI,CAAE;GACjF,KAAK,KAAK,SAAS,EAAE;EACvB,QAAQ;GACN,aAAa,GAAG,MAAM;IAAE,SAAS;IAAsC,MAAM;GAAO,CAAE;EACxF;CACF;CAxBW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAgB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAhB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAgB,cAAA;EAAA,UAAA;EAAA,UAAA;EAAA,UCb7B;EAsBA,cAAA,CAAA;GAAA,MAAA;GAAA,MDdY;GAAa,MAAA;EAAA,CAAA;EAAA,iBAAA,GAAA,wBAAA;CAAA,CAAA;;AAKZ,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAgB,YAAA,CAAA;EAP5B,MAAA;EACW,MAAA,CAAA;GAAA,UAAA;GAAuB,SACxB,CAAC,aAAa;GAAC,SACf,CAAC,sBAAsB;GAAC,iBAEhB,wBAAwB;GAAM,UAAA;EAAA,CAAA"}
|