@pasko70/pibo 1.6.0 → 1.7.1
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/dist/apps/chat/chat-trace-helpers.js +47 -4
- package/dist/apps/chat/trace-v2.js +302 -0
- package/dist/apps/chat/trace.js +31 -2
- package/dist/apps/chat/web-app.js +371 -10
- package/dist/apps/chat-ui/assets/{dist-aLS3alom.js → dist-B7ZRIJ16.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-DYqJWYtm.js → dist-BDNjNt4b.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-D87he9he.js → dist-BDxKfyTI.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-B0i7AU1O.js → dist-CA1Gi-1G.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-BwZj_mI4.js → dist-CTQ40XYd.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-wyhLeLW6.js → dist-CcwGcMtk.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CFoGUjhX.js → dist-D8Q2E5o5.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-Dm6UhVM6.js → dist-DJJN6SPt.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-BbCXk-v9.js → dist-exkn8clz.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-Yx8i6oQ1.js → dist-mG9WxdYM.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-C-UobPQQ.js → dist-r34sHBLi.js} +1 -1
- package/dist/apps/chat-ui/assets/index-C5smwAJD.js +166 -0
- package/dist/apps/chat-ui/assets/index-D8itqvK_.css +1 -0
- package/dist/apps/chat-ui/index.html +2 -2
- package/dist/apps/chat-ui/sw.js +7 -1
- package/dist/apps/chat-vscode-web/assets/index-lOZ1r-No.js +41 -0
- package/dist/apps/chat-vscode-web/index.html +1 -1
- package/dist/apps/vscode-artifacts/latest.vsix +0 -0
- package/dist/apps/vscode-artifacts/pibo-vscode-ext-1.7.1.vsix +0 -0
- package/dist/cli.js +10 -0
- package/dist/data/payload-store.js +18 -9
- package/dist/gateway/cli.js +108 -6
- package/dist/gateway/web.js +2 -0
- package/dist/session-ui/terminalRows.js +5 -0
- package/dist/web/http.js +17 -6
- package/package.json +93 -93
- package/dist/apps/chat-ui/assets/index-CNDX-4Kp.js +0 -166
- package/dist/apps/chat-ui/assets/index-DvBWSeIO.css +0 -1
- package/dist/apps/chat-vscode-web/assets/index-lA76A7Pc.js +0 -41
- package/dist/apps/vscode-artifacts/pibo-vscode-ext-1.6.0.vsix +0 -0
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { randomUUID } from "node:crypto";
|
|
1
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2
2
|
import os from "node:os";
|
|
3
|
+
import { monitorEventLoopDelay } from "node:perf_hooks";
|
|
3
4
|
import { PiboWebHttpError, readJsonBody, responseJson } from "../../web/http.js";
|
|
4
5
|
import { OutputCompactor } from "./output-compactor.js";
|
|
5
6
|
import { isLiveOnlyOutputEvent, isPersistableOutputEvent } from "./output-event-policy.js";
|
|
6
7
|
import { chatRoomIdFromMetadata, isDefaultPiboRoom, isPiboRoomArchived, roomWorkspaceFromMetadata, withChatRoomId, withPiboRoomWorkspace, } from "./types/rooms.js";
|
|
7
8
|
import { chatStreamFramesFromOutputEvent, createChatStreamState, nextTransientChatStreamFrameId } from "./stream.js";
|
|
8
|
-
import { buildSessionNodes, buildTraceView, createTraceViewVersion, loadPiSessionMetadata } from "./trace.js";
|
|
9
|
-
import { DEFAULT_TRACE_EVENTS_PAGE_SIZE,
|
|
9
|
+
import { buildSessionNodes, buildTraceView, createTraceViewVersion, loadPiSessionMetadata, readTailEntries } from "./trace.js";
|
|
10
|
+
import { DEFAULT_TRACE_EVENTS_PAGE_SIZE, annotateTracePage, etagForVersion, estimateTraceViewBytes, traceCacheEstimatedBytes, liveSnapshotVersion, requestMatchesVersion, setTraceCache, traceCacheKey, withLiveSnapshots, withRawTraceTail, } from "./chat-trace-helpers.js";
|
|
11
|
+
import { TRACE_V2_DEFAULT_TIMELINE_LIMIT, TRACE_V2_MAX_TIMELINE_LIMIT, TRACE_V2_PAYLOAD_DEFAULT_LIMIT_BYTES, TRACE_V2_PAYLOAD_MAX_LIMIT_BYTES, TRACE_V2_RAW_EVENTS_DEFAULT_LIMIT, TRACE_V2_RAW_EVENTS_MAX_LIMIT, TRACE_V2_TIMELINE_HARD_BYTES, parseTracePayloadRef, readTracePayloadChunk, traceRawEventsPageFromEvents, traceTimelinePageFromView, } from "./trace-v2.js";
|
|
10
12
|
import { isChatWebSessionArchived } from "./session-metadata.js";
|
|
11
13
|
import { withWorkflowSessionKind } from "../../sessions/workflow-session-kind.js";
|
|
12
14
|
import { CustomAgentStore, createDefaultCustomAgentStore, } from "./agent-store.js";
|
|
@@ -86,7 +88,12 @@ function loadBootstrapCatalog(state, context, webSession) {
|
|
|
86
88
|
return value;
|
|
87
89
|
}
|
|
88
90
|
const TRACE_CACHE_MAX_ENTRIES = 24;
|
|
91
|
+
const TRACE_V1_COMPAT_MAX_EVENTS_PER_REQUEST = DEFAULT_TRACE_EVENTS_PAGE_SIZE;
|
|
92
|
+
const TRACE_TIMELINE_PAGE_CACHE_MAX_BYTES = 2 * 1024 * 1024;
|
|
89
93
|
const TRANSIENT_REPLAY_BUFFER_MAX_EVENTS = 1000;
|
|
94
|
+
const TRANSIENT_REPLAY_BUFFER_MAX_BYTES = 2 * 1024 * 1024;
|
|
95
|
+
const RELIABILITY_INLINE_PAYLOAD_MAX_BYTES = 64 * 1024;
|
|
96
|
+
const RESOURCE_WARNING_RING_MAX = 25;
|
|
90
97
|
function writeSse(controller, event, payload, id) {
|
|
91
98
|
const encoder = new TextEncoder();
|
|
92
99
|
if (id)
|
|
@@ -197,6 +204,13 @@ function createDataStore(options) {
|
|
|
197
204
|
function createPersistenceMetrics() {
|
|
198
205
|
return { eventCount: 0, errorCount: 0, totalIndexingMs: 0, maxIndexingMs: 0 };
|
|
199
206
|
}
|
|
207
|
+
function createResourceMetrics() {
|
|
208
|
+
return {
|
|
209
|
+
reliabilityPayloadWrites: { inline: 0, over_64kb: 0, over_1mb: 0, over_10mb: 0 },
|
|
210
|
+
reliabilityPayloadExternalized: 0,
|
|
211
|
+
recentWarnings: [],
|
|
212
|
+
};
|
|
213
|
+
}
|
|
200
214
|
function recordPersistenceDuration(metrics, durationMs) {
|
|
201
215
|
metrics.eventCount += 1;
|
|
202
216
|
metrics.totalIndexingMs += durationMs;
|
|
@@ -214,6 +228,102 @@ function serializePersistenceMetrics(metrics) {
|
|
|
214
228
|
averageIndexingMs: metrics.eventCount > 0 ? metrics.totalIndexingMs / metrics.eventCount : 0,
|
|
215
229
|
};
|
|
216
230
|
}
|
|
231
|
+
function pushResourceWarning(metrics, message) {
|
|
232
|
+
metrics.recentWarnings.push({ at: new Date().toISOString(), message });
|
|
233
|
+
while (metrics.recentWarnings.length > RESOURCE_WARNING_RING_MAX)
|
|
234
|
+
metrics.recentWarnings.shift();
|
|
235
|
+
}
|
|
236
|
+
function serializeGatewayResourceDiagnostics(state) {
|
|
237
|
+
const memory = process.memoryUsage();
|
|
238
|
+
const activeEventStreams = [...state.activeEventStreams.values()].reduce((total, streams) => total + streams.size, 0);
|
|
239
|
+
return {
|
|
240
|
+
memory: {
|
|
241
|
+
heapUsed: memory.heapUsed,
|
|
242
|
+
heapTotal: memory.heapTotal,
|
|
243
|
+
rss: memory.rss,
|
|
244
|
+
external: memory.external,
|
|
245
|
+
arrayBuffers: memory.arrayBuffers,
|
|
246
|
+
},
|
|
247
|
+
eventLoopDelay: {
|
|
248
|
+
meanMs: Number.isFinite(state.eventLoopDelay.mean) ? state.eventLoopDelay.mean / 1_000_000 : 0,
|
|
249
|
+
maxMs: Number.isFinite(state.eventLoopDelay.max) ? state.eventLoopDelay.max / 1_000_000 : 0,
|
|
250
|
+
p95Ms: state.eventLoopDelay.percentile(95) / 1_000_000,
|
|
251
|
+
},
|
|
252
|
+
streams: {
|
|
253
|
+
liveListeners: state.liveListeners.size,
|
|
254
|
+
activeEventStreams,
|
|
255
|
+
activeTraceSessions: state.activeTraceSessions.size,
|
|
256
|
+
},
|
|
257
|
+
traceCache: {
|
|
258
|
+
entries: state.traceCache.size,
|
|
259
|
+
estimatedBytes: traceCacheEstimatedBytes(state.traceCache),
|
|
260
|
+
},
|
|
261
|
+
traceTimelinePageCache: {
|
|
262
|
+
entries: state.traceTimelinePageCache.size,
|
|
263
|
+
estimatedBytes: traceTimelinePageCacheEstimatedBytes(state.traceTimelinePageCache),
|
|
264
|
+
maxBytes: TRACE_TIMELINE_PAGE_CACHE_MAX_BYTES,
|
|
265
|
+
},
|
|
266
|
+
transientReplay: {
|
|
267
|
+
events: state.transientReplayBuffer.length,
|
|
268
|
+
estimatedBytes: state.transientReplayBufferBytes,
|
|
269
|
+
maxEvents: TRANSIENT_REPLAY_BUFFER_MAX_EVENTS,
|
|
270
|
+
maxBytes: TRANSIENT_REPLAY_BUFFER_MAX_BYTES,
|
|
271
|
+
},
|
|
272
|
+
reliabilityPayloads: state.resourceMetrics.reliabilityPayloadWrites,
|
|
273
|
+
reliabilityPayloadExternalized: state.resourceMetrics.reliabilityPayloadExternalized,
|
|
274
|
+
recentWarnings: state.resourceMetrics.recentWarnings,
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
function setTraceTimelinePageCache(cache, key, page, maxEntries = TRACE_CACHE_MAX_ENTRIES, maxBytes = TRACE_TIMELINE_PAGE_CACHE_MAX_BYTES) {
|
|
278
|
+
cache.delete(key);
|
|
279
|
+
cache.set(key, page);
|
|
280
|
+
while (cache.size > maxEntries || traceTimelinePageCacheEstimatedBytes(cache) > maxBytes) {
|
|
281
|
+
const oldestKey = cache.keys().next().value;
|
|
282
|
+
if (typeof oldestKey !== "string")
|
|
283
|
+
break;
|
|
284
|
+
cache.delete(oldestKey);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
function traceTimelinePageCacheEstimatedBytes(cache) {
|
|
288
|
+
let bytes = 0;
|
|
289
|
+
for (const page of cache.values())
|
|
290
|
+
bytes += Buffer.byteLength(JSON.stringify(page), "utf8");
|
|
291
|
+
return bytes;
|
|
292
|
+
}
|
|
293
|
+
function createFastTraceV2Version(input) {
|
|
294
|
+
const relevantSessions = input.sessions
|
|
295
|
+
.map((session) => ({
|
|
296
|
+
id: session.id,
|
|
297
|
+
parentId: session.parentId ?? null,
|
|
298
|
+
originId: session.originId ?? null,
|
|
299
|
+
updatedAt: session.updatedAt,
|
|
300
|
+
title: session.title ?? null,
|
|
301
|
+
}))
|
|
302
|
+
.sort((left, right) => left.id.localeCompare(right.id));
|
|
303
|
+
return createHash("sha1")
|
|
304
|
+
.update(JSON.stringify({
|
|
305
|
+
session: {
|
|
306
|
+
id: input.session.id,
|
|
307
|
+
piSessionId: input.session.piSessionId,
|
|
308
|
+
profile: input.session.profile,
|
|
309
|
+
title: input.session.title ?? null,
|
|
310
|
+
updatedAt: input.session.updatedAt,
|
|
311
|
+
},
|
|
312
|
+
status: input.status ?? "idle",
|
|
313
|
+
events: {
|
|
314
|
+
lastSequence: input.lastEventSequence,
|
|
315
|
+
lastActivityAt: input.lastActivityAt ?? null,
|
|
316
|
+
latestStreamId: input.latestStreamId ?? null,
|
|
317
|
+
},
|
|
318
|
+
transcript: {
|
|
319
|
+
sessionSize: input.transcript?.sessionSize ?? null,
|
|
320
|
+
sessionMtimeMs: input.transcript?.sessionMtimeMs ?? null,
|
|
321
|
+
modified: input.transcript?.modified ?? null,
|
|
322
|
+
},
|
|
323
|
+
sessions: relevantSessions,
|
|
324
|
+
}))
|
|
325
|
+
.digest("hex");
|
|
326
|
+
}
|
|
217
327
|
function ensureEventIndexing(state, context) {
|
|
218
328
|
if (state.subscribedContext === context && state.unsubscribe)
|
|
219
329
|
return;
|
|
@@ -282,7 +392,7 @@ function ensureEventIndexing(state, context) {
|
|
|
282
392
|
key: persistableEvent.piboSessionId,
|
|
283
393
|
eventId: `pibo.output:${persistableEvent.piboSessionId}:${persistableEvent.type}:${randomUUID()}`,
|
|
284
394
|
retentionClass: reliabilityRetentionClassForOutputEvent(persistableEvent),
|
|
285
|
-
payload: persistableEvent,
|
|
395
|
+
payload: boundedReliabilityOutputPayload(state, persistableEvent),
|
|
286
396
|
});
|
|
287
397
|
for (const listener of state.liveListeners)
|
|
288
398
|
listener(stored);
|
|
@@ -304,6 +414,69 @@ function reliabilityRetentionClassForOutputEvent(event) {
|
|
|
304
414
|
}
|
|
305
415
|
return "trace_event";
|
|
306
416
|
}
|
|
417
|
+
function boundedReliabilityOutputPayload(state, event) {
|
|
418
|
+
const bytes = estimateJsonBytes(event);
|
|
419
|
+
recordReliabilityPayloadBucket(state.resourceMetrics, bytes);
|
|
420
|
+
if (bytes <= RELIABILITY_INLINE_PAYLOAD_MAX_BYTES)
|
|
421
|
+
return event;
|
|
422
|
+
const compacted = compactLargeOutputEventFields(state, event);
|
|
423
|
+
const compactedBytes = estimateJsonBytes(compacted);
|
|
424
|
+
if (compactedBytes <= RELIABILITY_INLINE_PAYLOAD_MAX_BYTES) {
|
|
425
|
+
state.resourceMetrics.reliabilityPayloadExternalized += 1;
|
|
426
|
+
return compacted;
|
|
427
|
+
}
|
|
428
|
+
const payload = state.dataStore.payloads.writePayload({
|
|
429
|
+
value: toPiboJsonValue(event),
|
|
430
|
+
contentType: "application/json",
|
|
431
|
+
retentionClass: reliabilityRetentionClassForOutputEvent(event),
|
|
432
|
+
});
|
|
433
|
+
state.resourceMetrics.reliabilityPayloadExternalized += 1;
|
|
434
|
+
pushResourceWarning(state.resourceMetrics, `Externalized over-budget reliability payload for ${event.type} (${bytes} bytes).`);
|
|
435
|
+
return {
|
|
436
|
+
type: event.type,
|
|
437
|
+
piboSessionId: event.piboSessionId,
|
|
438
|
+
eventId: "eventId" in event && typeof event.eventId === "string" ? event.eventId : undefined,
|
|
439
|
+
payloadRef: payload.id,
|
|
440
|
+
payloadBytes: payload.byteSize,
|
|
441
|
+
preview: payload.previewText,
|
|
442
|
+
truncated: true,
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
function recordReliabilityPayloadBucket(metrics, bytes) {
|
|
446
|
+
if (bytes > 10 * 1024 * 1024)
|
|
447
|
+
metrics.reliabilityPayloadWrites.over_10mb += 1;
|
|
448
|
+
else if (bytes > 1024 * 1024)
|
|
449
|
+
metrics.reliabilityPayloadWrites.over_1mb += 1;
|
|
450
|
+
else if (bytes > RELIABILITY_INLINE_PAYLOAD_MAX_BYTES)
|
|
451
|
+
metrics.reliabilityPayloadWrites.over_64kb += 1;
|
|
452
|
+
else
|
|
453
|
+
metrics.reliabilityPayloadWrites.inline += 1;
|
|
454
|
+
}
|
|
455
|
+
function compactLargeOutputEventFields(state, event) {
|
|
456
|
+
if (!event || typeof event !== "object" || Array.isArray(event))
|
|
457
|
+
return event;
|
|
458
|
+
const result = { ...event };
|
|
459
|
+
for (const key of ["result", "partialResult", "text", "args", "errorDetails"]) {
|
|
460
|
+
if (!(key in result))
|
|
461
|
+
continue;
|
|
462
|
+
const value = result[key];
|
|
463
|
+
if (value === undefined || value === null || estimateJsonBytes(value) <= RELIABILITY_INLINE_PAYLOAD_MAX_BYTES / 2)
|
|
464
|
+
continue;
|
|
465
|
+
const payload = state.dataStore.payloads.writePayload({
|
|
466
|
+
value: toPiboJsonValue(value),
|
|
467
|
+
contentType: typeof value === "string" ? "text/plain; charset=utf-8" : "application/json",
|
|
468
|
+
retentionClass: reliabilityRetentionClassForOutputEvent(event),
|
|
469
|
+
});
|
|
470
|
+
result[`${key}PayloadRef`] = payload.id;
|
|
471
|
+
result[`${key}PayloadBytes`] = payload.byteSize;
|
|
472
|
+
result[`${key}Preview`] = payload.previewText;
|
|
473
|
+
result[key] = typeof value === "string" ? payload.previewText ?? "" : undefined;
|
|
474
|
+
}
|
|
475
|
+
return toPiboJsonValue(result);
|
|
476
|
+
}
|
|
477
|
+
function toPiboJsonValue(value) {
|
|
478
|
+
return JSON.parse(JSON.stringify(value));
|
|
479
|
+
}
|
|
307
480
|
function appendEventStreamDisconnectEvent(state, piboSessionId, type, payload) {
|
|
308
481
|
state.reliabilityStore.append({
|
|
309
482
|
topic: "chat.event_stream",
|
|
@@ -666,6 +839,15 @@ function parsePositiveIntSearchParam(url, name, fallback, max) {
|
|
|
666
839
|
return fallback;
|
|
667
840
|
return Math.min(parsed, max);
|
|
668
841
|
}
|
|
842
|
+
function parseNonNegativeIntSearchParam(url, name, fallback, max) {
|
|
843
|
+
const raw = url.searchParams.get(name);
|
|
844
|
+
if (!raw)
|
|
845
|
+
return fallback;
|
|
846
|
+
const parsed = Number.parseInt(raw, 10);
|
|
847
|
+
if (!Number.isFinite(parsed) || parsed < 0)
|
|
848
|
+
return fallback;
|
|
849
|
+
return Math.min(parsed, max);
|
|
850
|
+
}
|
|
669
851
|
function parseOptionalPositiveIntSearchParam(url, name) {
|
|
670
852
|
const raw = url.searchParams.get(name);
|
|
671
853
|
if (!raw)
|
|
@@ -2058,13 +2240,29 @@ function recordTransientReplayEvent(state, event) {
|
|
|
2058
2240
|
const replaySequence = ++state.transientReplaySequence;
|
|
2059
2241
|
const recorded = { ...event, replaySequence, createdAtMs: Date.now() };
|
|
2060
2242
|
state.transientReplayBuffer.push(recorded);
|
|
2061
|
-
|
|
2062
|
-
|
|
2243
|
+
state.transientReplayBufferBytes += estimateJsonBytes(recorded);
|
|
2244
|
+
while (state.transientReplayBuffer.length > TRANSIENT_REPLAY_BUFFER_MAX_EVENTS ||
|
|
2245
|
+
state.transientReplayBufferBytes > TRANSIENT_REPLAY_BUFFER_MAX_BYTES) {
|
|
2246
|
+
const removed = state.transientReplayBuffer.splice(0, Math.max(1, state.transientReplayBuffer.length - TRANSIENT_REPLAY_BUFFER_MAX_EVENTS));
|
|
2247
|
+
if (!removed.length)
|
|
2248
|
+
break;
|
|
2063
2249
|
for (const evicted of removed)
|
|
2064
2250
|
recordTransientReplayEviction(state, evicted);
|
|
2065
2251
|
}
|
|
2066
2252
|
return recorded;
|
|
2067
2253
|
}
|
|
2254
|
+
function parseTimelineBeforeCursor(url) {
|
|
2255
|
+
const before = parseOptionalPositiveIntSearchParam(url, "beforeSequence");
|
|
2256
|
+
if (before !== undefined)
|
|
2257
|
+
return before;
|
|
2258
|
+
const cursor = url.searchParams.get("before") ?? url.searchParams.get("cursor");
|
|
2259
|
+
if (!cursor || cursor === "tail")
|
|
2260
|
+
return undefined;
|
|
2261
|
+
const parsed = Number.parseInt(cursor, 10);
|
|
2262
|
+
if (!Number.isFinite(parsed) || parsed <= 0)
|
|
2263
|
+
throw new PiboWebHttpError("Trace cursor must be tail or a positive sequence", 400);
|
|
2264
|
+
return parsed;
|
|
2265
|
+
}
|
|
2068
2266
|
function transientReplayScopeKeys(input) {
|
|
2069
2267
|
const keys = [];
|
|
2070
2268
|
if (input.piboSessionId)
|
|
@@ -2074,10 +2272,19 @@ function transientReplayScopeKeys(input) {
|
|
|
2074
2272
|
return keys;
|
|
2075
2273
|
}
|
|
2076
2274
|
function recordTransientReplayEviction(state, event) {
|
|
2275
|
+
state.transientReplayBufferBytes = Math.max(0, state.transientReplayBufferBytes - estimateJsonBytes(event));
|
|
2077
2276
|
for (const key of transientReplayScopeKeys(event)) {
|
|
2078
2277
|
state.transientReplayEvictedBeforeByScope.set(key, Math.max(state.transientReplayEvictedBeforeByScope.get(key) ?? 0, event.replaySequence));
|
|
2079
2278
|
}
|
|
2080
2279
|
}
|
|
2280
|
+
function estimateJsonBytes(value) {
|
|
2281
|
+
try {
|
|
2282
|
+
return Buffer.byteLength(JSON.stringify(value), "utf8");
|
|
2283
|
+
}
|
|
2284
|
+
catch {
|
|
2285
|
+
return Buffer.byteLength(String(value), "utf8");
|
|
2286
|
+
}
|
|
2287
|
+
}
|
|
2081
2288
|
function transientReplayEvictedBefore(state, input) {
|
|
2082
2289
|
const values = transientReplayScopeKeys(input)
|
|
2083
2290
|
.map((key) => state.transientReplayEvictedBeforeByScope.get(key))
|
|
@@ -2659,6 +2866,8 @@ async function sendChatMessage(input) {
|
|
|
2659
2866
|
export function createChatWebApp(options = {}) {
|
|
2660
2867
|
const defaultProfile = options.defaultProfile ?? "base";
|
|
2661
2868
|
const dataStore = createDataStore(options);
|
|
2869
|
+
const eventLoopDelay = monitorEventLoopDelay({ resolution: 20 });
|
|
2870
|
+
eventLoopDelay.enable();
|
|
2662
2871
|
const state = {
|
|
2663
2872
|
sessionQuery: new ChatSessionQueryService(dataStore),
|
|
2664
2873
|
timelineQuery: new ChatTimelineQueryService(dataStore),
|
|
@@ -2673,14 +2882,18 @@ export function createChatWebApp(options = {}) {
|
|
|
2673
2882
|
dataStore,
|
|
2674
2883
|
ingestService: new ChatDataIngestService(dataStore),
|
|
2675
2884
|
traceCache: new Map(),
|
|
2885
|
+
traceTimelinePageCache: new Map(),
|
|
2676
2886
|
outputCompactor: new OutputCompactor(),
|
|
2677
2887
|
liveListeners: new Set(),
|
|
2678
2888
|
transientReplaySequence: 0,
|
|
2679
2889
|
transientReplayBuffer: [],
|
|
2890
|
+
transientReplayBufferBytes: 0,
|
|
2680
2891
|
transientReplayEvictedBeforeByScope: new Map(),
|
|
2681
2892
|
activeEventStreams: new Map(),
|
|
2682
2893
|
activeTraceSessions: new Set(),
|
|
2683
2894
|
persistenceMetrics: createPersistenceMetrics(),
|
|
2895
|
+
resourceMetrics: createResourceMetrics(),
|
|
2896
|
+
eventLoopDelay,
|
|
2684
2897
|
userSkillManager: new UserSkillManager(os.homedir()),
|
|
2685
2898
|
workflowDraftStore: new ChatWorkflowDraftStore(dataStore),
|
|
2686
2899
|
workflowPublishedVersionStore: new ChatWorkflowPublishedVersionStore(dataStore),
|
|
@@ -3786,6 +3999,141 @@ export function createChatWebApp(options = {}) {
|
|
|
3786
3999
|
};
|
|
3787
4000
|
return responseJson(summary, { headers });
|
|
3788
4001
|
}
|
|
4002
|
+
if (url.pathname === `${CHAT_WEB_API_PREFIX}/trace/timeline` && request.method === "GET") {
|
|
4003
|
+
const startedAt = performance.now();
|
|
4004
|
+
const webSession = await requireSession(request, context);
|
|
4005
|
+
const beforeSequence = parseTimelineBeforeCursor(url);
|
|
4006
|
+
const limit = parsePositiveIntSearchParam(url, "limit", TRACE_V2_DEFAULT_TIMELINE_LIMIT, TRACE_V2_MAX_TIMELINE_LIMIT);
|
|
4007
|
+
const selectedSession = resolveRequestedSession(state, context, webSession, defaultProfile, url.searchParams.get("piboSessionId") || undefined);
|
|
4008
|
+
state.sessionQuery.upsertSession(selectedSession);
|
|
4009
|
+
const ownedSessions = listSharedSessions(context);
|
|
4010
|
+
const indexedSession = state.sessionQuery.getSession(selectedSession.id);
|
|
4011
|
+
let metadataMs = 0;
|
|
4012
|
+
const lastEventSequence = state.timelineQuery.getLatestEventSequence(selectedSession.id);
|
|
4013
|
+
const latestStreamId = state.timelineQuery.getLatestStreamId({ piboSessionId: selectedSession.id });
|
|
4014
|
+
const liveSnapshots = beforeSequence === undefined ? state.outputCompactor.snapshotsForSession(selectedSession.id) : [];
|
|
4015
|
+
const transcriptMetadata = beforeSequence === undefined
|
|
4016
|
+
? await loadPiSessionMetadata(selectedSession, selectedSession.workspace ?? process.cwd())
|
|
4017
|
+
: undefined;
|
|
4018
|
+
const baseVersion = createFastTraceV2Version({
|
|
4019
|
+
session: selectedSession,
|
|
4020
|
+
sessions: ownedSessions,
|
|
4021
|
+
lastEventSequence,
|
|
4022
|
+
lastActivityAt: indexedSession?.lastActivityAt,
|
|
4023
|
+
status: indexedSession?.status,
|
|
4024
|
+
latestStreamId,
|
|
4025
|
+
transcript: transcriptMetadata,
|
|
4026
|
+
});
|
|
4027
|
+
const snapshotVersion = liveSnapshotVersion(liveSnapshots);
|
|
4028
|
+
const version = snapshotVersion ? `${baseVersion}:live:${snapshotVersion}` : baseVersion;
|
|
4029
|
+
const pageCursorKey = beforeSequence === undefined ? "tail" : `before:${beforeSequence}`;
|
|
4030
|
+
const cacheKey = traceCacheKey(selectedSession.id, `${baseVersion}:v2:limit:${limit}:${pageCursorKey}`);
|
|
4031
|
+
const pageCacheKey = traceCacheKey(selectedSession.id, `${version}:v2-page:limit:${limit}:${pageCursorKey}`);
|
|
4032
|
+
const cachedPage = state.traceTimelinePageCache.get(pageCacheKey);
|
|
4033
|
+
const cached = state.traceCache.get(cacheKey);
|
|
4034
|
+
const baseHeaders = {
|
|
4035
|
+
etag: etagForVersion(version),
|
|
4036
|
+
"x-pibo-trace-version": version,
|
|
4037
|
+
"cache-control": "no-store",
|
|
4038
|
+
};
|
|
4039
|
+
if (beforeSequence === undefined && requestMatchesVersion(request, version)) {
|
|
4040
|
+
return new Response(null, { status: 304, headers: baseHeaders });
|
|
4041
|
+
}
|
|
4042
|
+
if (cachedPage) {
|
|
4043
|
+
return responseJson(cachedPage, {
|
|
4044
|
+
headers: {
|
|
4045
|
+
...baseHeaders,
|
|
4046
|
+
"server-timing": [
|
|
4047
|
+
`trace_timeline;dur=${(performance.now() - startedAt).toFixed(1)}`,
|
|
4048
|
+
`trace_metadata;dur=${metadataMs.toFixed(1)}`,
|
|
4049
|
+
`trace_events;desc="0"`,
|
|
4050
|
+
`trace_cache;desc="page-hit"`,
|
|
4051
|
+
].join(", "),
|
|
4052
|
+
},
|
|
4053
|
+
});
|
|
4054
|
+
}
|
|
4055
|
+
let trace = cached;
|
|
4056
|
+
let eventCount = 0;
|
|
4057
|
+
if (!trace) {
|
|
4058
|
+
const events = state.timelineQuery.listTraceEvents({
|
|
4059
|
+
piboSessionId: selectedSession.id,
|
|
4060
|
+
limit,
|
|
4061
|
+
...(beforeSequence !== undefined ? { beforeSequence } : {}),
|
|
4062
|
+
});
|
|
4063
|
+
const transcriptEntries = beforeSequence === undefined && transcriptMetadata?.sessionPath
|
|
4064
|
+
? readTailEntries(transcriptMetadata.sessionPath)
|
|
4065
|
+
: [];
|
|
4066
|
+
eventCount = events.length;
|
|
4067
|
+
trace = await buildTraceView({
|
|
4068
|
+
session: selectedSession,
|
|
4069
|
+
sessions: ownedSessions,
|
|
4070
|
+
events,
|
|
4071
|
+
status: indexedSession?.status,
|
|
4072
|
+
metadata: transcriptMetadata ?? {},
|
|
4073
|
+
transcriptEntries,
|
|
4074
|
+
includeRawEvents: false,
|
|
4075
|
+
latestStreamId,
|
|
4076
|
+
});
|
|
4077
|
+
trace = annotateTracePage(trace, events, { lastEventSequence, pageSize: limit, beforeSequence });
|
|
4078
|
+
setTraceCache(state.traceCache, cacheKey, trace, TRACE_CACHE_MAX_ENTRIES);
|
|
4079
|
+
}
|
|
4080
|
+
trace = withLiveSnapshots(trace, liveSnapshots, {
|
|
4081
|
+
piboSessionId: selectedSession.id,
|
|
4082
|
+
lastEventSequence,
|
|
4083
|
+
status: liveSnapshots.length ? "running" : indexedSession?.status,
|
|
4084
|
+
});
|
|
4085
|
+
trace = { ...trace, version };
|
|
4086
|
+
const page = traceTimelinePageFromView({
|
|
4087
|
+
trace,
|
|
4088
|
+
payloadStore: state.dataStore.payloads,
|
|
4089
|
+
limit,
|
|
4090
|
+
byteLimit: TRACE_V2_TIMELINE_HARD_BYTES,
|
|
4091
|
+
fromTail: beforeSequence === undefined,
|
|
4092
|
+
});
|
|
4093
|
+
setTraceTimelinePageCache(state.traceTimelinePageCache, pageCacheKey, page);
|
|
4094
|
+
return responseJson(page, {
|
|
4095
|
+
headers: {
|
|
4096
|
+
...baseHeaders,
|
|
4097
|
+
"server-timing": [
|
|
4098
|
+
`trace_timeline;dur=${(performance.now() - startedAt).toFixed(1)}`,
|
|
4099
|
+
`trace_metadata;dur=${metadataMs.toFixed(1)}`,
|
|
4100
|
+
`trace_events;desc="${eventCount}"`,
|
|
4101
|
+
`trace_cache;desc="${cached ? "hit" : "miss"}"`,
|
|
4102
|
+
].join(", "),
|
|
4103
|
+
},
|
|
4104
|
+
});
|
|
4105
|
+
}
|
|
4106
|
+
if (url.pathname.startsWith(`${CHAT_WEB_API_PREFIX}/trace/payload/`) && request.method === "GET") {
|
|
4107
|
+
const webSession = await requireSession(request, context);
|
|
4108
|
+
const ref = decodeURIComponent(url.pathname.slice(`${CHAT_WEB_API_PREFIX}/trace/payload/`.length));
|
|
4109
|
+
const parsed = parseTracePayloadRef(ref);
|
|
4110
|
+
if (!parsed)
|
|
4111
|
+
throw new PiboWebHttpError("Invalid trace payload ref", 400);
|
|
4112
|
+
resolveRequestedSession(state, context, webSession, defaultProfile, parsed.piboSessionId);
|
|
4113
|
+
const offset = parseNonNegativeIntSearchParam(url, "offset", 0, Number.MAX_SAFE_INTEGER);
|
|
4114
|
+
const limit = parsePositiveIntSearchParam(url, "limit", TRACE_V2_PAYLOAD_DEFAULT_LIMIT_BYTES, TRACE_V2_PAYLOAD_MAX_LIMIT_BYTES);
|
|
4115
|
+
const chunk = readTracePayloadChunk({ payloadStore: state.dataStore.payloads, ref, offset, limit });
|
|
4116
|
+
if (!chunk)
|
|
4117
|
+
throw new PiboWebHttpError("Trace payload not found", 404);
|
|
4118
|
+
return responseJson(chunk, { headers: { "cache-control": "no-store" } });
|
|
4119
|
+
}
|
|
4120
|
+
if (url.pathname === `${CHAT_WEB_API_PREFIX}/trace/raw-events` && request.method === "GET") {
|
|
4121
|
+
const webSession = await requireSession(request, context);
|
|
4122
|
+
const beforeSequence = parseTimelineBeforeCursor(url);
|
|
4123
|
+
const limit = parsePositiveIntSearchParam(url, "limit", TRACE_V2_RAW_EVENTS_DEFAULT_LIMIT, TRACE_V2_RAW_EVENTS_MAX_LIMIT);
|
|
4124
|
+
const selectedSession = resolveRequestedSession(state, context, webSession, defaultProfile, url.searchParams.get("piboSessionId") || undefined);
|
|
4125
|
+
const events = state.timelineQuery.listTraceEvents({
|
|
4126
|
+
piboSessionId: selectedSession.id,
|
|
4127
|
+
limit,
|
|
4128
|
+
...(beforeSequence !== undefined ? { beforeSequence } : {}),
|
|
4129
|
+
});
|
|
4130
|
+
return responseJson(traceRawEventsPageFromEvents({
|
|
4131
|
+
piboSessionId: selectedSession.id,
|
|
4132
|
+
events,
|
|
4133
|
+
payloadStore: state.dataStore.payloads,
|
|
4134
|
+
limit,
|
|
4135
|
+
}), { headers: { "cache-control": "no-store" } });
|
|
4136
|
+
}
|
|
3789
4137
|
if (url.pathname === `${CHAT_WEB_API_PREFIX}/trace` && request.method === "GET") {
|
|
3790
4138
|
const startedAt = performance.now();
|
|
3791
4139
|
const webSession = await requireSession(request, context);
|
|
@@ -3793,8 +4141,8 @@ export function createChatWebApp(options = {}) {
|
|
|
3793
4141
|
const rawEventsLimit = parsePositiveIntSearchParam(url, "rawEventsLimit", 80, 1000);
|
|
3794
4142
|
const beforeSequence = parseOptionalPositiveIntSearchParam(url, "beforeSequence");
|
|
3795
4143
|
const eventLimit = url.searchParams.has("pageSize")
|
|
3796
|
-
? parsePositiveIntSearchParam(url, "pageSize", DEFAULT_TRACE_EVENTS_PAGE_SIZE,
|
|
3797
|
-
: parsePositiveIntSearchParam(url, "eventLimit", DEFAULT_TRACE_EVENTS_PAGE_SIZE,
|
|
4144
|
+
? parsePositiveIntSearchParam(url, "pageSize", DEFAULT_TRACE_EVENTS_PAGE_SIZE, TRACE_V1_COMPAT_MAX_EVENTS_PER_REQUEST)
|
|
4145
|
+
: parsePositiveIntSearchParam(url, "eventLimit", DEFAULT_TRACE_EVENTS_PAGE_SIZE, TRACE_V1_COMPAT_MAX_EVENTS_PER_REQUEST);
|
|
3798
4146
|
const selectedSession = resolveRequestedSession(state, context, webSession, defaultProfile, url.searchParams.get("piboSessionId") || undefined);
|
|
3799
4147
|
state.sessionQuery.upsertSession(selectedSession);
|
|
3800
4148
|
const ownedSessions = listSharedSessions(context);
|
|
@@ -3858,6 +4206,15 @@ export function createChatWebApp(options = {}) {
|
|
|
3858
4206
|
lastEventSequence,
|
|
3859
4207
|
status: liveSnapshots.length ? "running" : indexedSession?.status,
|
|
3860
4208
|
});
|
|
4209
|
+
const estimatedTraceBytes = estimateTraceViewBytes(trace);
|
|
4210
|
+
if (estimatedTraceBytes > TRACE_V2_TIMELINE_HARD_BYTES) {
|
|
4211
|
+
pushResourceWarning(state.resourceMetrics, `Rejected over-budget V1 trace response for ${selectedSession.id} (${estimatedTraceBytes} estimated bytes).`);
|
|
4212
|
+
return responseJson({
|
|
4213
|
+
error: "Full trace response exceeds the V1 compatibility budget. Use /api/chat/trace/timeline and payload refs.",
|
|
4214
|
+
estimatedBytes: estimatedTraceBytes,
|
|
4215
|
+
budgetBytes: TRACE_V2_TIMELINE_HARD_BYTES,
|
|
4216
|
+
}, { status: 413, headers: { ...baseHeaders, "x-pibo-trace-v1-deprecated": "true", ...serverTiming(cached ? "hit" : "miss", eventCount) } });
|
|
4217
|
+
}
|
|
3861
4218
|
if (includeRawEvents) {
|
|
3862
4219
|
const rawEvents = state.timelineQuery.listTraceEvents({
|
|
3863
4220
|
piboSessionId: selectedSession.id,
|
|
@@ -3865,9 +4222,9 @@ export function createChatWebApp(options = {}) {
|
|
|
3865
4222
|
...(beforeSequence !== undefined ? { beforeSequence } : {}),
|
|
3866
4223
|
});
|
|
3867
4224
|
eventCount = eventCount || rawEvents.length;
|
|
3868
|
-
return responseJson(withRawTraceTail(trace, rawEvents), { headers: { ...baseHeaders, ...serverTiming(cached ? "hit" : "miss", eventCount) } });
|
|
4225
|
+
return responseJson(withRawTraceTail(trace, rawEvents), { headers: { ...baseHeaders, "x-pibo-trace-v1-deprecated": "true", ...serverTiming(cached ? "hit" : "miss", eventCount) } });
|
|
3869
4226
|
}
|
|
3870
|
-
return responseJson({ ...trace, rawEvents: [] }, { headers: { ...baseHeaders, ...serverTiming(cached ? "hit" : "miss", eventCount) } });
|
|
4227
|
+
return responseJson({ ...trace, rawEvents: [] }, { headers: { ...baseHeaders, "x-pibo-trace-v1-deprecated": "true", ...serverTiming(cached ? "hit" : "miss", eventCount) } });
|
|
3871
4228
|
}
|
|
3872
4229
|
if (url.pathname === `${CHAT_WEB_API_PREFIX}/debug/persistence` && request.method === "GET") {
|
|
3873
4230
|
await requireSession(request, context);
|
|
@@ -3876,6 +4233,10 @@ export function createChatWebApp(options = {}) {
|
|
|
3876
4233
|
liveObservers: listLiveObservers(state),
|
|
3877
4234
|
});
|
|
3878
4235
|
}
|
|
4236
|
+
if (url.pathname === `${CHAT_WEB_API_PREFIX}/debug/resources` && request.method === "GET") {
|
|
4237
|
+
await requireSession(request, context);
|
|
4238
|
+
return responseJson({ gateway: serializeGatewayResourceDiagnostics(state) }, { headers: { "cache-control": "no-store" } });
|
|
4239
|
+
}
|
|
3879
4240
|
if (url.pathname === `${CHAT_WEB_API_PREFIX}/debug/trace-at-sequence` && request.method === "POST") {
|
|
3880
4241
|
requireSameOriginJsonRequest(request);
|
|
3881
4242
|
await requireSession(request, context);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{C as e,K as t,N as n,P as r,U as i,_t as a,j as o,m as s,o as c,r as l,y as u}from"./dist-SVPsM5Oi.js";import{n as d,r as f}from"./dist-tGfufz3b.js";import{html as p}from"./dist-D87he9he.js";var m=1,h=2,g=3,_=180,v=4,y=181,b=5,x=182,S=6;function C(e){return e>=65&&e<=90||e>=97&&e<=122}var w=new d(e=>{let t=e.pos;for(;;){let{next:n}=e;if(n<0)break;if(n==123){let n=e.peek(1);if(n==123){if(e.pos>t)break;e.acceptToken(m,2);return}else if(n==37){if(e.pos>t)break;let n=2,r=2;for(;;){let t=e.peek(n);if(t==32||t==10)++n;else if(t==35)for(++n;;){let t=e.peek(n);if(t<0||t==10)break;n++}else if(t==45&&r==2)r=++n;else{let i=t==101&&e.peek(n+1)==110&&e.peek(n+2)==100;e.acceptToken(i?g:h,r);return}}}}if(e.advance(),n==10)break}e.pos>t&&e.acceptToken(_)});function T(e,t,n){return new d(r=>{let i=r.pos;for(;;){let{next:t}=r;if(t==123&&r.peek(1)==37){let t=2;for(;;t++){let e=r.peek(t);if(e!=32&&e!=10)break}let a=``;for(;;t++){let e=r.peek(t);if(!C(e))break;a+=String.fromCharCode(e)}if(a==e){if(r.pos>i)break;r.acceptToken(n,2);break}}else if(t<0)break;if(r.advance(),t==10)break}r.pos>i&&r.acceptToken(t)})}var E=T(`endcomment`,x,b),D=T(`endraw`,y,v),O=new d(e=>{if(e.next==35){for(e.advance();!(e.next==10||e.next<0||(e.next==37||e.next==125)&&e.peek(1)==125);)e.advance();e.acceptToken(S)}}),k={__proto__:null,contains:34,or:38,and:38,true:52,false:52,empty:54,forloop:57,tablerowloop:59,continue:61,in:131,with:197,for:199,as:201,if:237,endif:241,unless:247,endunless:251,elsif:255,else:259,case:265,endcase:269,when:273,endfor:281,tablerow:287,endtablerow:291,break:295,cycle:301,echo:305,render:309,include:313,assign:317,capture:323,endcapture:327,increment:331,decrement:335},A={__proto__:null,if:86,endif:90,elsif:94,else:98,unless:104,endunless:108,case:114,endcase:118,when:122,for:128,endfor:138,tablerow:144,endtablerow:148,break:152,continue:156,cycle:160,comment:166,endcomment:172,raw:178,endraw:184,echo:188,render:192,include:204,assign:208,capture:214,endcapture:218,increment:222,decrement:226,liquid:230},j=f.deserialize({version:14,states:"KtQYOPOOOOOP'#F{'#F{OeOaO'#CdOsQhO'#CfO!bQxO'#DSO#{OPO'#DVO$ZOPO'#D`O$iOPO'#DeO$wOPO'#DlO%VOPO'#DtO%eOSO'#EPO%jOQO'#EVO%oOPO'#EiOOOP'#Ge'#GeOOOP'#G]'#G]OOOP'#Fz'#FzQYOPOOOOOP-E9y-E9yOOQW'#Cg'#CgO&cQ!jO,59QO&jQ!jO'#G^OsQhO'#CtOOQW'#Gb'#GbOOQW'#Gc'#GcOOQW'#Gd'#GdOOQW'#G^'#G^OOOP,59n,59nO)YQhO,59nOsQhO,59rOsQhO,59vO)dQhO,59xOsQhO,59{OsQhO,5:QOsQhO,5:UO!]QhO,5:XO!]QhO,5:aO)iQhO,5:eO)nQhO,5:gO)sQhO,5:iO)xQhO,5:lO)}QhO,5:rOsQhO,5:wOsQhO,5:yOsQhO,5;POsQhO,5;ROsQhO,5;UOsQhO,5;YOsQhO,5;[O+^QhO,5;^O+eOPO'#CdOOOP,59q,59qO#{OPO,59qO+sQxO'#DYOOOP,59z,59zO$ZOPO,59zO+xQxO'#DcOOOP,5:P,5:PO$iOPO,5:PO+}QxO'#DhOOOP,5:W,5:WO$wOPO,5:WO,SQxO'#DrOOOP,5:`,5:`O%VOPO,5:`O,XQxO'#DwOOOS'#GQ'#GQO,^OSO'#ESO,fOSO,5:kOOOQ'#GR'#GRO,kOQO'#EYO,sOQO,5:qOOOP,5;T,5;TO%oOPO,5;TO,xQxO'#ElOOOP-E9x-E9xO,}Q#|O,59SOsQhO,59VOsQhO,59WOsQhO,59WO-SQhO'#C}OOQW'#F|'#F|O-XQhO1G.lOOOP1G.l1G.lOsQhO,59WOsQhO,59[O-rQ!jO,59`O-yQ!jO1G/YO.QQhO1G/YOOOP1G/Y1G/YO.YQ!jO1G/^O.aQ!jO1G/bOOOP1G/d1G/dO.hQ!jO1G/gO.oQ!jO1G/lO.vQ!jO1G/pO/QQhO1G/sO/QQhO1G/{OOOP1G0P1G0POOOP1G0R1G0RO/VQhO1G0TOOOS1G0W1G0WOOOQ1G0^1G0^O/bQ!jO1G0cO/iQ!jO1G0eO/yQ!jO1G0kO0QQ!jO1G0mO0XQ!jO1G0pO0`Q!jO1G0tO0gQ!jO1G0vOOQW'#Gh'#GhOOQW'#Gk'#GkOsQhO'#EuO0nQhO'#EtOOQW'#Gm'#GmOsQhO'#EzO0uQhO'#EyOOQW'#Go'#GoOsQhO'#FOOOQW'#Gp'#GpOOQW'#FQ'#FQOOQW'#Gq'#GqOsQhO'#FTO0|QhO'#FSOOQW'#Gs'#GsOsQhO'#FXO!]QhO'#F[O1TQhO'#FZOOQW'#Gu'#GuO!]QhO'#F`O1[QhO'#F_OOQW'#Gw'#GwOOQW'#Fd'#FdOOQW'#Ff'#FfOOQW'#Gx'#GxO1cQhO'#FgOOQW'#Gy'#GyOsQhO'#FiOOQW'#Gz'#GzOsQhO'#FkOOQW'#G{'#G{OsQhO'#FmOOQW'#G|'#G|OsQhO'#FoOOQW'#G}'#G}OsQhO'#FrO1hQhO'#FqOOQW'#HP'#HPOsQhO'#FvOOQW'#HQ'#HQOsQhO'#FxOOQW'#Gj'#GjOOQW'#GT'#GTO1oQhO1G0xOOOP1G0x1G0xOOOP1G/]1G/]O1vQhO,59tOOOP1G/f1G/fO1{QhO,59}OOOP1G/k1G/kO2QQhO,5:SOOOP1G/r1G/rO2VQhO,5:^OOOP1G/z1G/zO2[QhO,5:cOOOS-E:O-E:OOOOP1G0V1G0VO2aQxO'#ETOOOQ-E:P-E:POOOP1G0]1G0]O2fQxO'#EZOOOP1G0o1G0oO2kQhO,5;WOOQW1G.n1G.nO2pQ!jO1G.qO5aQ!jO1G.rO5hQ!jO1G.rOOQW'#DP'#DPO7vQhO,59iOOQW-E9z-E9zOOOP7+$W7+$WO9pQ!jO1G.rO9wQ!jO1G.vOsQhO1G.zO<VQhO7+$tOOOP7+$t7+$tOOOP7+$x7+$xOOOP7+$|7+$|OOOP7+%R7+%ROOOP7+%W7+%WOsQhO'#F}O<_QhO7+%[OOOP7+%[7+%[OOQW'#Gf'#GfOsQhO7+%_OsQhO7+%gO<gQhO'#GPO<lQhO7+%oOOOP7+%o7+%oO<tQhO7+%oO<yQhO7+%}OOOP7+%}7+%}OOQW'#Gg'#GgO!]QhO'#EaOsQhO'#EaOOQW'#GS'#GSO=RQhO7+&POOOP7+&P7+&POOOP7+&V7+&VO=aQhO7+&XOOOP7+&X7+&XOOOP7+&[7+&[OOOP7+&`7+&`OOOP7+&b7+&bO=iQ!jO,5;aOOQW'#Gl'#GlOOQW'#Ew'#EwOOQW,5;`,5;`O0nQhO,5;`O>xQ!jO,5;fOOQW'#Gn'#GnOOQW'#E|'#E|OOQW,5;e,5;eO0uQhO,5;eO@XQ!jO,5;jOAzQ!jO,5;oOOQW'#Gr'#GrOOQW'#FV'#FVOOQW,5;n,5;nO0|QhO,5;nOCZQ!jO,5;sO/QQhO,5;vOOQW'#Gt'#GtOOQW'#F]'#F]OOQW,5;u,5;uO1TQhO,5;uO/QQhO,5;zOOQW'#Gv'#GvOOQW'#Fb'#FbOOQW,5;y,5;yO1[QhO,5;yOEPQhO,5<ROFvQ!jO,5<TOHiQ!jO,5<VOJbQ!jO,5<XOLTQ!jO,5<ZOMvQ!jO,5<^OOQW'#HO'#HOOOQW'#Ft'#FtOOQW,5<],5<]O1hQhO,5<]O! VQ!jO,5<bO!!xQ!jO,5<dOOQW-E:R-E:ROOOP7+&d7+&dOOOP1G/`1G/`OOOP1G/i1G/iOOOP1G/n1G/nOOOP1G/x1G/xOOOP1G/}1G/}O!$kQhO,5:oO!$pQhO,5:uOOOP1G0r1G0rOOQW7+$]7+$]OsQhO1G/TO!$uQ!jO7+$fOOOP<<H`<<H`O!$|Q!jO,5<iOOQW-E9{-E9{OOOP<<Hv<<HvO!&xQ!jO<<HyO!'SQ!jO<<IROOQW,5<k,5<kOOQW-E9}-E9}OOOP<<IZ<<IZO!'^QhO<<IZOOOP<<Ii<<IiO!'fQhO,5:{O!'kQ!jO,5:{OOQW-E:Q-E:QOOOP<<Ik<<IkOOOP<<Is<<IsOOQW1G0z1G0zOOQW1G1P1G1POOQW1G1Y1G1YO!)gQhO1G1_OsQhO1G1bOOQW1G1a1G1aOsQhO1G1fOOQW1G1e1G1eO!+ZQhO1G1mO!,}QhO1G1mO!-SQhO1G1oOOQW'#GU'#GUO!.vQhO1G1qO!0mQhO1G1uOOQW1G1w1G1wOOOP1G0Z1G0ZOOOP1G0a1G0aO!2aQ!jO7+$oOOQW<<HQ<<HQOOQW'#Dq'#DqO!4]QhO'#DpOOQW'#GO'#GOO!5vQhOAN>eOOOPAN>eAN>eO!6OQhOAN>mOOOPAN>mAN>mO!6WQhOAN>uOOOPAN>uAN>uOsQhO1G0gOOQW'#Gi'#GiO!]QhO1G0gO!6`Q!jO7+&|O!7rQ!jO7+'QO!9UQhO7+'XOOQW-E:S-E:SO!:xQhO<<HZOsQhO,5:[OOQW-E9|-E9|OOOPG24PG24POOOPG24XG24XOOOPG24aG24aO!<rQ!jO7+&ROOQW7+&R7+&RO!>kQhO<<JhO!?{QhO<<JlO!A]QhO<<JsO!CPQ!jO1G/v",stateData:"!Di~O%OOSUOS~OPROQSO$zPO~O$zPOPWXQWX$yWX~OgeOjiOkiOlfOmgOnhOoiOpiO%RbO~OwkOxjO{lO!PmO!RnO!UoO!ZpO!_qO!brO!jsO!ntO!puO!rvO!uwO!{xO#QyO#SzO#Y{O#[|O#_}O#c!OO#e!PO#g!QO~OPROQSOR!UO$zPO~OPROQSOR!XO$zPO~OPROQSOR![O$zPO~OPROQSOR!_O$zPO~OPROQSOR!bO$zPO~O$|!cO~O${!fO~OPROQSOR!kO$zPO~O]!mOa!uOb!oOc!pOr!qO%T!nO~OX!tO~P%}Oe!vOX%QX]%QXa%QXb%QXc%QXr%QX%T%QXi%QXx%QXu%QX#U%QX#V%QX%S%QXn%QX#j%QX#l%QX#o%QX#s%QX#u%QX#x%QX#|%QX$T%QX$X%QX$[%QX$^%QX$`%QX$b%QX$d%QX$g%QX$k%QX$m%QX#q%QX#z%QX$i%QXf%QX%R%QX#W%QX$Q%QX$V%QX~Or!qOx!zO~PsOx!}O~Ox#TO~Ox#UO~Oo#VO~Ox#WO~Ox#XO~OnhO#V#aO#j#bO#o#eO#s#hO#u#jO#x#lO#|#oO$T#sO$X#vO$[#yO$^#{O$`#}O$b$PO$d$RO$g$TO$k$WO$m$YO~Ox$_O~P*SO$zPOPWXQWXRWX~O}$aO~O!W$cO~O!]$eO~O!g$gO~O!l$iO~O$|!cOT!vX~OT$lO~O${!fOS!|X~OS$oO~O#a$qO~O^$rO~O%R$vO~OX$yOr!qO~O]!mOa!uOb!oOc!pO%T!nO~Oi$|O~P-aOx%OO~P%}Or!qOx%OO~Ox%PO~P-aOx%QO~P-aOx%RO~P-aOx%SO~P-aOu%TOx%VO~P-aO!c%WO~Ot%^Ou%ZOx%]O~Ox%`O~P%}Ou%bOx%fO#U%aO#V#aO~P-aOx%gO~P-aOx%iO~P%}Ox%jO~P-aOx%kO~P-aOx%lO~P-aO#l%nO~P*SO#q%sO~P*SO#z%yO~P*SO$Q&PO~P*SO$V&UO~P*SOo&YO~O$i&`O~P*SOx&gO~P*SOx&hO~Ox&iO~Ox&jO~Ox&kO~Ox&lO~O!x&mO~O#O&nO~Ox&oO~O%S&pO~P-aO]!mO%T!nOX`ia`ic`ir`ii`ix`iu`i#U`i#V`i%S`in`i#j`i#l`i#o`i#s`i#u`i#x`i#|`i$T`i$X`i$[`i$^`i$``i$b`i$d`i$g`i$k`i$m`i#q`i#z`i$i`if`i%R`i#W`i$Q`i$V`i~Ob`i~P2wOX`ir`ii`ix`iu`i#U`i#V`i%S`in`i#j`i#l`i#o`i#s`i#u`i#x`i#|`i$T`i$X`i$[`i$^`i$``i$b`i$d`i$g`i$k`i$m`i#q`i#z`i$i`if`i%R`i#W`i$Q`i$V`i~P-aOt&qOXqarqaxqanqa#Vqa#jqa#oqa#sqa#uqa#xqa#|qa$Tqa$Xqa$[qa$^qa$`qa$bqa$dqa$gqa$kqa$mqa#lqa#qqa#zqa$Qqa$Vqa$iqa~Ob!oO~P2wOXdirdiidixdiudi#Udi#Vdi%Sdindi#jdi#ldi#odi#sdi#udi#xdi#|di$Tdi$Xdi$[di$^di$`di$bdi$ddi$gdi$kdi$mdi#qdi#zdi$idifdi%Rdi#Wdi$Qdi$Vdi~P-aOr!qOx&sO~Ou%TOx&vO~Oo&yO~Ou%ZOx&{O~Oo&|O~Or!qOx&}O~Ou%bOx'RO#U%aO#V#aO~Or!qOx'SO~On#ia#V#ia#j#ia#l#ia#o#ia#s#ia#u#ia#x#ia#|#ia$T#ia$X#ia$[#ia$^#ia$`#ia$b#ia$d#ia$g#ia$k#ia$m#ia~P-aOn#na#V#na#j#na#o#na#q#na#s#na#u#na#x#na#|#na$T#na$X#na$[#na$^#na$`#na$b#na$d#na$g#na$k#na$m#na~P-aOn#rax#ra#V#ra#j#ra#o#ra#s#ra#u#ra#x#ra#|#ra$T#ra$X#ra$[#ra$^#ra$`#ra$b#ra$d#ra$g#ra$k#ra$m#ra#l#ra#q#ra#z#ra$Q#ra$V#ra$i#ra~P-aOn#wa#V#wa#j#wa#o#wa#s#wa#u#wa#x#wa#z#wa#|#wa$T#wa$X#wa$[#wa$^#wa$`#wa$b#wa$d#wa$g#wa$k#wa$m#wa~P-aOu%TOn#{ax#{a#V#{a#j#{a#o#{a#s#{a#u#{a#x#{a#|#{a$T#{a$X#{a$[#{a$^#{a$`#{a$b#{a$d#{a$g#{a$k#{a$m#{a#l#{a#q#{a#z#{a$Q#{a$V#{a$i#{a~P-aOt'^Ou%ZOn$Zax$Za#V$Za#j$Za#o$Za#s$Za#u$Za#x$Za#|$Za$T$Za$X$Za$[$Za$^$Za$`$Za$b$Za$d$Za$g$Za$k$Za$m$Za#l$Za#q$Za#z$Za$Q$Za$V$Za$i$Za~On$]ax$]a#V$]a#j$]a#o$]a#s$]a#u$]a#x$]a#|$]a$T$]a$X$]a$[$]a$^$]a$`$]a$b$]a$d$]a$g$]a$k$]a$m$]a#l$]a#q$]a#z$]a$Q$]a$V$]a$i$]a~P%}Ou%bO#U%aO#V#aOn$_ax$_a#j$_a#o$_a#s$_a#u$_a#x$_a#|$_a$T$_a$X$_a$[$_a$^$_a$`$_a$b$_a$d$_a$g$_a$k$_a$m$_a#l$_a#q$_a#z$_a$Q$_a$V$_a$i$_a~P-aOn$aax$aa#V$aa#j$aa#o$aa#s$aa#u$aa#x$aa#|$aa$T$aa$X$aa$[$aa$^$aa$`$aa$b$aa$d$aa$g$aa$k$aa$m$aa#l$aa#q$aa#z$aa$Q$aa$V$aa$i$aa~P-aOn$cax$ca#V$ca#j$ca#o$ca#s$ca#u$ca#x$ca#|$ca$T$ca$X$ca$[$ca$^$ca$`$ca$b$ca$d$ca$g$ca$k$ca$m$ca#l$ca#q$ca#z$ca$Q$ca$V$ca$i$ca~P%}On$fa#V$fa#j$fa#o$fa#s$fa#u$fa#x$fa#|$fa$T$fa$X$fa$[$fa$^$fa$`$fa$b$fa$d$fa$g$fa$i$fa$k$fa$m$fa~P-aOn$jax$ja#V$ja#j$ja#o$ja#s$ja#u$ja#x$ja#|$ja$T$ja$X$ja$[$ja$^$ja$`$ja$b$ja$d$ja$g$ja$k$ja$m$ja#l$ja#q$ja#z$ja$Q$ja$V$ja$i$ja~P-aOn$lax$la#V$la#j$la#o$la#s$la#u$la#x$la#|$la$T$la$X$la$[$la$^$la$`$la$b$la$d$la$g$la$k$la$m$la#l$la#q$la#z$la$Q$la$V$la$i$la~P-aOx'dO~Ox'eO~Of'gO~P-aOu$qax$qan$qa#V$qa#j$qa#o$qa#s$qa#u$qa#x$qa#|$qa$T$qa$X$qa$[$qa$^$qa$`$qa$b$qa$d$qa$g$qa$k$qa$m$qa#l$qa#q$qa#z$qa$Q$qa$V$qa$i$qaX$qar$qa~P-aOx'lO%R'hO~P-aOx'nO%R'hO~P-aOu%ZOx'pO~Ot'qO~O#W'rOu#Tax#Ta#U#Ta#V#Tan#Ta#j#Ta#o#Ta#s#Ta#u#Ta#x#Ta#|#Ta$T#Ta$X#Ta$[#Ta$^#Ta$`#Ta$b#Ta$d#Ta$g#Ta$k#Ta$m#Ta#l#Ta#q#Ta#z#Ta$Q#Ta$V#Ta$i#Ta~P-aOu%TOn#{ix#{i#V#{i#j#{i#o#{i#s#{i#u#{i#x#{i#|#{i$T#{i$X#{i$[#{i$^#{i$`#{i$b#{i$d#{i$g#{i$k#{i$m#{i#l#{i#q#{i#z#{i$Q#{i$V#{i$i#{i~Ou%ZOn$Zix$Zi#V$Zi#j$Zi#o$Zi#s$Zi#u$Zi#x$Zi#|$Zi$T$Zi$X$Zi$[$Zi$^$Zi$`$Zi$b$Zi$d$Zi$g$Zi$k$Zi$m$Zi#l$Zi#q$Zi#z$Zi$Q$Zi$V$Zi$i$Zi~Oo'vO~Or!qOn$]ix$]i#V$]i#j$]i#o$]i#s$]i#u$]i#x$]i#|$]i$T$]i$X$]i$[$]i$^$]i$`$]i$b$]i$d$]i$g$]i$k$]i$m$]i#l$]i#q$]i#z$]i$Q$]i$V$]i$i$]i~Ou%bO#U%aO#V#aOn$_ix$_i#j$_i#o$_i#s$_i#u$_i#x$_i#|$_i$T$_i$X$_i$[$_i$^$_i$`$_i$b$_i$d$_i$g$_i$k$_i$m$_i#l$_i#q$_i#z$_i$Q$_i$V$_i$i$_i~Or!qOn$cix$ci#V$ci#j$ci#o$ci#s$ci#u$ci#x$ci#|$ci$T$ci$X$ci$[$ci$^$ci$`$ci$b$ci$d$ci$g$ci$k$ci$m$ci#l$ci#q$ci#z$ci$Q$ci$V$ci$i$ci~Ou%TOXqqrqqxqqnqq#Vqq#jqq#oqq#sqq#uqq#xqq#|qq$Tqq$Xqq$[qq$^qq$`qq$bqq$dqq$gqq$kqq$mqq#lqq#qqq#zqq$Qqq$Vqq$iqq~P-aOt'yOx!dX%R!dXn!dX#V!dX#j!dX#o!dX#s!dX#u!dX#x!dX#|!dX$Q!dX$T!dX$X!dX$[!dX$^!dX$`!dX$b!dX$d!dX$g!dX$k!dX$m!dX$V!dX~Ox'{O%R'hO~Ox'|O%R'hO~Ou%ZOx'}O~O%R'hOn$Oq#V$Oq#j$Oq#o$Oq#s$Oq#u$Oq#x$Oq#|$Oq$Q$Oq$T$Oq$X$Oq$[$Oq$^$Oq$`$Oq$b$Oq$d$Oq$g$Oq$k$Oq$m$Oq~P-aO%R'hOn$Sq#V$Sq#j$Sq#o$Sq#s$Sq#u$Sq#x$Sq#|$Sq$T$Sq$V$Sq$X$Sq$[$Sq$^$Sq$`$Sq$b$Sq$d$Sq$g$Sq$k$Sq$m$Sq~P-aOu%ZOn$Zqx$Zq#V$Zq#j$Zq#o$Zq#s$Zq#u$Zq#x$Zq#|$Zq$T$Zq$X$Zq$[$Zq$^$Zq$`$Zq$b$Zq$d$Zq$g$Zq$k$Zq$m$Zq#l$Zq#q$Zq#z$Zq$Q$Zq$V$Zq$i$Zq~Ou%TOXqyrqyxqynqy#Vqy#jqy#oqy#sqy#uqy#xqy#|qy$Tqy$Xqy$[qy$^qy$`qy$bqy$dqy$gqy$kqy$mqy#lqy#qqy#zqy$Qqy$Vqy$iqy~Ou#Tqx#Tq#U#Tq#V#Tqn#Tq#j#Tq#o#Tq#s#Tq#u#Tq#x#Tq#|#Tq$T#Tq$X#Tq$[#Tq$^#Tq$`#Tq$b#Tq$d#Tq$g#Tq$k#Tq$m#Tq#l#Tq#q#Tq#z#Tq$Q#Tq$V#Tq$i#Tq~P-aO%R'hOn$Oy#V$Oy#j$Oy#o$Oy#s$Oy#u$Oy#x$Oy#|$Oy$Q$Oy$T$Oy$X$Oy$[$Oy$^$Oy$`$Oy$b$Oy$d$Oy$g$Oy$k$Oy$m$Oy~O%R'hOn$Sy#V$Sy#j$Sy#o$Sy#s$Sy#u$Sy#x$Sy#|$Sy$T$Sy$V$Sy$X$Sy$[$Sy$^$Sy$`$Sy$b$Sy$d$Sy$g$Sy$k$Sy$m$Sy~Ou%ZOn$Zyx$Zy#V$Zy#j$Zy#o$Zy#s$Zy#u$Zy#x$Zy#|$Zy$T$Zy$X$Zy$[$Zy$^$Zy$`$Zy$b$Zy$d$Zy$g$Zy$k$Zy$m$Zy#l$Zy#q$Zy#z$Zy$Q$Zy$V$Zy$i$Zy~Ox!di%R!din!di#V!di#j!di#o!di#s!di#u!di#x!di#|!di$Q!di$T!di$X!di$[!di$^!di$`!di$b!di$d!di$g!di$k!di$m!di$V!di~P-aO",goto:"@p%uPPPPPPPP%vP%v&W'hPP'h'hPPP'hPPP'hPPPPPPPP(fP(vPP(yPP(y)ZP)kP(yP(yP(y)qP*RP(y*XP*iP(yP(y*oPP+P+Z+eP(y+kP+{P(yP(yP(yP(y,RP,c,fP(y,iP,y,|P(yP(yP-PPPP(yP(yP(y-XP-iP(yP(yP(yP-o.PP.aP-o.gP.wP-oP-oP-o.}P/_P-oP-o/e/uP-o/{P0]P-oP-o-oP-oP-oP-oP-oP-o0cP0sP-oP-oP0y1i2P2o2}3a3s3y4P4V4uPPPPPP4{5]PPP'h'h8P%v9_9k9q:X:[:l:|;Q;b;f;v<W<h<l<|=Q=b=f=v>W>h>x?Y?j?z@O@`m^OTUVWX[`!T!W!Z!^!a!j!vdReklmopqyz{|}!O!P!n!o!p!u!v#c#f#i#m#p#|$O$Q$S$U$X$Z$|%T%X%Y%c&q'X'Z'q'yQ#RrQ#SsQ&O#qQ&T#tQ'O%bR(P's!wiReklmopqyz{|}!O!P!n!o!p!u!v#c#f#i#m#p#|$O$Q$S$U$X$Z$|%T%X%Y%c&q'X'Z'q'ym!rck!s!x!y#Y#]$}%_%h&Z&^'_'bR$w!qm]OTUVWX[`!T!W!Z!^!a!jmTOTUVWX[`!T!W!Z!^!a!jQ!STR$`!TmUOTUVWX[`!T!W!Z!^!a!jQ!VUR$b!WmVOTUVWX[`!T!W!Z!^!a!jQ!YVR$d!ZmWOTUVWX[`!T!W!Z!^!a!ja'j&w&x'k'm't'u(Q(Ra'i&w&x'k'm't'u(Q(RQ!]WR$f!^mXOTUVWX[`!T!W!Z!^!a!jQ!`XR$h!amYOTUVWX[`!T!W!Z!^!a!jR!eYR$k!emZOTUVWX[`!T!W!Z!^!a!jR!hZR$n!hS%d#Z%eT'`&['am[OTUVWX[`!T!W!Z!^!a!jQ!i[R$p!jm$[!Q#d#g#n#r#u$V$^%q%v%|&S&X&cm#d!Q#d#g#n#r#u$V$^%q%v%|&S&X&cQ%p#dR'T%qm#g!Q#d#g#n#r#u$V$^%q%v%|&S&X&cQ%u#gR'U%vm#n!Q#d#g#n#r#u$V$^%q%v%|&S&X&cQ%{#nR'V%|m#r!Q#d#g#n#r#u$V$^%q%v%|&S&X&cQ&R#rR'Y&Sm#u!Q#d#g#n#r#u$V$^%q%v%|&S&X&cQ&W#uR'[&Xm$V!Q#d#g#n#r#u$V$^%q%v%|&S&X&cQ&b$VR'c&cQ`OQ!TTQ!WUQ!ZVQ!^WQ!aXQ!j[_!l`!T!W!Z!^!a!jSQO`SaQ!Ri!RTUVWX[!T!W!Z!^!a!jQ!scQ!yk^$x!s!y$}%_%h'_'bQ$}!xQ%_#YQ%h#]Q'_&ZR'b&^Q%U#QU&u%U'W'xQ'W%}R'x'fQ'k&wQ'm&xW'z'k'm(Q(RQ(Q'tR(R'uQ%[#VW&z%[']'o(SQ']&YQ'o&|R(S'vQ!dYR$j!dQ!gZR$m!gQ%e#ZR'Q%eQ$^!QQ%q#dQ%v#gQ%|#nQ&S#rQ&X#uQ&c$V_&f$^%q%v%|&S&X&cQ'a&[R'w'am_OTUVWX[`!T!W!Z!^!a!jQcRQ!weQ!xkQ!{lQ!|mQ#OoQ#PpQ#QqQ#YyQ#ZzQ#[{Q#]|Q#^}Q#_!OQ#`!PQ$s!nQ$t!oQ$u!pQ$z!uQ${!vQ%m#cQ%r#fQ%w#iQ%x#mQ%}#pQ&Z#|Q&[$OQ&]$QQ&^$SQ&_$UQ&d$XQ&e$ZQ&r$|Q&t%TQ&w%XQ&x%YQ'P%cQ'f&qQ't'XQ'u'ZQ(O'qR(T'y!viReklmopqyz{|}!O!P!n!o!p!u!v#c#f#i#m#p#|$O$Q$S$U$X$Z$|%T%X%Y%c&q'X'Z'q'ym#x!Q#d#g#n#r#u$V$^%q%v%|&S&X&cQ%X#RQ%Y#SQ'X&OR'Z&TX%c#Z%e&['al#q!Q#d#g#n#r#u$V$^%q%v%|&S&X&cX%c#Z%e&['aR's'Pm$]!Q#d#g#n#r#u$V$^%q%v%|&S&X&cm#c!Q#d#g#n#r#u$V$^%q%v%|&S&X&cT%o#d%qm#f!Q#d#g#n#r#u$V$^%q%v%|&S&X&cT%t#g%vm#i!Q#d#g#n#r#u$V$^%q%v%|&S&X&cm#k!Q#d#g#n#r#u$V$^%q%v%|&S&X&cm#m!Q#d#g#n#r#u$V$^%q%v%|&S&X&cT%z#n%|m#p!Q#d#g#n#r#u$V$^%q%v%|&S&X&cT&Q#r&Sm#t!Q#d#g#n#r#u$V$^%q%v%|&S&X&cT&V#u&Xm#w!Q#d#g#n#r#u$V$^%q%v%|&S&X&cm#z!Q#d#g#n#r#u$V$^%q%v%|&S&X&cm#|!Q#d#g#n#r#u$V$^%q%v%|&S&X&cm$O!Q#d#g#n#r#u$V$^%q%v%|&S&X&cm$Q!Q#d#g#n#r#u$V$^%q%v%|&S&X&cm$S!Q#d#g#n#r#u$V$^%q%v%|&S&X&cm$U!Q#d#g#n#r#u$V$^%q%v%|&S&X&cT&a$V&cm$X!Q#d#g#n#r#u$V$^%q%v%|&S&X&cm$Z!Q#d#g#n#r#u$V$^%q%v%|&S&X&c",nodeNames:`⚠ {{ {% {% {% {% InlineComment Template Text }} Interpolation VariableName MemberExpression . PropertyName SubscriptExpression BinaryExpression contains CompareOp LogicOp AssignmentExpression AssignOp ) ( RangeExpression .. BooleanLiteral empty forloop tablerowloop continue StringLiteral NumberLiteral Filter | FilterName : , Tag TagName %} IfDirective Tag if EndTag endif Tag elsif Tag else UnlessDirective Tag unless EndTag endunless CaseDirective Tag case EndTag endcase Tag when ForDirective Tag for in Parameter ParameterName EndTag endfor TableDirective Tag tablerow EndTag endtablerow Tag break Tag continue Tag cycle Comment Tag comment CommentText EndTag endcomment RawDirective Tag raw RawText EndTag endraw Tag echo Tag render RenderParameter with for as Tag include Tag assign CaptureDirective Tag capture EndTag endcapture Tag increment Tag decrement Tag liquid IfDirective Tag if EndTag endif UnlessDirective Tag unless EndTag endunless Tag elsif Tag else CaseDirective Tag case EndTag endcase Tag when ForDirective Tag EndTag endfor TableDirective Tag tablerow EndTag endtablerow Tag break Tag Tag cycle Tag echo Tag render Tag include Tag assign CaptureDirective Tag capture EndTag endcapture Tag increment Tag decrement`,maxTerm:220,nodeProps:[[`closedBy`,1,`}}`,-4,2,3,4,5,`%}`,23,`)`],[`openedBy`,9,`{{`,22,`(`,40,`{%`],[`group`,-13,11,12,15,16,20,24,26,27,28,29,30,31,32,`Expression`]],skippedNodes:[0,6],repeatNodeCount:11,tokenData:")e~RmXY!|YZ!|]^!|pq!|qr#_rs#juv$[wx$gxy%Syz%X{|%^|}&x}!O&}!O!P'Z!Q![&g![!]'k!^!_'p!_!`'x!`!a'p!c!}(Q!}#O(y#P#Q)O#R#S(Q#T#o(Q#p#q)T#q#r)Y%W;'S(Q;'S;:j(s<%lO(Q~#RS%O~XY!|YZ!|]^!|pq!|~#bP!_!`#e~#jOb~~#mUOY#jZr#jrs$Ps;'S#j;'S;=`$U<%lO#j~$UOo~~$XP;=`<%l#j~$_P#q#r$b~$gOx~~$jUOY$gZw$gwx$Px;'S$g;'S;=`$|<%lO$g~%PP;=`<%l$g~%XOg~~%^Of~P%aQ!O!P%g!Q![&gP%jP!Q![%mP%rRpP!Q![%m!g!h%{#X#Y%{P&OR{|&X}!O&X!Q![&_P&[P!Q![&_P&dPpP!Q![&_P&lSpP!O!P%g!Q![&g!g!h%{#X#Y%{~&}Ou~~'QRuv$[!O!P%g!Q![&g~'`Q]S!O!P'f!Q![%m~'kOi~~'pOt~~'uPb~!_!`#e~'}Pe~!_!`#e_(ZW^WwQ%RT}!O(Q!Q![(Q!c!}(Q#R#S(Q#T#o(Q%W;'S(Q;'S;:j(s<%lO(Q_(vP;=`<%l(Q~)OO%T~~)TO%S~~)YOr~~)]P#q#r)`~)eOX~",tokenizers:[w,D,E,O,0,1,2,3],topRules:{Template:[0,7]},dynamicPrecedences:{190:1,191:1,192:1,194:1,195:1,196:1,197:1,199:1,200:1,201:1,202:1,203:1,204:1,205:1,206:1,207:1,208:1,209:1,210:1,211:1,212:1,213:1,214:1,215:1,216:1,217:1,218:1,219:1,220:1},specialized:[{term:187,get:e=>k[e]||-1},{term:39,get:e=>A[e]||-1}],tokenPrec:0});function M(e,t){return e.split(` `).map(e=>({label:e,type:t}))}var N=M(`abs append at_least at_most capitalize ceil compact concat date default divided_by downcase escape escape_once first floor join last lstrip map minus modulo newline_to_br plus prepend remove remove_first replace replace_first reverse round rstrip size slice sort sort_natural split strip strip_html strip_newlines sum times truncate truncatewords uniq upcase url_decode url_encode where`,`function`),P=M(`cycle comment endcomment raw endraw echo increment decrement liquid if elsif else endif unless endunless case endcase for endfor tablerow endtablerow break continue assign capture endcapture render include`,`keyword`),F=M(`empty forloop tablerowloop in with as`,`keyword`),I=M(`first index index0 last length rindex`,`property`),L=M(`col col0 col_first col_last first index index0 last length rindex rindex0 row`,`property`);function R(e){let{state:t,pos:n}=e,r=o(t).resolveInner(n,-1).enterUnfinishedNodesBefore(n),i=r.childBefore(n)?.name||r.name;if(r.name==`FilterName`)return{type:`filter`,node:r};if(e.explicit&&i==`|`)return{type:`filter`};if(r.name==`TagName`)return{type:`tag`,node:r};if(e.explicit&&i==`{%`)return{type:`tag`};if(r.name==`PropertyName`&&r.parent.name==`MemberExpression`)return{type:`property`,node:r,target:r.parent};if(r.name==`.`&&r.parent.name==`MemberExpression`)return{type:`property`,target:r.parent};if(r.name==`MemberExpression`&&i==`.`)return{type:`property`,target:r};if(r.name==`VariableName`)return{type:`expression`,from:r.from};let a=e.matchBefore(/[\w\u00c0-\uffff]+$/);return a?{type:`expression`,from:a.from}:e.explicit&&r.name!=`CommentText`&&r.name!=`StringLiteral`&&r.name!=`NumberLiteral`&&r.name!=`InlineComment`?{type:`expression`}:null}function z(e,t,n,r){let i=[];for(;;){let n=t.getChild(`Expression`);if(!n)return[];if(n.name==`VariableName`||n.name==`forloop`||n.name==`tablerowloop`){let t=e.sliceDoc(n.from,n.to);if(t==`forloop`)return i.length?[]:I;if(t==`tablerowloop`)return i.length?[]:L;i.unshift(t);break}else if(n.name==`MemberExpression`){let r=n.getChild(`PropertyName`);r&&i.unshift(e.sliceDoc(r.from,r.to)),t=n}else if(n.name==`SubscriptExpression`){let r=n.getChildren(`Expression`)[1];i.unshift(r?.name==`StringLiteral`?e.sliceDoc(r.from+1,r.to-1):`[]`),t=n}else return[]}return r?r(i,e,n):[]}function B(e={}){let t=e.filters?e.filters.concat(N):N,n=e.tags?e.tags.concat(P):P,r=e.variables?e.variables.concat(F):F,{properties:i}=e;return e=>{let a=R(e);if(!a)return null;let o=a.from??(a.node?a.node.from:e.pos),s;return s=a.type==`filter`?t:a.type==`tag`?n:a.type==`expression`?r:z(e.state,a.target,e,i),s.length?{options:s,from:o,validFor:/^[\w\u00c0-\uffff]*$/}:null}}var V=t.inputHandler.of((e,t,n,r)=>r!=`%`||t!=n||e.state.doc.sliceString(t-1,n+1)!=`{}`?!1:(e.dispatch(e.state.changeByRange(e=>({changes:{from:e.from,to:e.to,insert:`%%`},range:a.cursor(e.from+1)})),{scrollIntoView:!0,userEvent:`input.type`}),!0));function H(e){return t=>{let n=e.test(t.textAfter);return t.lineIndent(t.node.from)+(n?0:t.unit)}}var U=l.define({name:`liquid`,parser:j.configure({props:[n({"cycle comment endcomment raw endraw echo increment decrement liquid in with as":r.keyword,"empty forloop tablerowloop":r.atom,"if elsif else endif unless endunless case endcase for endfor tablerow endtablerow break continue":r.controlKeyword,"assign capture endcapture":r.definitionKeyword,contains:r.operatorKeyword,"render include":r.moduleKeyword,VariableName:r.variableName,TagName:r.tagName,FilterName:r.function(r.variableName),PropertyName:r.propertyName,CompareOp:r.compareOperator,AssignOp:r.definitionOperator,LogicOp:r.logicOperator,NumberLiteral:r.number,StringLiteral:r.string,BooleanLiteral:r.bool,InlineComment:r.lineComment,CommentText:r.blockComment,"{% %} {{ }}":r.brace,"[ ]":r.bracket,"( )":r.paren,".":r.derefOperator,", .. : |":r.punctuation}),e.add({Tag:s({closing:`%}`}),"UnlessDirective ForDirective TablerowDirective CaptureDirective":H(/^\s*(\{%-?\s*)?end\w/),IfDirective:H(/^\s*(\{%-?\s*)?(endif|else|elsif)\b/),CaseDirective:H(/^\s*(\{%-?\s*)?(endcase|when)\b/)}),u.add({"UnlessDirective ForDirective TablerowDirective CaptureDirective IfDirective CaseDirective RawDirective Comment"(e){let t=e.firstChild,n=e.lastChild;return!t||t.name!=`Tag`?null:{from:t.to,to:n.name==`EndTag`?n.from:e.to}}})]}),languageData:{commentTokens:{line:`#`},indentOnInput:/^\s*{%-?\s*(?:end|elsif|else|when|)$/}}),W=p();function G(e){return U.configure({wrap:i(t=>t.type.isTop?{parser:e.parser,overlay:e=>e.name==`Text`||e.name==`RawText`}:null)},`liquid`)}var K=G(W.language);function q(e={}){let t=e.base||W,n=t.language==W.language?K:G(t.language);return new c(n,[t.support,n.data.of({autocomplete:B(e)}),t.language.data.of({closeBrackets:{brackets:[`{`]}}),V])}export{q as liquid};
|
|
1
|
+
import{C as e,K as t,N as n,P as r,U as i,_t as a,j as o,m as s,o as c,r as l,y as u}from"./dist-SVPsM5Oi.js";import{n as d,r as f}from"./dist-tGfufz3b.js";import{html as p}from"./dist-BDxKfyTI.js";var m=1,h=2,g=3,_=180,v=4,y=181,b=5,x=182,S=6;function C(e){return e>=65&&e<=90||e>=97&&e<=122}var w=new d(e=>{let t=e.pos;for(;;){let{next:n}=e;if(n<0)break;if(n==123){let n=e.peek(1);if(n==123){if(e.pos>t)break;e.acceptToken(m,2);return}else if(n==37){if(e.pos>t)break;let n=2,r=2;for(;;){let t=e.peek(n);if(t==32||t==10)++n;else if(t==35)for(++n;;){let t=e.peek(n);if(t<0||t==10)break;n++}else if(t==45&&r==2)r=++n;else{let i=t==101&&e.peek(n+1)==110&&e.peek(n+2)==100;e.acceptToken(i?g:h,r);return}}}}if(e.advance(),n==10)break}e.pos>t&&e.acceptToken(_)});function T(e,t,n){return new d(r=>{let i=r.pos;for(;;){let{next:t}=r;if(t==123&&r.peek(1)==37){let t=2;for(;;t++){let e=r.peek(t);if(e!=32&&e!=10)break}let a=``;for(;;t++){let e=r.peek(t);if(!C(e))break;a+=String.fromCharCode(e)}if(a==e){if(r.pos>i)break;r.acceptToken(n,2);break}}else if(t<0)break;if(r.advance(),t==10)break}r.pos>i&&r.acceptToken(t)})}var E=T(`endcomment`,x,b),D=T(`endraw`,y,v),O=new d(e=>{if(e.next==35){for(e.advance();!(e.next==10||e.next<0||(e.next==37||e.next==125)&&e.peek(1)==125);)e.advance();e.acceptToken(S)}}),k={__proto__:null,contains:34,or:38,and:38,true:52,false:52,empty:54,forloop:57,tablerowloop:59,continue:61,in:131,with:197,for:199,as:201,if:237,endif:241,unless:247,endunless:251,elsif:255,else:259,case:265,endcase:269,when:273,endfor:281,tablerow:287,endtablerow:291,break:295,cycle:301,echo:305,render:309,include:313,assign:317,capture:323,endcapture:327,increment:331,decrement:335},A={__proto__:null,if:86,endif:90,elsif:94,else:98,unless:104,endunless:108,case:114,endcase:118,when:122,for:128,endfor:138,tablerow:144,endtablerow:148,break:152,continue:156,cycle:160,comment:166,endcomment:172,raw:178,endraw:184,echo:188,render:192,include:204,assign:208,capture:214,endcapture:218,increment:222,decrement:226,liquid:230},j=f.deserialize({version:14,states:"KtQYOPOOOOOP'#F{'#F{OeOaO'#CdOsQhO'#CfO!bQxO'#DSO#{OPO'#DVO$ZOPO'#D`O$iOPO'#DeO$wOPO'#DlO%VOPO'#DtO%eOSO'#EPO%jOQO'#EVO%oOPO'#EiOOOP'#Ge'#GeOOOP'#G]'#G]OOOP'#Fz'#FzQYOPOOOOOP-E9y-E9yOOQW'#Cg'#CgO&cQ!jO,59QO&jQ!jO'#G^OsQhO'#CtOOQW'#Gb'#GbOOQW'#Gc'#GcOOQW'#Gd'#GdOOQW'#G^'#G^OOOP,59n,59nO)YQhO,59nOsQhO,59rOsQhO,59vO)dQhO,59xOsQhO,59{OsQhO,5:QOsQhO,5:UO!]QhO,5:XO!]QhO,5:aO)iQhO,5:eO)nQhO,5:gO)sQhO,5:iO)xQhO,5:lO)}QhO,5:rOsQhO,5:wOsQhO,5:yOsQhO,5;POsQhO,5;ROsQhO,5;UOsQhO,5;YOsQhO,5;[O+^QhO,5;^O+eOPO'#CdOOOP,59q,59qO#{OPO,59qO+sQxO'#DYOOOP,59z,59zO$ZOPO,59zO+xQxO'#DcOOOP,5:P,5:PO$iOPO,5:PO+}QxO'#DhOOOP,5:W,5:WO$wOPO,5:WO,SQxO'#DrOOOP,5:`,5:`O%VOPO,5:`O,XQxO'#DwOOOS'#GQ'#GQO,^OSO'#ESO,fOSO,5:kOOOQ'#GR'#GRO,kOQO'#EYO,sOQO,5:qOOOP,5;T,5;TO%oOPO,5;TO,xQxO'#ElOOOP-E9x-E9xO,}Q#|O,59SOsQhO,59VOsQhO,59WOsQhO,59WO-SQhO'#C}OOQW'#F|'#F|O-XQhO1G.lOOOP1G.l1G.lOsQhO,59WOsQhO,59[O-rQ!jO,59`O-yQ!jO1G/YO.QQhO1G/YOOOP1G/Y1G/YO.YQ!jO1G/^O.aQ!jO1G/bOOOP1G/d1G/dO.hQ!jO1G/gO.oQ!jO1G/lO.vQ!jO1G/pO/QQhO1G/sO/QQhO1G/{OOOP1G0P1G0POOOP1G0R1G0RO/VQhO1G0TOOOS1G0W1G0WOOOQ1G0^1G0^O/bQ!jO1G0cO/iQ!jO1G0eO/yQ!jO1G0kO0QQ!jO1G0mO0XQ!jO1G0pO0`Q!jO1G0tO0gQ!jO1G0vOOQW'#Gh'#GhOOQW'#Gk'#GkOsQhO'#EuO0nQhO'#EtOOQW'#Gm'#GmOsQhO'#EzO0uQhO'#EyOOQW'#Go'#GoOsQhO'#FOOOQW'#Gp'#GpOOQW'#FQ'#FQOOQW'#Gq'#GqOsQhO'#FTO0|QhO'#FSOOQW'#Gs'#GsOsQhO'#FXO!]QhO'#F[O1TQhO'#FZOOQW'#Gu'#GuO!]QhO'#F`O1[QhO'#F_OOQW'#Gw'#GwOOQW'#Fd'#FdOOQW'#Ff'#FfOOQW'#Gx'#GxO1cQhO'#FgOOQW'#Gy'#GyOsQhO'#FiOOQW'#Gz'#GzOsQhO'#FkOOQW'#G{'#G{OsQhO'#FmOOQW'#G|'#G|OsQhO'#FoOOQW'#G}'#G}OsQhO'#FrO1hQhO'#FqOOQW'#HP'#HPOsQhO'#FvOOQW'#HQ'#HQOsQhO'#FxOOQW'#Gj'#GjOOQW'#GT'#GTO1oQhO1G0xOOOP1G0x1G0xOOOP1G/]1G/]O1vQhO,59tOOOP1G/f1G/fO1{QhO,59}OOOP1G/k1G/kO2QQhO,5:SOOOP1G/r1G/rO2VQhO,5:^OOOP1G/z1G/zO2[QhO,5:cOOOS-E:O-E:OOOOP1G0V1G0VO2aQxO'#ETOOOQ-E:P-E:POOOP1G0]1G0]O2fQxO'#EZOOOP1G0o1G0oO2kQhO,5;WOOQW1G.n1G.nO2pQ!jO1G.qO5aQ!jO1G.rO5hQ!jO1G.rOOQW'#DP'#DPO7vQhO,59iOOQW-E9z-E9zOOOP7+$W7+$WO9pQ!jO1G.rO9wQ!jO1G.vOsQhO1G.zO<VQhO7+$tOOOP7+$t7+$tOOOP7+$x7+$xOOOP7+$|7+$|OOOP7+%R7+%ROOOP7+%W7+%WOsQhO'#F}O<_QhO7+%[OOOP7+%[7+%[OOQW'#Gf'#GfOsQhO7+%_OsQhO7+%gO<gQhO'#GPO<lQhO7+%oOOOP7+%o7+%oO<tQhO7+%oO<yQhO7+%}OOOP7+%}7+%}OOQW'#Gg'#GgO!]QhO'#EaOsQhO'#EaOOQW'#GS'#GSO=RQhO7+&POOOP7+&P7+&POOOP7+&V7+&VO=aQhO7+&XOOOP7+&X7+&XOOOP7+&[7+&[OOOP7+&`7+&`OOOP7+&b7+&bO=iQ!jO,5;aOOQW'#Gl'#GlOOQW'#Ew'#EwOOQW,5;`,5;`O0nQhO,5;`O>xQ!jO,5;fOOQW'#Gn'#GnOOQW'#E|'#E|OOQW,5;e,5;eO0uQhO,5;eO@XQ!jO,5;jOAzQ!jO,5;oOOQW'#Gr'#GrOOQW'#FV'#FVOOQW,5;n,5;nO0|QhO,5;nOCZQ!jO,5;sO/QQhO,5;vOOQW'#Gt'#GtOOQW'#F]'#F]OOQW,5;u,5;uO1TQhO,5;uO/QQhO,5;zOOQW'#Gv'#GvOOQW'#Fb'#FbOOQW,5;y,5;yO1[QhO,5;yOEPQhO,5<ROFvQ!jO,5<TOHiQ!jO,5<VOJbQ!jO,5<XOLTQ!jO,5<ZOMvQ!jO,5<^OOQW'#HO'#HOOOQW'#Ft'#FtOOQW,5<],5<]O1hQhO,5<]O! VQ!jO,5<bO!!xQ!jO,5<dOOQW-E:R-E:ROOOP7+&d7+&dOOOP1G/`1G/`OOOP1G/i1G/iOOOP1G/n1G/nOOOP1G/x1G/xOOOP1G/}1G/}O!$kQhO,5:oO!$pQhO,5:uOOOP1G0r1G0rOOQW7+$]7+$]OsQhO1G/TO!$uQ!jO7+$fOOOP<<H`<<H`O!$|Q!jO,5<iOOQW-E9{-E9{OOOP<<Hv<<HvO!&xQ!jO<<HyO!'SQ!jO<<IROOQW,5<k,5<kOOQW-E9}-E9}OOOP<<IZ<<IZO!'^QhO<<IZOOOP<<Ii<<IiO!'fQhO,5:{O!'kQ!jO,5:{OOQW-E:Q-E:QOOOP<<Ik<<IkOOOP<<Is<<IsOOQW1G0z1G0zOOQW1G1P1G1POOQW1G1Y1G1YO!)gQhO1G1_OsQhO1G1bOOQW1G1a1G1aOsQhO1G1fOOQW1G1e1G1eO!+ZQhO1G1mO!,}QhO1G1mO!-SQhO1G1oOOQW'#GU'#GUO!.vQhO1G1qO!0mQhO1G1uOOQW1G1w1G1wOOOP1G0Z1G0ZOOOP1G0a1G0aO!2aQ!jO7+$oOOQW<<HQ<<HQOOQW'#Dq'#DqO!4]QhO'#DpOOQW'#GO'#GOO!5vQhOAN>eOOOPAN>eAN>eO!6OQhOAN>mOOOPAN>mAN>mO!6WQhOAN>uOOOPAN>uAN>uOsQhO1G0gOOQW'#Gi'#GiO!]QhO1G0gO!6`Q!jO7+&|O!7rQ!jO7+'QO!9UQhO7+'XOOQW-E:S-E:SO!:xQhO<<HZOsQhO,5:[OOQW-E9|-E9|OOOPG24PG24POOOPG24XG24XOOOPG24aG24aO!<rQ!jO7+&ROOQW7+&R7+&RO!>kQhO<<JhO!?{QhO<<JlO!A]QhO<<JsO!CPQ!jO1G/v",stateData:"!Di~O%OOSUOS~OPROQSO$zPO~O$zPOPWXQWX$yWX~OgeOjiOkiOlfOmgOnhOoiOpiO%RbO~OwkOxjO{lO!PmO!RnO!UoO!ZpO!_qO!brO!jsO!ntO!puO!rvO!uwO!{xO#QyO#SzO#Y{O#[|O#_}O#c!OO#e!PO#g!QO~OPROQSOR!UO$zPO~OPROQSOR!XO$zPO~OPROQSOR![O$zPO~OPROQSOR!_O$zPO~OPROQSOR!bO$zPO~O$|!cO~O${!fO~OPROQSOR!kO$zPO~O]!mOa!uOb!oOc!pOr!qO%T!nO~OX!tO~P%}Oe!vOX%QX]%QXa%QXb%QXc%QXr%QX%T%QXi%QXx%QXu%QX#U%QX#V%QX%S%QXn%QX#j%QX#l%QX#o%QX#s%QX#u%QX#x%QX#|%QX$T%QX$X%QX$[%QX$^%QX$`%QX$b%QX$d%QX$g%QX$k%QX$m%QX#q%QX#z%QX$i%QXf%QX%R%QX#W%QX$Q%QX$V%QX~Or!qOx!zO~PsOx!}O~Ox#TO~Ox#UO~Oo#VO~Ox#WO~Ox#XO~OnhO#V#aO#j#bO#o#eO#s#hO#u#jO#x#lO#|#oO$T#sO$X#vO$[#yO$^#{O$`#}O$b$PO$d$RO$g$TO$k$WO$m$YO~Ox$_O~P*SO$zPOPWXQWXRWX~O}$aO~O!W$cO~O!]$eO~O!g$gO~O!l$iO~O$|!cOT!vX~OT$lO~O${!fOS!|X~OS$oO~O#a$qO~O^$rO~O%R$vO~OX$yOr!qO~O]!mOa!uOb!oOc!pO%T!nO~Oi$|O~P-aOx%OO~P%}Or!qOx%OO~Ox%PO~P-aOx%QO~P-aOx%RO~P-aOx%SO~P-aOu%TOx%VO~P-aO!c%WO~Ot%^Ou%ZOx%]O~Ox%`O~P%}Ou%bOx%fO#U%aO#V#aO~P-aOx%gO~P-aOx%iO~P%}Ox%jO~P-aOx%kO~P-aOx%lO~P-aO#l%nO~P*SO#q%sO~P*SO#z%yO~P*SO$Q&PO~P*SO$V&UO~P*SOo&YO~O$i&`O~P*SOx&gO~P*SOx&hO~Ox&iO~Ox&jO~Ox&kO~Ox&lO~O!x&mO~O#O&nO~Ox&oO~O%S&pO~P-aO]!mO%T!nOX`ia`ic`ir`ii`ix`iu`i#U`i#V`i%S`in`i#j`i#l`i#o`i#s`i#u`i#x`i#|`i$T`i$X`i$[`i$^`i$``i$b`i$d`i$g`i$k`i$m`i#q`i#z`i$i`if`i%R`i#W`i$Q`i$V`i~Ob`i~P2wOX`ir`ii`ix`iu`i#U`i#V`i%S`in`i#j`i#l`i#o`i#s`i#u`i#x`i#|`i$T`i$X`i$[`i$^`i$``i$b`i$d`i$g`i$k`i$m`i#q`i#z`i$i`if`i%R`i#W`i$Q`i$V`i~P-aOt&qOXqarqaxqanqa#Vqa#jqa#oqa#sqa#uqa#xqa#|qa$Tqa$Xqa$[qa$^qa$`qa$bqa$dqa$gqa$kqa$mqa#lqa#qqa#zqa$Qqa$Vqa$iqa~Ob!oO~P2wOXdirdiidixdiudi#Udi#Vdi%Sdindi#jdi#ldi#odi#sdi#udi#xdi#|di$Tdi$Xdi$[di$^di$`di$bdi$ddi$gdi$kdi$mdi#qdi#zdi$idifdi%Rdi#Wdi$Qdi$Vdi~P-aOr!qOx&sO~Ou%TOx&vO~Oo&yO~Ou%ZOx&{O~Oo&|O~Or!qOx&}O~Ou%bOx'RO#U%aO#V#aO~Or!qOx'SO~On#ia#V#ia#j#ia#l#ia#o#ia#s#ia#u#ia#x#ia#|#ia$T#ia$X#ia$[#ia$^#ia$`#ia$b#ia$d#ia$g#ia$k#ia$m#ia~P-aOn#na#V#na#j#na#o#na#q#na#s#na#u#na#x#na#|#na$T#na$X#na$[#na$^#na$`#na$b#na$d#na$g#na$k#na$m#na~P-aOn#rax#ra#V#ra#j#ra#o#ra#s#ra#u#ra#x#ra#|#ra$T#ra$X#ra$[#ra$^#ra$`#ra$b#ra$d#ra$g#ra$k#ra$m#ra#l#ra#q#ra#z#ra$Q#ra$V#ra$i#ra~P-aOn#wa#V#wa#j#wa#o#wa#s#wa#u#wa#x#wa#z#wa#|#wa$T#wa$X#wa$[#wa$^#wa$`#wa$b#wa$d#wa$g#wa$k#wa$m#wa~P-aOu%TOn#{ax#{a#V#{a#j#{a#o#{a#s#{a#u#{a#x#{a#|#{a$T#{a$X#{a$[#{a$^#{a$`#{a$b#{a$d#{a$g#{a$k#{a$m#{a#l#{a#q#{a#z#{a$Q#{a$V#{a$i#{a~P-aOt'^Ou%ZOn$Zax$Za#V$Za#j$Za#o$Za#s$Za#u$Za#x$Za#|$Za$T$Za$X$Za$[$Za$^$Za$`$Za$b$Za$d$Za$g$Za$k$Za$m$Za#l$Za#q$Za#z$Za$Q$Za$V$Za$i$Za~On$]ax$]a#V$]a#j$]a#o$]a#s$]a#u$]a#x$]a#|$]a$T$]a$X$]a$[$]a$^$]a$`$]a$b$]a$d$]a$g$]a$k$]a$m$]a#l$]a#q$]a#z$]a$Q$]a$V$]a$i$]a~P%}Ou%bO#U%aO#V#aOn$_ax$_a#j$_a#o$_a#s$_a#u$_a#x$_a#|$_a$T$_a$X$_a$[$_a$^$_a$`$_a$b$_a$d$_a$g$_a$k$_a$m$_a#l$_a#q$_a#z$_a$Q$_a$V$_a$i$_a~P-aOn$aax$aa#V$aa#j$aa#o$aa#s$aa#u$aa#x$aa#|$aa$T$aa$X$aa$[$aa$^$aa$`$aa$b$aa$d$aa$g$aa$k$aa$m$aa#l$aa#q$aa#z$aa$Q$aa$V$aa$i$aa~P-aOn$cax$ca#V$ca#j$ca#o$ca#s$ca#u$ca#x$ca#|$ca$T$ca$X$ca$[$ca$^$ca$`$ca$b$ca$d$ca$g$ca$k$ca$m$ca#l$ca#q$ca#z$ca$Q$ca$V$ca$i$ca~P%}On$fa#V$fa#j$fa#o$fa#s$fa#u$fa#x$fa#|$fa$T$fa$X$fa$[$fa$^$fa$`$fa$b$fa$d$fa$g$fa$i$fa$k$fa$m$fa~P-aOn$jax$ja#V$ja#j$ja#o$ja#s$ja#u$ja#x$ja#|$ja$T$ja$X$ja$[$ja$^$ja$`$ja$b$ja$d$ja$g$ja$k$ja$m$ja#l$ja#q$ja#z$ja$Q$ja$V$ja$i$ja~P-aOn$lax$la#V$la#j$la#o$la#s$la#u$la#x$la#|$la$T$la$X$la$[$la$^$la$`$la$b$la$d$la$g$la$k$la$m$la#l$la#q$la#z$la$Q$la$V$la$i$la~P-aOx'dO~Ox'eO~Of'gO~P-aOu$qax$qan$qa#V$qa#j$qa#o$qa#s$qa#u$qa#x$qa#|$qa$T$qa$X$qa$[$qa$^$qa$`$qa$b$qa$d$qa$g$qa$k$qa$m$qa#l$qa#q$qa#z$qa$Q$qa$V$qa$i$qaX$qar$qa~P-aOx'lO%R'hO~P-aOx'nO%R'hO~P-aOu%ZOx'pO~Ot'qO~O#W'rOu#Tax#Ta#U#Ta#V#Tan#Ta#j#Ta#o#Ta#s#Ta#u#Ta#x#Ta#|#Ta$T#Ta$X#Ta$[#Ta$^#Ta$`#Ta$b#Ta$d#Ta$g#Ta$k#Ta$m#Ta#l#Ta#q#Ta#z#Ta$Q#Ta$V#Ta$i#Ta~P-aOu%TOn#{ix#{i#V#{i#j#{i#o#{i#s#{i#u#{i#x#{i#|#{i$T#{i$X#{i$[#{i$^#{i$`#{i$b#{i$d#{i$g#{i$k#{i$m#{i#l#{i#q#{i#z#{i$Q#{i$V#{i$i#{i~Ou%ZOn$Zix$Zi#V$Zi#j$Zi#o$Zi#s$Zi#u$Zi#x$Zi#|$Zi$T$Zi$X$Zi$[$Zi$^$Zi$`$Zi$b$Zi$d$Zi$g$Zi$k$Zi$m$Zi#l$Zi#q$Zi#z$Zi$Q$Zi$V$Zi$i$Zi~Oo'vO~Or!qOn$]ix$]i#V$]i#j$]i#o$]i#s$]i#u$]i#x$]i#|$]i$T$]i$X$]i$[$]i$^$]i$`$]i$b$]i$d$]i$g$]i$k$]i$m$]i#l$]i#q$]i#z$]i$Q$]i$V$]i$i$]i~Ou%bO#U%aO#V#aOn$_ix$_i#j$_i#o$_i#s$_i#u$_i#x$_i#|$_i$T$_i$X$_i$[$_i$^$_i$`$_i$b$_i$d$_i$g$_i$k$_i$m$_i#l$_i#q$_i#z$_i$Q$_i$V$_i$i$_i~Or!qOn$cix$ci#V$ci#j$ci#o$ci#s$ci#u$ci#x$ci#|$ci$T$ci$X$ci$[$ci$^$ci$`$ci$b$ci$d$ci$g$ci$k$ci$m$ci#l$ci#q$ci#z$ci$Q$ci$V$ci$i$ci~Ou%TOXqqrqqxqqnqq#Vqq#jqq#oqq#sqq#uqq#xqq#|qq$Tqq$Xqq$[qq$^qq$`qq$bqq$dqq$gqq$kqq$mqq#lqq#qqq#zqq$Qqq$Vqq$iqq~P-aOt'yOx!dX%R!dXn!dX#V!dX#j!dX#o!dX#s!dX#u!dX#x!dX#|!dX$Q!dX$T!dX$X!dX$[!dX$^!dX$`!dX$b!dX$d!dX$g!dX$k!dX$m!dX$V!dX~Ox'{O%R'hO~Ox'|O%R'hO~Ou%ZOx'}O~O%R'hOn$Oq#V$Oq#j$Oq#o$Oq#s$Oq#u$Oq#x$Oq#|$Oq$Q$Oq$T$Oq$X$Oq$[$Oq$^$Oq$`$Oq$b$Oq$d$Oq$g$Oq$k$Oq$m$Oq~P-aO%R'hOn$Sq#V$Sq#j$Sq#o$Sq#s$Sq#u$Sq#x$Sq#|$Sq$T$Sq$V$Sq$X$Sq$[$Sq$^$Sq$`$Sq$b$Sq$d$Sq$g$Sq$k$Sq$m$Sq~P-aOu%ZOn$Zqx$Zq#V$Zq#j$Zq#o$Zq#s$Zq#u$Zq#x$Zq#|$Zq$T$Zq$X$Zq$[$Zq$^$Zq$`$Zq$b$Zq$d$Zq$g$Zq$k$Zq$m$Zq#l$Zq#q$Zq#z$Zq$Q$Zq$V$Zq$i$Zq~Ou%TOXqyrqyxqynqy#Vqy#jqy#oqy#sqy#uqy#xqy#|qy$Tqy$Xqy$[qy$^qy$`qy$bqy$dqy$gqy$kqy$mqy#lqy#qqy#zqy$Qqy$Vqy$iqy~Ou#Tqx#Tq#U#Tq#V#Tqn#Tq#j#Tq#o#Tq#s#Tq#u#Tq#x#Tq#|#Tq$T#Tq$X#Tq$[#Tq$^#Tq$`#Tq$b#Tq$d#Tq$g#Tq$k#Tq$m#Tq#l#Tq#q#Tq#z#Tq$Q#Tq$V#Tq$i#Tq~P-aO%R'hOn$Oy#V$Oy#j$Oy#o$Oy#s$Oy#u$Oy#x$Oy#|$Oy$Q$Oy$T$Oy$X$Oy$[$Oy$^$Oy$`$Oy$b$Oy$d$Oy$g$Oy$k$Oy$m$Oy~O%R'hOn$Sy#V$Sy#j$Sy#o$Sy#s$Sy#u$Sy#x$Sy#|$Sy$T$Sy$V$Sy$X$Sy$[$Sy$^$Sy$`$Sy$b$Sy$d$Sy$g$Sy$k$Sy$m$Sy~Ou%ZOn$Zyx$Zy#V$Zy#j$Zy#o$Zy#s$Zy#u$Zy#x$Zy#|$Zy$T$Zy$X$Zy$[$Zy$^$Zy$`$Zy$b$Zy$d$Zy$g$Zy$k$Zy$m$Zy#l$Zy#q$Zy#z$Zy$Q$Zy$V$Zy$i$Zy~Ox!di%R!din!di#V!di#j!di#o!di#s!di#u!di#x!di#|!di$Q!di$T!di$X!di$[!di$^!di$`!di$b!di$d!di$g!di$k!di$m!di$V!di~P-aO",goto:"@p%uPPPPPPPP%vP%v&W'hPP'h'hPPP'hPPP'hPPPPPPPP(fP(vPP(yPP(y)ZP)kP(yP(yP(y)qP*RP(y*XP*iP(yP(y*oPP+P+Z+eP(y+kP+{P(yP(yP(yP(y,RP,c,fP(y,iP,y,|P(yP(yP-PPPP(yP(yP(y-XP-iP(yP(yP(yP-o.PP.aP-o.gP.wP-oP-oP-o.}P/_P-oP-o/e/uP-o/{P0]P-oP-o-oP-oP-oP-oP-oP-o0cP0sP-oP-oP0y1i2P2o2}3a3s3y4P4V4uPPPPPP4{5]PPP'h'h8P%v9_9k9q:X:[:l:|;Q;b;f;v<W<h<l<|=Q=b=f=v>W>h>x?Y?j?z@O@`m^OTUVWX[`!T!W!Z!^!a!j!vdReklmopqyz{|}!O!P!n!o!p!u!v#c#f#i#m#p#|$O$Q$S$U$X$Z$|%T%X%Y%c&q'X'Z'q'yQ#RrQ#SsQ&O#qQ&T#tQ'O%bR(P's!wiReklmopqyz{|}!O!P!n!o!p!u!v#c#f#i#m#p#|$O$Q$S$U$X$Z$|%T%X%Y%c&q'X'Z'q'ym!rck!s!x!y#Y#]$}%_%h&Z&^'_'bR$w!qm]OTUVWX[`!T!W!Z!^!a!jmTOTUVWX[`!T!W!Z!^!a!jQ!STR$`!TmUOTUVWX[`!T!W!Z!^!a!jQ!VUR$b!WmVOTUVWX[`!T!W!Z!^!a!jQ!YVR$d!ZmWOTUVWX[`!T!W!Z!^!a!ja'j&w&x'k'm't'u(Q(Ra'i&w&x'k'm't'u(Q(RQ!]WR$f!^mXOTUVWX[`!T!W!Z!^!a!jQ!`XR$h!amYOTUVWX[`!T!W!Z!^!a!jR!eYR$k!emZOTUVWX[`!T!W!Z!^!a!jR!hZR$n!hS%d#Z%eT'`&['am[OTUVWX[`!T!W!Z!^!a!jQ!i[R$p!jm$[!Q#d#g#n#r#u$V$^%q%v%|&S&X&cm#d!Q#d#g#n#r#u$V$^%q%v%|&S&X&cQ%p#dR'T%qm#g!Q#d#g#n#r#u$V$^%q%v%|&S&X&cQ%u#gR'U%vm#n!Q#d#g#n#r#u$V$^%q%v%|&S&X&cQ%{#nR'V%|m#r!Q#d#g#n#r#u$V$^%q%v%|&S&X&cQ&R#rR'Y&Sm#u!Q#d#g#n#r#u$V$^%q%v%|&S&X&cQ&W#uR'[&Xm$V!Q#d#g#n#r#u$V$^%q%v%|&S&X&cQ&b$VR'c&cQ`OQ!TTQ!WUQ!ZVQ!^WQ!aXQ!j[_!l`!T!W!Z!^!a!jSQO`SaQ!Ri!RTUVWX[!T!W!Z!^!a!jQ!scQ!yk^$x!s!y$}%_%h'_'bQ$}!xQ%_#YQ%h#]Q'_&ZR'b&^Q%U#QU&u%U'W'xQ'W%}R'x'fQ'k&wQ'm&xW'z'k'm(Q(RQ(Q'tR(R'uQ%[#VW&z%[']'o(SQ']&YQ'o&|R(S'vQ!dYR$j!dQ!gZR$m!gQ%e#ZR'Q%eQ$^!QQ%q#dQ%v#gQ%|#nQ&S#rQ&X#uQ&c$V_&f$^%q%v%|&S&X&cQ'a&[R'w'am_OTUVWX[`!T!W!Z!^!a!jQcRQ!weQ!xkQ!{lQ!|mQ#OoQ#PpQ#QqQ#YyQ#ZzQ#[{Q#]|Q#^}Q#_!OQ#`!PQ$s!nQ$t!oQ$u!pQ$z!uQ${!vQ%m#cQ%r#fQ%w#iQ%x#mQ%}#pQ&Z#|Q&[$OQ&]$QQ&^$SQ&_$UQ&d$XQ&e$ZQ&r$|Q&t%TQ&w%XQ&x%YQ'P%cQ'f&qQ't'XQ'u'ZQ(O'qR(T'y!viReklmopqyz{|}!O!P!n!o!p!u!v#c#f#i#m#p#|$O$Q$S$U$X$Z$|%T%X%Y%c&q'X'Z'q'ym#x!Q#d#g#n#r#u$V$^%q%v%|&S&X&cQ%X#RQ%Y#SQ'X&OR'Z&TX%c#Z%e&['al#q!Q#d#g#n#r#u$V$^%q%v%|&S&X&cX%c#Z%e&['aR's'Pm$]!Q#d#g#n#r#u$V$^%q%v%|&S&X&cm#c!Q#d#g#n#r#u$V$^%q%v%|&S&X&cT%o#d%qm#f!Q#d#g#n#r#u$V$^%q%v%|&S&X&cT%t#g%vm#i!Q#d#g#n#r#u$V$^%q%v%|&S&X&cm#k!Q#d#g#n#r#u$V$^%q%v%|&S&X&cm#m!Q#d#g#n#r#u$V$^%q%v%|&S&X&cT%z#n%|m#p!Q#d#g#n#r#u$V$^%q%v%|&S&X&cT&Q#r&Sm#t!Q#d#g#n#r#u$V$^%q%v%|&S&X&cT&V#u&Xm#w!Q#d#g#n#r#u$V$^%q%v%|&S&X&cm#z!Q#d#g#n#r#u$V$^%q%v%|&S&X&cm#|!Q#d#g#n#r#u$V$^%q%v%|&S&X&cm$O!Q#d#g#n#r#u$V$^%q%v%|&S&X&cm$Q!Q#d#g#n#r#u$V$^%q%v%|&S&X&cm$S!Q#d#g#n#r#u$V$^%q%v%|&S&X&cm$U!Q#d#g#n#r#u$V$^%q%v%|&S&X&cT&a$V&cm$X!Q#d#g#n#r#u$V$^%q%v%|&S&X&cm$Z!Q#d#g#n#r#u$V$^%q%v%|&S&X&c",nodeNames:`⚠ {{ {% {% {% {% InlineComment Template Text }} Interpolation VariableName MemberExpression . PropertyName SubscriptExpression BinaryExpression contains CompareOp LogicOp AssignmentExpression AssignOp ) ( RangeExpression .. BooleanLiteral empty forloop tablerowloop continue StringLiteral NumberLiteral Filter | FilterName : , Tag TagName %} IfDirective Tag if EndTag endif Tag elsif Tag else UnlessDirective Tag unless EndTag endunless CaseDirective Tag case EndTag endcase Tag when ForDirective Tag for in Parameter ParameterName EndTag endfor TableDirective Tag tablerow EndTag endtablerow Tag break Tag continue Tag cycle Comment Tag comment CommentText EndTag endcomment RawDirective Tag raw RawText EndTag endraw Tag echo Tag render RenderParameter with for as Tag include Tag assign CaptureDirective Tag capture EndTag endcapture Tag increment Tag decrement Tag liquid IfDirective Tag if EndTag endif UnlessDirective Tag unless EndTag endunless Tag elsif Tag else CaseDirective Tag case EndTag endcase Tag when ForDirective Tag EndTag endfor TableDirective Tag tablerow EndTag endtablerow Tag break Tag Tag cycle Tag echo Tag render Tag include Tag assign CaptureDirective Tag capture EndTag endcapture Tag increment Tag decrement`,maxTerm:220,nodeProps:[[`closedBy`,1,`}}`,-4,2,3,4,5,`%}`,23,`)`],[`openedBy`,9,`{{`,22,`(`,40,`{%`],[`group`,-13,11,12,15,16,20,24,26,27,28,29,30,31,32,`Expression`]],skippedNodes:[0,6],repeatNodeCount:11,tokenData:")e~RmXY!|YZ!|]^!|pq!|qr#_rs#juv$[wx$gxy%Syz%X{|%^|}&x}!O&}!O!P'Z!Q![&g![!]'k!^!_'p!_!`'x!`!a'p!c!}(Q!}#O(y#P#Q)O#R#S(Q#T#o(Q#p#q)T#q#r)Y%W;'S(Q;'S;:j(s<%lO(Q~#RS%O~XY!|YZ!|]^!|pq!|~#bP!_!`#e~#jOb~~#mUOY#jZr#jrs$Ps;'S#j;'S;=`$U<%lO#j~$UOo~~$XP;=`<%l#j~$_P#q#r$b~$gOx~~$jUOY$gZw$gwx$Px;'S$g;'S;=`$|<%lO$g~%PP;=`<%l$g~%XOg~~%^Of~P%aQ!O!P%g!Q![&gP%jP!Q![%mP%rRpP!Q![%m!g!h%{#X#Y%{P&OR{|&X}!O&X!Q![&_P&[P!Q![&_P&dPpP!Q![&_P&lSpP!O!P%g!Q![&g!g!h%{#X#Y%{~&}Ou~~'QRuv$[!O!P%g!Q![&g~'`Q]S!O!P'f!Q![%m~'kOi~~'pOt~~'uPb~!_!`#e~'}Pe~!_!`#e_(ZW^WwQ%RT}!O(Q!Q![(Q!c!}(Q#R#S(Q#T#o(Q%W;'S(Q;'S;:j(s<%lO(Q_(vP;=`<%l(Q~)OO%T~~)TO%S~~)YOr~~)]P#q#r)`~)eOX~",tokenizers:[w,D,E,O,0,1,2,3],topRules:{Template:[0,7]},dynamicPrecedences:{190:1,191:1,192:1,194:1,195:1,196:1,197:1,199:1,200:1,201:1,202:1,203:1,204:1,205:1,206:1,207:1,208:1,209:1,210:1,211:1,212:1,213:1,214:1,215:1,216:1,217:1,218:1,219:1,220:1},specialized:[{term:187,get:e=>k[e]||-1},{term:39,get:e=>A[e]||-1}],tokenPrec:0});function M(e,t){return e.split(` `).map(e=>({label:e,type:t}))}var N=M(`abs append at_least at_most capitalize ceil compact concat date default divided_by downcase escape escape_once first floor join last lstrip map minus modulo newline_to_br plus prepend remove remove_first replace replace_first reverse round rstrip size slice sort sort_natural split strip strip_html strip_newlines sum times truncate truncatewords uniq upcase url_decode url_encode where`,`function`),P=M(`cycle comment endcomment raw endraw echo increment decrement liquid if elsif else endif unless endunless case endcase for endfor tablerow endtablerow break continue assign capture endcapture render include`,`keyword`),F=M(`empty forloop tablerowloop in with as`,`keyword`),I=M(`first index index0 last length rindex`,`property`),L=M(`col col0 col_first col_last first index index0 last length rindex rindex0 row`,`property`);function R(e){let{state:t,pos:n}=e,r=o(t).resolveInner(n,-1).enterUnfinishedNodesBefore(n),i=r.childBefore(n)?.name||r.name;if(r.name==`FilterName`)return{type:`filter`,node:r};if(e.explicit&&i==`|`)return{type:`filter`};if(r.name==`TagName`)return{type:`tag`,node:r};if(e.explicit&&i==`{%`)return{type:`tag`};if(r.name==`PropertyName`&&r.parent.name==`MemberExpression`)return{type:`property`,node:r,target:r.parent};if(r.name==`.`&&r.parent.name==`MemberExpression`)return{type:`property`,target:r.parent};if(r.name==`MemberExpression`&&i==`.`)return{type:`property`,target:r};if(r.name==`VariableName`)return{type:`expression`,from:r.from};let a=e.matchBefore(/[\w\u00c0-\uffff]+$/);return a?{type:`expression`,from:a.from}:e.explicit&&r.name!=`CommentText`&&r.name!=`StringLiteral`&&r.name!=`NumberLiteral`&&r.name!=`InlineComment`?{type:`expression`}:null}function z(e,t,n,r){let i=[];for(;;){let n=t.getChild(`Expression`);if(!n)return[];if(n.name==`VariableName`||n.name==`forloop`||n.name==`tablerowloop`){let t=e.sliceDoc(n.from,n.to);if(t==`forloop`)return i.length?[]:I;if(t==`tablerowloop`)return i.length?[]:L;i.unshift(t);break}else if(n.name==`MemberExpression`){let r=n.getChild(`PropertyName`);r&&i.unshift(e.sliceDoc(r.from,r.to)),t=n}else if(n.name==`SubscriptExpression`){let r=n.getChildren(`Expression`)[1];i.unshift(r?.name==`StringLiteral`?e.sliceDoc(r.from+1,r.to-1):`[]`),t=n}else return[]}return r?r(i,e,n):[]}function B(e={}){let t=e.filters?e.filters.concat(N):N,n=e.tags?e.tags.concat(P):P,r=e.variables?e.variables.concat(F):F,{properties:i}=e;return e=>{let a=R(e);if(!a)return null;let o=a.from??(a.node?a.node.from:e.pos),s;return s=a.type==`filter`?t:a.type==`tag`?n:a.type==`expression`?r:z(e.state,a.target,e,i),s.length?{options:s,from:o,validFor:/^[\w\u00c0-\uffff]*$/}:null}}var V=t.inputHandler.of((e,t,n,r)=>r!=`%`||t!=n||e.state.doc.sliceString(t-1,n+1)!=`{}`?!1:(e.dispatch(e.state.changeByRange(e=>({changes:{from:e.from,to:e.to,insert:`%%`},range:a.cursor(e.from+1)})),{scrollIntoView:!0,userEvent:`input.type`}),!0));function H(e){return t=>{let n=e.test(t.textAfter);return t.lineIndent(t.node.from)+(n?0:t.unit)}}var U=l.define({name:`liquid`,parser:j.configure({props:[n({"cycle comment endcomment raw endraw echo increment decrement liquid in with as":r.keyword,"empty forloop tablerowloop":r.atom,"if elsif else endif unless endunless case endcase for endfor tablerow endtablerow break continue":r.controlKeyword,"assign capture endcapture":r.definitionKeyword,contains:r.operatorKeyword,"render include":r.moduleKeyword,VariableName:r.variableName,TagName:r.tagName,FilterName:r.function(r.variableName),PropertyName:r.propertyName,CompareOp:r.compareOperator,AssignOp:r.definitionOperator,LogicOp:r.logicOperator,NumberLiteral:r.number,StringLiteral:r.string,BooleanLiteral:r.bool,InlineComment:r.lineComment,CommentText:r.blockComment,"{% %} {{ }}":r.brace,"[ ]":r.bracket,"( )":r.paren,".":r.derefOperator,", .. : |":r.punctuation}),e.add({Tag:s({closing:`%}`}),"UnlessDirective ForDirective TablerowDirective CaptureDirective":H(/^\s*(\{%-?\s*)?end\w/),IfDirective:H(/^\s*(\{%-?\s*)?(endif|else|elsif)\b/),CaseDirective:H(/^\s*(\{%-?\s*)?(endcase|when)\b/)}),u.add({"UnlessDirective ForDirective TablerowDirective CaptureDirective IfDirective CaseDirective RawDirective Comment"(e){let t=e.firstChild,n=e.lastChild;return!t||t.name!=`Tag`?null:{from:t.to,to:n.name==`EndTag`?n.from:e.to}}})]}),languageData:{commentTokens:{line:`#`},indentOnInput:/^\s*{%-?\s*(?:end|elsif|else|when|)$/}}),W=p();function G(e){return U.configure({wrap:i(t=>t.type.isTop?{parser:e.parser,overlay:e=>e.name==`Text`||e.name==`RawText`}:null)},`liquid`)}var K=G(W.language);function q(e={}){let t=e.base||W,n=t.language==W.language?K:G(t.language);return new c(n,[t.support,n.data.of({autocomplete:B(e)}),t.language.data.of({closeBrackets:{brackets:[`{`]}}),V])}export{q as liquid};
|