@unabridged/midwest 0.23.3 → 0.24.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/app/assets/javascript/midwest/index.ts +4 -0
- package/app/assets/javascript/midwest.js +576 -8
- package/app/assets/javascript/midwest.js.map +1 -1
- package/app/assets/stylesheets/midwest/dark-mode.css +51 -1
- package/app/assets/stylesheets/midwest/form-group.css +5 -5
- package/app/assets/stylesheets/midwest/tailwind.css +101 -6
- package/app/assets/stylesheets/midwest/tokens.css +108 -0
- package/app/assets/stylesheets/midwest/utilities.css +20 -20
- package/app/assets/stylesheets/midwest.css +2 -2
- package/app/assets/stylesheets/midwest.tailwind.css +24 -1
- package/config/tailwind.theme.css +59 -0
- package/config/tailwind.theme.js +6 -2
- package/dist/css/midwest.css +2 -2
- package/dist/javascript/collection/app/assets/javascript/midwest/index.js +4 -0
- package/dist/javascript/collection/app/assets/javascript/midwest/index.js.map +1 -1
- package/dist/javascript/collection/app/components/midwest/command_palette_component/command_palette_component_controller.js +66 -8
- package/dist/javascript/collection/app/components/midwest/command_palette_component/command_palette_component_controller.js.map +1 -1
- package/dist/javascript/collection/app/components/midwest/panorama_component/panorama_component_controller.js +296 -0
- package/dist/javascript/collection/app/components/midwest/panorama_component/panorama_component_controller.js.map +1 -0
- package/dist/javascript/collection/app/components/midwest/playlist_component/playlist_component_controller.js +220 -0
- package/dist/javascript/collection/app/components/midwest/playlist_component/playlist_component_controller.js.map +1 -0
- package/dist/javascript/midwest.js +576 -8
- package/dist/javascript/midwest.js.map +1 -1
- package/package.json +6 -6
|
@@ -36,6 +36,8 @@ import ViewportObserver from '../../../components/midwest/intersection_observer_
|
|
|
36
36
|
import FocusTrap from '../../../components/midwest/focus_trap_component/focus_trap_component_controller.js';
|
|
37
37
|
import Onboarding from '../../../components/midwest/onboarding_component/onboarding_component_controller.js';
|
|
38
38
|
import ThemeSwitch from '../../../components/midwest/form/switch_component/theme_switch_controller.js';
|
|
39
|
+
import Panorama from '../../../components/midwest/panorama_component/panorama_component_controller.js';
|
|
40
|
+
import Playlist from '../../../components/midwest/playlist_component/playlist_component_controller.js';
|
|
39
41
|
|
|
40
42
|
function registerMidwestControllers(application) {
|
|
41
43
|
application.register("midwest-card", Card);
|
|
@@ -76,6 +78,8 @@ function registerMidwestControllers(application) {
|
|
|
76
78
|
application.register("midwest-focus-trap", FocusTrap);
|
|
77
79
|
application.register("midwest-onboarding", Onboarding);
|
|
78
80
|
application.register("midwest-theme-switch", ThemeSwitch);
|
|
81
|
+
application.register("midwest-panorama", Panorama);
|
|
82
|
+
application.register("midwest-playlist", Playlist);
|
|
79
83
|
}
|
|
80
84
|
|
|
81
85
|
export { Banner, Card, Chart, CountdownTimer, registerMidwestControllers };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../../../../app/assets/javascript/midwest/index.ts"],"sourcesContent":["import Card from '../../../components/midwest/card_component/card_component_controller'\nimport Banner from '../../../components/midwest/banner_component/banner_component_controller'\nimport Input from '../../../components/midwest/form/input_component/input_component_controller'\nimport File from '../../../components/midwest/form/file_component/file_component_controller'\nimport Dropdown from '../../../components/midwest/dropdown_component/dropdown_component_controller'\nimport Prose from '../../../components/midwest/prose_component/prose_component_controller'\nimport Dialog from '../../../components/midwest/dialog_component/dialog_component_controller'\nimport Tabs from '../../../components/midwest/tabs_component/tabs_component_controller'\nimport Tooltip from '../../../components/midwest/tooltip_component/tooltip_component_controller'\nimport Carousel from '../../../components/midwest/carousel_component/carousel_component_controller'\nimport FormLiveSummary from '../../../components/midwest/form/live_summary_component/live_summary_component_controller'\nimport Form from '../../../components/midwest/form/form_controller'\nimport CountdownTimer from '../../../components/midwest/countdown_timer_component/countdown_timer_component_controller'\nimport Badge from '../../../components/midwest/badge_component/badge_component_controller'\nimport Confirmation from '../../../components/midwest/confirmation_component/confirmation_component_controller'\nimport Chart from '../../../components/midwest/chart_component/chart_component_controller'\nimport Range from '../../../components/midwest/form/range_component/range_component_controller'\nimport Rating from '../../../components/midwest/rating_component/rating_component_controller'\nimport Autocomplete from '../../../components/midwest/form/autocomplete_component/autocomplete_component_controller'\nimport Image from '../../../components/midwest/image_component/image_component_controller'\nimport ColorPicker from '../../../components/midwest/form/color_picker_component/color_picker_component_controller'\nimport Notification from '../../../components/midwest/notification_component/notification_component_controller'\nimport HorizontalScroll from '../../../components/midwest/horizontal_scroll_component/horizontal_scroll_component_controller'\nimport Table from '../../../components/midwest/table_component/table_component_controller'\nimport LoadMore from '../../../components/midwest/table_component/load_more_controller'\nimport Pagination from '../../../components/midwest/pagination_component/pagination_component_controller'\nimport ShowIf from '../../../components/midwest/show_if_component/show_if_component_controller'\nimport TreeView from '../../../components/midwest/tree_view_component/tree_view_component_controller'\nimport CommandPalette from '../../../components/midwest/command_palette_component/command_palette_component_controller'\nimport Repeatable from '../../../components/midwest/form/repeatable_component/repeatable_component_controller'\nimport PasswordRequirements from '../../../components/midwest/password_requirements_component/password_requirements_component_controller'\nimport CodeBlock from '../../../components/midwest/code_block_component/code_block_component_controller'\nimport DatePicker from '../../../components/midwest/form/date_picker_component/date_picker_component_controller'\nimport TimePicker from '../../../components/midwest/form/time_picker_component/time_picker_component_controller'\nimport IntersectionObserver from '../../../components/midwest/intersection_observer_component/intersection_observer_component_controller'\nimport FocusTrap from '../../../components/midwest/focus_trap_component/focus_trap_component_controller'\nimport Onboarding from '../../../components/midwest/onboarding_component/onboarding_component_controller'\nimport ThemeSwitch from '../../../components/midwest/form/switch_component/theme_switch_controller'\n/* IMPORTS */\n\nexport { Card, Banner, CountdownTimer, Chart }\n\nexport function registerMidwestControllers (application: any) {\n application.register('midwest-card', Card)\n application.register('midwest-banner', Banner)\n application.register('midwest-countdown-timer', CountdownTimer)\n application.register('midwest-input', Input)\n application.register('midwest-file', File)\n application.register('midwest-dropdown', Dropdown)\n application.register('midwest-prose', Prose)\n application.register('midwest-dialog', Dialog)\n application.register('midwest-tabs', Tabs)\n application.register('midwest-tooltip', Tooltip)\n application.register('midwest-carousel', Carousel)\n application.register('midwest-form-live-summary', FormLiveSummary)\n application.register('midwest-form', Form)\n application.register('midwest-badge', Badge)\n application.register('midwest-confirmation', Confirmation)\n application.register('midwest-chart', Chart)\n application.register('midwest-range', Range)\n application.register('midwest-rating', Rating)\n application.register('midwest-autocomplete', Autocomplete)\n application.register('midwest-image', Image)\n application.register('midwest-color-picker', ColorPicker)\n application.register('midwest-notification', Notification)\n application.register('midwest-horizontal-scroll', HorizontalScroll)\n application.register('midwest-table', Table)\n application.register('midwest-load-more', LoadMore)\n application.register('midwest-pagination', Pagination)\n application.register('midwest-show-if', ShowIf)\n application.register('midwest-tree-view', TreeView)\n application.register('midwest-command-palette', CommandPalette)\n application.register('midwest-repeatable', Repeatable)\n application.register('midwest-password-requirements', PasswordRequirements)\n application.register('midwest-code-block', CodeBlock)\n application.register('midwest-date-picker', DatePicker)\n application.register('midwest-time-picker', TimePicker)\n application.register('midwest-intersection-observer', IntersectionObserver)\n application.register('midwest-focus-trap', FocusTrap)\n application.register('midwest-onboarding', Onboarding)\n application.register('midwest-theme-switch', ThemeSwitch)\n /* EXPORTS */\n}\n"],"names":["Confirmation","IntersectionObserver"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../../../../app/assets/javascript/midwest/index.ts"],"sourcesContent":["import Card from '../../../components/midwest/card_component/card_component_controller'\nimport Banner from '../../../components/midwest/banner_component/banner_component_controller'\nimport Input from '../../../components/midwest/form/input_component/input_component_controller'\nimport File from '../../../components/midwest/form/file_component/file_component_controller'\nimport Dropdown from '../../../components/midwest/dropdown_component/dropdown_component_controller'\nimport Prose from '../../../components/midwest/prose_component/prose_component_controller'\nimport Dialog from '../../../components/midwest/dialog_component/dialog_component_controller'\nimport Tabs from '../../../components/midwest/tabs_component/tabs_component_controller'\nimport Tooltip from '../../../components/midwest/tooltip_component/tooltip_component_controller'\nimport Carousel from '../../../components/midwest/carousel_component/carousel_component_controller'\nimport FormLiveSummary from '../../../components/midwest/form/live_summary_component/live_summary_component_controller'\nimport Form from '../../../components/midwest/form/form_controller'\nimport CountdownTimer from '../../../components/midwest/countdown_timer_component/countdown_timer_component_controller'\nimport Badge from '../../../components/midwest/badge_component/badge_component_controller'\nimport Confirmation from '../../../components/midwest/confirmation_component/confirmation_component_controller'\nimport Chart from '../../../components/midwest/chart_component/chart_component_controller'\nimport Range from '../../../components/midwest/form/range_component/range_component_controller'\nimport Rating from '../../../components/midwest/rating_component/rating_component_controller'\nimport Autocomplete from '../../../components/midwest/form/autocomplete_component/autocomplete_component_controller'\nimport Image from '../../../components/midwest/image_component/image_component_controller'\nimport ColorPicker from '../../../components/midwest/form/color_picker_component/color_picker_component_controller'\nimport Notification from '../../../components/midwest/notification_component/notification_component_controller'\nimport HorizontalScroll from '../../../components/midwest/horizontal_scroll_component/horizontal_scroll_component_controller'\nimport Table from '../../../components/midwest/table_component/table_component_controller'\nimport LoadMore from '../../../components/midwest/table_component/load_more_controller'\nimport Pagination from '../../../components/midwest/pagination_component/pagination_component_controller'\nimport ShowIf from '../../../components/midwest/show_if_component/show_if_component_controller'\nimport TreeView from '../../../components/midwest/tree_view_component/tree_view_component_controller'\nimport CommandPalette from '../../../components/midwest/command_palette_component/command_palette_component_controller'\nimport Repeatable from '../../../components/midwest/form/repeatable_component/repeatable_component_controller'\nimport PasswordRequirements from '../../../components/midwest/password_requirements_component/password_requirements_component_controller'\nimport CodeBlock from '../../../components/midwest/code_block_component/code_block_component_controller'\nimport DatePicker from '../../../components/midwest/form/date_picker_component/date_picker_component_controller'\nimport TimePicker from '../../../components/midwest/form/time_picker_component/time_picker_component_controller'\nimport IntersectionObserver from '../../../components/midwest/intersection_observer_component/intersection_observer_component_controller'\nimport FocusTrap from '../../../components/midwest/focus_trap_component/focus_trap_component_controller'\nimport Onboarding from '../../../components/midwest/onboarding_component/onboarding_component_controller'\nimport ThemeSwitch from '../../../components/midwest/form/switch_component/theme_switch_controller'\nimport Panorama from '../../../components/midwest/panorama_component/panorama_component_controller'\nimport Playlist from '../../../components/midwest/playlist_component/playlist_component_controller'\n/* IMPORTS */\n\nexport { Card, Banner, CountdownTimer, Chart }\n\nexport function registerMidwestControllers (application: any) {\n application.register('midwest-card', Card)\n application.register('midwest-banner', Banner)\n application.register('midwest-countdown-timer', CountdownTimer)\n application.register('midwest-input', Input)\n application.register('midwest-file', File)\n application.register('midwest-dropdown', Dropdown)\n application.register('midwest-prose', Prose)\n application.register('midwest-dialog', Dialog)\n application.register('midwest-tabs', Tabs)\n application.register('midwest-tooltip', Tooltip)\n application.register('midwest-carousel', Carousel)\n application.register('midwest-form-live-summary', FormLiveSummary)\n application.register('midwest-form', Form)\n application.register('midwest-badge', Badge)\n application.register('midwest-confirmation', Confirmation)\n application.register('midwest-chart', Chart)\n application.register('midwest-range', Range)\n application.register('midwest-rating', Rating)\n application.register('midwest-autocomplete', Autocomplete)\n application.register('midwest-image', Image)\n application.register('midwest-color-picker', ColorPicker)\n application.register('midwest-notification', Notification)\n application.register('midwest-horizontal-scroll', HorizontalScroll)\n application.register('midwest-table', Table)\n application.register('midwest-load-more', LoadMore)\n application.register('midwest-pagination', Pagination)\n application.register('midwest-show-if', ShowIf)\n application.register('midwest-tree-view', TreeView)\n application.register('midwest-command-palette', CommandPalette)\n application.register('midwest-repeatable', Repeatable)\n application.register('midwest-password-requirements', PasswordRequirements)\n application.register('midwest-code-block', CodeBlock)\n application.register('midwest-date-picker', DatePicker)\n application.register('midwest-time-picker', TimePicker)\n application.register('midwest-intersection-observer', IntersectionObserver)\n application.register('midwest-focus-trap', FocusTrap)\n application.register('midwest-onboarding', Onboarding)\n application.register('midwest-theme-switch', ThemeSwitch)\n application.register('midwest-panorama', Panorama)\n application.register('midwest-playlist', Playlist)\n /* EXPORTS */\n}\n"],"names":["Confirmation","IntersectionObserver"],"mappings":"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"}
|
|
@@ -40,11 +40,16 @@ class CommandPalette extends Controller {
|
|
|
40
40
|
commandPlaceholder = "";
|
|
41
41
|
messages = [];
|
|
42
42
|
streamAbort = null;
|
|
43
|
+
// While true, new/streamed content pins the transcript to the bottom. Turns
|
|
44
|
+
// false when the user scrolls up to read history so we don't yank them down.
|
|
45
|
+
stickToBottom = true;
|
|
43
46
|
connect() {
|
|
44
47
|
this.allItems = this.itemsValue;
|
|
45
48
|
this.commandPlaceholder = this.inputTarget.placeholder;
|
|
46
49
|
document.addEventListener("keydown", this.handleGlobalKeydown);
|
|
47
50
|
this.element.addEventListener("click", this.handleBackdropClick);
|
|
51
|
+
if (this.hasBodyTarget)
|
|
52
|
+
this.bodyTarget.addEventListener("scroll", this.handleTranscriptScroll, { passive: true });
|
|
48
53
|
if (!this.turboFrameUrlValue) {
|
|
49
54
|
this.renderItems(this.allItems);
|
|
50
55
|
}
|
|
@@ -52,6 +57,8 @@ class CommandPalette extends Controller {
|
|
|
52
57
|
disconnect() {
|
|
53
58
|
document.removeEventListener("keydown", this.handleGlobalKeydown);
|
|
54
59
|
this.element.removeEventListener("click", this.handleBackdropClick);
|
|
60
|
+
if (this.hasBodyTarget)
|
|
61
|
+
this.bodyTarget.removeEventListener("scroll", this.handleTranscriptScroll);
|
|
55
62
|
if (this.fetchAbort)
|
|
56
63
|
this.fetchAbort.abort();
|
|
57
64
|
if (this.streamAbort)
|
|
@@ -195,6 +202,7 @@ class CommandPalette extends Controller {
|
|
|
195
202
|
this.transcriptTarget.innerHTML = "";
|
|
196
203
|
if (this.hasStartersTarget)
|
|
197
204
|
this.startersTarget.hidden = false;
|
|
205
|
+
this.stickToBottom = true;
|
|
198
206
|
this.setBusy(false);
|
|
199
207
|
this.setMode("command");
|
|
200
208
|
}
|
|
@@ -234,6 +242,7 @@ class CommandPalette extends Controller {
|
|
|
234
242
|
const text = this.inputTarget.value.trim();
|
|
235
243
|
if (!text)
|
|
236
244
|
return;
|
|
245
|
+
this.stickToBottom = true;
|
|
237
246
|
this.appendMessage("user", text);
|
|
238
247
|
this.messages.push({ role: "user", content: text });
|
|
239
248
|
this.inputTarget.value = "";
|
|
@@ -305,16 +314,31 @@ class CommandPalette extends Controller {
|
|
|
305
314
|
return null;
|
|
306
315
|
}
|
|
307
316
|
}
|
|
308
|
-
// Agentic events: the server streams a tool "action row"
|
|
309
|
-
// directive (navigate / run a palette command).
|
|
310
|
-
// execution path as manual selection.
|
|
317
|
+
// Agentic events: the server streams a tool "action row", a live preview
|
|
318
|
+
// ("embed"), and/or a client directive (navigate / run a palette command).
|
|
319
|
+
// Directives reuse the same execution path as manual selection.
|
|
311
320
|
handleAgentEvent(event) {
|
|
312
321
|
if (event.type === "tool") {
|
|
313
322
|
this.appendActionRow(event);
|
|
323
|
+
} else if (event.type === "embed" && event.srcdoc) {
|
|
324
|
+
this.appendEmbed(event);
|
|
314
325
|
} else if (event.type === "directive" && event.directive) {
|
|
315
326
|
this.performDirective(event.directive);
|
|
327
|
+
} else if (event.type === "error") {
|
|
328
|
+
this.renderStreamError(event.message);
|
|
316
329
|
}
|
|
317
330
|
}
|
|
331
|
+
// A server-reported failure (e.g. provider billing/rate-limit error). Render
|
|
332
|
+
// it into the current assistant bubble instead of failing silently.
|
|
333
|
+
renderStreamError(message) {
|
|
334
|
+
const last = this.currentAssistantMessage();
|
|
335
|
+
if (!last)
|
|
336
|
+
return;
|
|
337
|
+
last.classList.add("is-error");
|
|
338
|
+
const bubble = last.querySelector(".command-palette-message-bubble");
|
|
339
|
+
if (bubble)
|
|
340
|
+
bubble.textContent = message || "Something went wrong. Please try again.";
|
|
341
|
+
}
|
|
318
342
|
// Action rows live in the current assistant message's card footer.
|
|
319
343
|
appendActionRow(event) {
|
|
320
344
|
if (!this.hasActionTemplateTarget)
|
|
@@ -323,19 +347,42 @@ class CommandPalette extends Controller {
|
|
|
323
347
|
if (!footer)
|
|
324
348
|
return;
|
|
325
349
|
const action = cloneTemplate(this.actionTemplateTarget);
|
|
326
|
-
const label = action.querySelector(".
|
|
350
|
+
const label = action.querySelector(".value");
|
|
327
351
|
if (label)
|
|
328
352
|
label.textContent = event.label || "Action";
|
|
329
353
|
footer.hidden = false;
|
|
330
354
|
footer.appendChild(action);
|
|
331
355
|
this.scrollTranscript();
|
|
332
356
|
}
|
|
357
|
+
// A live preview streamed by an agentic tool (e.g. generate_iframe). The
|
|
358
|
+
// server sends only the inner document; the client owns the <iframe> element
|
|
359
|
+
// and hard-codes the sandbox (no allow-scripts) so injected markup is styled
|
|
360
|
+
// but never executed — the markdown text path can't render HTML at all.
|
|
361
|
+
appendEmbed(event) {
|
|
362
|
+
const message = this.currentAssistantMessage();
|
|
363
|
+
if (!message || !event.srcdoc)
|
|
364
|
+
return;
|
|
365
|
+
const body = message.querySelector(".command-palette-message-body") || message;
|
|
366
|
+
const frame = document.createElement("iframe");
|
|
367
|
+
frame.className = "command-palette-embed";
|
|
368
|
+
frame.setAttribute("sandbox", "allow-same-origin");
|
|
369
|
+
frame.setAttribute("loading", "lazy");
|
|
370
|
+
frame.title = event.title || "Preview";
|
|
371
|
+
frame.srcdoc = event.srcdoc;
|
|
372
|
+
if (event.height)
|
|
373
|
+
frame.style.height = `${event.height}px`;
|
|
374
|
+
body.appendChild(frame);
|
|
375
|
+
this.scrollTranscript();
|
|
376
|
+
}
|
|
333
377
|
currentActionFooter() {
|
|
378
|
+
const last = this.currentAssistantMessage();
|
|
379
|
+
return last ? last.querySelector(".command-palette-action-footer") : null;
|
|
380
|
+
}
|
|
381
|
+
currentAssistantMessage() {
|
|
334
382
|
const messages = this.transcriptTarget.querySelectorAll(
|
|
335
383
|
".command-palette-message.role-assistant"
|
|
336
384
|
);
|
|
337
|
-
|
|
338
|
-
return last ? last.querySelector(".command-palette-action-footer") : null;
|
|
385
|
+
return messages[messages.length - 1] || null;
|
|
339
386
|
}
|
|
340
387
|
performDirective(directive) {
|
|
341
388
|
if (directive.url) {
|
|
@@ -375,10 +422,21 @@ class CommandPalette extends Controller {
|
|
|
375
422
|
if (this.hasTranscriptTarget)
|
|
376
423
|
this.transcriptTarget.setAttribute("aria-busy", String(busy));
|
|
377
424
|
}
|
|
425
|
+
// The body is the scrollable region; the transcript itself does not scroll.
|
|
378
426
|
scrollTranscript() {
|
|
379
|
-
if (this.
|
|
380
|
-
this.
|
|
427
|
+
if (this.hasBodyTarget && this.stickToBottom) {
|
|
428
|
+
this.bodyTarget.scrollTop = this.bodyTarget.scrollHeight;
|
|
429
|
+
}
|
|
381
430
|
}
|
|
431
|
+
// Track whether the user is anchored to the bottom. Once they scroll up to
|
|
432
|
+
// read earlier messages we stop auto-scrolling; returning to the bottom
|
|
433
|
+
// re-arms it so streamed text keeps the latest content on screen.
|
|
434
|
+
handleTranscriptScroll = () => {
|
|
435
|
+
if (!this.hasBodyTarget)
|
|
436
|
+
return;
|
|
437
|
+
const { scrollHeight, scrollTop, clientHeight } = this.bodyTarget;
|
|
438
|
+
this.stickToBottom = scrollHeight - scrollTop - clientHeight < 24;
|
|
439
|
+
};
|
|
382
440
|
appendMessage(role, text) {
|
|
383
441
|
const li = cloneTemplate(this.messageTemplateTarget);
|
|
384
442
|
li.classList.add(`role-${role}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command_palette_component_controller.js","sources":["../../../../../../../app/components/midwest/command_palette_component/command_palette_component_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\nimport { cloneTemplate } from '../../../assets/javascript/midwest/template_helpers'\nimport { renderMarkdown } from '../../../assets/javascript/midwest/markdown'\n\ninterface ChatMessage {\n role: 'user' | 'assistant'\n content: string\n}\n\ninterface Directive {\n action?: string\n url?: string\n method?: string\n}\n\ninterface AgentEvent {\n type: 'tool' | 'directive'\n label?: string\n icon?: string\n status?: string\n directive?: Directive\n}\n\ninterface SseData {\n choices?: { delta?: { content?: string } }[]\n midwest?: AgentEvent\n}\n\ninterface PaletteItem {\n label: string\n description?: string\n icon?: string\n url?: string\n action?: string\n group?: string\n shortcut?: string\n method?: string\n confirm?: string\n}\n\nexport default class CommandPalette extends Controller<HTMLDialogElement> {\n static targets = [\n 'input', 'list', 'empty', 'body', 'turboList', 'itemTemplate', 'groupTemplate',\n 'modes', 'chat', 'transcript', 'starters', 'messageTemplate', 'actionTemplate'\n ]\n\n static values = {\n hotkey: { type: String, default: 'k' },\n items: { type: Array, default: [] },\n src: { type: String, default: '' },\n turboFrameUrl: { type: String, default: '' },\n chatEnabled: { type: Boolean, default: false },\n chatMode: { type: String, default: 'proxy' },\n chatTrigger: { type: String, default: 'toggle' },\n chatAgentic: { type: Boolean, default: true },\n chatPlaceholder: { type: String, default: 'Ask AI…' },\n chatEndpoint: { type: String, default: '' },\n chatUrl: { type: String, default: '' },\n chatModel: { type: String, default: '' }\n }\n\n declare readonly inputTarget: HTMLInputElement\n declare readonly listTarget: HTMLElement\n declare readonly emptyTarget: HTMLElement\n declare readonly bodyTarget: HTMLElement\n declare readonly turboListTarget: HTMLElement\n declare readonly hasTurboListTarget: boolean\n declare readonly hasListTarget: boolean\n declare readonly itemTemplateTarget: HTMLTemplateElement\n declare readonly groupTemplateTarget: HTMLTemplateElement\n declare readonly modesTarget: HTMLElement\n declare readonly hasModesTarget: boolean\n declare readonly chatTarget: HTMLElement\n declare readonly hasChatTarget: boolean\n declare readonly transcriptTarget: HTMLElement\n declare readonly hasTranscriptTarget: boolean\n declare readonly startersTarget: HTMLElement\n declare readonly hasStartersTarget: boolean\n declare readonly messageTemplateTarget: HTMLTemplateElement\n declare readonly actionTemplateTarget: HTMLTemplateElement\n declare readonly hasActionTemplateTarget: boolean\n declare readonly stopTarget: HTMLElement\n declare readonly hasStopTarget: boolean\n\n declare hotkeyValue: string\n declare itemsValue: PaletteItem[]\n declare srcValue: string\n declare turboFrameUrlValue: string\n declare chatEnabledValue: boolean\n declare chatModeValue: string\n declare chatTriggerValue: string\n declare chatAgenticValue: boolean\n declare chatPlaceholderValue: string\n declare chatEndpointValue: string\n declare chatUrlValue: string\n declare chatModelValue: string\n\n private highlightedIndex = -1\n private fetchAbort: AbortController | null = null\n private searchTimer: number | undefined\n private allItems: PaletteItem[] = []\n private mode: 'command' | 'chat' = 'command'\n private commandPlaceholder = ''\n private messages: ChatMessage[] = []\n private streamAbort: AbortController | null = null\n\n connect () {\n this.allItems = this.itemsValue\n this.commandPlaceholder = this.inputTarget.placeholder\n document.addEventListener('keydown', this.handleGlobalKeydown)\n this.element.addEventListener('click', this.handleBackdropClick)\n\n // Only render client-side items when not in turbo-frame mode\n if (!this.turboFrameUrlValue) {\n this.renderItems(this.allItems)\n }\n }\n\n disconnect () {\n document.removeEventListener('keydown', this.handleGlobalKeydown)\n this.element.removeEventListener('click', this.handleBackdropClick)\n if (this.fetchAbort) this.fetchAbort.abort()\n if (this.streamAbort) this.streamAbort.abort()\n if (this.searchTimer) clearTimeout(this.searchTimer)\n }\n\n // ── Turbo frame lifecycle ───────────────────────────────────────────\n\n turboListTargetConnected (el: HTMLElement) {\n el.addEventListener('turbo:frame-load', this.onFrameLoad)\n }\n\n turboListTargetDisconnected (el: HTMLElement) {\n el.removeEventListener('turbo:frame-load', this.onFrameLoad)\n }\n\n private onFrameLoad = () => {\n if (!this.hasListTarget) return\n\n const items = this.listTarget.querySelectorAll<HTMLElement>('.command-palette-item')\n if (items.length > 0) {\n this.highlightedIndex = 0\n this.updateHighlight()\n this.emptyTarget.hidden = true\n if (this.hasListTarget) this.listTarget.hidden = false\n } else {\n this.emptyTarget.hidden = false\n if (this.hasListTarget) this.listTarget.hidden = true\n }\n }\n\n // ── Public actions ──────────────────────────────────────────────────\n\n open () {\n if (this.element.open) return\n this.element.showModal()\n this.inputTarget.value = ''\n this.highlightedIndex = -1\n\n // Chat resets to a fresh conversation in command mode on every open.\n if (this.chatEnabledValue) this.resetChat()\n\n if (this.turboFrameUrlValue) {\n this.navigateFrame('')\n } else {\n this.renderItems(this.allItems)\n }\n\n requestAnimationFrame(() => this.inputTarget.focus())\n }\n\n close () {\n if (!this.element.open) return\n this.element.close()\n }\n\n filter () {\n // In chat mode the input is the composer — typing must not filter commands.\n if (this.mode === 'chat') return\n\n const query = this.inputTarget.value.trim().toLowerCase()\n\n if (this.turboFrameUrlValue) {\n this.debouncedNavigateFrame(query)\n return\n }\n\n if (this.srcValue && query.length > 0) {\n this.fetchRemote(query)\n return\n }\n\n if (query.length === 0) {\n this.renderItems(this.allItems)\n return\n }\n\n const filtered = this.allItems.filter(item => {\n const haystack = `${item.label} ${item.description || ''} ${item.group || ''}`.toLowerCase()\n return haystack.includes(query)\n })\n\n this.renderItems(filtered)\n }\n\n navigate (event: KeyboardEvent) {\n if (this.mode === 'chat') {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault()\n this.send()\n } else if (event.key === 'Escape') {\n event.preventDefault()\n this.close()\n }\n return\n }\n\n // Tab from an empty query enters chat mode (toggle trigger only).\n if (\n event.key === 'Tab' && !event.shiftKey &&\n this.chatEnabledValue && this.chatTriggerValue === 'toggle' &&\n this.inputTarget.value.trim() === ''\n ) {\n event.preventDefault()\n this.setMode('chat')\n return\n }\n\n const items = this.visibleItems\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault()\n this.highlightedIndex = Math.min(this.highlightedIndex + 1, items.length - 1)\n this.updateHighlight()\n break\n case 'ArrowUp':\n event.preventDefault()\n this.highlightedIndex = Math.max(this.highlightedIndex - 1, 0)\n this.updateHighlight()\n break\n case 'Enter':\n event.preventDefault()\n if (this.highlightedIndex >= 0 && this.highlightedIndex < items.length) {\n this.selectItem(items[this.highlightedIndex])\n }\n break\n case 'Escape':\n event.preventDefault()\n this.close()\n break\n }\n }\n\n select (event: Event) {\n const el = (event.target as HTMLElement).closest<HTMLElement>('.command-palette-item')\n if (!el) return\n const index = parseInt(el.dataset.index || '-1', 10)\n const items = this.visibleItems\n if (index >= 0 && index < items.length) {\n this.selectItem(items[index])\n }\n }\n\n // ── Chat mode ───────────────────────────────────────────────────────\n\n switchMode (event: Event) {\n const mode = (event.currentTarget as HTMLElement).dataset.mode === 'chat' ? 'chat' : 'command'\n this.setMode(mode)\n if (mode === 'command') this.filter()\n this.inputTarget.focus()\n }\n\n useStarter (event: Event) {\n this.inputTarget.value = (event.currentTarget as HTMLElement).textContent?.trim() || ''\n this.send()\n }\n\n private resetChat () {\n if (this.streamAbort) this.streamAbort.abort()\n this.messages = []\n if (this.hasTranscriptTarget) this.transcriptTarget.innerHTML = ''\n if (this.hasStartersTarget) this.startersTarget.hidden = false\n this.setBusy(false)\n this.setMode('command')\n }\n\n private setMode (mode: 'command' | 'chat') {\n if (!this.chatEnabledValue) return\n this.mode = mode\n const chat = mode === 'chat'\n this.element.classList.toggle('chat-active', chat)\n\n if (this.hasModesTarget) {\n this.modesTarget.querySelectorAll<HTMLElement>('.command-palette-mode').forEach(el => {\n el.setAttribute('aria-pressed', String(el.dataset.mode === mode))\n })\n }\n\n if (this.hasChatTarget) this.chatTarget.hidden = !chat\n\n if (chat) {\n this.emptyTarget.hidden = true\n if (this.hasListTarget) this.listTarget.hidden = true\n if (this.hasTurboListTarget) this.turboListTarget.hidden = true\n this.inputTarget.placeholder = this.chatPlaceholderValue\n } else {\n this.inputTarget.placeholder = this.commandPlaceholder\n if (this.hasTurboListTarget) this.turboListTarget.hidden = false\n }\n }\n\n stop () {\n if (this.streamAbort) this.streamAbort.abort()\n }\n\n private send () {\n if (this.streamAbort) return // a reply is already streaming\n\n const text = this.inputTarget.value.trim()\n if (!text) return\n\n this.appendMessage('user', text)\n this.messages.push({ role: 'user', content: text })\n this.inputTarget.value = ''\n if (this.hasStartersTarget) this.startersTarget.hidden = true\n\n void this.streamReply()\n }\n\n private async streamReply () {\n const message = this.appendMessage('assistant', '')\n const bubble = message.querySelector('.command-palette-message-bubble') as HTMLElement\n this.setBusy(true)\n this.streamAbort = new AbortController()\n\n let reply = ''\n try {\n const response = await fetch(this.chatRequestUrl(), {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Accept: 'text/event-stream' },\n body: JSON.stringify(this.chatRequestBody()),\n signal: this.streamAbort.signal\n })\n\n if (!response.ok || !response.body) throw new Error(`Chat request failed (${response.status})`)\n\n const reader = response.body.getReader()\n const decoder = new TextDecoder()\n let buffer = ''\n\n for (;;) {\n const { value, done } = await reader.read()\n if (done) break\n buffer += decoder.decode(value, { stream: true })\n\n const events = buffer.split('\\n\\n')\n buffer = events.pop() || ''\n\n for (const event of events) {\n const data = this.parseSseData(event)\n if (!data) continue\n\n const delta = data.choices?.[0]?.delta?.content\n if (delta) {\n reply += delta\n bubble.innerHTML = renderMarkdown(reply)\n this.scrollTranscript()\n } else if (data.midwest) {\n this.handleAgentEvent(data.midwest)\n }\n }\n }\n\n this.messages.push({ role: 'assistant', content: reply })\n } catch (error) {\n if ((error as Error).name === 'AbortError') {\n if (reply) this.messages.push({ role: 'assistant', content: reply })\n } else {\n message.classList.add('is-error')\n bubble.textContent = 'Something went wrong. Please try again.'\n }\n } finally {\n this.streamAbort = null\n this.setBusy(false)\n this.scrollTranscript()\n }\n }\n\n private parseSseData (event: string): SseData | null {\n const data = event\n .split('\\n')\n .filter(line => line.startsWith('data:'))\n .map(line => line.slice(5).trim())\n .join('')\n\n if (!data || data === '[DONE]') return null\n\n try {\n return JSON.parse(data) as SseData\n } catch {\n return null\n }\n }\n\n // Agentic events: the server streams a tool \"action row\" and/or a client\n // directive (navigate / run a palette command). Directives reuse the same\n // execution path as manual selection.\n private handleAgentEvent (event: AgentEvent) {\n if (event.type === 'tool') {\n this.appendActionRow(event)\n } else if (event.type === 'directive' && event.directive) {\n this.performDirective(event.directive)\n }\n }\n\n // Action rows live in the current assistant message's card footer.\n private appendActionRow (event: AgentEvent) {\n if (!this.hasActionTemplateTarget) return\n\n const footer = this.currentActionFooter()\n if (!footer) return\n\n const action = cloneTemplate(this.actionTemplateTarget)\n const label = action.querySelector('.command-palette-action-label')\n if (label) label.textContent = event.label || 'Action'\n\n footer.hidden = false\n footer.appendChild(action)\n this.scrollTranscript()\n }\n\n private currentActionFooter (): HTMLElement | null {\n const messages = this.transcriptTarget.querySelectorAll<HTMLElement>(\n '.command-palette-message.role-assistant'\n )\n const last = messages[messages.length - 1]\n return last ? last.querySelector<HTMLElement>('.command-palette-action-footer') : null\n }\n\n private performDirective (directive: Directive) {\n if (directive.url) {\n this.visit(directive.url, directive.method)\n } else if (directive.action) {\n this.element.dispatchEvent(\n new CustomEvent('midwest-command-palette:action', {\n bubbles: true,\n detail: { action: directive.action }\n })\n )\n }\n }\n\n private chatRequestUrl (): string {\n return this.chatModeValue === 'proxy' ? this.chatEndpointValue : this.chatUrlValue\n }\n\n private chatRequestBody (): Record<string, unknown> {\n const body: Record<string, unknown> = { messages: this.messages, stream: true }\n // In proxy mode the server owns the model; only direct mode sends it.\n if (this.chatModeValue !== 'proxy' && this.chatModelValue) body.model = this.chatModelValue\n // Expose the palette's commands as tools the model can invoke (proxy only).\n if (this.chatModeValue === 'proxy' && this.chatAgenticValue) {\n body.commands = this.allItems.map(item => ({\n label: item.label,\n description: item.description,\n url: item.url,\n action: item.action,\n method: item.method,\n icon: item.icon\n }))\n }\n return body\n }\n\n private setBusy (busy: boolean) {\n this.element.classList.toggle('chat-busy', busy)\n if (this.hasStopTarget) this.stopTarget.hidden = !busy\n // Hold the polite live region until the reply finishes so screen readers\n // announce the completed message instead of every streamed token.\n if (this.hasTranscriptTarget) this.transcriptTarget.setAttribute('aria-busy', String(busy))\n }\n\n private scrollTranscript () {\n if (this.hasTranscriptTarget) this.transcriptTarget.scrollTop = this.transcriptTarget.scrollHeight\n }\n\n private appendMessage (role: 'user' | 'assistant', text: string): HTMLElement {\n const li = cloneTemplate(this.messageTemplateTarget)\n li.classList.add(`role-${role}`)\n if (role === 'user') li.classList.add('is-end') // user messages sit on the trailing side\n\n const roleEl = li.querySelector('.command-palette-message-role')\n if (roleEl) roleEl.textContent = role === 'user' ? 'You' : 'Assistant'\n\n const bubble = li.querySelector('.command-palette-message-bubble') as HTMLElement\n if (text) bubble.textContent = text\n\n this.transcriptTarget.appendChild(li)\n this.scrollTranscript()\n return li\n }\n\n // ── Remote search ───────────────────────────────────────────────────\n\n private fetchRemote (query: string) {\n if (this.fetchAbort) this.fetchAbort.abort()\n if (this.searchTimer) clearTimeout(this.searchTimer)\n\n this.searchTimer = window.setTimeout(async () => {\n this.fetchAbort = new AbortController()\n try {\n const url = new URL(this.srcValue, window.location.origin)\n url.searchParams.set('q', query)\n const response = await fetch(url.toString(), {\n headers: { Accept: 'application/json' },\n signal: this.fetchAbort.signal\n })\n if (response.ok) {\n const data: PaletteItem[] = await response.json()\n this.renderItems(data)\n }\n } catch (e) {\n if ((e as Error).name !== 'AbortError') throw e\n }\n }, 200)\n }\n\n // ── Turbo frame navigation ──────────────────────────────────────────\n\n private navigateFrame (query: string) {\n if (!this.hasTurboListTarget) return\n const url = new URL(this.turboFrameUrlValue, window.location.href)\n if (query) url.searchParams.set('q', query)\n this.turboListTarget.setAttribute('src', url.toString())\n }\n\n private debouncedNavigateFrame (query: string) {\n if (this.searchTimer) clearTimeout(this.searchTimer)\n\n this.searchTimer = window.setTimeout(() => {\n this.navigateFrame(query)\n }, 200)\n }\n\n // ── Rendering ───────────────────────────────────────────────────────\n\n private renderItems (items: PaletteItem[]) {\n if (!this.hasListTarget) return\n\n this.listTarget.innerHTML = ''\n this.highlightedIndex = -1\n\n if (items.length === 0) {\n this.emptyTarget.hidden = false\n this.listTarget.hidden = true\n return\n }\n\n this.emptyTarget.hidden = true\n this.listTarget.hidden = false\n\n // Group items\n const groups = new Map<string, PaletteItem[]>()\n for (const item of items) {\n const group = item.group || ''\n if (!groups.has(group)) groups.set(group, [])\n groups.get(group)!.push(item) // eslint-disable-line @typescript-eslint/no-non-null-assertion\n }\n\n let index = 0\n for (const [groupName, groupItems] of groups) {\n if (groupName) {\n this.listTarget.appendChild(this.buildGroup(groupName))\n }\n\n for (const item of groupItems) {\n this.listTarget.appendChild(this.buildItem(item, index))\n index++\n }\n }\n\n // Highlight first item\n if (items.length > 0) {\n this.highlightedIndex = 0\n this.updateHighlight()\n }\n }\n\n private buildGroup (name: string): HTMLElement {\n const li = cloneTemplate(this.groupTemplateTarget)\n const h6 = li.querySelector('.midwest-label')\n if (h6) h6.textContent = name\n return li\n }\n\n private buildItem (item: PaletteItem, index: number): HTMLElement {\n const li = cloneTemplate(this.itemTemplateTarget)\n li.dataset.index = String(index)\n\n if (item.url) li.dataset.url = item.url\n if (item.action) li.dataset.paletteAction = item.action\n if (item.method) li.dataset.turboMethod = item.method\n if (item.confirm) li.dataset.turboConfirm = item.confirm\n\n // Icon\n const iconSpan = li.querySelector('.command-palette-item-icon') as HTMLElement\n if (item.icon) {\n iconSpan.innerHTML = this.getIconSvg(item.icon)\n iconSpan.hidden = false\n } else {\n iconSpan.remove()\n }\n\n // Label\n const label = li.querySelector('.command-palette-item-label') as Element\n label.textContent = item.label\n\n // Description\n const desc = li.querySelector('.command-palette-item-description') as HTMLElement\n if (item.description) {\n desc.textContent = item.description\n desc.hidden = false\n } else {\n desc.remove()\n }\n\n // Shortcut\n const shortcutSpan = li.querySelector('.command-palette-item-shortcut') as HTMLElement\n if (item.shortcut) {\n item.shortcut.split('+').forEach(key => {\n const kbd = document.createElement('kbd')\n kbd.className = 'midwest-kbd'\n kbd.textContent = key.trim()\n shortcutSpan.appendChild(kbd)\n })\n shortcutSpan.hidden = false\n } else {\n shortcutSpan.remove()\n }\n\n return li\n }\n\n // ── Selection ───────────────────────────────────────────────────────\n\n private selectItem (item: PaletteItem) {\n if (item.confirm && !window.confirm(item.confirm)) return\n\n this.close()\n\n if (item.url) {\n this.visit(item.url, item.method)\n return\n }\n\n if (item.action) {\n this.element.dispatchEvent(\n new CustomEvent('midwest-command-palette:action', {\n bubbles: true,\n detail: { action: item.action, item }\n })\n )\n }\n }\n\n private visit (url: string, method?: string) {\n if (method && method.toLowerCase() !== 'get') {\n // Non-GET methods: create a temporary link with data-turbo-method\n // and let Turbo handle the request\n const link = document.createElement('a')\n link.href = url\n link.dataset.turboMethod = method\n link.style.display = 'none'\n document.body.appendChild(link)\n link.click()\n link.remove()\n return\n }\n\n const turbo = (window as any).Turbo\n if (turbo?.visit) {\n turbo.visit(url)\n } else {\n window.location.href = url\n }\n }\n\n // ── Highlight ───────────────────────────────────────────────────────\n\n private get visibleItems (): PaletteItem[] {\n if (!this.hasListTarget) return []\n\n const items: PaletteItem[] = []\n const els = this.listTarget.querySelectorAll<HTMLElement>('.command-palette-item')\n for (const el of els) {\n items.push({\n label: el.querySelector('.command-palette-item-label')?.textContent || '',\n url: el.dataset.url,\n action: el.dataset.paletteAction,\n method: el.dataset.turboMethod,\n confirm: el.dataset.turboConfirm\n })\n }\n return items\n }\n\n private updateHighlight () {\n if (!this.hasListTarget) return\n\n const items = this.listTarget.querySelectorAll<HTMLElement>('.command-palette-item')\n items.forEach((el, i) => {\n el.setAttribute('aria-selected', String(i === this.highlightedIndex))\n })\n\n const highlighted = items[this.highlightedIndex]\n if (highlighted) {\n highlighted.scrollIntoView({ block: 'nearest' })\n this.inputTarget.setAttribute('aria-activedescendant', highlighted.id || '')\n }\n }\n\n // ── Hotkey ──────────────────────────────────────────────────────────\n\n private handleGlobalKeydown = (event: KeyboardEvent) => {\n if ((event.metaKey || event.ctrlKey) && event.key === this.hotkeyValue) {\n event.preventDefault()\n if (this.element.open) {\n this.close()\n } else {\n this.open()\n }\n }\n }\n\n private handleBackdropClick = (event: Event) => {\n if (event.target === this.element) this.close()\n }\n\n // ── Helpers ─────────────────────────────────────────────────────────\n\n private getIconSvg (name: string): string {\n const existing = document.querySelector(`.Midwest-Icon__Svg[aria-label=\"${name}\"]`)\n if (existing) return existing.outerHTML\n\n const allIcons = document.querySelectorAll('.Midwest-Icon__Svg')\n for (const icon of allIcons) {\n if (icon.getAttribute('aria-label')?.toLowerCase() === name.toLowerCase()) {\n return icon.outerHTML\n }\n }\n\n return ''\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"command_palette_component_controller.js","sources":["../../../../../../../app/components/midwest/command_palette_component/command_palette_component_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\nimport { cloneTemplate } from '../../../assets/javascript/midwest/template_helpers'\nimport { renderMarkdown } from '../../../assets/javascript/midwest/markdown'\n\ninterface ChatMessage {\n role: 'user' | 'assistant'\n content: string\n}\n\ninterface Directive {\n action?: string\n url?: string\n method?: string\n}\n\ninterface AgentEvent {\n type: 'tool' | 'directive' | 'error' | 'embed'\n label?: string\n icon?: string\n status?: string\n message?: string\n directive?: Directive\n srcdoc?: string\n title?: string\n height?: number\n}\n\ninterface SseData {\n choices?: { delta?: { content?: string } }[]\n midwest?: AgentEvent\n}\n\ninterface PaletteItem {\n label: string\n description?: string\n icon?: string\n url?: string\n action?: string\n group?: string\n shortcut?: string\n method?: string\n confirm?: string\n}\n\nexport default class CommandPalette extends Controller<HTMLDialogElement> {\n static targets = [\n 'input', 'list', 'empty', 'body', 'turboList', 'itemTemplate', 'groupTemplate',\n 'modes', 'chat', 'transcript', 'starters', 'messageTemplate', 'actionTemplate'\n ]\n\n static values = {\n hotkey: { type: String, default: 'k' },\n items: { type: Array, default: [] },\n src: { type: String, default: '' },\n turboFrameUrl: { type: String, default: '' },\n chatEnabled: { type: Boolean, default: false },\n chatMode: { type: String, default: 'proxy' },\n chatTrigger: { type: String, default: 'toggle' },\n chatAgentic: { type: Boolean, default: true },\n chatPlaceholder: { type: String, default: 'Ask AI…' },\n chatEndpoint: { type: String, default: '' },\n chatUrl: { type: String, default: '' },\n chatModel: { type: String, default: '' }\n }\n\n declare readonly inputTarget: HTMLInputElement\n declare readonly listTarget: HTMLElement\n declare readonly emptyTarget: HTMLElement\n declare readonly bodyTarget: HTMLElement\n declare readonly hasBodyTarget: boolean\n declare readonly turboListTarget: HTMLElement\n declare readonly hasTurboListTarget: boolean\n declare readonly hasListTarget: boolean\n declare readonly itemTemplateTarget: HTMLTemplateElement\n declare readonly groupTemplateTarget: HTMLTemplateElement\n declare readonly modesTarget: HTMLElement\n declare readonly hasModesTarget: boolean\n declare readonly chatTarget: HTMLElement\n declare readonly hasChatTarget: boolean\n declare readonly transcriptTarget: HTMLElement\n declare readonly hasTranscriptTarget: boolean\n declare readonly startersTarget: HTMLElement\n declare readonly hasStartersTarget: boolean\n declare readonly messageTemplateTarget: HTMLTemplateElement\n declare readonly actionTemplateTarget: HTMLTemplateElement\n declare readonly hasActionTemplateTarget: boolean\n declare readonly stopTarget: HTMLElement\n declare readonly hasStopTarget: boolean\n\n declare hotkeyValue: string\n declare itemsValue: PaletteItem[]\n declare srcValue: string\n declare turboFrameUrlValue: string\n declare chatEnabledValue: boolean\n declare chatModeValue: string\n declare chatTriggerValue: string\n declare chatAgenticValue: boolean\n declare chatPlaceholderValue: string\n declare chatEndpointValue: string\n declare chatUrlValue: string\n declare chatModelValue: string\n\n private highlightedIndex = -1\n private fetchAbort: AbortController | null = null\n private searchTimer: number | undefined\n private allItems: PaletteItem[] = []\n private mode: 'command' | 'chat' = 'command'\n private commandPlaceholder = ''\n private messages: ChatMessage[] = []\n private streamAbort: AbortController | null = null\n // While true, new/streamed content pins the transcript to the bottom. Turns\n // false when the user scrolls up to read history so we don't yank them down.\n private stickToBottom = true\n\n connect () {\n this.allItems = this.itemsValue\n this.commandPlaceholder = this.inputTarget.placeholder\n document.addEventListener('keydown', this.handleGlobalKeydown)\n this.element.addEventListener('click', this.handleBackdropClick)\n if (this.hasBodyTarget) this.bodyTarget.addEventListener('scroll', this.handleTranscriptScroll, { passive: true })\n\n // Only render client-side items when not in turbo-frame mode\n if (!this.turboFrameUrlValue) {\n this.renderItems(this.allItems)\n }\n }\n\n disconnect () {\n document.removeEventListener('keydown', this.handleGlobalKeydown)\n this.element.removeEventListener('click', this.handleBackdropClick)\n if (this.hasBodyTarget) this.bodyTarget.removeEventListener('scroll', this.handleTranscriptScroll)\n if (this.fetchAbort) this.fetchAbort.abort()\n if (this.streamAbort) this.streamAbort.abort()\n if (this.searchTimer) clearTimeout(this.searchTimer)\n }\n\n // ── Turbo frame lifecycle ───────────────────────────────────────────\n\n turboListTargetConnected (el: HTMLElement) {\n el.addEventListener('turbo:frame-load', this.onFrameLoad)\n }\n\n turboListTargetDisconnected (el: HTMLElement) {\n el.removeEventListener('turbo:frame-load', this.onFrameLoad)\n }\n\n private onFrameLoad = () => {\n if (!this.hasListTarget) return\n\n const items = this.listTarget.querySelectorAll<HTMLElement>('.command-palette-item')\n if (items.length > 0) {\n this.highlightedIndex = 0\n this.updateHighlight()\n this.emptyTarget.hidden = true\n if (this.hasListTarget) this.listTarget.hidden = false\n } else {\n this.emptyTarget.hidden = false\n if (this.hasListTarget) this.listTarget.hidden = true\n }\n }\n\n // ── Public actions ──────────────────────────────────────────────────\n\n open () {\n if (this.element.open) return\n this.element.showModal()\n this.inputTarget.value = ''\n this.highlightedIndex = -1\n\n // Chat resets to a fresh conversation in command mode on every open.\n if (this.chatEnabledValue) this.resetChat()\n\n if (this.turboFrameUrlValue) {\n this.navigateFrame('')\n } else {\n this.renderItems(this.allItems)\n }\n\n requestAnimationFrame(() => this.inputTarget.focus())\n }\n\n close () {\n if (!this.element.open) return\n this.element.close()\n }\n\n filter () {\n // In chat mode the input is the composer — typing must not filter commands.\n if (this.mode === 'chat') return\n\n const query = this.inputTarget.value.trim().toLowerCase()\n\n if (this.turboFrameUrlValue) {\n this.debouncedNavigateFrame(query)\n return\n }\n\n if (this.srcValue && query.length > 0) {\n this.fetchRemote(query)\n return\n }\n\n if (query.length === 0) {\n this.renderItems(this.allItems)\n return\n }\n\n const filtered = this.allItems.filter(item => {\n const haystack = `${item.label} ${item.description || ''} ${item.group || ''}`.toLowerCase()\n return haystack.includes(query)\n })\n\n this.renderItems(filtered)\n }\n\n navigate (event: KeyboardEvent) {\n if (this.mode === 'chat') {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault()\n this.send()\n } else if (event.key === 'Escape') {\n event.preventDefault()\n this.close()\n }\n return\n }\n\n // Tab from an empty query enters chat mode (toggle trigger only).\n if (\n event.key === 'Tab' && !event.shiftKey &&\n this.chatEnabledValue && this.chatTriggerValue === 'toggle' &&\n this.inputTarget.value.trim() === ''\n ) {\n event.preventDefault()\n this.setMode('chat')\n return\n }\n\n const items = this.visibleItems\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault()\n this.highlightedIndex = Math.min(this.highlightedIndex + 1, items.length - 1)\n this.updateHighlight()\n break\n case 'ArrowUp':\n event.preventDefault()\n this.highlightedIndex = Math.max(this.highlightedIndex - 1, 0)\n this.updateHighlight()\n break\n case 'Enter':\n event.preventDefault()\n if (this.highlightedIndex >= 0 && this.highlightedIndex < items.length) {\n this.selectItem(items[this.highlightedIndex])\n }\n break\n case 'Escape':\n event.preventDefault()\n this.close()\n break\n }\n }\n\n select (event: Event) {\n const el = (event.target as HTMLElement).closest<HTMLElement>('.command-palette-item')\n if (!el) return\n const index = parseInt(el.dataset.index || '-1', 10)\n const items = this.visibleItems\n if (index >= 0 && index < items.length) {\n this.selectItem(items[index])\n }\n }\n\n // ── Chat mode ───────────────────────────────────────────────────────\n\n switchMode (event: Event) {\n const mode = (event.currentTarget as HTMLElement).dataset.mode === 'chat' ? 'chat' : 'command'\n this.setMode(mode)\n if (mode === 'command') this.filter()\n this.inputTarget.focus()\n }\n\n useStarter (event: Event) {\n this.inputTarget.value = (event.currentTarget as HTMLElement).textContent?.trim() || ''\n this.send()\n }\n\n private resetChat () {\n if (this.streamAbort) this.streamAbort.abort()\n this.messages = []\n if (this.hasTranscriptTarget) this.transcriptTarget.innerHTML = ''\n if (this.hasStartersTarget) this.startersTarget.hidden = false\n this.stickToBottom = true\n this.setBusy(false)\n this.setMode('command')\n }\n\n private setMode (mode: 'command' | 'chat') {\n if (!this.chatEnabledValue) return\n this.mode = mode\n const chat = mode === 'chat'\n this.element.classList.toggle('chat-active', chat)\n\n if (this.hasModesTarget) {\n this.modesTarget.querySelectorAll<HTMLElement>('.command-palette-mode').forEach(el => {\n el.setAttribute('aria-pressed', String(el.dataset.mode === mode))\n })\n }\n\n if (this.hasChatTarget) this.chatTarget.hidden = !chat\n\n if (chat) {\n this.emptyTarget.hidden = true\n if (this.hasListTarget) this.listTarget.hidden = true\n if (this.hasTurboListTarget) this.turboListTarget.hidden = true\n this.inputTarget.placeholder = this.chatPlaceholderValue\n } else {\n this.inputTarget.placeholder = this.commandPlaceholder\n if (this.hasTurboListTarget) this.turboListTarget.hidden = false\n }\n }\n\n stop () {\n if (this.streamAbort) this.streamAbort.abort()\n }\n\n private send () {\n if (this.streamAbort) return // a reply is already streaming\n\n const text = this.inputTarget.value.trim()\n if (!text) return\n\n // Sending re-anchors to the bottom for the new exchange.\n this.stickToBottom = true\n this.appendMessage('user', text)\n this.messages.push({ role: 'user', content: text })\n this.inputTarget.value = ''\n if (this.hasStartersTarget) this.startersTarget.hidden = true\n\n void this.streamReply()\n }\n\n private async streamReply () {\n const message = this.appendMessage('assistant', '')\n const bubble = message.querySelector('.command-palette-message-bubble') as HTMLElement\n this.setBusy(true)\n this.streamAbort = new AbortController()\n\n let reply = ''\n try {\n const response = await fetch(this.chatRequestUrl(), {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Accept: 'text/event-stream' },\n body: JSON.stringify(this.chatRequestBody()),\n signal: this.streamAbort.signal\n })\n\n if (!response.ok || !response.body) throw new Error(`Chat request failed (${response.status})`)\n\n const reader = response.body.getReader()\n const decoder = new TextDecoder()\n let buffer = ''\n\n for (;;) {\n const { value, done } = await reader.read()\n if (done) break\n buffer += decoder.decode(value, { stream: true })\n\n const events = buffer.split('\\n\\n')\n buffer = events.pop() || ''\n\n for (const event of events) {\n const data = this.parseSseData(event)\n if (!data) continue\n\n const delta = data.choices?.[0]?.delta?.content\n if (delta) {\n reply += delta\n bubble.innerHTML = renderMarkdown(reply)\n this.scrollTranscript()\n } else if (data.midwest) {\n this.handleAgentEvent(data.midwest)\n }\n }\n }\n\n this.messages.push({ role: 'assistant', content: reply })\n } catch (error) {\n if ((error as Error).name === 'AbortError') {\n if (reply) this.messages.push({ role: 'assistant', content: reply })\n } else {\n message.classList.add('is-error')\n bubble.textContent = 'Something went wrong. Please try again.'\n }\n } finally {\n this.streamAbort = null\n this.setBusy(false)\n this.scrollTranscript()\n }\n }\n\n private parseSseData (event: string): SseData | null {\n const data = event\n .split('\\n')\n .filter(line => line.startsWith('data:'))\n .map(line => line.slice(5).trim())\n .join('')\n\n if (!data || data === '[DONE]') return null\n\n try {\n return JSON.parse(data) as SseData\n } catch {\n return null\n }\n }\n\n // Agentic events: the server streams a tool \"action row\", a live preview\n // (\"embed\"), and/or a client directive (navigate / run a palette command).\n // Directives reuse the same execution path as manual selection.\n private handleAgentEvent (event: AgentEvent) {\n if (event.type === 'tool') {\n this.appendActionRow(event)\n } else if (event.type === 'embed' && event.srcdoc) {\n this.appendEmbed(event)\n } else if (event.type === 'directive' && event.directive) {\n this.performDirective(event.directive)\n } else if (event.type === 'error') {\n this.renderStreamError(event.message)\n }\n }\n\n // A server-reported failure (e.g. provider billing/rate-limit error). Render\n // it into the current assistant bubble instead of failing silently.\n private renderStreamError (message?: string) {\n const last = this.currentAssistantMessage()\n if (!last) return\n\n last.classList.add('is-error')\n const bubble = last.querySelector('.command-palette-message-bubble') as HTMLElement | null\n if (bubble) bubble.textContent = message || 'Something went wrong. Please try again.'\n }\n\n // Action rows live in the current assistant message's card footer.\n private appendActionRow (event: AgentEvent) {\n if (!this.hasActionTemplateTarget) return\n\n const footer = this.currentActionFooter()\n if (!footer) return\n\n const action = cloneTemplate(this.actionTemplateTarget)\n // The action row is an \"MCP Request\" Badge; its value holds the tool label.\n const label = action.querySelector('.value')\n if (label) label.textContent = event.label || 'Action'\n\n footer.hidden = false\n footer.appendChild(action)\n this.scrollTranscript()\n }\n\n // A live preview streamed by an agentic tool (e.g. generate_iframe). The\n // server sends only the inner document; the client owns the <iframe> element\n // and hard-codes the sandbox (no allow-scripts) so injected markup is styled\n // but never executed — the markdown text path can't render HTML at all.\n private appendEmbed (event: AgentEvent) {\n const message = this.currentAssistantMessage()\n if (!message || !event.srcdoc) return\n\n const body = message.querySelector<HTMLElement>('.command-palette-message-body') || message\n\n const frame = document.createElement('iframe')\n frame.className = 'command-palette-embed'\n frame.setAttribute('sandbox', 'allow-same-origin')\n frame.setAttribute('loading', 'lazy')\n frame.title = event.title || 'Preview'\n frame.srcdoc = event.srcdoc\n if (event.height) frame.style.height = `${event.height}px`\n\n body.appendChild(frame)\n this.scrollTranscript()\n }\n\n private currentActionFooter (): HTMLElement | null {\n const last = this.currentAssistantMessage()\n return last ? last.querySelector<HTMLElement>('.command-palette-action-footer') : null\n }\n\n private currentAssistantMessage (): HTMLElement | null {\n const messages = this.transcriptTarget.querySelectorAll<HTMLElement>(\n '.command-palette-message.role-assistant'\n )\n return messages[messages.length - 1] || null\n }\n\n private performDirective (directive: Directive) {\n if (directive.url) {\n this.visit(directive.url, directive.method)\n } else if (directive.action) {\n this.element.dispatchEvent(\n new CustomEvent('midwest-command-palette:action', {\n bubbles: true,\n detail: { action: directive.action }\n })\n )\n }\n }\n\n private chatRequestUrl (): string {\n return this.chatModeValue === 'proxy' ? this.chatEndpointValue : this.chatUrlValue\n }\n\n private chatRequestBody (): Record<string, unknown> {\n const body: Record<string, unknown> = { messages: this.messages, stream: true }\n // In proxy mode the server owns the model; only direct mode sends it.\n if (this.chatModeValue !== 'proxy' && this.chatModelValue) body.model = this.chatModelValue\n // Expose the palette's commands as tools the model can invoke (proxy only).\n if (this.chatModeValue === 'proxy' && this.chatAgenticValue) {\n body.commands = this.allItems.map(item => ({\n label: item.label,\n description: item.description,\n url: item.url,\n action: item.action,\n method: item.method,\n icon: item.icon\n }))\n }\n return body\n }\n\n private setBusy (busy: boolean) {\n this.element.classList.toggle('chat-busy', busy)\n if (this.hasStopTarget) this.stopTarget.hidden = !busy\n // Hold the polite live region until the reply finishes so screen readers\n // announce the completed message instead of every streamed token.\n if (this.hasTranscriptTarget) this.transcriptTarget.setAttribute('aria-busy', String(busy))\n }\n\n // The body is the scrollable region; the transcript itself does not scroll.\n private scrollTranscript () {\n if (this.hasBodyTarget && this.stickToBottom) {\n this.bodyTarget.scrollTop = this.bodyTarget.scrollHeight\n }\n }\n\n // Track whether the user is anchored to the bottom. Once they scroll up to\n // read earlier messages we stop auto-scrolling; returning to the bottom\n // re-arms it so streamed text keeps the latest content on screen.\n private handleTranscriptScroll = () => {\n if (!this.hasBodyTarget) return\n const { scrollHeight, scrollTop, clientHeight } = this.bodyTarget\n this.stickToBottom = scrollHeight - scrollTop - clientHeight < 24\n }\n\n private appendMessage (role: 'user' | 'assistant', text: string): HTMLElement {\n const li = cloneTemplate(this.messageTemplateTarget)\n li.classList.add(`role-${role}`)\n if (role === 'user') li.classList.add('is-end') // user messages sit on the trailing side\n\n const roleEl = li.querySelector('.command-palette-message-role')\n if (roleEl) roleEl.textContent = role === 'user' ? 'You' : 'Assistant'\n\n const bubble = li.querySelector('.command-palette-message-bubble') as HTMLElement\n if (text) bubble.textContent = text\n\n this.transcriptTarget.appendChild(li)\n this.scrollTranscript()\n return li\n }\n\n // ── Remote search ───────────────────────────────────────────────────\n\n private fetchRemote (query: string) {\n if (this.fetchAbort) this.fetchAbort.abort()\n if (this.searchTimer) clearTimeout(this.searchTimer)\n\n this.searchTimer = window.setTimeout(async () => {\n this.fetchAbort = new AbortController()\n try {\n const url = new URL(this.srcValue, window.location.origin)\n url.searchParams.set('q', query)\n const response = await fetch(url.toString(), {\n headers: { Accept: 'application/json' },\n signal: this.fetchAbort.signal\n })\n if (response.ok) {\n const data: PaletteItem[] = await response.json()\n this.renderItems(data)\n }\n } catch (e) {\n if ((e as Error).name !== 'AbortError') throw e\n }\n }, 200)\n }\n\n // ── Turbo frame navigation ──────────────────────────────────────────\n\n private navigateFrame (query: string) {\n if (!this.hasTurboListTarget) return\n const url = new URL(this.turboFrameUrlValue, window.location.href)\n if (query) url.searchParams.set('q', query)\n this.turboListTarget.setAttribute('src', url.toString())\n }\n\n private debouncedNavigateFrame (query: string) {\n if (this.searchTimer) clearTimeout(this.searchTimer)\n\n this.searchTimer = window.setTimeout(() => {\n this.navigateFrame(query)\n }, 200)\n }\n\n // ── Rendering ───────────────────────────────────────────────────────\n\n private renderItems (items: PaletteItem[]) {\n if (!this.hasListTarget) return\n\n this.listTarget.innerHTML = ''\n this.highlightedIndex = -1\n\n if (items.length === 0) {\n this.emptyTarget.hidden = false\n this.listTarget.hidden = true\n return\n }\n\n this.emptyTarget.hidden = true\n this.listTarget.hidden = false\n\n // Group items\n const groups = new Map<string, PaletteItem[]>()\n for (const item of items) {\n const group = item.group || ''\n if (!groups.has(group)) groups.set(group, [])\n groups.get(group)!.push(item) // eslint-disable-line @typescript-eslint/no-non-null-assertion\n }\n\n let index = 0\n for (const [groupName, groupItems] of groups) {\n if (groupName) {\n this.listTarget.appendChild(this.buildGroup(groupName))\n }\n\n for (const item of groupItems) {\n this.listTarget.appendChild(this.buildItem(item, index))\n index++\n }\n }\n\n // Highlight first item\n if (items.length > 0) {\n this.highlightedIndex = 0\n this.updateHighlight()\n }\n }\n\n private buildGroup (name: string): HTMLElement {\n const li = cloneTemplate(this.groupTemplateTarget)\n const h6 = li.querySelector('.midwest-label')\n if (h6) h6.textContent = name\n return li\n }\n\n private buildItem (item: PaletteItem, index: number): HTMLElement {\n const li = cloneTemplate(this.itemTemplateTarget)\n li.dataset.index = String(index)\n\n if (item.url) li.dataset.url = item.url\n if (item.action) li.dataset.paletteAction = item.action\n if (item.method) li.dataset.turboMethod = item.method\n if (item.confirm) li.dataset.turboConfirm = item.confirm\n\n // Icon\n const iconSpan = li.querySelector('.command-palette-item-icon') as HTMLElement\n if (item.icon) {\n iconSpan.innerHTML = this.getIconSvg(item.icon)\n iconSpan.hidden = false\n } else {\n iconSpan.remove()\n }\n\n // Label\n const label = li.querySelector('.command-palette-item-label') as Element\n label.textContent = item.label\n\n // Description\n const desc = li.querySelector('.command-palette-item-description') as HTMLElement\n if (item.description) {\n desc.textContent = item.description\n desc.hidden = false\n } else {\n desc.remove()\n }\n\n // Shortcut\n const shortcutSpan = li.querySelector('.command-palette-item-shortcut') as HTMLElement\n if (item.shortcut) {\n item.shortcut.split('+').forEach(key => {\n const kbd = document.createElement('kbd')\n kbd.className = 'midwest-kbd'\n kbd.textContent = key.trim()\n shortcutSpan.appendChild(kbd)\n })\n shortcutSpan.hidden = false\n } else {\n shortcutSpan.remove()\n }\n\n return li\n }\n\n // ── Selection ───────────────────────────────────────────────────────\n\n private selectItem (item: PaletteItem) {\n if (item.confirm && !window.confirm(item.confirm)) return\n\n this.close()\n\n if (item.url) {\n this.visit(item.url, item.method)\n return\n }\n\n if (item.action) {\n this.element.dispatchEvent(\n new CustomEvent('midwest-command-palette:action', {\n bubbles: true,\n detail: { action: item.action, item }\n })\n )\n }\n }\n\n private visit (url: string, method?: string) {\n if (method && method.toLowerCase() !== 'get') {\n // Non-GET methods: create a temporary link with data-turbo-method\n // and let Turbo handle the request\n const link = document.createElement('a')\n link.href = url\n link.dataset.turboMethod = method\n link.style.display = 'none'\n document.body.appendChild(link)\n link.click()\n link.remove()\n return\n }\n\n const turbo = (window as any).Turbo\n if (turbo?.visit) {\n turbo.visit(url)\n } else {\n window.location.href = url\n }\n }\n\n // ── Highlight ───────────────────────────────────────────────────────\n\n private get visibleItems (): PaletteItem[] {\n if (!this.hasListTarget) return []\n\n const items: PaletteItem[] = []\n const els = this.listTarget.querySelectorAll<HTMLElement>('.command-palette-item')\n for (const el of els) {\n items.push({\n label: el.querySelector('.command-palette-item-label')?.textContent || '',\n url: el.dataset.url,\n action: el.dataset.paletteAction,\n method: el.dataset.turboMethod,\n confirm: el.dataset.turboConfirm\n })\n }\n return items\n }\n\n private updateHighlight () {\n if (!this.hasListTarget) return\n\n const items = this.listTarget.querySelectorAll<HTMLElement>('.command-palette-item')\n items.forEach((el, i) => {\n el.setAttribute('aria-selected', String(i === this.highlightedIndex))\n })\n\n const highlighted = items[this.highlightedIndex]\n if (highlighted) {\n highlighted.scrollIntoView({ block: 'nearest' })\n this.inputTarget.setAttribute('aria-activedescendant', highlighted.id || '')\n }\n }\n\n // ── Hotkey ──────────────────────────────────────────────────────────\n\n private handleGlobalKeydown = (event: KeyboardEvent) => {\n if ((event.metaKey || event.ctrlKey) && event.key === this.hotkeyValue) {\n event.preventDefault()\n if (this.element.open) {\n this.close()\n } else {\n this.open()\n }\n }\n }\n\n private handleBackdropClick = (event: Event) => {\n if (event.target === this.element) this.close()\n }\n\n // ── Helpers ─────────────────────────────────────────────────────────\n\n private getIconSvg (name: string): string {\n const existing = document.querySelector(`.Midwest-Icon__Svg[aria-label=\"${name}\"]`)\n if (existing) return existing.outerHTML\n\n const allIcons = document.querySelectorAll('.Midwest-Icon__Svg')\n for (const icon of allIcons) {\n if (icon.getAttribute('aria-label')?.toLowerCase() === name.toLowerCase()) {\n return icon.outerHTML\n }\n }\n\n return ''\n }\n}\n"],"names":[],"mappings":";;;;AA4CA,MAAqB,uBAAuB,UAA8B,CAAA;AAAA,EACxE,OAAO,OAAU,GAAA;AAAA,IACf,OAAA;AAAA,IAAS,MAAA;AAAA,IAAQ,OAAA;AAAA,IAAS,MAAA;AAAA,IAAQ,WAAA;AAAA,IAAa,cAAA;AAAA,IAAgB,eAAA;AAAA,IAC/D,OAAA;AAAA,IAAS,MAAA;AAAA,IAAQ,YAAA;AAAA,IAAc,UAAA;AAAA,IAAY,iBAAA;AAAA,IAAmB,gBAAA;AAAA,GAChE,CAAA;AAAA,EAEA,OAAO,MAAS,GAAA;AAAA,IACd,MAAQ,EAAA,EAAE,IAAM,EAAA,MAAA,EAAQ,SAAS,GAAI,EAAA;AAAA,IACrC,OAAO,EAAE,IAAA,EAAM,KAAO,EAAA,OAAA,EAAS,EAAG,EAAA;AAAA,IAClC,GAAK,EAAA,EAAE,IAAM,EAAA,MAAA,EAAQ,SAAS,EAAG,EAAA;AAAA,IACjC,aAAe,EAAA,EAAE,IAAM,EAAA,MAAA,EAAQ,SAAS,EAAG,EAAA;AAAA,IAC3C,WAAa,EAAA,EAAE,IAAM,EAAA,OAAA,EAAS,SAAS,KAAM,EAAA;AAAA,IAC7C,QAAU,EAAA,EAAE,IAAM,EAAA,MAAA,EAAQ,SAAS,OAAQ,EAAA;AAAA,IAC3C,WAAa,EAAA,EAAE,IAAM,EAAA,MAAA,EAAQ,SAAS,QAAS,EAAA;AAAA,IAC/C,WAAa,EAAA,EAAE,IAAM,EAAA,OAAA,EAAS,SAAS,IAAK,EAAA;AAAA,IAC5C,eAAiB,EAAA,EAAE,IAAM,EAAA,MAAA,EAAQ,SAAS,cAAU,EAAA;AAAA,IACpD,YAAc,EAAA,EAAE,IAAM,EAAA,MAAA,EAAQ,SAAS,EAAG,EAAA;AAAA,IAC1C,OAAS,EAAA,EAAE,IAAM,EAAA,MAAA,EAAQ,SAAS,EAAG,EAAA;AAAA,IACrC,SAAW,EAAA,EAAE,IAAM,EAAA,MAAA,EAAQ,SAAS,EAAG,EAAA;AAAA,GACzC,CAAA;AAAA,EAuCQ,gBAAmB,GAAA,CAAA,CAAA,CAAA;AAAA,EACnB,UAAqC,GAAA,IAAA,CAAA;AAAA,EACrC,WAAA,CAAA;AAAA,EACA,WAA0B,EAAC,CAAA;AAAA,EAC3B,IAA2B,GAAA,SAAA,CAAA;AAAA,EAC3B,kBAAqB,GAAA,EAAA,CAAA;AAAA,EACrB,WAA0B,EAAC,CAAA;AAAA,EAC3B,WAAsC,GAAA,IAAA,CAAA;AAAA;AAAA;AAAA,EAGtC,aAAgB,GAAA,IAAA,CAAA;AAAA,EAExB,OAAW,GAAA;AACT,IAAA,IAAA,CAAK,WAAW,IAAK,CAAA,UAAA,CAAA;AACrB,IAAK,IAAA,CAAA,kBAAA,GAAqB,KAAK,WAAY,CAAA,WAAA,CAAA;AAC3C,IAAS,QAAA,CAAA,gBAAA,CAAiB,SAAW,EAAA,IAAA,CAAK,mBAAmB,CAAA,CAAA;AAC7D,IAAA,IAAA,CAAK,OAAQ,CAAA,gBAAA,CAAiB,OAAS,EAAA,IAAA,CAAK,mBAAmB,CAAA,CAAA;AAC/D,IAAA,IAAI,IAAK,CAAA,aAAA;AAAe,MAAK,IAAA,CAAA,UAAA,CAAW,iBAAiB,QAAU,EAAA,IAAA,CAAK,wBAAwB,EAAE,OAAA,EAAS,MAAM,CAAA,CAAA;AAGjH,IAAI,IAAA,CAAC,KAAK,kBAAoB,EAAA;AAC5B,MAAK,IAAA,CAAA,WAAA,CAAY,KAAK,QAAQ,CAAA,CAAA;AAAA,KAChC;AAAA,GACF;AAAA,EAEA,UAAc,GAAA;AACZ,IAAS,QAAA,CAAA,mBAAA,CAAoB,SAAW,EAAA,IAAA,CAAK,mBAAmB,CAAA,CAAA;AAChE,IAAA,IAAA,CAAK,OAAQ,CAAA,mBAAA,CAAoB,OAAS,EAAA,IAAA,CAAK,mBAAmB,CAAA,CAAA;AAClE,IAAA,IAAI,IAAK,CAAA,aAAA;AAAe,MAAA,IAAA,CAAK,UAAW,CAAA,mBAAA,CAAoB,QAAU,EAAA,IAAA,CAAK,sBAAsB,CAAA,CAAA;AACjG,IAAA,IAAI,IAAK,CAAA,UAAA;AAAY,MAAA,IAAA,CAAK,WAAW,KAAM,EAAA,CAAA;AAC3C,IAAA,IAAI,IAAK,CAAA,WAAA;AAAa,MAAA,IAAA,CAAK,YAAY,KAAM,EAAA,CAAA;AAC7C,IAAA,IAAI,IAAK,CAAA,WAAA;AAAa,MAAA,YAAA,CAAa,KAAK,WAAW,CAAA,CAAA;AAAA,GACrD;AAAA;AAAA,EAIA,yBAA0B,EAAiB,EAAA;AACzC,IAAG,EAAA,CAAA,gBAAA,CAAiB,kBAAoB,EAAA,IAAA,CAAK,WAAW,CAAA,CAAA;AAAA,GAC1D;AAAA,EAEA,4BAA6B,EAAiB,EAAA;AAC5C,IAAG,EAAA,CAAA,mBAAA,CAAoB,kBAAoB,EAAA,IAAA,CAAK,WAAW,CAAA,CAAA;AAAA,GAC7D;AAAA,EAEQ,cAAc,MAAM;AAC1B,IAAA,IAAI,CAAC,IAAK,CAAA,aAAA;AAAe,MAAA,OAAA;AAEzB,IAAA,MAAM,KAAQ,GAAA,IAAA,CAAK,UAAW,CAAA,gBAAA,CAA8B,uBAAuB,CAAA,CAAA;AACnF,IAAI,IAAA,KAAA,CAAM,SAAS,CAAG,EAAA;AACpB,MAAA,IAAA,CAAK,gBAAmB,GAAA,CAAA,CAAA;AACxB,MAAA,IAAA,CAAK,eAAgB,EAAA,CAAA;AACrB,MAAA,IAAA,CAAK,YAAY,MAAS,GAAA,IAAA,CAAA;AAC1B,MAAA,IAAI,IAAK,CAAA,aAAA;AAAe,QAAA,IAAA,CAAK,WAAW,MAAS,GAAA,KAAA,CAAA;AAAA,KAC5C,MAAA;AACL,MAAA,IAAA,CAAK,YAAY,MAAS,GAAA,KAAA,CAAA;AAC1B,MAAA,IAAI,IAAK,CAAA,aAAA;AAAe,QAAA,IAAA,CAAK,WAAW,MAAS,GAAA,IAAA,CAAA;AAAA,KACnD;AAAA,GACF,CAAA;AAAA;AAAA,EAIA,IAAQ,GAAA;AACN,IAAA,IAAI,KAAK,OAAQ,CAAA,IAAA;AAAM,MAAA,OAAA;AACvB,IAAA,IAAA,CAAK,QAAQ,SAAU,EAAA,CAAA;AACvB,IAAA,IAAA,CAAK,YAAY,KAAQ,GAAA,EAAA,CAAA;AACzB,IAAA,IAAA,CAAK,gBAAmB,GAAA,CAAA,CAAA,CAAA;AAGxB,IAAA,IAAI,IAAK,CAAA,gBAAA;AAAkB,MAAA,IAAA,CAAK,SAAU,EAAA,CAAA;AAE1C,IAAA,IAAI,KAAK,kBAAoB,EAAA;AAC3B,MAAA,IAAA,CAAK,cAAc,EAAE,CAAA,CAAA;AAAA,KAChB,MAAA;AACL,MAAK,IAAA,CAAA,WAAA,CAAY,KAAK,QAAQ,CAAA,CAAA;AAAA,KAChC;AAEA,IAAA,qBAAA,CAAsB,MAAM,IAAA,CAAK,WAAY,CAAA,KAAA,EAAO,CAAA,CAAA;AAAA,GACtD;AAAA,EAEA,KAAS,GAAA;AACP,IAAI,IAAA,CAAC,KAAK,OAAQ,CAAA,IAAA;AAAM,MAAA,OAAA;AACxB,IAAA,IAAA,CAAK,QAAQ,KAAM,EAAA,CAAA;AAAA,GACrB;AAAA,EAEA,MAAU,GAAA;AAER,IAAA,IAAI,KAAK,IAAS,KAAA,MAAA;AAAQ,MAAA,OAAA;AAE1B,IAAA,MAAM,QAAQ,IAAK,CAAA,WAAA,CAAY,KAAM,CAAA,IAAA,GAAO,WAAY,EAAA,CAAA;AAExD,IAAA,IAAI,KAAK,kBAAoB,EAAA;AAC3B,MAAA,IAAA,CAAK,uBAAuB,KAAK,CAAA,CAAA;AACjC,MAAA,OAAA;AAAA,KACF;AAEA,IAAA,IAAI,IAAK,CAAA,QAAA,IAAY,KAAM,CAAA,MAAA,GAAS,CAAG,EAAA;AACrC,MAAA,IAAA,CAAK,YAAY,KAAK,CAAA,CAAA;AACtB,MAAA,OAAA;AAAA,KACF;AAEA,IAAI,IAAA,KAAA,CAAM,WAAW,CAAG,EAAA;AACtB,MAAK,IAAA,CAAA,WAAA,CAAY,KAAK,QAAQ,CAAA,CAAA;AAC9B,MAAA,OAAA;AAAA,KACF;AAEA,IAAA,MAAM,QAAW,GAAA,IAAA,CAAK,QAAS,CAAA,MAAA,CAAO,CAAQ,IAAA,KAAA;AAC5C,MAAM,MAAA,QAAA,GAAW,CAAG,EAAA,IAAA,CAAK,KAAS,CAAA,CAAA,EAAA,IAAA,CAAK,eAAe,EAAM,CAAA,CAAA,EAAA,IAAA,CAAK,KAAS,IAAA,EAAA,CAAA,CAAA,CAAK,WAAY,EAAA,CAAA;AAC3F,MAAO,OAAA,QAAA,CAAS,SAAS,KAAK,CAAA,CAAA;AAAA,KAC/B,CAAA,CAAA;AAED,IAAA,IAAA,CAAK,YAAY,QAAQ,CAAA,CAAA;AAAA,GAC3B;AAAA,EAEA,SAAU,KAAsB,EAAA;AAC9B,IAAI,IAAA,IAAA,CAAK,SAAS,MAAQ,EAAA;AACxB,MAAA,IAAI,KAAM,CAAA,GAAA,KAAQ,OAAW,IAAA,CAAC,MAAM,QAAU,EAAA;AAC5C,QAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AACrB,QAAA,IAAA,CAAK,IAAK,EAAA,CAAA;AAAA,OACZ,MAAA,IAAW,KAAM,CAAA,GAAA,KAAQ,QAAU,EAAA;AACjC,QAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AACrB,QAAA,IAAA,CAAK,KAAM,EAAA,CAAA;AAAA,OACb;AACA,MAAA,OAAA;AAAA,KACF;AAGA,IAAA,IACE,MAAM,GAAQ,KAAA,KAAA,IAAS,CAAC,KAAA,CAAM,YAC9B,IAAK,CAAA,gBAAA,IAAoB,IAAK,CAAA,gBAAA,KAAqB,YACnD,IAAK,CAAA,WAAA,CAAY,KAAM,CAAA,IAAA,OAAW,EAClC,EAAA;AACA,MAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AACrB,MAAA,IAAA,CAAK,QAAQ,MAAM,CAAA,CAAA;AACnB,MAAA,OAAA;AAAA,KACF;AAEA,IAAA,MAAM,QAAQ,IAAK,CAAA,YAAA,CAAA;AAEnB,IAAA,QAAQ,MAAM,GAAK;AAAA,MACjB,KAAK,WAAA;AACH,QAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AACrB,QAAK,IAAA,CAAA,gBAAA,GAAmB,KAAK,GAAI,CAAA,IAAA,CAAK,mBAAmB,CAAG,EAAA,KAAA,CAAM,SAAS,CAAC,CAAA,CAAA;AAC5E,QAAA,IAAA,CAAK,eAAgB,EAAA,CAAA;AACrB,QAAA,MAAA;AAAA,MACF,KAAK,SAAA;AACH,QAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AACrB,QAAA,IAAA,CAAK,mBAAmB,IAAK,CAAA,GAAA,CAAI,IAAK,CAAA,gBAAA,GAAmB,GAAG,CAAC,CAAA,CAAA;AAC7D,QAAA,IAAA,CAAK,eAAgB,EAAA,CAAA;AACrB,QAAA,MAAA;AAAA,MACF,KAAK,OAAA;AACH,QAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AACrB,QAAA,IAAI,KAAK,gBAAoB,IAAA,CAAA,IAAK,IAAK,CAAA,gBAAA,GAAmB,MAAM,MAAQ,EAAA;AACtE,UAAA,IAAA,CAAK,UAAW,CAAA,KAAA,CAAM,IAAK,CAAA,gBAAgB,CAAC,CAAA,CAAA;AAAA,SAC9C;AACA,QAAA,MAAA;AAAA,MACF,KAAK,QAAA;AACH,QAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AACrB,QAAA,IAAA,CAAK,KAAM,EAAA,CAAA;AACX,QAAA,MAAA;AAAA,KACJ;AAAA,GACF;AAAA,EAEA,OAAQ,KAAc,EAAA;AACpB,IAAA,MAAM,EAAM,GAAA,KAAA,CAAM,MAAuB,CAAA,OAAA,CAAqB,uBAAuB,CAAA,CAAA;AACrF,IAAA,IAAI,CAAC,EAAA;AAAI,MAAA,OAAA;AACT,IAAA,MAAM,QAAQ,QAAS,CAAA,EAAA,CAAG,OAAQ,CAAA,KAAA,IAAS,MAAM,EAAE,CAAA,CAAA;AACnD,IAAA,MAAM,QAAQ,IAAK,CAAA,YAAA,CAAA;AACnB,IAAA,IAAI,KAAS,IAAA,CAAA,IAAK,KAAQ,GAAA,KAAA,CAAM,MAAQ,EAAA;AACtC,MAAK,IAAA,CAAA,UAAA,CAAW,KAAM,CAAA,KAAK,CAAC,CAAA,CAAA;AAAA,KAC9B;AAAA,GACF;AAAA;AAAA,EAIA,WAAY,KAAc,EAAA;AACxB,IAAA,MAAM,OAAQ,KAAM,CAAA,aAAA,CAA8B,OAAQ,CAAA,IAAA,KAAS,SAAS,MAAS,GAAA,SAAA,CAAA;AACrF,IAAA,IAAA,CAAK,QAAQ,IAAI,CAAA,CAAA;AACjB,IAAA,IAAI,IAAS,KAAA,SAAA;AAAW,MAAA,IAAA,CAAK,MAAO,EAAA,CAAA;AACpC,IAAA,IAAA,CAAK,YAAY,KAAM,EAAA,CAAA;AAAA,GACzB;AAAA,EAEA,WAAY,KAAc,EAAA;AACxB,IAAA,IAAA,CAAK,YAAY,KAAS,GAAA,KAAA,CAAM,aAA8B,CAAA,WAAA,EAAa,MAAU,IAAA,EAAA,CAAA;AACrF,IAAA,IAAA,CAAK,IAAK,EAAA,CAAA;AAAA,GACZ;AAAA,EAEQ,SAAa,GAAA;AACnB,IAAA,IAAI,IAAK,CAAA,WAAA;AAAa,MAAA,IAAA,CAAK,YAAY,KAAM,EAAA,CAAA;AAC7C,IAAA,IAAA,CAAK,WAAW,EAAC,CAAA;AACjB,IAAA,IAAI,IAAK,CAAA,mBAAA;AAAqB,MAAA,IAAA,CAAK,iBAAiB,SAAY,GAAA,EAAA,CAAA;AAChE,IAAA,IAAI,IAAK,CAAA,iBAAA;AAAmB,MAAA,IAAA,CAAK,eAAe,MAAS,GAAA,KAAA,CAAA;AACzD,IAAA,IAAA,CAAK,aAAgB,GAAA,IAAA,CAAA;AACrB,IAAA,IAAA,CAAK,QAAQ,KAAK,CAAA,CAAA;AAClB,IAAA,IAAA,CAAK,QAAQ,SAAS,CAAA,CAAA;AAAA,GACxB;AAAA,EAEQ,QAAS,IAA0B,EAAA;AACzC,IAAA,IAAI,CAAC,IAAK,CAAA,gBAAA;AAAkB,MAAA,OAAA;AAC5B,IAAA,IAAA,CAAK,IAAO,GAAA,IAAA,CAAA;AACZ,IAAA,MAAM,OAAO,IAAS,KAAA,MAAA,CAAA;AACtB,IAAA,IAAA,CAAK,OAAQ,CAAA,SAAA,CAAU,MAAO,CAAA,aAAA,EAAe,IAAI,CAAA,CAAA;AAEjD,IAAA,IAAI,KAAK,cAAgB,EAAA;AACvB,MAAA,IAAA,CAAK,WAAY,CAAA,gBAAA,CAA8B,uBAAuB,CAAA,CAAE,QAAQ,CAAM,EAAA,KAAA;AACpF,QAAA,EAAA,CAAG,aAAa,cAAgB,EAAA,MAAA,CAAO,GAAG,OAAQ,CAAA,IAAA,KAAS,IAAI,CAAC,CAAA,CAAA;AAAA,OACjE,CAAA,CAAA;AAAA,KACH;AAEA,IAAA,IAAI,IAAK,CAAA,aAAA;AAAe,MAAK,IAAA,CAAA,UAAA,CAAW,SAAS,CAAC,IAAA,CAAA;AAElD,IAAA,IAAI,IAAM,EAAA;AACR,MAAA,IAAA,CAAK,YAAY,MAAS,GAAA,IAAA,CAAA;AAC1B,MAAA,IAAI,IAAK,CAAA,aAAA;AAAe,QAAA,IAAA,CAAK,WAAW,MAAS,GAAA,IAAA,CAAA;AACjD,MAAA,IAAI,IAAK,CAAA,kBAAA;AAAoB,QAAA,IAAA,CAAK,gBAAgB,MAAS,GAAA,IAAA,CAAA;AAC3D,MAAK,IAAA,CAAA,WAAA,CAAY,cAAc,IAAK,CAAA,oBAAA,CAAA;AAAA,KAC/B,MAAA;AACL,MAAK,IAAA,CAAA,WAAA,CAAY,cAAc,IAAK,CAAA,kBAAA,CAAA;AACpC,MAAA,IAAI,IAAK,CAAA,kBAAA;AAAoB,QAAA,IAAA,CAAK,gBAAgB,MAAS,GAAA,KAAA,CAAA;AAAA,KAC7D;AAAA,GACF;AAAA,EAEA,IAAQ,GAAA;AACN,IAAA,IAAI,IAAK,CAAA,WAAA;AAAa,MAAA,IAAA,CAAK,YAAY,KAAM,EAAA,CAAA;AAAA,GAC/C;AAAA,EAEQ,IAAQ,GAAA;AACd,IAAA,IAAI,IAAK,CAAA,WAAA;AAAa,MAAA,OAAA;AAEtB,IAAA,MAAM,IAAO,GAAA,IAAA,CAAK,WAAY,CAAA,KAAA,CAAM,IAAK,EAAA,CAAA;AACzC,IAAA,IAAI,CAAC,IAAA;AAAM,MAAA,OAAA;AAGX,IAAA,IAAA,CAAK,aAAgB,GAAA,IAAA,CAAA;AACrB,IAAK,IAAA,CAAA,aAAA,CAAc,QAAQ,IAAI,CAAA,CAAA;AAC/B,IAAA,IAAA,CAAK,SAAS,IAAK,CAAA,EAAE,MAAM,MAAQ,EAAA,OAAA,EAAS,MAAM,CAAA,CAAA;AAClD,IAAA,IAAA,CAAK,YAAY,KAAQ,GAAA,EAAA,CAAA;AACzB,IAAA,IAAI,IAAK,CAAA,iBAAA;AAAmB,MAAA,IAAA,CAAK,eAAe,MAAS,GAAA,IAAA,CAAA;AAEzD,IAAA,KAAK,KAAK,WAAY,EAAA,CAAA;AAAA,GACxB;AAAA,EAEA,MAAc,WAAe,GAAA;AAC3B,IAAA,MAAM,OAAU,GAAA,IAAA,CAAK,aAAc,CAAA,WAAA,EAAa,EAAE,CAAA,CAAA;AAClD,IAAM,MAAA,MAAA,GAAS,OAAQ,CAAA,aAAA,CAAc,iCAAiC,CAAA,CAAA;AACtE,IAAA,IAAA,CAAK,QAAQ,IAAI,CAAA,CAAA;AACjB,IAAK,IAAA,CAAA,WAAA,GAAc,IAAI,eAAgB,EAAA,CAAA;AAEvC,IAAA,IAAI,KAAQ,GAAA,EAAA,CAAA;AACZ,IAAI,IAAA;AACF,MAAA,MAAM,QAAW,GAAA,MAAM,KAAM,CAAA,IAAA,CAAK,gBAAkB,EAAA;AAAA,QAClD,MAAQ,EAAA,MAAA;AAAA,QACR,OAAS,EAAA,EAAE,cAAgB,EAAA,kBAAA,EAAoB,QAAQ,mBAAoB,EAAA;AAAA,QAC3E,IAAM,EAAA,IAAA,CAAK,SAAU,CAAA,IAAA,CAAK,iBAAiB,CAAA;AAAA,QAC3C,MAAA,EAAQ,KAAK,WAAY,CAAA,MAAA;AAAA,OAC1B,CAAA,CAAA;AAED,MAAA,IAAI,CAAC,QAAA,CAAS,EAAM,IAAA,CAAC,QAAS,CAAA,IAAA;AAAM,QAAA,MAAM,IAAI,KAAA,CAAM,CAAwB,qBAAA,EAAA,QAAA,CAAS,MAAS,CAAA,CAAA,CAAA,CAAA,CAAA;AAE9F,MAAM,MAAA,MAAA,GAAS,QAAS,CAAA,IAAA,CAAK,SAAU,EAAA,CAAA;AACvC,MAAM,MAAA,OAAA,GAAU,IAAI,WAAY,EAAA,CAAA;AAChC,MAAA,IAAI,MAAS,GAAA,EAAA,CAAA;AAEb,MAAS,WAAA;AACP,QAAA,MAAM,EAAE,KAAO,EAAA,IAAA,EAAS,GAAA,MAAM,OAAO,IAAK,EAAA,CAAA;AAC1C,QAAI,IAAA,IAAA;AAAM,UAAA,MAAA;AACV,QAAA,MAAA,IAAU,QAAQ,MAAO,CAAA,KAAA,EAAO,EAAE,MAAA,EAAQ,MAAM,CAAA,CAAA;AAEhD,QAAM,MAAA,MAAA,GAAS,MAAO,CAAA,KAAA,CAAM,MAAM,CAAA,CAAA;AAClC,QAAS,MAAA,GAAA,MAAA,CAAO,KAAS,IAAA,EAAA,CAAA;AAEzB,QAAA,KAAA,MAAW,SAAS,MAAQ,EAAA;AAC1B,UAAM,MAAA,IAAA,GAAO,IAAK,CAAA,YAAA,CAAa,KAAK,CAAA,CAAA;AACpC,UAAA,IAAI,CAAC,IAAA;AAAM,YAAA,SAAA;AAEX,UAAA,MAAM,KAAQ,GAAA,IAAA,CAAK,OAAU,GAAA,CAAC,GAAG,KAAO,EAAA,OAAA,CAAA;AACxC,UAAA,IAAI,KAAO,EAAA;AACT,YAAS,KAAA,IAAA,KAAA,CAAA;AACT,YAAO,MAAA,CAAA,SAAA,GAAY,eAAe,KAAK,CAAA,CAAA;AACvC,YAAA,IAAA,CAAK,gBAAiB,EAAA,CAAA;AAAA,WACxB,MAAA,IAAW,KAAK,OAAS,EAAA;AACvB,YAAK,IAAA,CAAA,gBAAA,CAAiB,KAAK,OAAO,CAAA,CAAA;AAAA,WACpC;AAAA,SACF;AAAA,OACF;AAEA,MAAA,IAAA,CAAK,SAAS,IAAK,CAAA,EAAE,MAAM,WAAa,EAAA,OAAA,EAAS,OAAO,CAAA,CAAA;AAAA,aACjD,KAAP,EAAA;AACA,MAAK,IAAA,KAAA,CAAgB,SAAS,YAAc,EAAA;AAC1C,QAAI,IAAA,KAAA;AAAO,UAAA,IAAA,CAAK,SAAS,IAAK,CAAA,EAAE,MAAM,WAAa,EAAA,OAAA,EAAS,OAAO,CAAA,CAAA;AAAA,OAC9D,MAAA;AACL,QAAQ,OAAA,CAAA,SAAA,CAAU,IAAI,UAAU,CAAA,CAAA;AAChC,QAAA,MAAA,CAAO,WAAc,GAAA,yCAAA,CAAA;AAAA,OACvB;AAAA,KACA,SAAA;AACA,MAAA,IAAA,CAAK,WAAc,GAAA,IAAA,CAAA;AACnB,MAAA,IAAA,CAAK,QAAQ,KAAK,CAAA,CAAA;AAClB,MAAA,IAAA,CAAK,gBAAiB,EAAA,CAAA;AAAA,KACxB;AAAA,GACF;AAAA,EAEQ,aAAc,KAA+B,EAAA;AACnD,IAAM,MAAA,IAAA,GAAO,MACV,KAAM,CAAA,IAAI,EACV,MAAO,CAAA,CAAA,IAAA,KAAQ,IAAK,CAAA,UAAA,CAAW,OAAO,CAAC,EACvC,GAAI,CAAA,CAAA,IAAA,KAAQ,KAAK,KAAM,CAAA,CAAC,EAAE,IAAK,EAAC,CAChC,CAAA,IAAA,CAAK,EAAE,CAAA,CAAA;AAEV,IAAI,IAAA,CAAC,QAAQ,IAAS,KAAA,QAAA;AAAU,MAAO,OAAA,IAAA,CAAA;AAEvC,IAAI,IAAA;AACF,MAAO,OAAA,IAAA,CAAK,MAAM,IAAI,CAAA,CAAA;AAAA,KACtB,CAAA,MAAA;AACA,MAAO,OAAA,IAAA,CAAA;AAAA,KACT;AAAA,GACF;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAkB,KAAmB,EAAA;AAC3C,IAAI,IAAA,KAAA,CAAM,SAAS,MAAQ,EAAA;AACzB,MAAA,IAAA,CAAK,gBAAgB,KAAK,CAAA,CAAA;AAAA,KACjB,MAAA,IAAA,KAAA,CAAM,IAAS,KAAA,OAAA,IAAW,MAAM,MAAQ,EAAA;AACjD,MAAA,IAAA,CAAK,YAAY,KAAK,CAAA,CAAA;AAAA,KACb,MAAA,IAAA,KAAA,CAAM,IAAS,KAAA,WAAA,IAAe,MAAM,SAAW,EAAA;AACxD,MAAK,IAAA,CAAA,gBAAA,CAAiB,MAAM,SAAS,CAAA,CAAA;AAAA,KACvC,MAAA,IAAW,KAAM,CAAA,IAAA,KAAS,OAAS,EAAA;AACjC,MAAK,IAAA,CAAA,iBAAA,CAAkB,MAAM,OAAO,CAAA,CAAA;AAAA,KACtC;AAAA,GACF;AAAA;AAAA;AAAA,EAIQ,kBAAmB,OAAkB,EAAA;AAC3C,IAAM,MAAA,IAAA,GAAO,KAAK,uBAAwB,EAAA,CAAA;AAC1C,IAAA,IAAI,CAAC,IAAA;AAAM,MAAA,OAAA;AAEX,IAAK,IAAA,CAAA,SAAA,CAAU,IAAI,UAAU,CAAA,CAAA;AAC7B,IAAM,MAAA,MAAA,GAAS,IAAK,CAAA,aAAA,CAAc,iCAAiC,CAAA,CAAA;AACnE,IAAI,IAAA,MAAA;AAAQ,MAAA,MAAA,CAAO,cAAc,OAAW,IAAA,yCAAA,CAAA;AAAA,GAC9C;AAAA;AAAA,EAGQ,gBAAiB,KAAmB,EAAA;AAC1C,IAAA,IAAI,CAAC,IAAK,CAAA,uBAAA;AAAyB,MAAA,OAAA;AAEnC,IAAM,MAAA,MAAA,GAAS,KAAK,mBAAoB,EAAA,CAAA;AACxC,IAAA,IAAI,CAAC,MAAA;AAAQ,MAAA,OAAA;AAEb,IAAM,MAAA,MAAA,GAAS,aAAc,CAAA,IAAA,CAAK,oBAAoB,CAAA,CAAA;AAEtD,IAAM,MAAA,KAAA,GAAQ,MAAO,CAAA,aAAA,CAAc,QAAQ,CAAA,CAAA;AAC3C,IAAI,IAAA,KAAA;AAAO,MAAM,KAAA,CAAA,WAAA,GAAc,MAAM,KAAS,IAAA,QAAA,CAAA;AAE9C,IAAA,MAAA,CAAO,MAAS,GAAA,KAAA,CAAA;AAChB,IAAA,MAAA,CAAO,YAAY,MAAM,CAAA,CAAA;AACzB,IAAA,IAAA,CAAK,gBAAiB,EAAA,CAAA;AAAA,GACxB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,YAAa,KAAmB,EAAA;AACtC,IAAM,MAAA,OAAA,GAAU,KAAK,uBAAwB,EAAA,CAAA;AAC7C,IAAI,IAAA,CAAC,OAAW,IAAA,CAAC,KAAM,CAAA,MAAA;AAAQ,MAAA,OAAA;AAE/B,IAAA,MAAM,IAAO,GAAA,OAAA,CAAQ,aAA2B,CAAA,+BAA+B,CAAK,IAAA,OAAA,CAAA;AAEpF,IAAM,MAAA,KAAA,GAAQ,QAAS,CAAA,aAAA,CAAc,QAAQ,CAAA,CAAA;AAC7C,IAAA,KAAA,CAAM,SAAY,GAAA,uBAAA,CAAA;AAClB,IAAM,KAAA,CAAA,YAAA,CAAa,WAAW,mBAAmB,CAAA,CAAA;AACjD,IAAM,KAAA,CAAA,YAAA,CAAa,WAAW,MAAM,CAAA,CAAA;AACpC,IAAM,KAAA,CAAA,KAAA,GAAQ,MAAM,KAAS,IAAA,SAAA,CAAA;AAC7B,IAAA,KAAA,CAAM,SAAS,KAAM,CAAA,MAAA,CAAA;AACrB,IAAA,IAAI,KAAM,CAAA,MAAA;AAAQ,MAAM,KAAA,CAAA,KAAA,CAAM,MAAS,GAAA,CAAA,EAAG,KAAM,CAAA,MAAA,CAAA,EAAA,CAAA,CAAA;AAEhD,IAAA,IAAA,CAAK,YAAY,KAAK,CAAA,CAAA;AACtB,IAAA,IAAA,CAAK,gBAAiB,EAAA,CAAA;AAAA,GACxB;AAAA,EAEQ,mBAA2C,GAAA;AACjD,IAAM,MAAA,IAAA,GAAO,KAAK,uBAAwB,EAAA,CAAA;AAC1C,IAAA,OAAO,IAAO,GAAA,IAAA,CAAK,aAA2B,CAAA,gCAAgC,CAAI,GAAA,IAAA,CAAA;AAAA,GACpF;AAAA,EAEQ,uBAA+C,GAAA;AACrD,IAAM,MAAA,QAAA,GAAW,KAAK,gBAAiB,CAAA,gBAAA;AAAA,MACrC,yCAAA;AAAA,KACF,CAAA;AACA,IAAA,OAAO,QAAS,CAAA,QAAA,CAAS,MAAS,GAAA,CAAC,CAAK,IAAA,IAAA,CAAA;AAAA,GAC1C;AAAA,EAEQ,iBAAkB,SAAsB,EAAA;AAC9C,IAAA,IAAI,UAAU,GAAK,EAAA;AACjB,MAAA,IAAA,CAAK,KAAM,CAAA,SAAA,CAAU,GAAK,EAAA,SAAA,CAAU,MAAM,CAAA,CAAA;AAAA,KAC5C,MAAA,IAAW,UAAU,MAAQ,EAAA;AAC3B,MAAA,IAAA,CAAK,OAAQ,CAAA,aAAA;AAAA,QACX,IAAI,YAAY,gCAAkC,EAAA;AAAA,UAChD,OAAS,EAAA,IAAA;AAAA,UACT,MAAQ,EAAA,EAAE,MAAQ,EAAA,SAAA,CAAU,MAAO,EAAA;AAAA,SACpC,CAAA;AAAA,OACH,CAAA;AAAA,KACF;AAAA,GACF;AAAA,EAEQ,cAA0B,GAAA;AAChC,IAAA,OAAO,IAAK,CAAA,aAAA,KAAkB,OAAU,GAAA,IAAA,CAAK,oBAAoB,IAAK,CAAA,YAAA,CAAA;AAAA,GACxE;AAAA,EAEQ,eAA4C,GAAA;AAClD,IAAA,MAAM,OAAgC,EAAE,QAAA,EAAU,IAAK,CAAA,QAAA,EAAU,QAAQ,IAAK,EAAA,CAAA;AAE9E,IAAI,IAAA,IAAA,CAAK,aAAkB,KAAA,OAAA,IAAW,IAAK,CAAA,cAAA;AAAgB,MAAA,IAAA,CAAK,QAAQ,IAAK,CAAA,cAAA,CAAA;AAE7E,IAAA,IAAI,IAAK,CAAA,aAAA,KAAkB,OAAW,IAAA,IAAA,CAAK,gBAAkB,EAAA;AAC3D,MAAA,IAAA,CAAK,QAAW,GAAA,IAAA,CAAK,QAAS,CAAA,GAAA,CAAI,CAAS,IAAA,MAAA;AAAA,QACzC,OAAO,IAAK,CAAA,KAAA;AAAA,QACZ,aAAa,IAAK,CAAA,WAAA;AAAA,QAClB,KAAK,IAAK,CAAA,GAAA;AAAA,QACV,QAAQ,IAAK,CAAA,MAAA;AAAA,QACb,QAAQ,IAAK,CAAA,MAAA;AAAA,QACb,MAAM,IAAK,CAAA,IAAA;AAAA,OACX,CAAA,CAAA,CAAA;AAAA,KACJ;AACA,IAAO,OAAA,IAAA,CAAA;AAAA,GACT;AAAA,EAEQ,QAAS,IAAe,EAAA;AAC9B,IAAA,IAAA,CAAK,OAAQ,CAAA,SAAA,CAAU,MAAO,CAAA,WAAA,EAAa,IAAI,CAAA,CAAA;AAC/C,IAAA,IAAI,IAAK,CAAA,aAAA;AAAe,MAAK,IAAA,CAAA,UAAA,CAAW,SAAS,CAAC,IAAA,CAAA;AAGlD,IAAA,IAAI,IAAK,CAAA,mBAAA;AAAqB,MAAA,IAAA,CAAK,gBAAiB,CAAA,YAAA,CAAa,WAAa,EAAA,MAAA,CAAO,IAAI,CAAC,CAAA,CAAA;AAAA,GAC5F;AAAA;AAAA,EAGQ,gBAAoB,GAAA;AAC1B,IAAI,IAAA,IAAA,CAAK,aAAiB,IAAA,IAAA,CAAK,aAAe,EAAA;AAC5C,MAAK,IAAA,CAAA,UAAA,CAAW,SAAY,GAAA,IAAA,CAAK,UAAW,CAAA,YAAA,CAAA;AAAA,KAC9C;AAAA,GACF;AAAA;AAAA;AAAA;AAAA,EAKQ,yBAAyB,MAAM;AACrC,IAAA,IAAI,CAAC,IAAK,CAAA,aAAA;AAAe,MAAA,OAAA;AACzB,IAAA,MAAM,EAAE,YAAA,EAAc,SAAW,EAAA,YAAA,KAAiB,IAAK,CAAA,UAAA,CAAA;AACvD,IAAK,IAAA,CAAA,aAAA,GAAgB,YAAe,GAAA,SAAA,GAAY,YAAe,GAAA,EAAA,CAAA;AAAA,GACjE,CAAA;AAAA,EAEQ,aAAA,CAAe,MAA4B,IAA2B,EAAA;AAC5E,IAAM,MAAA,EAAA,GAAK,aAAc,CAAA,IAAA,CAAK,qBAAqB,CAAA,CAAA;AACnD,IAAG,EAAA,CAAA,SAAA,CAAU,GAAI,CAAA,CAAA,KAAA,EAAQ,IAAM,CAAA,CAAA,CAAA,CAAA;AAC/B,IAAA,IAAI,IAAS,KAAA,MAAA;AAAQ,MAAG,EAAA,CAAA,SAAA,CAAU,IAAI,QAAQ,CAAA,CAAA;AAE9C,IAAM,MAAA,MAAA,GAAS,EAAG,CAAA,aAAA,CAAc,+BAA+B,CAAA,CAAA;AAC/D,IAAI,IAAA,MAAA;AAAQ,MAAO,MAAA,CAAA,WAAA,GAAc,IAAS,KAAA,MAAA,GAAS,KAAQ,GAAA,WAAA,CAAA;AAE3D,IAAM,MAAA,MAAA,GAAS,EAAG,CAAA,aAAA,CAAc,iCAAiC,CAAA,CAAA;AACjE,IAAI,IAAA,IAAA;AAAM,MAAA,MAAA,CAAO,WAAc,GAAA,IAAA,CAAA;AAE/B,IAAK,IAAA,CAAA,gBAAA,CAAiB,YAAY,EAAE,CAAA,CAAA;AACpC,IAAA,IAAA,CAAK,gBAAiB,EAAA,CAAA;AACtB,IAAO,OAAA,EAAA,CAAA;AAAA,GACT;AAAA;AAAA,EAIQ,YAAa,KAAe,EAAA;AAClC,IAAA,IAAI,IAAK,CAAA,UAAA;AAAY,MAAA,IAAA,CAAK,WAAW,KAAM,EAAA,CAAA;AAC3C,IAAA,IAAI,IAAK,CAAA,WAAA;AAAa,MAAA,YAAA,CAAa,KAAK,WAAW,CAAA,CAAA;AAEnD,IAAK,IAAA,CAAA,WAAA,GAAc,MAAO,CAAA,UAAA,CAAW,YAAY;AAC/C,MAAK,IAAA,CAAA,UAAA,GAAa,IAAI,eAAgB,EAAA,CAAA;AACtC,MAAI,IAAA;AACF,QAAA,MAAM,MAAM,IAAI,GAAA,CAAI,KAAK,QAAU,EAAA,MAAA,CAAO,SAAS,MAAM,CAAA,CAAA;AACzD,QAAI,GAAA,CAAA,YAAA,CAAa,GAAI,CAAA,GAAA,EAAK,KAAK,CAAA,CAAA;AAC/B,QAAA,MAAM,QAAW,GAAA,MAAM,KAAM,CAAA,GAAA,CAAI,UAAY,EAAA;AAAA,UAC3C,OAAA,EAAS,EAAE,MAAA,EAAQ,kBAAmB,EAAA;AAAA,UACtC,MAAA,EAAQ,KAAK,UAAW,CAAA,MAAA;AAAA,SACzB,CAAA,CAAA;AACD,QAAA,IAAI,SAAS,EAAI,EAAA;AACf,UAAM,MAAA,IAAA,GAAsB,MAAM,QAAA,CAAS,IAAK,EAAA,CAAA;AAChD,UAAA,IAAA,CAAK,YAAY,IAAI,CAAA,CAAA;AAAA,SACvB;AAAA,eACO,CAAP,EAAA;AACA,QAAA,IAAK,EAAY,IAAS,KAAA,YAAA;AAAc,UAAM,MAAA,CAAA,CAAA;AAAA,OAChD;AAAA,OACC,GAAG,CAAA,CAAA;AAAA,GACR;AAAA;AAAA,EAIQ,cAAe,KAAe,EAAA;AACpC,IAAA,IAAI,CAAC,IAAK,CAAA,kBAAA;AAAoB,MAAA,OAAA;AAC9B,IAAA,MAAM,MAAM,IAAI,GAAA,CAAI,KAAK,kBAAoB,EAAA,MAAA,CAAO,SAAS,IAAI,CAAA,CAAA;AACjE,IAAI,IAAA,KAAA;AAAO,MAAI,GAAA,CAAA,YAAA,CAAa,GAAI,CAAA,GAAA,EAAK,KAAK,CAAA,CAAA;AAC1C,IAAA,IAAA,CAAK,eAAgB,CAAA,YAAA,CAAa,KAAO,EAAA,GAAA,CAAI,UAAU,CAAA,CAAA;AAAA,GACzD;AAAA,EAEQ,uBAAwB,KAAe,EAAA;AAC7C,IAAA,IAAI,IAAK,CAAA,WAAA;AAAa,MAAA,YAAA,CAAa,KAAK,WAAW,CAAA,CAAA;AAEnD,IAAK,IAAA,CAAA,WAAA,GAAc,MAAO,CAAA,UAAA,CAAW,MAAM;AACzC,MAAA,IAAA,CAAK,cAAc,KAAK,CAAA,CAAA;AAAA,OACvB,GAAG,CAAA,CAAA;AAAA,GACR;AAAA;AAAA,EAIQ,YAAa,KAAsB,EAAA;AACzC,IAAA,IAAI,CAAC,IAAK,CAAA,aAAA;AAAe,MAAA,OAAA;AAEzB,IAAA,IAAA,CAAK,WAAW,SAAY,GAAA,EAAA,CAAA;AAC5B,IAAA,IAAA,CAAK,gBAAmB,GAAA,CAAA,CAAA,CAAA;AAExB,IAAI,IAAA,KAAA,CAAM,WAAW,CAAG,EAAA;AACtB,MAAA,IAAA,CAAK,YAAY,MAAS,GAAA,KAAA,CAAA;AAC1B,MAAA,IAAA,CAAK,WAAW,MAAS,GAAA,IAAA,CAAA;AACzB,MAAA,OAAA;AAAA,KACF;AAEA,IAAA,IAAA,CAAK,YAAY,MAAS,GAAA,IAAA,CAAA;AAC1B,IAAA,IAAA,CAAK,WAAW,MAAS,GAAA,KAAA,CAAA;AAGzB,IAAM,MAAA,MAAA,uBAAa,GAA2B,EAAA,CAAA;AAC9C,IAAA,KAAA,MAAW,QAAQ,KAAO,EAAA;AACxB,MAAM,MAAA,KAAA,GAAQ,KAAK,KAAS,IAAA,EAAA,CAAA;AAC5B,MAAI,IAAA,CAAC,MAAO,CAAA,GAAA,CAAI,KAAK,CAAA;AAAG,QAAO,MAAA,CAAA,GAAA,CAAI,KAAO,EAAA,EAAE,CAAA,CAAA;AAC5C,MAAA,MAAA,CAAO,GAAI,CAAA,KAAK,CAAG,CAAA,IAAA,CAAK,IAAI,CAAA,CAAA;AAAA,KAC9B;AAEA,IAAA,IAAI,KAAQ,GAAA,CAAA,CAAA;AACZ,IAAA,KAAA,MAAW,CAAC,SAAA,EAAW,UAAU,CAAA,IAAK,MAAQ,EAAA;AAC5C,MAAA,IAAI,SAAW,EAAA;AACb,QAAA,IAAA,CAAK,UAAW,CAAA,WAAA,CAAY,IAAK,CAAA,UAAA,CAAW,SAAS,CAAC,CAAA,CAAA;AAAA,OACxD;AAEA,MAAA,KAAA,MAAW,QAAQ,UAAY,EAAA;AAC7B,QAAA,IAAA,CAAK,WAAW,WAAY,CAAA,IAAA,CAAK,SAAU,CAAA,IAAA,EAAM,KAAK,CAAC,CAAA,CAAA;AACvD,QAAA,KAAA,EAAA,CAAA;AAAA,OACF;AAAA,KACF;AAGA,IAAI,IAAA,KAAA,CAAM,SAAS,CAAG,EAAA;AACpB,MAAA,IAAA,CAAK,gBAAmB,GAAA,CAAA,CAAA;AACxB,MAAA,IAAA,CAAK,eAAgB,EAAA,CAAA;AAAA,KACvB;AAAA,GACF;AAAA,EAEQ,WAAY,IAA2B,EAAA;AAC7C,IAAM,MAAA,EAAA,GAAK,aAAc,CAAA,IAAA,CAAK,mBAAmB,CAAA,CAAA;AACjD,IAAM,MAAA,EAAA,GAAK,EAAG,CAAA,aAAA,CAAc,gBAAgB,CAAA,CAAA;AAC5C,IAAI,IAAA,EAAA;AAAI,MAAA,EAAA,CAAG,WAAc,GAAA,IAAA,CAAA;AACzB,IAAO,OAAA,EAAA,CAAA;AAAA,GACT;AAAA,EAEQ,SAAA,CAAW,MAAmB,KAA4B,EAAA;AAChE,IAAM,MAAA,EAAA,GAAK,aAAc,CAAA,IAAA,CAAK,kBAAkB,CAAA,CAAA;AAChD,IAAG,EAAA,CAAA,OAAA,CAAQ,KAAQ,GAAA,MAAA,CAAO,KAAK,CAAA,CAAA;AAE/B,IAAA,IAAI,IAAK,CAAA,GAAA;AAAK,MAAG,EAAA,CAAA,OAAA,CAAQ,MAAM,IAAK,CAAA,GAAA,CAAA;AACpC,IAAA,IAAI,IAAK,CAAA,MAAA;AAAQ,MAAG,EAAA,CAAA,OAAA,CAAQ,gBAAgB,IAAK,CAAA,MAAA,CAAA;AACjD,IAAA,IAAI,IAAK,CAAA,MAAA;AAAQ,MAAG,EAAA,CAAA,OAAA,CAAQ,cAAc,IAAK,CAAA,MAAA,CAAA;AAC/C,IAAA,IAAI,IAAK,CAAA,OAAA;AAAS,MAAG,EAAA,CAAA,OAAA,CAAQ,eAAe,IAAK,CAAA,OAAA,CAAA;AAGjD,IAAM,MAAA,QAAA,GAAW,EAAG,CAAA,aAAA,CAAc,4BAA4B,CAAA,CAAA;AAC9D,IAAA,IAAI,KAAK,IAAM,EAAA;AACb,MAAA,QAAA,CAAS,SAAY,GAAA,IAAA,CAAK,UAAW,CAAA,IAAA,CAAK,IAAI,CAAA,CAAA;AAC9C,MAAA,QAAA,CAAS,MAAS,GAAA,KAAA,CAAA;AAAA,KACb,MAAA;AACL,MAAA,QAAA,CAAS,MAAO,EAAA,CAAA;AAAA,KAClB;AAGA,IAAM,MAAA,KAAA,GAAQ,EAAG,CAAA,aAAA,CAAc,6BAA6B,CAAA,CAAA;AAC5D,IAAA,KAAA,CAAM,cAAc,IAAK,CAAA,KAAA,CAAA;AAGzB,IAAM,MAAA,IAAA,GAAO,EAAG,CAAA,aAAA,CAAc,mCAAmC,CAAA,CAAA;AACjE,IAAA,IAAI,KAAK,WAAa,EAAA;AACpB,MAAA,IAAA,CAAK,cAAc,IAAK,CAAA,WAAA,CAAA;AACxB,MAAA,IAAA,CAAK,MAAS,GAAA,KAAA,CAAA;AAAA,KACT,MAAA;AACL,MAAA,IAAA,CAAK,MAAO,EAAA,CAAA;AAAA,KACd;AAGA,IAAM,MAAA,YAAA,GAAe,EAAG,CAAA,aAAA,CAAc,gCAAgC,CAAA,CAAA;AACtE,IAAA,IAAI,KAAK,QAAU,EAAA;AACjB,MAAA,IAAA,CAAK,QAAS,CAAA,KAAA,CAAM,GAAG,CAAA,CAAE,QAAQ,CAAO,GAAA,KAAA;AACtC,QAAM,MAAA,GAAA,GAAM,QAAS,CAAA,aAAA,CAAc,KAAK,CAAA,CAAA;AACxC,QAAA,GAAA,CAAI,SAAY,GAAA,aAAA,CAAA;AAChB,QAAI,GAAA,CAAA,WAAA,GAAc,IAAI,IAAK,EAAA,CAAA;AAC3B,QAAA,YAAA,CAAa,YAAY,GAAG,CAAA,CAAA;AAAA,OAC7B,CAAA,CAAA;AACD,MAAA,YAAA,CAAa,MAAS,GAAA,KAAA,CAAA;AAAA,KACjB,MAAA;AACL,MAAA,YAAA,CAAa,MAAO,EAAA,CAAA;AAAA,KACtB;AAEA,IAAO,OAAA,EAAA,CAAA;AAAA,GACT;AAAA;AAAA,EAIQ,WAAY,IAAmB,EAAA;AACrC,IAAA,IAAI,KAAK,OAAW,IAAA,CAAC,MAAO,CAAA,OAAA,CAAQ,KAAK,OAAO,CAAA;AAAG,MAAA,OAAA;AAEnD,IAAA,IAAA,CAAK,KAAM,EAAA,CAAA;AAEX,IAAA,IAAI,KAAK,GAAK,EAAA;AACZ,MAAA,IAAA,CAAK,KAAM,CAAA,IAAA,CAAK,GAAK,EAAA,IAAA,CAAK,MAAM,CAAA,CAAA;AAChC,MAAA,OAAA;AAAA,KACF;AAEA,IAAA,IAAI,KAAK,MAAQ,EAAA;AACf,MAAA,IAAA,CAAK,OAAQ,CAAA,aAAA;AAAA,QACX,IAAI,YAAY,gCAAkC,EAAA;AAAA,UAChD,OAAS,EAAA,IAAA;AAAA,UACT,MAAQ,EAAA,EAAE,MAAQ,EAAA,IAAA,CAAK,QAAQ,IAAK,EAAA;AAAA,SACrC,CAAA;AAAA,OACH,CAAA;AAAA,KACF;AAAA,GACF;AAAA,EAEQ,KAAA,CAAO,KAAa,MAAiB,EAAA;AAC3C,IAAA,IAAI,MAAU,IAAA,MAAA,CAAO,WAAY,EAAA,KAAM,KAAO,EAAA;AAG5C,MAAM,MAAA,IAAA,GAAO,QAAS,CAAA,aAAA,CAAc,GAAG,CAAA,CAAA;AACvC,MAAA,IAAA,CAAK,IAAO,GAAA,GAAA,CAAA;AACZ,MAAA,IAAA,CAAK,QAAQ,WAAc,GAAA,MAAA,CAAA;AAC3B,MAAA,IAAA,CAAK,MAAM,OAAU,GAAA,MAAA,CAAA;AACrB,MAAS,QAAA,CAAA,IAAA,CAAK,YAAY,IAAI,CAAA,CAAA;AAC9B,MAAA,IAAA,CAAK,KAAM,EAAA,CAAA;AACX,MAAA,IAAA,CAAK,MAAO,EAAA,CAAA;AACZ,MAAA,OAAA;AAAA,KACF;AAEA,IAAA,MAAM,QAAS,MAAe,CAAA,KAAA,CAAA;AAC9B,IAAA,IAAI,OAAO,KAAO,EAAA;AAChB,MAAA,KAAA,CAAM,MAAM,GAAG,CAAA,CAAA;AAAA,KACV,MAAA;AACL,MAAA,MAAA,CAAO,SAAS,IAAO,GAAA,GAAA,CAAA;AAAA,KACzB;AAAA,GACF;AAAA;AAAA,EAIA,IAAY,YAA+B,GAAA;AACzC,IAAA,IAAI,CAAC,IAAK,CAAA,aAAA;AAAe,MAAA,OAAO,EAAC,CAAA;AAEjC,IAAA,MAAM,QAAuB,EAAC,CAAA;AAC9B,IAAA,MAAM,GAAM,GAAA,IAAA,CAAK,UAAW,CAAA,gBAAA,CAA8B,uBAAuB,CAAA,CAAA;AACjF,IAAA,KAAA,MAAW,MAAM,GAAK,EAAA;AACpB,MAAA,KAAA,CAAM,IAAK,CAAA;AAAA,QACT,KAAO,EAAA,EAAA,CAAG,aAAc,CAAA,6BAA6B,GAAG,WAAe,IAAA,EAAA;AAAA,QACvE,GAAA,EAAK,GAAG,OAAQ,CAAA,GAAA;AAAA,QAChB,MAAA,EAAQ,GAAG,OAAQ,CAAA,aAAA;AAAA,QACnB,MAAA,EAAQ,GAAG,OAAQ,CAAA,WAAA;AAAA,QACnB,OAAA,EAAS,GAAG,OAAQ,CAAA,YAAA;AAAA,OACrB,CAAA,CAAA;AAAA,KACH;AACA,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AAAA,EAEQ,eAAmB,GAAA;AACzB,IAAA,IAAI,CAAC,IAAK,CAAA,aAAA;AAAe,MAAA,OAAA;AAEzB,IAAA,MAAM,KAAQ,GAAA,IAAA,CAAK,UAAW,CAAA,gBAAA,CAA8B,uBAAuB,CAAA,CAAA;AACnF,IAAM,KAAA,CAAA,OAAA,CAAQ,CAAC,EAAA,EAAI,CAAM,KAAA;AACvB,MAAA,EAAA,CAAG,aAAa,eAAiB,EAAA,MAAA,CAAO,CAAM,KAAA,IAAA,CAAK,gBAAgB,CAAC,CAAA,CAAA;AAAA,KACrE,CAAA,CAAA;AAED,IAAM,MAAA,WAAA,GAAc,KAAM,CAAA,IAAA,CAAK,gBAAgB,CAAA,CAAA;AAC/C,IAAA,IAAI,WAAa,EAAA;AACf,MAAA,WAAA,CAAY,cAAe,CAAA,EAAE,KAAO,EAAA,SAAA,EAAW,CAAA,CAAA;AAC/C,MAAA,IAAA,CAAK,WAAY,CAAA,YAAA,CAAa,uBAAyB,EAAA,WAAA,CAAY,MAAM,EAAE,CAAA,CAAA;AAAA,KAC7E;AAAA,GACF;AAAA;AAAA,EAIQ,mBAAA,GAAsB,CAAC,KAAyB,KAAA;AACtD,IAAA,IAAA,CAAK,MAAM,OAAW,IAAA,KAAA,CAAM,YAAY,KAAM,CAAA,GAAA,KAAQ,KAAK,WAAa,EAAA;AACtE,MAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AACrB,MAAI,IAAA,IAAA,CAAK,QAAQ,IAAM,EAAA;AACrB,QAAA,IAAA,CAAK,KAAM,EAAA,CAAA;AAAA,OACN,MAAA;AACL,QAAA,IAAA,CAAK,IAAK,EAAA,CAAA;AAAA,OACZ;AAAA,KACF;AAAA,GACF,CAAA;AAAA,EAEQ,mBAAA,GAAsB,CAAC,KAAiB,KAAA;AAC9C,IAAI,IAAA,KAAA,CAAM,WAAW,IAAK,CAAA,OAAA;AAAS,MAAA,IAAA,CAAK,KAAM,EAAA,CAAA;AAAA,GAChD,CAAA;AAAA;AAAA,EAIQ,WAAY,IAAsB,EAAA;AACxC,IAAA,MAAM,QAAW,GAAA,QAAA,CAAS,aAAc,CAAA,CAAA,+BAAA,EAAkC,IAAQ,CAAA,EAAA,CAAA,CAAA,CAAA;AAClF,IAAI,IAAA,QAAA;AAAU,MAAA,OAAO,QAAS,CAAA,SAAA,CAAA;AAE9B,IAAM,MAAA,QAAA,GAAW,QAAS,CAAA,gBAAA,CAAiB,oBAAoB,CAAA,CAAA;AAC/D,IAAA,KAAA,MAAW,QAAQ,QAAU,EAAA;AAC3B,MAAI,IAAA,IAAA,CAAK,aAAa,YAAY,CAAA,EAAG,aAAkB,KAAA,IAAA,CAAK,aAAe,EAAA;AACzE,QAAA,OAAO,IAAK,CAAA,SAAA,CAAA;AAAA,OACd;AAAA,KACF;AAEA,IAAO,OAAA,EAAA,CAAA;AAAA,GACT;AACF;;;;"}
|