@liteforge/calendar 0.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/LICENSE +21 -0
- package/README.md +395 -0
- package/dist/calendar.d.ts +6 -0
- package/dist/calendar.d.ts.map +1 -0
- package/dist/calendar.js +318 -0
- package/dist/calendar.js.map +1 -0
- package/dist/components/toolbar.d.ts +18 -0
- package/dist/components/toolbar.d.ts.map +1 -0
- package/dist/components/toolbar.js +84 -0
- package/dist/components/toolbar.js.map +1 -0
- package/dist/date-utils.d.ts +104 -0
- package/dist/date-utils.d.ts.map +1 -0
- package/dist/date-utils.js +323 -0
- package/dist/date-utils.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/interactions/drag-drop.d.ts +30 -0
- package/dist/interactions/drag-drop.d.ts.map +1 -0
- package/dist/interactions/drag-drop.js +207 -0
- package/dist/interactions/drag-drop.js.map +1 -0
- package/dist/interactions/index.d.ts +10 -0
- package/dist/interactions/index.d.ts.map +1 -0
- package/dist/interactions/index.js +7 -0
- package/dist/interactions/index.js.map +1 -0
- package/dist/interactions/resize.d.ts +25 -0
- package/dist/interactions/resize.d.ts.map +1 -0
- package/dist/interactions/resize.js +116 -0
- package/dist/interactions/resize.js.map +1 -0
- package/dist/interactions/slot-selection.d.ts +25 -0
- package/dist/interactions/slot-selection.d.ts.map +1 -0
- package/dist/interactions/slot-selection.js +151 -0
- package/dist/interactions/slot-selection.js.map +1 -0
- package/dist/recurring.d.ts +15 -0
- package/dist/recurring.d.ts.map +1 -0
- package/dist/recurring.js +158 -0
- package/dist/recurring.js.map +1 -0
- package/dist/styles.d.ts +6 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/styles.js +632 -0
- package/dist/styles.js.map +1 -0
- package/dist/types.d.ts +169 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/views/agenda-view.d.ts +19 -0
- package/dist/views/agenda-view.d.ts.map +1 -0
- package/dist/views/agenda-view.js +114 -0
- package/dist/views/agenda-view.js.map +1 -0
- package/dist/views/day-view.d.ts +30 -0
- package/dist/views/day-view.d.ts.map +1 -0
- package/dist/views/day-view.js +432 -0
- package/dist/views/day-view.js.map +1 -0
- package/dist/views/month-view.d.ts +17 -0
- package/dist/views/month-view.d.ts.map +1 -0
- package/dist/views/month-view.js +123 -0
- package/dist/views/month-view.js.map +1 -0
- package/dist/views/shared.d.ts +30 -0
- package/dist/views/shared.d.ts.map +1 -0
- package/dist/views/shared.js +281 -0
- package/dist/views/shared.js.map +1 -0
- package/dist/views/week-view.d.ts +24 -0
- package/dist/views/week-view.d.ts.map +1 -0
- package/dist/views/week-view.js +377 -0
- package/dist/views/week-view.js.map +1 -0
- package/package.json +61 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @liteforge/calendar - Type Definitions
|
|
3
|
+
*/
|
|
4
|
+
export type CalendarView = 'day' | 'week' | 'month' | 'agenda';
|
|
5
|
+
export interface DateRange {
|
|
6
|
+
start: Date;
|
|
7
|
+
end: Date;
|
|
8
|
+
}
|
|
9
|
+
export interface RecurringRule {
|
|
10
|
+
frequency: 'daily' | 'weekly' | 'biweekly' | 'monthly';
|
|
11
|
+
interval?: number;
|
|
12
|
+
endDate?: Date;
|
|
13
|
+
count?: number;
|
|
14
|
+
daysOfWeek?: number[];
|
|
15
|
+
exceptions?: Date[];
|
|
16
|
+
}
|
|
17
|
+
export interface CalendarEvent {
|
|
18
|
+
id: string;
|
|
19
|
+
title: string;
|
|
20
|
+
start: Date;
|
|
21
|
+
end: Date;
|
|
22
|
+
resourceId?: string;
|
|
23
|
+
color?: string;
|
|
24
|
+
status?: string;
|
|
25
|
+
allDay?: boolean;
|
|
26
|
+
editable?: boolean;
|
|
27
|
+
recurring?: RecurringRule;
|
|
28
|
+
[key: string]: unknown;
|
|
29
|
+
}
|
|
30
|
+
export interface WorkingHours {
|
|
31
|
+
start: number;
|
|
32
|
+
end: number;
|
|
33
|
+
}
|
|
34
|
+
export interface Resource {
|
|
35
|
+
id: string;
|
|
36
|
+
name: string;
|
|
37
|
+
color?: string;
|
|
38
|
+
avatar?: string;
|
|
39
|
+
role?: string;
|
|
40
|
+
workingHours?: {
|
|
41
|
+
[day: number]: WorkingHours | null;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export interface TimeConfig {
|
|
45
|
+
slotDuration?: number;
|
|
46
|
+
dayStart?: number;
|
|
47
|
+
dayEnd?: number;
|
|
48
|
+
weekStart?: 0 | 1;
|
|
49
|
+
hiddenDays?: number[];
|
|
50
|
+
nowIndicator?: boolean;
|
|
51
|
+
}
|
|
52
|
+
export interface ResolvedTimeConfig {
|
|
53
|
+
slotDuration: number;
|
|
54
|
+
dayStart: number;
|
|
55
|
+
dayEnd: number;
|
|
56
|
+
weekStart: 0 | 1;
|
|
57
|
+
hiddenDays: number[];
|
|
58
|
+
nowIndicator: boolean;
|
|
59
|
+
}
|
|
60
|
+
export interface SlotSelection {
|
|
61
|
+
start: Date;
|
|
62
|
+
end: Date;
|
|
63
|
+
resourceId: string | undefined;
|
|
64
|
+
}
|
|
65
|
+
export interface CalendarOptions<T extends CalendarEvent> {
|
|
66
|
+
/** Reactive event source */
|
|
67
|
+
events: () => T[];
|
|
68
|
+
/** Initial view (default: 'week') */
|
|
69
|
+
view?: CalendarView;
|
|
70
|
+
/** Initial date (default: today) */
|
|
71
|
+
defaultDate?: Date;
|
|
72
|
+
/** Time configuration */
|
|
73
|
+
time?: TimeConfig;
|
|
74
|
+
/** Resources (therapists / rooms) */
|
|
75
|
+
resources?: Resource[];
|
|
76
|
+
/** Enable drag & drop + resize globally (default: false) */
|
|
77
|
+
editable?: boolean;
|
|
78
|
+
/** Enable slot selection (default: false) */
|
|
79
|
+
selectable?: boolean;
|
|
80
|
+
/** Event handlers */
|
|
81
|
+
onEventClick?: (event: T) => void;
|
|
82
|
+
onEventDrop?: (event: T, newStart: Date, newEnd: Date, newResourceId?: string) => void;
|
|
83
|
+
onEventResize?: (event: T, newEnd: Date) => void;
|
|
84
|
+
onSlotClick?: (start: Date, end: Date, resourceId?: string) => void;
|
|
85
|
+
onSlotSelect?: (start: Date, end: Date, resourceId?: string) => void;
|
|
86
|
+
onViewChange?: (view: CalendarView, dateRange: DateRange) => void;
|
|
87
|
+
onDateChange?: (date: Date) => void;
|
|
88
|
+
/** Custom rendering */
|
|
89
|
+
eventContent?: (event: T) => Node;
|
|
90
|
+
slotContent?: (date: Date, resourceId?: string) => Node | null;
|
|
91
|
+
dayHeaderContent?: (date: Date) => Node;
|
|
92
|
+
/** Styling */
|
|
93
|
+
unstyled?: boolean;
|
|
94
|
+
classes?: Partial<CalendarClasses>;
|
|
95
|
+
locale?: string;
|
|
96
|
+
}
|
|
97
|
+
export interface CalendarClasses {
|
|
98
|
+
root: string;
|
|
99
|
+
toolbar: string;
|
|
100
|
+
toolbarNav: string;
|
|
101
|
+
toolbarTitle: string;
|
|
102
|
+
toolbarViews: string;
|
|
103
|
+
header: string;
|
|
104
|
+
headerCell: string;
|
|
105
|
+
body: string;
|
|
106
|
+
timeColumn: string;
|
|
107
|
+
timeLabel: string;
|
|
108
|
+
grid: string;
|
|
109
|
+
dayColumn: string;
|
|
110
|
+
resourceColumn: string;
|
|
111
|
+
timeSlot: string;
|
|
112
|
+
event: string;
|
|
113
|
+
eventDragging: string;
|
|
114
|
+
eventResizing: string;
|
|
115
|
+
nowIndicator: string;
|
|
116
|
+
monthGrid: string;
|
|
117
|
+
monthCell: string;
|
|
118
|
+
monthEvent: string;
|
|
119
|
+
monthMore: string;
|
|
120
|
+
agendaDay: string;
|
|
121
|
+
agendaDayHeader: string;
|
|
122
|
+
agendaItem: string;
|
|
123
|
+
}
|
|
124
|
+
export interface CalendarResult<T extends CalendarEvent> {
|
|
125
|
+
/** The calendar grid component */
|
|
126
|
+
Root: () => Node;
|
|
127
|
+
/** Optional toolbar component */
|
|
128
|
+
Toolbar: () => Node;
|
|
129
|
+
/** Current date (signal) */
|
|
130
|
+
currentDate: () => Date;
|
|
131
|
+
/** Current view (signal) */
|
|
132
|
+
currentView: () => CalendarView;
|
|
133
|
+
/** Visible date range (signal) */
|
|
134
|
+
dateRange: () => DateRange;
|
|
135
|
+
/** Navigation */
|
|
136
|
+
today: () => void;
|
|
137
|
+
next: () => void;
|
|
138
|
+
prev: () => void;
|
|
139
|
+
goTo: (date: Date) => void;
|
|
140
|
+
setView: (view: CalendarView) => void;
|
|
141
|
+
/** Events in visible range */
|
|
142
|
+
events: () => T[];
|
|
143
|
+
getEvent: (id: string) => T | undefined;
|
|
144
|
+
addEvent: (event: T) => void;
|
|
145
|
+
updateEvent: (id: string, changes: Partial<T>) => void;
|
|
146
|
+
removeEvent: (id: string) => void;
|
|
147
|
+
/** Resources */
|
|
148
|
+
resources: () => Resource[];
|
|
149
|
+
visibleResources: () => string[];
|
|
150
|
+
showResource: (id: string) => void;
|
|
151
|
+
hideResource: (id: string) => void;
|
|
152
|
+
toggleResource: (id: string) => void;
|
|
153
|
+
/** Selection */
|
|
154
|
+
selectedEvent: () => T | null;
|
|
155
|
+
selectedSlot: () => SlotSelection | null;
|
|
156
|
+
}
|
|
157
|
+
export interface OverlapLayout<T extends CalendarEvent> {
|
|
158
|
+
event: T;
|
|
159
|
+
column: number;
|
|
160
|
+
totalColumns: number;
|
|
161
|
+
}
|
|
162
|
+
export interface RenderedEvent<T extends CalendarEvent> {
|
|
163
|
+
event: T;
|
|
164
|
+
top: number;
|
|
165
|
+
height: number;
|
|
166
|
+
left: number;
|
|
167
|
+
width: number;
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @liteforge/calendar - Agenda View Renderer
|
|
3
|
+
*
|
|
4
|
+
* Simple chronological list grouped by day.
|
|
5
|
+
* Only shows days that have events.
|
|
6
|
+
*/
|
|
7
|
+
import type { CalendarEvent, Resource, ResolvedTimeConfig, CalendarClasses, DateRange } from '../types.js';
|
|
8
|
+
interface AgendaViewOptions<T extends CalendarEvent> {
|
|
9
|
+
dateRange: () => DateRange;
|
|
10
|
+
events: () => T[];
|
|
11
|
+
resources: () => Resource[];
|
|
12
|
+
config: ResolvedTimeConfig;
|
|
13
|
+
locale: string;
|
|
14
|
+
classes: Partial<CalendarClasses>;
|
|
15
|
+
onEventClick: ((event: T) => void) | undefined;
|
|
16
|
+
}
|
|
17
|
+
export declare function renderAgendaView<T extends CalendarEvent>(options: AgendaViewOptions<T>): HTMLDivElement;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=agenda-view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agenda-view.d.ts","sourceRoot":"","sources":["../../src/views/agenda-view.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EACV,aAAa,EACb,QAAQ,EACR,kBAAkB,EAClB,eAAe,EACf,SAAS,EACV,MAAM,aAAa,CAAA;AASpB,UAAU,iBAAiB,CAAC,CAAC,SAAS,aAAa;IACjD,SAAS,EAAE,MAAM,SAAS,CAAA;IAC1B,MAAM,EAAE,MAAM,CAAC,EAAE,CAAA;IACjB,SAAS,EAAE,MAAM,QAAQ,EAAE,CAAA;IAC3B,MAAM,EAAE,kBAAkB,CAAA;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,CAAA;IACjC,YAAY,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;CAC/C;AAED,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,aAAa,EACtD,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAC5B,cAAc,CAyIhB"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @liteforge/calendar - Agenda View Renderer
|
|
3
|
+
*
|
|
4
|
+
* Simple chronological list grouped by day.
|
|
5
|
+
* Only shows days that have events.
|
|
6
|
+
*/
|
|
7
|
+
import { effect } from '@liteforge/core';
|
|
8
|
+
import { getDaysInRange, formatFullDate, formatTime, isToday, } from '../date-utils.js';
|
|
9
|
+
import { getClass } from './shared.js';
|
|
10
|
+
export function renderAgendaView(options) {
|
|
11
|
+
const { dateRange, events, resources, config: _config, locale, classes, onEventClick, } = options;
|
|
12
|
+
const container = document.createElement('div');
|
|
13
|
+
container.className = getClass('root', classes, 'lf-cal-agenda');
|
|
14
|
+
// Reactive rendering
|
|
15
|
+
effect(() => {
|
|
16
|
+
const range = dateRange();
|
|
17
|
+
const allEvents = events();
|
|
18
|
+
const allResources = resources();
|
|
19
|
+
container.innerHTML = '';
|
|
20
|
+
// Group events by day
|
|
21
|
+
const eventsByDay = new Map();
|
|
22
|
+
for (const event of allEvents) {
|
|
23
|
+
const dayKeyStr = event.start.toISOString().split('T')[0] ?? '';
|
|
24
|
+
if (!eventsByDay.has(dayKeyStr)) {
|
|
25
|
+
eventsByDay.set(dayKeyStr, []);
|
|
26
|
+
}
|
|
27
|
+
eventsByDay.get(dayKeyStr).push(event);
|
|
28
|
+
}
|
|
29
|
+
// Sort each day's events by start time
|
|
30
|
+
for (const dayEvts of eventsByDay.values()) {
|
|
31
|
+
dayEvts.sort((a, b) => a.start.getTime() - b.start.getTime());
|
|
32
|
+
}
|
|
33
|
+
// Get all days in range and render those with events
|
|
34
|
+
const days = getDaysInRange(range.start, range.end);
|
|
35
|
+
let hasAnyEvents = false;
|
|
36
|
+
for (const day of days) {
|
|
37
|
+
const dayKey = day.toISOString().split('T')[0] ?? '';
|
|
38
|
+
const dayEvents = eventsByDay.get(dayKey);
|
|
39
|
+
if (!dayEvents || dayEvents.length === 0)
|
|
40
|
+
continue;
|
|
41
|
+
hasAnyEvents = true;
|
|
42
|
+
// Day group
|
|
43
|
+
const dayGroup = document.createElement('div');
|
|
44
|
+
dayGroup.className = getClass('agendaDay', classes, 'lf-cal-agenda-day');
|
|
45
|
+
// Day header
|
|
46
|
+
const dayHeader = document.createElement('div');
|
|
47
|
+
let headerClass = getClass('agendaDayHeader', classes, 'lf-cal-agenda-day-header');
|
|
48
|
+
if (isToday(day)) {
|
|
49
|
+
headerClass += ' lf-cal-agenda-day-header--today';
|
|
50
|
+
}
|
|
51
|
+
dayHeader.className = headerClass;
|
|
52
|
+
dayHeader.textContent = formatFullDate(day, locale);
|
|
53
|
+
dayGroup.appendChild(dayHeader);
|
|
54
|
+
// Events list
|
|
55
|
+
for (const event of dayEvents) {
|
|
56
|
+
const item = document.createElement('div');
|
|
57
|
+
item.className = getClass('agendaItem', classes, 'lf-cal-agenda-item');
|
|
58
|
+
// Time
|
|
59
|
+
const timeEl = document.createElement('div');
|
|
60
|
+
timeEl.className = 'lf-cal-agenda-item-time';
|
|
61
|
+
timeEl.textContent = `${formatTime(event.start, locale)} - ${formatTime(event.end, locale)}`;
|
|
62
|
+
item.appendChild(timeEl);
|
|
63
|
+
// Color indicator
|
|
64
|
+
const indicator = document.createElement('div');
|
|
65
|
+
indicator.className = 'lf-cal-agenda-item-indicator';
|
|
66
|
+
// Find resource color
|
|
67
|
+
const resource = event.resourceId
|
|
68
|
+
? allResources.find((r) => r.id === event.resourceId)
|
|
69
|
+
: undefined;
|
|
70
|
+
indicator.style.background = event.color ?? resource?.color ?? '#3b82f6';
|
|
71
|
+
item.appendChild(indicator);
|
|
72
|
+
// Content
|
|
73
|
+
const content = document.createElement('div');
|
|
74
|
+
content.className = 'lf-cal-agenda-item-content';
|
|
75
|
+
const title = document.createElement('div');
|
|
76
|
+
title.className = 'lf-cal-agenda-item-title';
|
|
77
|
+
title.textContent = event.title;
|
|
78
|
+
content.appendChild(title);
|
|
79
|
+
// Details (resource name, status, etc.)
|
|
80
|
+
const details = [];
|
|
81
|
+
if (resource) {
|
|
82
|
+
details.push(resource.name);
|
|
83
|
+
}
|
|
84
|
+
if (event.status) {
|
|
85
|
+
details.push(event.status);
|
|
86
|
+
}
|
|
87
|
+
if (details.length > 0) {
|
|
88
|
+
const detailsEl = document.createElement('div');
|
|
89
|
+
detailsEl.className = 'lf-cal-agenda-item-details';
|
|
90
|
+
detailsEl.textContent = details.join(' • ');
|
|
91
|
+
content.appendChild(detailsEl);
|
|
92
|
+
}
|
|
93
|
+
item.appendChild(content);
|
|
94
|
+
// Click handler
|
|
95
|
+
if (onEventClick) {
|
|
96
|
+
item.addEventListener('click', () => {
|
|
97
|
+
onEventClick(event);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
dayGroup.appendChild(item);
|
|
101
|
+
}
|
|
102
|
+
container.appendChild(dayGroup);
|
|
103
|
+
}
|
|
104
|
+
// Empty state
|
|
105
|
+
if (!hasAnyEvents) {
|
|
106
|
+
const empty = document.createElement('div');
|
|
107
|
+
empty.className = 'lf-cal-empty';
|
|
108
|
+
empty.textContent = 'No events in this period';
|
|
109
|
+
container.appendChild(empty);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
return container;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=agenda-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agenda-view.js","sourceRoot":"","sources":["../../src/views/agenda-view.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @liteforge/calendar - Day View Renderer
|
|
3
|
+
*
|
|
4
|
+
* Day view with optional resource columns (therapists/rooms).
|
|
5
|
+
* Without resources: single day column.
|
|
6
|
+
* With resources: one column per visible resource.
|
|
7
|
+
*/
|
|
8
|
+
import type { CalendarEvent, Resource, ResolvedTimeConfig, CalendarClasses } from '../types.js';
|
|
9
|
+
interface DayViewOptions<T extends CalendarEvent> {
|
|
10
|
+
date: () => Date;
|
|
11
|
+
events: () => T[];
|
|
12
|
+
resources: () => Resource[];
|
|
13
|
+
visibleResources: () => string[];
|
|
14
|
+
config: ResolvedTimeConfig;
|
|
15
|
+
locale: string;
|
|
16
|
+
classes: Partial<CalendarClasses>;
|
|
17
|
+
eventContent: ((event: T) => Node) | undefined;
|
|
18
|
+
slotContent: ((date: Date, resourceId?: string) => Node | null) | undefined;
|
|
19
|
+
dayHeaderContent: ((date: Date) => Node) | undefined;
|
|
20
|
+
onEventClick: ((event: T) => void) | undefined;
|
|
21
|
+
onSlotClick: ((start: Date, end: Date, resourceId?: string) => void) | undefined;
|
|
22
|
+
onSlotSelect: ((start: Date, end: Date, resourceId?: string) => void) | undefined;
|
|
23
|
+
onEventDrop: ((event: T, newStart: Date, newEnd: Date, newResourceId?: string) => void) | undefined;
|
|
24
|
+
onEventResize: ((event: T, newEnd: Date) => void) | undefined;
|
|
25
|
+
editable: boolean | undefined;
|
|
26
|
+
selectable: boolean | undefined;
|
|
27
|
+
}
|
|
28
|
+
export declare function renderDayView<T extends CalendarEvent>(options: DayViewOptions<T>): HTMLDivElement;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=day-view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"day-view.d.ts","sourceRoot":"","sources":["../../src/views/day-view.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EACV,aAAa,EACb,QAAQ,EACR,kBAAkB,EAClB,eAAe,EAChB,MAAM,aAAa,CAAA;AAsBpB,UAAU,cAAc,CAAC,CAAC,SAAS,aAAa;IAC9C,IAAI,EAAE,MAAM,IAAI,CAAA;IAChB,MAAM,EAAE,MAAM,CAAC,EAAE,CAAA;IACjB,SAAS,EAAE,MAAM,QAAQ,EAAE,CAAA;IAC3B,gBAAgB,EAAE,MAAM,MAAM,EAAE,CAAA;IAChC,MAAM,EAAE,kBAAkB,CAAA;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,CAAA;IACjC,YAAY,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAC9C,WAAW,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC,GAAG,SAAS,CAAA;IAC3E,gBAAgB,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IACpD,YAAY,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAC9C,WAAW,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAChF,YAAY,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IACjF,WAAW,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IACnG,aAAa,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAC7D,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAA;IAC7B,UAAU,EAAE,OAAO,GAAG,SAAS,CAAA;CAChC;AAED,wBAAgB,aAAa,CAAC,CAAC,SAAS,aAAa,EACnD,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,GACzB,cAAc,CAshBhB"}
|