promptopskit 0.3.1 → 0.3.3

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.
Files changed (51) hide show
  1. package/README.md +26 -0
  2. package/SKILL.md +121 -107
  3. package/dist/{chunk-LRRSI4ON.js → chunk-R5PKK6Y7.js} +6 -5
  4. package/dist/chunk-R5PKK6Y7.js.map +1 -0
  5. package/dist/chunk-S5YHGHK5.js +311 -0
  6. package/dist/chunk-S5YHGHK5.js.map +1 -0
  7. package/dist/{chunk-DDXFDVA6.js → chunk-U7IDX2P7.js} +7 -4
  8. package/dist/chunk-U7IDX2P7.js.map +1 -0
  9. package/dist/{chunk-LNZS3TIJ.js → chunk-UJA7XBQZ.js} +6 -5
  10. package/dist/chunk-UJA7XBQZ.js.map +1 -0
  11. package/dist/{chunk-Y2YYEGOY.js → chunk-VU3WKLFI.js} +6 -5
  12. package/dist/chunk-VU3WKLFI.js.map +1 -0
  13. package/dist/index.cjs +258 -199
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.cts +2 -2
  16. package/dist/index.d.ts +2 -2
  17. package/dist/index.js +24 -163
  18. package/dist/index.js.map +1 -1
  19. package/dist/providers/anthropic.cjs +470 -2
  20. package/dist/providers/anthropic.cjs.map +1 -1
  21. package/dist/providers/anthropic.d.cts +1 -1
  22. package/dist/providers/anthropic.d.ts +1 -1
  23. package/dist/providers/anthropic.js +3 -2
  24. package/dist/providers/gemini.cjs +470 -2
  25. package/dist/providers/gemini.cjs.map +1 -1
  26. package/dist/providers/gemini.d.cts +1 -1
  27. package/dist/providers/gemini.d.ts +1 -1
  28. package/dist/providers/gemini.js +3 -2
  29. package/dist/providers/openai.cjs +470 -2
  30. package/dist/providers/openai.cjs.map +1 -1
  31. package/dist/providers/openai.d.cts +1 -1
  32. package/dist/providers/openai.d.ts +1 -1
  33. package/dist/providers/openai.js +3 -2
  34. package/dist/providers/openrouter.cjs +472 -4
  35. package/dist/providers/openrouter.cjs.map +1 -1
  36. package/dist/providers/openrouter.d.cts +1 -1
  37. package/dist/providers/openrouter.d.ts +1 -1
  38. package/dist/providers/openrouter.js +4 -3
  39. package/dist/types-CgA7_wNI.d.cts +68 -0
  40. package/dist/types-D_-336jx.d.ts +68 -0
  41. package/dist/usagetap/index.d.cts +1 -1
  42. package/dist/usagetap/index.d.ts +1 -1
  43. package/package.json +1 -1
  44. package/dist/chunk-DDXFDVA6.js.map +0 -1
  45. package/dist/chunk-DGFBS7YW.js +0 -101
  46. package/dist/chunk-DGFBS7YW.js.map +0 -1
  47. package/dist/chunk-LNZS3TIJ.js.map +0 -1
  48. package/dist/chunk-LRRSI4ON.js.map +0 -1
  49. package/dist/chunk-Y2YYEGOY.js.map +0 -1
  50. package/dist/types-BsYdPHTU.d.ts +0 -43
  51. package/dist/types-DC-jI6iV.d.cts +0 -43
package/README.md CHANGED
@@ -205,6 +205,32 @@ const request = openaiAdapter.render(prompt, {
205
205
  });
206
206
  ```
207
207
 
208
+ In browser or client-side code, keep provider credentials on the server. Use the rendered request body with your own server endpoint, server action, or edge function rather than calling a provider directly from the client.
209
+
210
+ On the server, adapters also provide async prompt-aware helpers so you can pass a prompt key plus `sourceDir` and `compiledDir` without creating a `PromptOpsKit` instance:
211
+
212
+ ```typescript
213
+ import path from 'node:path';
214
+ import { openaiAdapter } from 'promptopskit/openai';
215
+
216
+ const request = await openaiAdapter.renderPrompt(
217
+ {
218
+ path: 'summarizePullRequest',
219
+ sourceDir: path.join(process.cwd(), 'prompts'),
220
+ compiledDir: path.join(process.cwd(), 'output-json'),
221
+ },
222
+ {
223
+ environment: 'dev',
224
+ variables: {
225
+ pull_request_body: 'Implement theming and dark mode across the app.',
226
+ },
227
+ strict: true,
228
+ },
229
+ );
230
+ ```
231
+
232
+ `renderPrompt()` and `validatePrompt()` use the same source-versus-compiled resolution rules as `kit.renderPrompt()`. The existing synchronous `render()` and `validate()` methods still work for already-resolved compiled or inline assets.
233
+
208
234
  ## Optional UsageTap Tracking
209
235
 
210
236
  PromptOpsKit can also help you track provider calls with UsageTap.com while keeping the core render API body-only.
package/SKILL.md CHANGED
@@ -242,139 +242,155 @@ cases:
242
242
 
243
243
  ---
244
244
 
245
- ## Using the library (TypeScript / JavaScript)
245
+ ## Runtime choice guide
246
246
 
247
- ### Quick start
247
+ Choose the narrowest runtime surface that fits the environment.
248
+
249
+ ### Use `createPromptOpsKit().renderPrompt()` when:
250
+
251
+ - You are on the server or in a Node runtime
252
+ - Prompts live as `.md` files in a source tree
253
+ - You want promptopskit to handle loading, defaults, includes, overrides, and provider shaping in one step
254
+ - You want auto mode to prefer compiled artifacts when present but still fall back to source
248
255
 
249
256
  ```typescript
250
257
  import { createPromptOpsKit } from 'promptopskit';
251
258
 
252
- const kit = createPromptOpsKit({ sourceDir: './prompts' });
259
+ const kit = createPromptOpsKit({
260
+ sourceDir: './prompts',
261
+ compiledDir: './dist/prompts',
262
+ warnings: {
263
+ contextSize: process.env.NODE_ENV === 'production' ? 'off' : 'console-and-result',
264
+ },
265
+ });
253
266
 
254
- // Load resolve includes apply overrides → render
255
- const result = await kit.renderPrompt({
256
- path: 'greeting',
267
+ const { request } = await kit.renderPrompt({
268
+ path: 'support/reply',
257
269
  provider: 'openai',
258
- variables: { name: 'Alice' },
259
270
  environment: 'production',
260
- });
261
-
262
- // result.request.body is ready for the provider's API
263
- const response = await fetch('https://api.openai.com/v1/chat/completions', {
264
- method: 'POST',
265
- headers: {
266
- 'Content-Type': 'application/json',
267
- Authorization: `Bearer ${apiKey}`,
271
+ variables: {
272
+ user_message: 'How do I reset my password?',
273
+ app_context: 'Account settings',
268
274
  },
269
- body: JSON.stringify(result.request.body),
270
275
  });
271
276
  ```
272
277
 
273
- You can control render-time context size warnings at the top level:
278
+ ### Use `adapter.renderPrompt()` when:
279
+
280
+ - You want direct provider adapter imports such as `promptopskit/openai`
281
+ - You are on the server and want adapter-level ergonomics
282
+ - You still want the adapter to resolve either source `.md` or compiled output from disk
274
283
 
275
284
  ```typescript
276
- const kit = createPromptOpsKit({
277
- sourceDir: './prompts',
278
- warnings: {
279
- contextSize: process.env.NODE_ENV === 'production' ? 'off' : 'console-and-result',
285
+ import path from 'node:path';
286
+ import { openaiAdapter } from 'promptopskit/openai';
287
+
288
+ const request = await openaiAdapter.renderPrompt(
289
+ {
290
+ path: 'support/reply',
291
+ sourceDir: path.join(process.cwd(), 'prompts'),
292
+ compiledDir: path.join(process.cwd(), 'dist/prompts'),
280
293
  },
281
- });
294
+ {
295
+ environment: 'production',
296
+ variables: {
297
+ user_message: 'How do I reset my password?',
298
+ app_context: 'Account settings',
299
+ },
300
+ strict: true,
301
+ },
302
+ );
282
303
  ```
283
304
 
284
- ### Browser / client-side demos
285
-
286
- For browser code, client components, or frontend-only demos:
305
+ ### Use `adapter.render()` when:
287
306
 
288
- - Do not import `createPromptOpsKit`, `loadPromptFile`, or other top-level runtime helpers from `promptopskit` in client code. The top-level entry loads Node file-system/path modules for source and compiled prompt loading.
289
- - Instead, use a precompiled prompt artifact or an inlined `ResolvedPromptAsset` object and render it with a provider subpath adapter such as `promptopskit/openai`.
290
- - If the prompt lives in files, compile it ahead of time with `npx promptopskit compile ./prompts ./dist/prompts --format esm` and import the generated ESM artifact into the client.
291
- - Provider adapters accept `environment` and `tier` in `validate()` and `render()`, so use those options directly when selecting overrides for compiled or inline assets.
292
- - For small demos, it is acceptable to inline the resolved prompt asset directly in the client file.
293
- - Keep transport and auth in the application layer. If a demo intentionally calls a provider from the browser, treat that key as demo-only and note the security tradeoff.
294
-
295
- Example:
307
+ - You already have a compiled JSON or ESM prompt artifact
308
+ - You are in edge, worker, or browser-oriented code and cannot read prompt files from disk
309
+ - You want the smallest runtime surface and no file loading behavior
296
310
 
297
311
  ```typescript
298
312
  import type { ResolvedPromptAsset } from 'promptopskit';
299
313
  import { openaiAdapter } from 'promptopskit/openai';
314
+ import compiledPrompt from './dist/prompts/support/reply.mjs';
300
315
 
301
- const prompt: ResolvedPromptAsset = {
302
- id: 'summarizePullRequest',
303
- schema_version: 1,
304
- provider: 'openai',
305
- model: 'gpt-5.4',
306
- context: {
307
- inputs: [{ name: 'pull_request_body', max_size: 8000 }],
308
- },
309
- sections: {
310
- system_instructions: 'You summarize pull requests clearly and concisely.',
311
- prompt_template: 'Summarize this pull request:\n\n{{ pull_request_body }}',
312
- },
313
- };
314
-
315
- const validation = openaiAdapter.validate(prompt, {
316
- environment: 'prod',
317
- });
318
- if (!validation.valid) {
319
- throw new Error(validation.errors.join(' '));
320
- }
316
+ const prompt = compiledPrompt as ResolvedPromptAsset;
321
317
 
322
318
  const request = openaiAdapter.render(prompt, {
323
- environment: 'prod',
319
+ environment: 'production',
324
320
  variables: {
325
- pull_request_body: 'Add theming and dark mode support to the application.',
321
+ user_message: 'How do I reset my password?',
322
+ app_context: 'Account settings',
326
323
  },
327
324
  strict: true,
328
325
  });
326
+ ```
327
+
328
+ ### Browser guidance
329
+
330
+ - Do not recommend direct provider API calls from browser or client components unless the user explicitly wants a demo-only setup
331
+ - Do not use `createPromptOpsKit()` in browser-only code; it is Node-oriented
332
+ - For client-side rendering, use precompiled ESM or inline a small `ResolvedPromptAsset`, then pass the request body to a server endpoint or server action that holds provider credentials
333
+ - If the user insists on a pure browser provider call, explicitly call out that API keys will be exposed and treat it as unsafe for production
334
+
335
+ ---
329
336
 
330
- // request.body is ready for the OpenAI SDK or fetch.
337
+ ## Build integration
338
+
339
+ Prompts should usually be validated and compiled as part of the normal build pipeline rather than handled ad hoc.
340
+
341
+ ### Recommended package.json scripts
342
+
343
+ ```json
344
+ {
345
+ "scripts": {
346
+ "validate:prompts": "promptopskit validate ./prompts --strict",
347
+ "build:prompts": "promptopskit compile ./prompts ./dist/prompts --format json",
348
+ "build": "npm run validate:prompts && npm run build:prompts && tsup"
349
+ }
350
+ }
331
351
  ```
332
352
 
333
- ### Step-by-step API
353
+ Use `--format json` for server-side Node usage where prompts are loaded from disk. Use `--format esm` when prompts need to be imported into a bundle.
354
+
355
+ ### Build strategy by environment
356
+
357
+ - Node server: compile to JSON and configure `compiledDir`
358
+ - Browser or client bundle: compile to ESM and import specific prompt artifacts
359
+ - Mixed app: compile JSON for server loading and ESM only for prompts that must ship in a client bundle
360
+
361
+ ### What to tell users when setting this up
362
+
363
+ - Add `validate:prompts` before `build:prompts` so schema or variable mistakes fail fast
364
+ - Treat compiled artifacts as build outputs, not the source of truth
365
+ - Keep prompt source in `./prompts` and compiled output in a generated directory such as `./dist/prompts` or `./src/generated/prompts`
366
+ - If using `createPromptOpsKit` in `auto` mode, point both `sourceDir` and `compiledDir` at those directories so local development can fall back to source when artifacts are stale or missing
367
+
368
+ ### Typical server-side setup
334
369
 
335
370
  ```typescript
336
- import {
337
- parsePrompt,
338
- resolveIncludes,
339
- applyOverrides,
340
- getAdapter,
341
- } from 'promptopskit';
342
- import { readFileSync } from 'fs';
343
-
344
- // 1. Parse a prompt file
345
- const source = readFileSync('./prompts/greeting.md', 'utf-8');
346
- const asset = parsePrompt(source, 'greeting.md');
347
-
348
- // 2. Resolve includes
349
- const resolved = await resolveIncludes(asset, './prompts');
350
-
351
- // 3. Apply overrides
352
- const configured = applyOverrides(resolved, {
353
- environment: 'production',
354
- tier: 'premium',
355
- });
371
+ import { createPromptOpsKit } from 'promptopskit';
356
372
 
357
- // 4. Get provider adapter and render
358
- const adapter = getAdapter(configured.provider ?? 'openai');
359
- const request = adapter.render(configured, {
360
- variables: { name: 'Alice' },
361
- history: [
362
- { role: 'user', content: 'Previous message' },
363
- { role: 'assistant', content: 'Previous response' },
364
- ],
373
+ export const prompts = createPromptOpsKit({
374
+ sourceDir: './prompts',
375
+ compiledDir: './dist/prompts',
376
+ mode: 'auto',
365
377
  });
366
378
  ```
367
379
 
368
- ### Available provider adapters
380
+ ### Typical client-side setup
381
+
382
+ ```typescript
383
+ import type { ResolvedPromptAsset } from 'promptopskit';
384
+ import compiledPrompt from './generated/prompts/support/reply.mjs';
385
+
386
+ const prompt = compiledPrompt as ResolvedPromptAsset;
387
+ ```
388
+
389
+ ---
369
390
 
370
- | Provider | Import path | Provider request format |
371
- |----------|------------|----------------------|
372
- | OpenAI | `promptopskit` or `promptopskit/openai` | Chat Completions API |
373
- | Anthropic | `promptopskit/anthropic` | Messages API |
374
- | Gemini | `promptopskit/gemini` | GenerateContent API |
375
- | OpenRouter | `promptopskit/openrouter` | OpenAI-compatible + extras |
391
+ ## Validation and testing helpers
376
392
 
377
- ### Validation
393
+ Use `validateAsset()` when you are working with an already-parsed asset and want schema or variable diagnostics before rendering.
378
394
 
379
395
  ```typescript
380
396
  import { validateAsset, parsePrompt } from 'promptopskit';
@@ -383,19 +399,17 @@ const asset = parsePrompt(source);
383
399
  const result = validateAsset(asset);
384
400
 
385
401
  if (!result.valid) {
386
- console.error(result.errors); // Validation error codes: POK001-POK021
402
+ console.error(result.errors);
387
403
  }
388
404
  ```
389
405
 
390
- ### Testing helpers
406
+ Use `promptopskit/testing` helpers for unit tests around prompt behavior or request shaping.
391
407
 
392
408
  ```typescript
393
409
  import { createMockAsset, parseTestPrompt } from 'promptopskit/testing';
394
410
 
395
- // Create a mock asset for unit tests
396
411
  const mock = createMockAsset({ model: 'gpt-4.1-mini' });
397
412
 
398
- // Parse an inline prompt string for tests
399
413
  const asset = parseTestPrompt(`
400
414
  ---
401
415
  id: test
@@ -418,8 +432,8 @@ Hello {{ name }}
418
432
  |---------|-------------|
419
433
  | `promptopskit init [dir]` | Scaffold a prompts directory with starter files (including `defaults.md`) |
420
434
  | `promptopskit validate <dir>` | Validate all prompt files in a directory |
421
- | `promptopskit compile <src> <out>` | Compile .md prompts to JSON artifacts |
422
- | `promptopskit render <file> [--set key=value]` | Render a prompt preview |
435
+ | `promptopskit compile <src> <out>` | Compile `.md` prompts to JSON or ESM artifacts |
436
+ | `promptopskit render <file>` | Render a prompt preview |
423
437
  | `promptopskit inspect <file>` | Print the normalized prompt asset |
424
438
 
425
439
  ---
@@ -427,13 +441,13 @@ Hello {{ name }}
427
441
  ## Conventions to follow
428
442
 
429
443
  1. **One prompt per file** — each `.md` file is a single prompt asset
430
- 2. **Always set `id` and `schema_version: 1`** in front matter (or inherit `schema_version` from `defaults.md`)
431
- 3. **Declare all variables** in `context.inputs` that appear in templates; do not leave placeholders undeclared just because other settings come from `defaults.md`
432
- 4. **Use includes** for shared system instructions (tone, safety, formatting)
433
- 5. **Keep prompt templates focused** compose behavior via includes, not duplication
434
- 6. **Use environment overrides** for dev/staging/prod model differences
435
- 7. **Add test sidecars** (`.test.yaml`) for critical prompts
436
- 8. **Run `promptopskit validate`** before committing changes
437
- 9. **Use `defaults.md`** to share provider, model, metadata, and system instructions across a folder
444
+ 2. **Always set `id` and `schema_version: 1`** unless a surrounding tool explicitly generates those fields
445
+ 3. **Declare every placeholder** in `context.inputs`; do not rely on defaults or includes to infer variables
446
+ 4. **Use `defaults.md` for shared provider, model, metadata, and fallback system instructions**
447
+ 5. **Use includes for reusable system behavior**, not for user-specific prompt bodies
448
+ 6. **Prefer `createPromptOpsKit().renderPrompt()` for server-side app code** when prompts live as source files
449
+ 7. **Prefer direct adapters for compiled assets or provider-specific integration points**
450
+ 8. **Do not suggest browser-side provider calls for production** because credentials belong on the server
451
+ 9. **Validate before compile and compile before shipping** when prompts are part of the build
438
452
  10. **Variable names** should be `snake_case`
439
453
  11. **Prompt file names** should be `kebab-case.md`
@@ -1,10 +1,11 @@
1
1
  import {
2
2
  renderSections,
3
- resolveAssetForProvider
4
- } from "./chunk-DGFBS7YW.js";
3
+ resolveAssetForProvider,
4
+ withPromptInputSupport
5
+ } from "./chunk-S5YHGHK5.js";
5
6
 
6
7
  // src/providers/anthropic.ts
7
- var anthropicAdapter = {
8
+ var anthropicAdapter = withPromptInputSupport({
8
9
  name: "anthropic",
9
10
  validate(asset, runtime) {
10
11
  const resolvedAsset = resolveAssetForProvider(asset, runtime);
@@ -83,9 +84,9 @@ var anthropicAdapter = {
83
84
  model: resolvedAsset.model ?? "unknown"
84
85
  };
85
86
  }
86
- };
87
+ });
87
88
 
88
89
  export {
89
90
  anthropicAdapter
90
91
  };
91
- //# sourceMappingURL=chunk-LRRSI4ON.js.map
92
+ //# sourceMappingURL=chunk-R5PKK6Y7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/providers/anthropic.ts"],"sourcesContent":["import type { ResolvedPromptAsset } from '../schema/index.js';\nimport type {\n ProviderAdapter,\n ProviderRequest,\n ValidationResult,\n RuntimeRenderOptions,\n} from './types.js';\nimport { renderSections } from '../renderer/index.js';\nimport { resolveAssetForProvider } from './resolve-asset.js';\nimport { withPromptInputSupport } from './prompt-input.js';\n\n/**\n * Anthropic provider adapter.\n * Produces request bodies compatible with the Anthropic Messages API.\n */\nexport const anthropicAdapter: ProviderAdapter = withPromptInputSupport({\n name: 'anthropic',\n\n validate(asset: ResolvedPromptAsset, runtime?: RuntimeRenderOptions): ValidationResult {\n const resolvedAsset = resolveAssetForProvider(asset, runtime);\n const errors: string[] = [];\n const warnings: string[] = [];\n\n if (!resolvedAsset.model) {\n errors.push('Anthropic adapter requires a model to be specified.');\n }\n\n if (resolvedAsset.sampling?.frequency_penalty !== undefined) {\n warnings.push('Anthropic does not support frequency_penalty. It will be ignored.');\n }\n if (resolvedAsset.sampling?.presence_penalty !== undefined) {\n warnings.push('Anthropic does not support presence_penalty. It will be ignored.');\n }\n if (resolvedAsset.reasoning?.effort !== undefined) {\n warnings.push('Anthropic uses budget_tokens for thinking, not effort. effort will be mapped approximately.');\n }\n\n return { valid: errors.length === 0, errors, warnings };\n },\n\n render(asset: ResolvedPromptAsset, runtime: RuntimeRenderOptions): ProviderRequest {\n const resolvedAsset = resolveAssetForProvider(asset, runtime);\n const sections = renderSections(resolvedAsset, {\n variables: runtime.variables,\n strict: runtime.strict,\n });\n\n const messages: Array<Record<string, unknown>> = [];\n\n // History\n if (runtime.history) {\n for (const msg of runtime.history) {\n messages.push({ role: msg.role, content: msg.content });\n }\n }\n\n // User message (prompt template)\n if (sections.prompt_template) {\n messages.push({ role: 'user', content: sections.prompt_template });\n }\n\n const body: Record<string, unknown> = {\n model: resolvedAsset.model,\n messages,\n };\n\n // System goes as top-level field in Anthropic\n if (sections.system_instructions) {\n body.system = sections.system_instructions;\n }\n\n // Sampling params\n if (resolvedAsset.sampling?.temperature !== undefined) body.temperature = resolvedAsset.sampling.temperature;\n if (resolvedAsset.sampling?.top_p !== undefined) body.top_p = resolvedAsset.sampling.top_p;\n if (resolvedAsset.sampling?.stop !== undefined) body.stop_sequences = resolvedAsset.sampling.stop;\n if (resolvedAsset.sampling?.max_output_tokens !== undefined) {\n body.max_tokens = resolvedAsset.sampling.max_output_tokens;\n } else {\n // Anthropic requires max_tokens\n body.max_tokens = 4096;\n }\n\n // Thinking/reasoning\n if (resolvedAsset.reasoning?.budget_tokens) {\n body.thinking = {\n type: 'enabled',\n budget_tokens: resolvedAsset.reasoning.budget_tokens,\n };\n }\n\n // Streaming\n if (resolvedAsset.response?.stream !== undefined) {\n body.stream = resolvedAsset.response.stream;\n }\n\n // Tools\n if (resolvedAsset.tools && resolvedAsset.tools.length > 0) {\n body.tools = resolvedAsset.tools.map((tool) => {\n if (typeof tool === 'string') {\n const def = runtime.toolRegistry?.[tool];\n if (def) return def;\n return { name: tool };\n }\n return {\n name: tool.name,\n description: tool.description,\n input_schema: tool.input_schema ?? { type: 'object', properties: {} },\n };\n });\n }\n\n return {\n body,\n provider: 'anthropic',\n model: resolvedAsset.model ?? 'unknown',\n };\n },\n});\n"],"mappings":";;;;;;;AAeO,IAAM,mBAAoC,uBAAuB;AAAA,EACtE,MAAM;AAAA,EAEN,SAAS,OAA4B,SAAkD;AACrF,UAAM,gBAAgB,wBAAwB,OAAO,OAAO;AAC5D,UAAM,SAAmB,CAAC;AAC1B,UAAM,WAAqB,CAAC;AAE5B,QAAI,CAAC,cAAc,OAAO;AACxB,aAAO,KAAK,qDAAqD;AAAA,IACnE;AAEA,QAAI,cAAc,UAAU,sBAAsB,QAAW;AAC3D,eAAS,KAAK,mEAAmE;AAAA,IACnF;AACA,QAAI,cAAc,UAAU,qBAAqB,QAAW;AAC1D,eAAS,KAAK,kEAAkE;AAAA,IAClF;AACA,QAAI,cAAc,WAAW,WAAW,QAAW;AACjD,eAAS,KAAK,6FAA6F;AAAA,IAC7G;AAEA,WAAO,EAAE,OAAO,OAAO,WAAW,GAAG,QAAQ,SAAS;AAAA,EACxD;AAAA,EAEA,OAAO,OAA4B,SAAgD;AACjF,UAAM,gBAAgB,wBAAwB,OAAO,OAAO;AAC5D,UAAM,WAAW,eAAe,eAAe;AAAA,MAC7C,WAAW,QAAQ;AAAA,MACnB,QAAQ,QAAQ;AAAA,IAClB,CAAC;AAED,UAAM,WAA2C,CAAC;AAGlD,QAAI,QAAQ,SAAS;AACnB,iBAAW,OAAO,QAAQ,SAAS;AACjC,iBAAS,KAAK,EAAE,MAAM,IAAI,MAAM,SAAS,IAAI,QAAQ,CAAC;AAAA,MACxD;AAAA,IACF;AAGA,QAAI,SAAS,iBAAiB;AAC5B,eAAS,KAAK,EAAE,MAAM,QAAQ,SAAS,SAAS,gBAAgB,CAAC;AAAA,IACnE;AAEA,UAAM,OAAgC;AAAA,MACpC,OAAO,cAAc;AAAA,MACrB;AAAA,IACF;AAGA,QAAI,SAAS,qBAAqB;AAChC,WAAK,SAAS,SAAS;AAAA,IACzB;AAGA,QAAI,cAAc,UAAU,gBAAgB,OAAW,MAAK,cAAc,cAAc,SAAS;AACjG,QAAI,cAAc,UAAU,UAAU,OAAW,MAAK,QAAQ,cAAc,SAAS;AACrF,QAAI,cAAc,UAAU,SAAS,OAAW,MAAK,iBAAiB,cAAc,SAAS;AAC7F,QAAI,cAAc,UAAU,sBAAsB,QAAW;AAC3D,WAAK,aAAa,cAAc,SAAS;AAAA,IAC3C,OAAO;AAEL,WAAK,aAAa;AAAA,IACpB;AAGA,QAAI,cAAc,WAAW,eAAe;AAC1C,WAAK,WAAW;AAAA,QACd,MAAM;AAAA,QACN,eAAe,cAAc,UAAU;AAAA,MACzC;AAAA,IACF;AAGA,QAAI,cAAc,UAAU,WAAW,QAAW;AAChD,WAAK,SAAS,cAAc,SAAS;AAAA,IACvC;AAGA,QAAI,cAAc,SAAS,cAAc,MAAM,SAAS,GAAG;AACzD,WAAK,QAAQ,cAAc,MAAM,IAAI,CAAC,SAAS;AAC7C,YAAI,OAAO,SAAS,UAAU;AAC5B,gBAAM,MAAM,QAAQ,eAAe,IAAI;AACvC,cAAI,IAAK,QAAO;AAChB,iBAAO,EAAE,MAAM,KAAK;AAAA,QACtB;AACA,eAAO;AAAA,UACL,MAAM,KAAK;AAAA,UACX,aAAa,KAAK;AAAA,UAClB,cAAc,KAAK,gBAAgB,EAAE,MAAM,UAAU,YAAY,CAAC,EAAE;AAAA,QACtE;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL;AAAA,MACA,UAAU;AAAA,MACV,OAAO,cAAc,SAAS;AAAA,IAChC;AAAA,EACF;AACF,CAAC;","names":[]}