Spaces:
Paused
Paused
Add persistent multi-file artifact workspaces
Browse filesAdd OPFS-backed multi-file artifact deployments, file tools and repair loop, opaque client-side VFS previews, per-chat restoration, Files/Rendered UX, and deterministic browser security/persistence coverage. WebGPU runtimes and model assets are unchanged.
- README.md +35 -5
- dist/artifact-sw.js +40 -0
- dist/assets/{c-DwI-mMi7.js → c-DU7sDOfO.js} +0 -0
- dist/assets/{cpp--8bnlU9V.js → cpp-DLjLoKqK.js} +0 -0
- dist/assets/{graphql-Z0wBBrAm.js → graphql-CnQ6-SC9.js} +1 -1
- dist/assets/{index-BMceOeSr.css → index-B4DG8rDO.css} +0 -0
- dist/assets/index-CdsWm6Hd.js +0 -0
- dist/assets/index-Qym19Dm5.js +0 -0
- dist/assets/{java-B_DCJEsk.js → java-DisdHHsr.js} +1 -1
- dist/assets/{jsx-CtOK3bhZ.js → jsx-7UQWTecr.js} +0 -0
- dist/assets/{lua-CUc9ktct.js → lua-DNHyM1z9.js} +1 -1
- dist/assets/{nginx-DUHU2Dqn.js → nginx-D7gToQuB.js} +1 -1
- dist/assets/{perl-DCcfytl_.js → perl-jST4v011.js} +1 -1
- dist/assets/{php-Btwm84O4.js → php-B7QoxYrN.js} +0 -0
- dist/assets/{ruby--A1ICNIQ.js → ruby-CJjou4ZR.js} +0 -0
- dist/assets/{tsx-qUOhHegv.js → tsx-DD_ZyZUf.js} +0 -0
- dist/assets/{typescript-T-I1Y_bC.js → typescript-D7sEy3Rx.js} +0 -0
- dist/assets/{xml-CkTAj7zh.js → xml-DoonlvgL.js} +1 -1
- dist/index.html +2 -2
- nginx.conf +9 -0
- public/artifact-sw.js +40 -0
- scripts/test-artifact-csp.mjs +146 -18
- scripts/test-persistence.mjs +71 -7
- src/app/App.test.ts +46 -11
- src/app/App.tsx +55 -24
- src/app/components/ArtifactCard.tsx +106 -23
- src/app/components/ChatSurface.test.tsx +8 -7
- src/app/components/InspectorPanel.tsx +1 -1
- src/app/styles.css +168 -2
- src/lib/agent-tools.test.ts +25 -2
- src/lib/agent-tools.ts +212 -30
- src/lib/artifact-runtime.ts +403 -31
- src/lib/artifact-workspace.test.ts +54 -0
- src/lib/artifact-workspace.ts +337 -0
- src/lib/tool-routing.test.ts +9 -9
- src/lib/tool-routing.ts +6 -6
README.md
CHANGED
|
@@ -65,6 +65,20 @@ artifacts as one chronological transcript across repeated agent rounds. Fenced
|
|
| 65 |
code is highlighted incrementally with the pinned Shiki streaming tokenizer,
|
| 66 |
including incomplete fences while generation is active.
|
| 67 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
## Browser requirements
|
| 69 |
|
| 70 |
Chrome or Edge with WebGPU is recommended. Safari uses the stable compatibility
|
|
@@ -176,11 +190,27 @@ Tools are off by default. Memory writes/deletes require operator confirmation.
|
|
| 176 |
`js_eval` runs in a disposable opaque-origin Worker with network and browser
|
| 177 |
storage blocked, a 5-second timeout, and bounded output. The bounded agent loop
|
| 178 |
returns every tool result to the model and keeps each call and result inline at
|
| 179 |
-
its actual position in the answer.
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
`web_search` call sends its query to Wikipedia.
|
| 185 |
|
| 186 |
## Provenance
|
|
|
|
| 65 |
code is highlighted incrementally with the pinned Shiki streaming tokenizer,
|
| 66 |
including incomplete fences while generation is active.
|
| 67 |
|
| 68 |
+
Each artifact is one persistent, versioned web deployment rather than one HTML
|
| 69 |
+
string. Its browser-ready HTML, CSS, JavaScript, SVG, JSON, and other text files
|
| 70 |
+
live in a private OPFS workspace; the conversation also keeps a recovery
|
| 71 |
+
snapshot, so reopening or switching chats restores the matching emulator. The
|
| 72 |
+
file browser and rendered page stay inline in the transcript, while the right
|
| 73 |
+
sidebar is only an index that scrolls to them. A successful test opens
|
| 74 |
+
**Rendered** automatically. A failed test stays on **Files** with console
|
| 75 |
+
diagnostics for the next agent round. Updating an older deployment preserves
|
| 76 |
+
its stable ID and moves the current artifact card to the new tool-call position.
|
| 77 |
+
|
| 78 |
+
Workspaces currently accept up to 48 text files, 512 KiB per file, and 2 MiB
|
| 79 |
+
total. They are for browser-ready sites: there is no npm install, build daemon,
|
| 80 |
+
server process, WebContainer, binary-file writer, or backend.
|
| 81 |
+
|
| 82 |
## Browser requirements
|
| 83 |
|
| 84 |
Chrome or Edge with WebGPU is recommended. Safari uses the stable compatibility
|
|
|
|
| 190 |
`js_eval` runs in a disposable opaque-origin Worker with network and browser
|
| 191 |
storage blocked, a 5-second timeout, and bounded output. The bounded agent loop
|
| 192 |
returns every tool result to the model and keeps each call and result inline at
|
| 193 |
+
its actual position in the answer. `artifact_deploy` creates a file tree,
|
| 194 |
+
`artifact_write` adds/replaces/deletes files, `artifact_inspect` reads its
|
| 195 |
+
manifest or selected files, and `artifact_test` returns fresh console and DOM
|
| 196 |
+
diagnostics. The same stable deployment ID is used across repair rounds.
|
| 197 |
+
|
| 198 |
+
OPFS is the editable source of truth. Each version is also copied to an
|
| 199 |
+
immutable Cache Storage namespace served by a Service Worker, but cached HTML
|
| 200 |
+
is deliberately inert (`script-src 'none'`). Hugging Face Spaces cannot give
|
| 201 |
+
each deployment its own origin, and an executable same-origin Service Worker
|
| 202 |
+
URL would make `allow-same-origin` unsafe. The executable preview therefore
|
| 203 |
+
uses a stricter in-frame VFS: CSS and local assets are resolved from the
|
| 204 |
+
snapshot, ES modules use an injected local import map, and relative `fetch()`
|
| 205 |
+
reads through a read-only VFS response shim.
|
| 206 |
+
|
| 207 |
+
That runner is a credentialless opaque-origin `allow-scripts` iframe without
|
| 208 |
+
`allow-same-origin`. A strict CSP blocks external network, storage, workers,
|
| 209 |
+
frames, forms, popups, and navigation; runtime messages are accepted only from
|
| 210 |
+
the exact iframe window with serialized origin `null` and the current
|
| 211 |
+
deployment token. Console and DOM diagnostics return to the agent loop.
|
| 212 |
+
Prompt, token, tool, artifact, and memory data stay in the browser;
|
| 213 |
+
model/static asset downloads contact Hugging Face, and an approved
|
| 214 |
`web_search` call sends its query to Wikipedia.
|
| 215 |
|
| 216 |
## Provenance
|
dist/artifact-sw.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const ARTIFACT_CACHE = 'bonsai-artifact-deployments-v2';
|
| 2 |
+
const ROUTE_MARKER = '/__bonsai_artifact__/';
|
| 3 |
+
|
| 4 |
+
self.addEventListener('install', (event) => {
|
| 5 |
+
event.waitUntil(self.skipWaiting());
|
| 6 |
+
});
|
| 7 |
+
|
| 8 |
+
self.addEventListener('activate', (event) => {
|
| 9 |
+
event.waitUntil(self.clients.claim());
|
| 10 |
+
});
|
| 11 |
+
|
| 12 |
+
self.addEventListener('fetch', (event) => {
|
| 13 |
+
const url = new URL(event.request.url);
|
| 14 |
+
const marker = url.pathname.indexOf(ROUTE_MARKER);
|
| 15 |
+
if (marker < 0 || event.request.method !== 'GET') return;
|
| 16 |
+
event.respondWith((async () => {
|
| 17 |
+
const cache = await caches.open(ARTIFACT_CACHE);
|
| 18 |
+
const exact = await cache.match(event.request, { ignoreSearch: true });
|
| 19 |
+
if (exact) return exact;
|
| 20 |
+
if (event.request.mode === 'navigate') {
|
| 21 |
+
const route = url.pathname.slice(0, marker + ROUTE_MARKER.length);
|
| 22 |
+
const tail = url.pathname.slice(marker + ROUTE_MARKER.length).split('/').filter(Boolean);
|
| 23 |
+
if (tail.length >= 2) {
|
| 24 |
+
const root = `${url.origin}${route}${tail[0]}/${tail[1]}/`;
|
| 25 |
+
const fallback = await cache.match(root, { ignoreSearch: true });
|
| 26 |
+
if (fallback) return fallback;
|
| 27 |
+
}
|
| 28 |
+
}
|
| 29 |
+
return new Response('Artifact file not found', {
|
| 30 |
+
status: 404,
|
| 31 |
+
headers: {
|
| 32 |
+
'Access-Control-Allow-Origin': '*',
|
| 33 |
+
'Cache-Control': 'no-store',
|
| 34 |
+
'Content-Type': 'text/plain; charset=utf-8',
|
| 35 |
+
'Cross-Origin-Resource-Policy': 'cross-origin',
|
| 36 |
+
'X-Content-Type-Options': 'nosniff',
|
| 37 |
+
},
|
| 38 |
+
});
|
| 39 |
+
})());
|
| 40 |
+
});
|
dist/assets/{c-DwI-mMi7.js → c-DU7sDOfO.js}
RENAMED
|
The diff for this file is too large to render.
See raw diff
|
|
|
dist/assets/{cpp--8bnlU9V.js → cpp-DLjLoKqK.js}
RENAMED
|
The diff for this file is too large to render.
See raw diff
|
|
|
dist/assets/{graphql-Z0wBBrAm.js → graphql-CnQ6-SC9.js}
RENAMED
|
@@ -1 +1 @@
|
|
| 1 |
-
import e from"./javascript-BgS3c2Ky.js";import{t}from"./typescript-T-I1Y_bC.js";import{t as n}from"./jsx-CtOK3bhZ.js";import{t as r}from"./tsx-qUOhHegv.js";var i=Object.freeze(JSON.parse(`{"displayName":"GraphQL","fileTypes":["graphql","graphqls","gql","graphcool"],"name":"graphql","patterns":[{"include":"#graphql"}],"repository":{"graphql":{"patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-fragment-definition"},{"include":"#graphql-directive-definition"},{"include":"#graphql-type-interface"},{"include":"#graphql-enum"},{"include":"#graphql-scalar"},{"include":"#graphql-union"},{"include":"#graphql-schema"},{"include":"#graphql-operation-def"},{"include":"#literal-quasi-embedded"}]},"graphql-ampersand":{"captures":{"1":{"name":"keyword.operator.logical.graphql"}},"match":"\\\\s*(&)"},"graphql-arguments":{"begin":"\\\\s*(\\\\()","beginCaptures":{"1":{"name":"meta.brace.round.directive.graphql"}},"end":"\\\\s*(\\\\))","endCaptures":{"1":{"name":"meta.brace.round.directive.graphql"}},"name":"meta.arguments.graphql","patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"begin":"\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)\\\\s*(:)","beginCaptures":{"1":{"name":"variable.parameter.graphql"},"2":{"name":"punctuation.colon.graphql"}},"end":"(?=\\\\s*(?:([A-Z_a-z][0-9A-Z_a-z]*)\\\\s*(:)|\\\\)))|\\\\s*(,)","endCaptures":{"3":{"name":"punctuation.comma.graphql"}},"patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-directive"},{"include":"#graphql-value"},{"include":"#graphql-skip-newlines"}]},{"include":"#literal-quasi-embedded"}]},"graphql-boolean-value":{"captures":{"1":{"name":"constant.language.boolean.graphql"}},"match":"\\\\s*\\\\b(true|false)\\\\b"},"graphql-colon":{"captures":{"1":{"name":"punctuation.colon.graphql"}},"match":"\\\\s*(:)"},"graphql-comma":{"captures":{"1":{"name":"punctuation.comma.graphql"}},"match":"\\\\s*(,)"},"graphql-comment":{"patterns":[{"captures":{"1":{"name":"punctuation.whitespace.comment.leading.graphql"}},"match":"(\\\\s*)(#).*","name":"comment.line.graphql.js"},{"begin":"(\\"\\"\\")","beginCaptures":{"1":{"name":"punctuation.whitespace.comment.leading.graphql"}},"end":"(\\"\\"\\")","name":"comment.line.graphql.js"},{"begin":"(\\")","beginCaptures":{"1":{"name":"punctuation.whitespace.comment.leading.graphql"}},"end":"(\\")","name":"comment.line.graphql.js"}]},"graphql-description-docstring":{"begin":"\\"\\"\\"","end":"\\"\\"\\"","name":"comment.block.graphql"},"graphql-description-singleline":{"match":"#(?=([^\\"]*\\"[^\\"]*\\")*[^\\"]*$).*$","name":"comment.line.number-sign.graphql"},"graphql-directive":{"applyEndPatternLast":1,"begin":"\\\\s*((@)\\\\s*([A-Z_a-z][0-9A-Z_a-z]*))","beginCaptures":{"1":{"name":"entity.name.function.directive.graphql"}},"end":"(?=.)","patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-arguments"},{"include":"#literal-quasi-embedded"},{"include":"#graphql-skip-newlines"}]},"graphql-directive-definition":{"applyEndPatternLast":1,"begin":"\\\\s*\\\\b(directive)\\\\b\\\\s*(@[A-Z_a-z][0-9A-Z_a-z]*)","beginCaptures":{"1":{"name":"keyword.directive.graphql"},"2":{"name":"entity.name.function.directive.graphql"},"3":{"name":"keyword.on.graphql"},"4":{"name":"support.type.graphql"}},"end":"(?=.)","patterns":[{"include":"#graphql-variable-definitions"},{"applyEndPatternLast":1,"begin":"\\\\s*\\\\b(on)\\\\b\\\\s*([A-Z_a-z]*)","beginCaptures":{"1":{"name":"keyword.on.graphql"},"2":{"name":"support.type.location.graphql"}},"end":"(?=.)","patterns":[{"include":"#graphql-skip-newlines"},{"include":"#graphql-comment"},{"include":"#literal-quasi-embedded"},{"captures":{"2":{"name":"support.type.location.graphql"}},"match":"\\\\s*(\\\\|)\\\\s*([A-Z_a-z]*)"}]},{"include":"#graphql-skip-newlines"},{"include":"#graphql-comment"},{"include":"#literal-quasi-embedded"}]},"graphql-enum":{"begin":"\\\\s*+\\\\b(enum)\\\\b\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)","beginCaptures":{"1":{"name":"keyword.enum.graphql"},"2":{"name":"support.type.enum.graphql"}},"end":"(?<=})","name":"meta.enum.graphql","patterns":[{"begin":"\\\\s*(\\\\{)","beginCaptures":{"1":{"name":"punctuation.operation.graphql"}},"end":"\\\\s*(})","endCaptures":{"1":{"name":"punctuation.operation.graphql"}},"name":"meta.type.object.graphql","patterns":[{"include":"#graphql-object-type"},{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-directive"},{"include":"#graphql-enum-value"},{"include":"#literal-quasi-embedded"}]},{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-directive"}]},"graphql-enum-value":{"match":"\\\\s*(?!=\\\\b(true|false|null)\\\\b)([A-Z_a-z][0-9A-Z_a-z]*)","name":"constant.character.enum.graphql"},"graphql-field":{"patterns":[{"captures":{"1":{"name":"string.unquoted.alias.graphql"},"2":{"name":"punctuation.colon.graphql"}},"match":"\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)\\\\s*(:)"},{"captures":{"1":{"name":"variable.graphql"}},"match":"\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)"},{"include":"#graphql-arguments"},{"include":"#graphql-directive"},{"include":"#graphql-selection-set"},{"include":"#literal-quasi-embedded"},{"include":"#graphql-skip-newlines"}]},"graphql-float-value":{"captures":{"1":{"name":"constant.numeric.float.graphql"}},"match":"\\\\s*(-?(0|[1-9][0-9]*)(\\\\.[0-9]+)?(([Ee])([-+])?[0-9]+)?)"},"graphql-fragment-definition":{"begin":"\\\\s*\\\\b(fragment)\\\\b\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)?\\\\s*\\\\b(on)\\\\b\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)","captures":{"1":{"name":"keyword.fragment.graphql"},"2":{"name":"entity.name.fragment.graphql"},"3":{"name":"keyword.on.graphql"},"4":{"name":"support.type.graphql"}},"end":"(?<=})","name":"meta.fragment.graphql","patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-selection-set"},{"include":"#graphql-directive"},{"include":"#graphql-skip-newlines"},{"include":"#literal-quasi-embedded"}]},"graphql-fragment-spread":{"applyEndPatternLast":1,"begin":"\\\\s*(\\\\.\\\\.\\\\.)\\\\s*(?!\\\\bon\\\\b)([A-Z_a-z][0-9A-Z_a-z]*)","captures":{"1":{"name":"keyword.operator.spread.graphql"},"2":{"name":"variable.fragment.graphql"}},"end":"(?=.)","patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-selection-set"},{"include":"#graphql-directive"},{"include":"#literal-quasi-embedded"},{"include":"#graphql-skip-newlines"}]},"graphql-ignore-spaces":{"match":"\\\\s*"},"graphql-inline-fragment":{"applyEndPatternLast":1,"begin":"\\\\s*(\\\\.\\\\.\\\\.)\\\\s*(?:\\\\b(on)\\\\b\\\\s*([A-Z_a-z][0-9A-Z_a-z]*))?","captures":{"1":{"name":"keyword.operator.spread.graphql"},"2":{"name":"keyword.on.graphql"},"3":{"name":"support.type.graphql"}},"end":"(?=.)","patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-selection-set"},{"include":"#graphql-directive"},{"include":"#graphql-skip-newlines"},{"include":"#literal-quasi-embedded"}]},"graphql-input-types":{"patterns":[{"include":"#graphql-scalar-type"},{"captures":{"1":{"name":"support.type.graphql"},"2":{"name":"keyword.operator.nulltype.graphql"}},"match":"\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)(?:\\\\s*(!))?"},{"begin":"\\\\s*(\\\\[)","captures":{"1":{"name":"meta.brace.square.graphql"},"2":{"name":"keyword.operator.nulltype.graphql"}},"end":"\\\\s*(])(?:\\\\s*(!))?","name":"meta.type.list.graphql","patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-input-types"},{"include":"#graphql-comma"},{"include":"#literal-quasi-embedded"}]}]},"graphql-list-value":{"patterns":[{"begin":"\\\\s*+(\\\\[)","beginCaptures":{"1":{"name":"meta.brace.square.graphql"}},"end":"\\\\s*(])","endCaptures":{"1":{"name":"meta.brace.square.graphql"}},"name":"meta.listvalues.graphql","patterns":[{"include":"#graphql-value"}]}]},"graphql-name":{"captures":{"1":{"name":"entity.name.function.graphql"}},"match":"\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)"},"graphql-null-value":{"captures":{"1":{"name":"constant.language.null.graphql"}},"match":"\\\\s*\\\\b(null)\\\\b"},"graphql-object-field":{"captures":{"1":{"name":"constant.object.key.graphql"},"2":{"name":"string.unquoted.graphql"},"3":{"name":"punctuation.graphql"}},"match":"\\\\s*(([A-Z_a-z][0-9A-Z_a-z]*))\\\\s*(:)"},"graphql-object-value":{"patterns":[{"begin":"\\\\s*+(\\\\{)","beginCaptures":{"1":{"name":"meta.brace.curly.graphql"}},"end":"\\\\s*(})","endCaptures":{"1":{"name":"meta.brace.curly.graphql"}},"name":"meta.objectvalues.graphql","patterns":[{"include":"#graphql-object-field"},{"include":"#graphql-value"}]}]},"graphql-operation-def":{"patterns":[{"include":"#graphql-query-mutation"},{"include":"#graphql-name"},{"include":"#graphql-variable-definitions"},{"include":"#graphql-directive"},{"include":"#graphql-selection-set"}]},"graphql-query-mutation":{"captures":{"1":{"name":"keyword.operation.graphql"}},"match":"\\\\s*\\\\b(query|mutation)\\\\b"},"graphql-scalar":{"captures":{"1":{"name":"keyword.scalar.graphql"},"2":{"name":"entity.scalar.graphql"}},"match":"\\\\s*\\\\b(scalar)\\\\b\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)"},"graphql-scalar-type":{"captures":{"1":{"name":"support.type.builtin.graphql"},"2":{"name":"keyword.operator.nulltype.graphql"}},"match":"\\\\s*\\\\b(Int|Float|String|Boolean|ID)\\\\b(?:\\\\s*(!))?"},"graphql-schema":{"begin":"\\\\s*\\\\b(schema)\\\\b","beginCaptures":{"1":{"name":"keyword.schema.graphql"}},"end":"(?<=})","patterns":[{"begin":"\\\\s*(\\\\{)","beginCaptures":{"1":{"name":"punctuation.operation.graphql"}},"end":"\\\\s*(})","endCaptures":{"1":{"name":"punctuation.operation.graphql"}},"patterns":[{"begin":"\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)(?=\\\\s*\\\\(|:)","beginCaptures":{"1":{"name":"variable.arguments.graphql"}},"end":"(?=\\\\s*(([A-Z_a-z][0-9A-Z_a-z]*)\\\\s*([(:])|(})))|\\\\s*(,)","endCaptures":{"5":{"name":"punctuation.comma.graphql"}},"patterns":[{"captures":{"1":{"name":"support.type.graphql"}},"match":"\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)"},{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-colon"},{"include":"#graphql-skip-newlines"}]},{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-skip-newlines"}]},{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-directive"},{"include":"#graphql-skip-newlines"}]},"graphql-selection-set":{"begin":"\\\\s*(\\\\{)","beginCaptures":{"1":{"name":"punctuation.operation.graphql"}},"end":"\\\\s*(})","endCaptures":{"1":{"name":"punctuation.operation.graphql"}},"name":"meta.selectionset.graphql","patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-field"},{"include":"#graphql-fragment-spread"},{"include":"#graphql-inline-fragment"},{"include":"#graphql-comma"},{"include":"#native-interpolation"},{"include":"#literal-quasi-embedded"}]},"graphql-skip-newlines":{"match":"\\\\s*\\\\n"},"graphql-string-content":{"patterns":[{"match":"\\\\\\\\[\\"'/\\\\\\\\bfnrt]","name":"constant.character.escape.graphql"},{"match":"\\\\\\\\u(\\\\h{4})","name":"constant.character.escape.graphql"}]},"graphql-string-value":{"begin":"\\\\s*+((\\"))","beginCaptures":{"1":{"name":"string.quoted.double.graphql"},"2":{"name":"punctuation.definition.string.begin.graphql"}},"contentName":"string.quoted.double.graphql","end":"\\\\s*+(?:((\\"))|(\\\\n))","endCaptures":{"1":{"name":"string.quoted.double.graphql"},"2":{"name":"punctuation.definition.string.end.graphql"},"3":{"name":"invalid.illegal.newline.graphql"}},"patterns":[{"include":"#graphql-string-content"},{"include":"#literal-quasi-embedded"}]},"graphql-type-definition":{"begin":"\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)(?=\\\\s*\\\\(|:)","beginCaptures":{"1":{"name":"variable.graphql"}},"end":"(?=\\\\s*(([A-Z_a-z][0-9A-Z_a-z]*)\\\\s*([(:])|(})))|\\\\s*(,)","endCaptures":{"5":{"name":"punctuation.comma.graphql"}},"patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-directive"},{"include":"#graphql-variable-definitions"},{"include":"#graphql-type-object"},{"include":"#graphql-colon"},{"include":"#graphql-input-types"},{"include":"#literal-quasi-embedded"}]},"graphql-type-interface":{"applyEndPatternLast":1,"begin":"\\\\s*\\\\b(?:(extends?)?\\\\b\\\\s*\\\\b(type)|(interface)|(input))\\\\b\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)?","captures":{"1":{"name":"keyword.type.graphql"},"2":{"name":"keyword.type.graphql"},"3":{"name":"keyword.interface.graphql"},"4":{"name":"keyword.input.graphql"},"5":{"name":"support.type.graphql"}},"end":"(?=.)","name":"meta.type.interface.graphql","patterns":[{"begin":"\\\\s*\\\\b(implements)\\\\b\\\\s*","beginCaptures":{"1":{"name":"keyword.implements.graphql"}},"end":"\\\\s*(?=\\\\{)","patterns":[{"captures":{"1":{"name":"support.type.graphql"}},"match":"\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)"},{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-directive"},{"include":"#graphql-ampersand"},{"include":"#graphql-comma"}]},{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-directive"},{"include":"#graphql-type-object"},{"include":"#literal-quasi-embedded"},{"include":"#graphql-ignore-spaces"}]},"graphql-type-object":{"begin":"\\\\s*(\\\\{)","beginCaptures":{"1":{"name":"punctuation.operation.graphql"}},"end":"\\\\s*(})","endCaptures":{"1":{"name":"punctuation.operation.graphql"}},"name":"meta.type.object.graphql","patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-object-type"},{"include":"#graphql-type-definition"},{"include":"#literal-quasi-embedded"}]},"graphql-union":{"applyEndPatternLast":1,"begin":"\\\\s*\\\\b(union)\\\\b\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)","captures":{"1":{"name":"keyword.union.graphql"},"2":{"name":"support.type.graphql"}},"end":"(?=.)","patterns":[{"applyEndPatternLast":1,"begin":"\\\\s*(=)\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)","captures":{"1":{"name":"punctuation.assignment.graphql"},"2":{"name":"support.type.graphql"}},"end":"(?=.)","patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-skip-newlines"},{"include":"#literal-quasi-embedded"},{"captures":{"1":{"name":"punctuation.or.graphql"},"2":{"name":"support.type.graphql"}},"match":"\\\\s*(\\\\|)\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)"}]},{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-skip-newlines"},{"include":"#literal-quasi-embedded"}]},"graphql-union-mark":{"captures":{"1":{"name":"punctuation.union.graphql"}},"match":"\\\\s*(\\\\|)"},"graphql-value":{"patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-variable-name"},{"include":"#graphql-float-value"},{"include":"#graphql-string-value"},{"include":"#graphql-boolean-value"},{"include":"#graphql-null-value"},{"include":"#graphql-enum-value"},{"include":"#graphql-list-value"},{"include":"#graphql-object-value"},{"include":"#literal-quasi-embedded"}]},"graphql-variable-assignment":{"applyEndPatternLast":1,"begin":"\\\\s(=)","beginCaptures":{"1":{"name":"punctuation.assignment.graphql"}},"end":"(?=[\\\\n),])","patterns":[{"include":"#graphql-value"}]},"graphql-variable-definition":{"begin":"\\\\s*(\\\\$?[A-Z_a-z][0-9A-Z_a-z]*)(?=\\\\s*\\\\(|:)","beginCaptures":{"1":{"name":"variable.parameter.graphql"}},"end":"(?=\\\\s*((\\\\$?[A-Z_a-z][0-9A-Z_a-z]*)\\\\s*([(:])|([)}])))|\\\\s*(,)","endCaptures":{"5":{"name":"punctuation.comma.graphql"}},"name":"meta.variables.graphql","patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-directive"},{"include":"#graphql-colon"},{"include":"#graphql-input-types"},{"include":"#graphql-variable-assignment"},{"include":"#literal-quasi-embedded"},{"include":"#graphql-skip-newlines"}]},"graphql-variable-definitions":{"begin":"\\\\s*(\\\\()","captures":{"1":{"name":"meta.brace.round.graphql"}},"end":"\\\\s*(\\\\))","patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-variable-definition"},{"include":"#literal-quasi-embedded"}]},"graphql-variable-name":{"captures":{"1":{"name":"variable.graphql"}},"match":"\\\\s*(\\\\$[A-Z_a-z][0-9A-Z_a-z]*)"},"native-interpolation":{"begin":"\\\\s*(\\\\$\\\\{)","beginCaptures":{"1":{"name":"keyword.other.substitution.begin"}},"end":"(})","endCaptures":{"1":{"name":"keyword.other.substitution.end"}},"name":"native.interpolation","patterns":[{"include":"source.js"},{"include":"source.ts"},{"include":"source.js.jsx"},{"include":"source.tsx"}]}},"scopeName":"source.graphql","embeddedLangs":["javascript","typescript","jsx","tsx"],"aliases":["gql"]}`)),a=[...e,...t,...n,...r,i];export{a as default};
|
|
|
|
| 1 |
+
import e from"./javascript-BgS3c2Ky.js";import{t}from"./typescript-D7sEy3Rx.js";import{t as n}from"./jsx-7UQWTecr.js";import{t as r}from"./tsx-DD_ZyZUf.js";var i=Object.freeze(JSON.parse(`{"displayName":"GraphQL","fileTypes":["graphql","graphqls","gql","graphcool"],"name":"graphql","patterns":[{"include":"#graphql"}],"repository":{"graphql":{"patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-fragment-definition"},{"include":"#graphql-directive-definition"},{"include":"#graphql-type-interface"},{"include":"#graphql-enum"},{"include":"#graphql-scalar"},{"include":"#graphql-union"},{"include":"#graphql-schema"},{"include":"#graphql-operation-def"},{"include":"#literal-quasi-embedded"}]},"graphql-ampersand":{"captures":{"1":{"name":"keyword.operator.logical.graphql"}},"match":"\\\\s*(&)"},"graphql-arguments":{"begin":"\\\\s*(\\\\()","beginCaptures":{"1":{"name":"meta.brace.round.directive.graphql"}},"end":"\\\\s*(\\\\))","endCaptures":{"1":{"name":"meta.brace.round.directive.graphql"}},"name":"meta.arguments.graphql","patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"begin":"\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)\\\\s*(:)","beginCaptures":{"1":{"name":"variable.parameter.graphql"},"2":{"name":"punctuation.colon.graphql"}},"end":"(?=\\\\s*(?:([A-Z_a-z][0-9A-Z_a-z]*)\\\\s*(:)|\\\\)))|\\\\s*(,)","endCaptures":{"3":{"name":"punctuation.comma.graphql"}},"patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-directive"},{"include":"#graphql-value"},{"include":"#graphql-skip-newlines"}]},{"include":"#literal-quasi-embedded"}]},"graphql-boolean-value":{"captures":{"1":{"name":"constant.language.boolean.graphql"}},"match":"\\\\s*\\\\b(true|false)\\\\b"},"graphql-colon":{"captures":{"1":{"name":"punctuation.colon.graphql"}},"match":"\\\\s*(:)"},"graphql-comma":{"captures":{"1":{"name":"punctuation.comma.graphql"}},"match":"\\\\s*(,)"},"graphql-comment":{"patterns":[{"captures":{"1":{"name":"punctuation.whitespace.comment.leading.graphql"}},"match":"(\\\\s*)(#).*","name":"comment.line.graphql.js"},{"begin":"(\\"\\"\\")","beginCaptures":{"1":{"name":"punctuation.whitespace.comment.leading.graphql"}},"end":"(\\"\\"\\")","name":"comment.line.graphql.js"},{"begin":"(\\")","beginCaptures":{"1":{"name":"punctuation.whitespace.comment.leading.graphql"}},"end":"(\\")","name":"comment.line.graphql.js"}]},"graphql-description-docstring":{"begin":"\\"\\"\\"","end":"\\"\\"\\"","name":"comment.block.graphql"},"graphql-description-singleline":{"match":"#(?=([^\\"]*\\"[^\\"]*\\")*[^\\"]*$).*$","name":"comment.line.number-sign.graphql"},"graphql-directive":{"applyEndPatternLast":1,"begin":"\\\\s*((@)\\\\s*([A-Z_a-z][0-9A-Z_a-z]*))","beginCaptures":{"1":{"name":"entity.name.function.directive.graphql"}},"end":"(?=.)","patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-arguments"},{"include":"#literal-quasi-embedded"},{"include":"#graphql-skip-newlines"}]},"graphql-directive-definition":{"applyEndPatternLast":1,"begin":"\\\\s*\\\\b(directive)\\\\b\\\\s*(@[A-Z_a-z][0-9A-Z_a-z]*)","beginCaptures":{"1":{"name":"keyword.directive.graphql"},"2":{"name":"entity.name.function.directive.graphql"},"3":{"name":"keyword.on.graphql"},"4":{"name":"support.type.graphql"}},"end":"(?=.)","patterns":[{"include":"#graphql-variable-definitions"},{"applyEndPatternLast":1,"begin":"\\\\s*\\\\b(on)\\\\b\\\\s*([A-Z_a-z]*)","beginCaptures":{"1":{"name":"keyword.on.graphql"},"2":{"name":"support.type.location.graphql"}},"end":"(?=.)","patterns":[{"include":"#graphql-skip-newlines"},{"include":"#graphql-comment"},{"include":"#literal-quasi-embedded"},{"captures":{"2":{"name":"support.type.location.graphql"}},"match":"\\\\s*(\\\\|)\\\\s*([A-Z_a-z]*)"}]},{"include":"#graphql-skip-newlines"},{"include":"#graphql-comment"},{"include":"#literal-quasi-embedded"}]},"graphql-enum":{"begin":"\\\\s*+\\\\b(enum)\\\\b\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)","beginCaptures":{"1":{"name":"keyword.enum.graphql"},"2":{"name":"support.type.enum.graphql"}},"end":"(?<=})","name":"meta.enum.graphql","patterns":[{"begin":"\\\\s*(\\\\{)","beginCaptures":{"1":{"name":"punctuation.operation.graphql"}},"end":"\\\\s*(})","endCaptures":{"1":{"name":"punctuation.operation.graphql"}},"name":"meta.type.object.graphql","patterns":[{"include":"#graphql-object-type"},{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-directive"},{"include":"#graphql-enum-value"},{"include":"#literal-quasi-embedded"}]},{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-directive"}]},"graphql-enum-value":{"match":"\\\\s*(?!=\\\\b(true|false|null)\\\\b)([A-Z_a-z][0-9A-Z_a-z]*)","name":"constant.character.enum.graphql"},"graphql-field":{"patterns":[{"captures":{"1":{"name":"string.unquoted.alias.graphql"},"2":{"name":"punctuation.colon.graphql"}},"match":"\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)\\\\s*(:)"},{"captures":{"1":{"name":"variable.graphql"}},"match":"\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)"},{"include":"#graphql-arguments"},{"include":"#graphql-directive"},{"include":"#graphql-selection-set"},{"include":"#literal-quasi-embedded"},{"include":"#graphql-skip-newlines"}]},"graphql-float-value":{"captures":{"1":{"name":"constant.numeric.float.graphql"}},"match":"\\\\s*(-?(0|[1-9][0-9]*)(\\\\.[0-9]+)?(([Ee])([-+])?[0-9]+)?)"},"graphql-fragment-definition":{"begin":"\\\\s*\\\\b(fragment)\\\\b\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)?\\\\s*\\\\b(on)\\\\b\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)","captures":{"1":{"name":"keyword.fragment.graphql"},"2":{"name":"entity.name.fragment.graphql"},"3":{"name":"keyword.on.graphql"},"4":{"name":"support.type.graphql"}},"end":"(?<=})","name":"meta.fragment.graphql","patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-selection-set"},{"include":"#graphql-directive"},{"include":"#graphql-skip-newlines"},{"include":"#literal-quasi-embedded"}]},"graphql-fragment-spread":{"applyEndPatternLast":1,"begin":"\\\\s*(\\\\.\\\\.\\\\.)\\\\s*(?!\\\\bon\\\\b)([A-Z_a-z][0-9A-Z_a-z]*)","captures":{"1":{"name":"keyword.operator.spread.graphql"},"2":{"name":"variable.fragment.graphql"}},"end":"(?=.)","patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-selection-set"},{"include":"#graphql-directive"},{"include":"#literal-quasi-embedded"},{"include":"#graphql-skip-newlines"}]},"graphql-ignore-spaces":{"match":"\\\\s*"},"graphql-inline-fragment":{"applyEndPatternLast":1,"begin":"\\\\s*(\\\\.\\\\.\\\\.)\\\\s*(?:\\\\b(on)\\\\b\\\\s*([A-Z_a-z][0-9A-Z_a-z]*))?","captures":{"1":{"name":"keyword.operator.spread.graphql"},"2":{"name":"keyword.on.graphql"},"3":{"name":"support.type.graphql"}},"end":"(?=.)","patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-selection-set"},{"include":"#graphql-directive"},{"include":"#graphql-skip-newlines"},{"include":"#literal-quasi-embedded"}]},"graphql-input-types":{"patterns":[{"include":"#graphql-scalar-type"},{"captures":{"1":{"name":"support.type.graphql"},"2":{"name":"keyword.operator.nulltype.graphql"}},"match":"\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)(?:\\\\s*(!))?"},{"begin":"\\\\s*(\\\\[)","captures":{"1":{"name":"meta.brace.square.graphql"},"2":{"name":"keyword.operator.nulltype.graphql"}},"end":"\\\\s*(])(?:\\\\s*(!))?","name":"meta.type.list.graphql","patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-input-types"},{"include":"#graphql-comma"},{"include":"#literal-quasi-embedded"}]}]},"graphql-list-value":{"patterns":[{"begin":"\\\\s*+(\\\\[)","beginCaptures":{"1":{"name":"meta.brace.square.graphql"}},"end":"\\\\s*(])","endCaptures":{"1":{"name":"meta.brace.square.graphql"}},"name":"meta.listvalues.graphql","patterns":[{"include":"#graphql-value"}]}]},"graphql-name":{"captures":{"1":{"name":"entity.name.function.graphql"}},"match":"\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)"},"graphql-null-value":{"captures":{"1":{"name":"constant.language.null.graphql"}},"match":"\\\\s*\\\\b(null)\\\\b"},"graphql-object-field":{"captures":{"1":{"name":"constant.object.key.graphql"},"2":{"name":"string.unquoted.graphql"},"3":{"name":"punctuation.graphql"}},"match":"\\\\s*(([A-Z_a-z][0-9A-Z_a-z]*))\\\\s*(:)"},"graphql-object-value":{"patterns":[{"begin":"\\\\s*+(\\\\{)","beginCaptures":{"1":{"name":"meta.brace.curly.graphql"}},"end":"\\\\s*(})","endCaptures":{"1":{"name":"meta.brace.curly.graphql"}},"name":"meta.objectvalues.graphql","patterns":[{"include":"#graphql-object-field"},{"include":"#graphql-value"}]}]},"graphql-operation-def":{"patterns":[{"include":"#graphql-query-mutation"},{"include":"#graphql-name"},{"include":"#graphql-variable-definitions"},{"include":"#graphql-directive"},{"include":"#graphql-selection-set"}]},"graphql-query-mutation":{"captures":{"1":{"name":"keyword.operation.graphql"}},"match":"\\\\s*\\\\b(query|mutation)\\\\b"},"graphql-scalar":{"captures":{"1":{"name":"keyword.scalar.graphql"},"2":{"name":"entity.scalar.graphql"}},"match":"\\\\s*\\\\b(scalar)\\\\b\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)"},"graphql-scalar-type":{"captures":{"1":{"name":"support.type.builtin.graphql"},"2":{"name":"keyword.operator.nulltype.graphql"}},"match":"\\\\s*\\\\b(Int|Float|String|Boolean|ID)\\\\b(?:\\\\s*(!))?"},"graphql-schema":{"begin":"\\\\s*\\\\b(schema)\\\\b","beginCaptures":{"1":{"name":"keyword.schema.graphql"}},"end":"(?<=})","patterns":[{"begin":"\\\\s*(\\\\{)","beginCaptures":{"1":{"name":"punctuation.operation.graphql"}},"end":"\\\\s*(})","endCaptures":{"1":{"name":"punctuation.operation.graphql"}},"patterns":[{"begin":"\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)(?=\\\\s*\\\\(|:)","beginCaptures":{"1":{"name":"variable.arguments.graphql"}},"end":"(?=\\\\s*(([A-Z_a-z][0-9A-Z_a-z]*)\\\\s*([(:])|(})))|\\\\s*(,)","endCaptures":{"5":{"name":"punctuation.comma.graphql"}},"patterns":[{"captures":{"1":{"name":"support.type.graphql"}},"match":"\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)"},{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-colon"},{"include":"#graphql-skip-newlines"}]},{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-skip-newlines"}]},{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-directive"},{"include":"#graphql-skip-newlines"}]},"graphql-selection-set":{"begin":"\\\\s*(\\\\{)","beginCaptures":{"1":{"name":"punctuation.operation.graphql"}},"end":"\\\\s*(})","endCaptures":{"1":{"name":"punctuation.operation.graphql"}},"name":"meta.selectionset.graphql","patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-field"},{"include":"#graphql-fragment-spread"},{"include":"#graphql-inline-fragment"},{"include":"#graphql-comma"},{"include":"#native-interpolation"},{"include":"#literal-quasi-embedded"}]},"graphql-skip-newlines":{"match":"\\\\s*\\\\n"},"graphql-string-content":{"patterns":[{"match":"\\\\\\\\[\\"'/\\\\\\\\bfnrt]","name":"constant.character.escape.graphql"},{"match":"\\\\\\\\u(\\\\h{4})","name":"constant.character.escape.graphql"}]},"graphql-string-value":{"begin":"\\\\s*+((\\"))","beginCaptures":{"1":{"name":"string.quoted.double.graphql"},"2":{"name":"punctuation.definition.string.begin.graphql"}},"contentName":"string.quoted.double.graphql","end":"\\\\s*+(?:((\\"))|(\\\\n))","endCaptures":{"1":{"name":"string.quoted.double.graphql"},"2":{"name":"punctuation.definition.string.end.graphql"},"3":{"name":"invalid.illegal.newline.graphql"}},"patterns":[{"include":"#graphql-string-content"},{"include":"#literal-quasi-embedded"}]},"graphql-type-definition":{"begin":"\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)(?=\\\\s*\\\\(|:)","beginCaptures":{"1":{"name":"variable.graphql"}},"end":"(?=\\\\s*(([A-Z_a-z][0-9A-Z_a-z]*)\\\\s*([(:])|(})))|\\\\s*(,)","endCaptures":{"5":{"name":"punctuation.comma.graphql"}},"patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-directive"},{"include":"#graphql-variable-definitions"},{"include":"#graphql-type-object"},{"include":"#graphql-colon"},{"include":"#graphql-input-types"},{"include":"#literal-quasi-embedded"}]},"graphql-type-interface":{"applyEndPatternLast":1,"begin":"\\\\s*\\\\b(?:(extends?)?\\\\b\\\\s*\\\\b(type)|(interface)|(input))\\\\b\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)?","captures":{"1":{"name":"keyword.type.graphql"},"2":{"name":"keyword.type.graphql"},"3":{"name":"keyword.interface.graphql"},"4":{"name":"keyword.input.graphql"},"5":{"name":"support.type.graphql"}},"end":"(?=.)","name":"meta.type.interface.graphql","patterns":[{"begin":"\\\\s*\\\\b(implements)\\\\b\\\\s*","beginCaptures":{"1":{"name":"keyword.implements.graphql"}},"end":"\\\\s*(?=\\\\{)","patterns":[{"captures":{"1":{"name":"support.type.graphql"}},"match":"\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)"},{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-directive"},{"include":"#graphql-ampersand"},{"include":"#graphql-comma"}]},{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-directive"},{"include":"#graphql-type-object"},{"include":"#literal-quasi-embedded"},{"include":"#graphql-ignore-spaces"}]},"graphql-type-object":{"begin":"\\\\s*(\\\\{)","beginCaptures":{"1":{"name":"punctuation.operation.graphql"}},"end":"\\\\s*(})","endCaptures":{"1":{"name":"punctuation.operation.graphql"}},"name":"meta.type.object.graphql","patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-object-type"},{"include":"#graphql-type-definition"},{"include":"#literal-quasi-embedded"}]},"graphql-union":{"applyEndPatternLast":1,"begin":"\\\\s*\\\\b(union)\\\\b\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)","captures":{"1":{"name":"keyword.union.graphql"},"2":{"name":"support.type.graphql"}},"end":"(?=.)","patterns":[{"applyEndPatternLast":1,"begin":"\\\\s*(=)\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)","captures":{"1":{"name":"punctuation.assignment.graphql"},"2":{"name":"support.type.graphql"}},"end":"(?=.)","patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-skip-newlines"},{"include":"#literal-quasi-embedded"},{"captures":{"1":{"name":"punctuation.or.graphql"},"2":{"name":"support.type.graphql"}},"match":"\\\\s*(\\\\|)\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)"}]},{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-skip-newlines"},{"include":"#literal-quasi-embedded"}]},"graphql-union-mark":{"captures":{"1":{"name":"punctuation.union.graphql"}},"match":"\\\\s*(\\\\|)"},"graphql-value":{"patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-variable-name"},{"include":"#graphql-float-value"},{"include":"#graphql-string-value"},{"include":"#graphql-boolean-value"},{"include":"#graphql-null-value"},{"include":"#graphql-enum-value"},{"include":"#graphql-list-value"},{"include":"#graphql-object-value"},{"include":"#literal-quasi-embedded"}]},"graphql-variable-assignment":{"applyEndPatternLast":1,"begin":"\\\\s(=)","beginCaptures":{"1":{"name":"punctuation.assignment.graphql"}},"end":"(?=[\\\\n),])","patterns":[{"include":"#graphql-value"}]},"graphql-variable-definition":{"begin":"\\\\s*(\\\\$?[A-Z_a-z][0-9A-Z_a-z]*)(?=\\\\s*\\\\(|:)","beginCaptures":{"1":{"name":"variable.parameter.graphql"}},"end":"(?=\\\\s*((\\\\$?[A-Z_a-z][0-9A-Z_a-z]*)\\\\s*([(:])|([)}])))|\\\\s*(,)","endCaptures":{"5":{"name":"punctuation.comma.graphql"}},"name":"meta.variables.graphql","patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-directive"},{"include":"#graphql-colon"},{"include":"#graphql-input-types"},{"include":"#graphql-variable-assignment"},{"include":"#literal-quasi-embedded"},{"include":"#graphql-skip-newlines"}]},"graphql-variable-definitions":{"begin":"\\\\s*(\\\\()","captures":{"1":{"name":"meta.brace.round.graphql"}},"end":"\\\\s*(\\\\))","patterns":[{"include":"#graphql-comment"},{"include":"#graphql-description-docstring"},{"include":"#graphql-description-singleline"},{"include":"#graphql-variable-definition"},{"include":"#literal-quasi-embedded"}]},"graphql-variable-name":{"captures":{"1":{"name":"variable.graphql"}},"match":"\\\\s*(\\\\$[A-Z_a-z][0-9A-Z_a-z]*)"},"native-interpolation":{"begin":"\\\\s*(\\\\$\\\\{)","beginCaptures":{"1":{"name":"keyword.other.substitution.begin"}},"end":"(})","endCaptures":{"1":{"name":"keyword.other.substitution.end"}},"name":"native.interpolation","patterns":[{"include":"source.js"},{"include":"source.ts"},{"include":"source.js.jsx"},{"include":"source.tsx"}]}},"scopeName":"source.graphql","embeddedLangs":["javascript","typescript","jsx","tsx"],"aliases":["gql"]}`)),a=[...e,...t,...n,...r,i];export{a as default};
|
dist/assets/{index-BMceOeSr.css → index-B4DG8rDO.css}
RENAMED
|
The diff for this file is too large to render.
See raw diff
|
|
|
dist/assets/index-CdsWm6Hd.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
dist/assets/index-Qym19Dm5.js
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
dist/assets/{java-B_DCJEsk.js → java-DisdHHsr.js}
RENAMED
|
@@ -1 +1 @@
|
|
| 1 |
-
import{t as e}from"./index-CdsWm6Hd.js";var t=e({default:()=>n}),n=[Object.freeze(JSON.parse(`{"displayName":"Java","name":"java","patterns":[{"begin":"\\\\b(package)\\\\b\\\\s*","beginCaptures":{"1":{"name":"keyword.other.package.java"}},"contentName":"storage.modifier.package.java","end":"\\\\s*(;)","endCaptures":{"1":{"name":"punctuation.terminator.java"}},"name":"meta.package.java","patterns":[{"include":"#comments"},{"match":"(?<=\\\\.)\\\\s*\\\\.|\\\\.(?=\\\\s*;)","name":"invalid.illegal.character_not_allowed_here.java"},{"match":"(?<!_)_(?=\\\\s*([.;]))|\\\\b\\\\d+|-+","name":"invalid.illegal.character_not_allowed_here.java"},{"match":"[A-Z]+","name":"invalid.deprecated.package_name_not_lowercase.java"},{"match":"\\\\b(?<!\\\\$)(abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|native|new|non-sealed|package|permits|private|protected|public|return|sealed|short|static|strictfp|super|switch|syncronized|this|throws??|transient|try|void|volatile|while|yield|true|false|null)\\\\b","name":"invalid.illegal.character_not_allowed_here.java"},{"match":"\\\\.","name":"punctuation.separator.java"}]},{"begin":"\\\\b(import)\\\\b\\\\s*\\\\b(static)?\\\\b\\\\s","beginCaptures":{"1":{"name":"keyword.other.import.java"},"2":{"name":"storage.modifier.java"}},"contentName":"storage.modifier.import.java","end":"\\\\s*(;)","endCaptures":{"1":{"name":"punctuation.terminator.java"}},"name":"meta.import.java","patterns":[{"include":"#comments"},{"match":"(?<=\\\\.)\\\\s*\\\\.|\\\\.(?=\\\\s*;)","name":"invalid.illegal.character_not_allowed_here.java"},{"match":"(?<!\\\\.)\\\\s*\\\\*","name":"invalid.illegal.character_not_allowed_here.java"},{"match":"(?<!_)_(?=\\\\s*([.;]))|\\\\b\\\\d+|-+","name":"invalid.illegal.character_not_allowed_here.java"},{"match":"\\\\b(?<!\\\\$)(abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|native|new|non-sealed|package|permits|private|protected|public|return|sealed|short|static|strictfp|super|switch|syncronized|this|throws??|transient|try|void|volatile|while|yield|true|false|null)\\\\b","name":"invalid.illegal.character_not_allowed_here.java"},{"match":"\\\\.","name":"punctuation.separator.java"},{"match":"\\\\*","name":"variable.language.wildcard.java"}]},{"include":"#comments-javadoc"},{"include":"#code"},{"include":"#module"}],"repository":{"all-types":{"patterns":[{"include":"#primitive-arrays"},{"include":"#primitive-types"},{"include":"#object-types"}]},"annotations":{"patterns":[{"begin":"((@)\\\\s*([^(\\\\s]+))(\\\\()","beginCaptures":{"2":{"name":"punctuation.definition.annotation.java"},"3":{"name":"storage.type.annotation.java"},"4":{"name":"punctuation.definition.annotation-arguments.begin.bracket.round.java"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.annotation-arguments.end.bracket.round.java"}},"name":"meta.declaration.annotation.java","patterns":[{"captures":{"1":{"name":"constant.other.key.java"},"2":{"name":"keyword.operator.assignment.java"}},"match":"(\\\\w*)\\\\s*(=)"},{"include":"#code"}]},{"captures":{"1":{"name":"punctuation.definition.annotation.java"},"2":{"name":"storage.modifier.java"},"3":{"name":"storage.type.annotation.java"},"5":{"name":"punctuation.definition.annotation.java"},"6":{"name":"storage.type.annotation.java"}},"match":"(@)(interface)\\\\s+(\\\\w*)|((@)\\\\s*(\\\\w+))","name":"meta.declaration.annotation.java"}]},"anonymous-block-and-instance-initializer":{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.block.begin.bracket.curly.java"}},"end":"}","endCaptures":{"0":{"name":"punctuation.section.block.end.bracket.curly.java"}},"patterns":[{"include":"#code"}]},"anonymous-classes-and-new":{"begin":"\\\\bnew\\\\b","beginCaptures":{"0":{"name":"keyword.control.new.java"}},"end":"(?=[])-.:;?}]|/(?![*/])|[!%\\\\&=^|])","patterns":[{"include":"#comments"},{"include":"#function-call"},{"include":"#all-types"},{"begin":"(?<=\\\\))","end":"(?=[])-.:;?}]|/(?![*/])|[!%\\\\&=^|])","patterns":[{"include":"#comments"},{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.inner-class.begin.bracket.curly.java"}},"end":"}","endCaptures":{"0":{"name":"punctuation.section.inner-class.end.bracket.curly.java"}},"name":"meta.inner-class.java","patterns":[{"include":"#class-body"}]}]},{"begin":"(?<=])","end":"(?=[])-.:;?}]|/(?![*/])|[!%\\\\&=^|])","patterns":[{"include":"#comments"},{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.array-initializer.begin.bracket.curly.java"}},"end":"}","endCaptures":{"0":{"name":"punctuation.section.array-initializer.end.bracket.curly.java"}},"name":"meta.array-initializer.java","patterns":[{"include":"#code"}]}]},{"include":"#parens"}]},"assertions":{"patterns":[{"begin":"\\\\b(assert)\\\\s","beginCaptures":{"1":{"name":"keyword.control.assert.java"}},"end":"$","name":"meta.declaration.assertion.java","patterns":[{"match":":","name":"keyword.operator.assert.expression-separator.java"},{"include":"#code"}]}]},"class":{"begin":"(?=\\\\w?[-\\\\w\\\\s]*\\\\b(?:class|(?<!@)interface|enum)\\\\s+[$\\\\w]+)","end":"}","endCaptures":{"0":{"name":"punctuation.section.class.end.bracket.curly.java"}},"name":"meta.class.java","patterns":[{"include":"#storage-modifiers"},{"include":"#generics"},{"include":"#comments"},{"captures":{"1":{"name":"storage.modifier.java"},"2":{"name":"entity.name.type.class.java"}},"match":"(class|(?<!@)interface|enum)\\\\s+([$\\\\w]+)","name":"meta.class.identifier.java"},{"begin":"extends","beginCaptures":{"0":{"name":"storage.modifier.extends.java"}},"end":"(?=\\\\{|implements|permits)","name":"meta.definition.class.inherited.classes.java","patterns":[{"include":"#object-types-inherited"},{"include":"#comments"}]},{"begin":"(implements)\\\\s","beginCaptures":{"1":{"name":"storage.modifier.implements.java"}},"end":"(?=\\\\s*extends|permits|\\\\{)","name":"meta.definition.class.implemented.interfaces.java","patterns":[{"include":"#object-types-inherited"},{"include":"#comments"}]},{"begin":"(permits)\\\\s","beginCaptures":{"1":{"name":"storage.modifier.permits.java"}},"end":"(?=\\\\s*extends|implements|\\\\{)","name":"meta.definition.class.permits.classes.java","patterns":[{"include":"#object-types-inherited"},{"include":"#comments"}]},{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.class.begin.bracket.curly.java"}},"contentName":"meta.class.body.java","end":"(?=})","patterns":[{"include":"#class-body"}]}]},"class-body":{"patterns":[{"include":"#comments-javadoc"},{"include":"#comments"},{"include":"#enums"},{"include":"#class"},{"include":"#generics"},{"include":"#static-initializer"},{"include":"#class-fields-and-methods"},{"include":"#annotations"},{"include":"#storage-modifiers"},{"include":"#member-variables"},{"include":"#code"}]},"class-fields-and-methods":{"patterns":[{"begin":"(?==)","end":"(?=;)","patterns":[{"include":"#code"}]},{"include":"#methods"}]},"code":{"patterns":[{"include":"#annotations"},{"include":"#comments"},{"include":"#enums"},{"include":"#class"},{"include":"#record"},{"include":"#anonymous-block-and-instance-initializer"},{"include":"#try-catch-finally"},{"include":"#assertions"},{"include":"#parens"},{"include":"#constants-and-special-vars"},{"include":"#numbers"},{"include":"#anonymous-classes-and-new"},{"include":"#lambda-expression"},{"include":"#keywords"},{"include":"#storage-modifiers"},{"include":"#method-call"},{"include":"#function-call"},{"include":"#variables"},{"include":"#variables-local"},{"include":"#objects"},{"include":"#properties"},{"include":"#strings"},{"include":"#all-types"},{"match":",","name":"punctuation.separator.delimiter.java"},{"match":"\\\\.","name":"punctuation.separator.period.java"},{"match":";","name":"punctuation.terminator.java"}]},"comments":{"patterns":[{"captures":{"0":{"name":"punctuation.definition.comment.java"}},"match":"/\\\\*\\\\*/","name":"comment.block.empty.java"},{"include":"#comments-inline"}]},"comments-inline":{"patterns":[{"begin":"/\\\\*","captures":{"0":{"name":"punctuation.definition.comment.java"}},"end":"\\\\*/","name":"comment.block.java"},{"begin":"(^[\\\\t ]+)?(?=//)","beginCaptures":{"1":{"name":"punctuation.whitespace.comment.leading.java"}},"end":"(?!\\\\G)","patterns":[{"begin":"//","beginCaptures":{"0":{"name":"punctuation.definition.comment.java"}},"end":"\\\\n","name":"comment.line.double-slash.java"}]}]},"comments-javadoc":{"patterns":[{"begin":"^\\\\s*(/\\\\*\\\\*)(?!/)","beginCaptures":{"1":{"name":"punctuation.definition.comment.java"}},"end":"\\\\*/","endCaptures":{"0":{"name":"punctuation.definition.comment.java"}},"name":"comment.block.javadoc.java","patterns":[{"match":"@(author|deprecated|return|see|serial|since|version)\\\\b","name":"keyword.other.documentation.javadoc.java"},{"captures":{"1":{"name":"keyword.other.documentation.javadoc.java"},"2":{"name":"variable.parameter.java"}},"match":"(@param)\\\\s+(\\\\S+)"},{"captures":{"1":{"name":"keyword.other.documentation.javadoc.java"},"2":{"name":"entity.name.type.class.java"}},"match":"(@(?:exception|throws))\\\\s+(\\\\S+)"},{"captures":{"1":{"name":"keyword.other.documentation.javadoc.java"},"2":{"name":"entity.name.type.class.java"},"3":{"name":"variable.parameter.java"}},"match":"\\\\{(@link)\\\\s+(\\\\S+)?#([$\\\\w]+\\\\s*\\\\([^()]*\\\\)).*?}"}]}]},"constants-and-special-vars":{"patterns":[{"match":"\\\\b(true|false|null)\\\\b","name":"constant.language.java"},{"match":"\\\\bthis\\\\b","name":"variable.language.this.java"},{"match":"\\\\bsuper\\\\b","name":"variable.language.java"}]},"enums":{"begin":"^\\\\s*([\\\\w\\\\s]*)(enum)\\\\s+(\\\\w+)","beginCaptures":{"1":{"patterns":[{"include":"#storage-modifiers"}]},"2":{"name":"storage.modifier.java"},"3":{"name":"entity.name.type.enum.java"}},"end":"}","endCaptures":{"0":{"name":"punctuation.section.enum.end.bracket.curly.java"}},"name":"meta.enum.java","patterns":[{"begin":"\\\\b(extends)\\\\b","beginCaptures":{"1":{"name":"storage.modifier.extends.java"}},"end":"(?=\\\\{|\\\\bimplements\\\\b)","name":"meta.definition.class.inherited.classes.java","patterns":[{"include":"#object-types-inherited"},{"include":"#comments"}]},{"begin":"\\\\b(implements)\\\\b","beginCaptures":{"1":{"name":"storage.modifier.implements.java"}},"end":"(?=\\\\{|\\\\bextends\\\\b)","name":"meta.definition.class.implemented.interfaces.java","patterns":[{"include":"#object-types-inherited"},{"include":"#comments"}]},{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.enum.begin.bracket.curly.java"}},"end":"(?=})","patterns":[{"begin":"(?<=\\\\{)","end":"(?=[;}])","patterns":[{"include":"#comments-javadoc"},{"include":"#comments"},{"begin":"\\\\b(\\\\w+)\\\\b","beginCaptures":{"1":{"name":"constant.other.enum.java"}},"end":"(,)|(?=[;}])","endCaptures":{"1":{"name":"punctuation.separator.delimiter.java"}},"patterns":[{"include":"#comments-javadoc"},{"include":"#comments"},{"begin":"\\\\(","beginCaptures":{"0":{"name":"punctuation.bracket.round.java"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.bracket.round.java"}},"patterns":[{"include":"#code"}]},{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.bracket.curly.java"}},"end":"}","endCaptures":{"0":{"name":"punctuation.bracket.curly.java"}},"patterns":[{"include":"#class-body"}]}]}]},{"include":"#class-body"}]}]},"function-call":{"begin":"([$A-Z_a-z][$\\\\w]*)\\\\s*(\\\\()","beginCaptures":{"1":{"name":"entity.name.function.java"},"2":{"name":"punctuation.definition.parameters.begin.bracket.round.java"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.parameters.end.bracket.round.java"}},"name":"meta.function-call.java","patterns":[{"include":"#code"}]},"generics":{"begin":"<","beginCaptures":{"0":{"name":"punctuation.bracket.angle.java"}},"end":">","endCaptures":{"0":{"name":"punctuation.bracket.angle.java"}},"patterns":[{"match":"\\\\b(extends|super)\\\\b","name":"storage.modifier.$1.java"},{"captures":{"1":{"name":"storage.type.java"}},"match":"(?<!\\\\.)([$A-Z_a-z][$0-9A-Z_a-z]*)(?=\\\\s*<)"},{"include":"#primitive-arrays"},{"match":"[$A-Z_a-z][$0-9A-Z_a-z]*","name":"storage.type.generic.java"},{"match":"\\\\?","name":"storage.type.generic.wildcard.java"},{"match":"&","name":"punctuation.separator.types.java"},{"match":",","name":"punctuation.separator.delimiter.java"},{"match":"\\\\.","name":"punctuation.separator.period.java"},{"include":"#parens"},{"include":"#generics"},{"include":"#comments"}]},"keywords":{"patterns":[{"match":"\\\\bthrow\\\\b","name":"keyword.control.throw.java"},{"match":"[:?]","name":"keyword.control.ternary.java"},{"match":"\\\\b(return|yield|break|case|continue|default|do|while|for|switch|if|else)\\\\b","name":"keyword.control.java"},{"match":"\\\\b(instanceof)\\\\b","name":"keyword.operator.instanceof.java"},{"match":"(<<|>>>?|[\\\\^~])","name":"keyword.operator.bitwise.java"},{"match":"(([\\\\&^|]|<<|>>>?)=)","name":"keyword.operator.assignment.bitwise.java"},{"match":"(===?|!=|<=|>=|<>|[<>])","name":"keyword.operator.comparison.java"},{"match":"([-%*+/]=)","name":"keyword.operator.assignment.arithmetic.java"},{"match":"(=)","name":"keyword.operator.assignment.java"},{"match":"(--|\\\\+\\\\+)","name":"keyword.operator.increment-decrement.java"},{"match":"([-%*+/])","name":"keyword.operator.arithmetic.java"},{"match":"(!|&&|\\\\|\\\\|)","name":"keyword.operator.logical.java"},{"match":"([\\\\&|])","name":"keyword.operator.bitwise.java"},{"match":"\\\\b(const|goto)\\\\b","name":"keyword.reserved.java"}]},"lambda-expression":{"patterns":[{"match":"->","name":"storage.type.function.arrow.java"}]},"member-variables":{"begin":"(?=private|protected|public|native|synchronized|abstract|threadsafe|transient|static|final)","end":"(?=[;=])","patterns":[{"include":"#storage-modifiers"},{"include":"#variables"},{"include":"#primitive-arrays"},{"include":"#object-types"}]},"method-call":{"begin":"(\\\\.)\\\\s*([$A-Z_a-z][$\\\\w]*)\\\\s*(\\\\()","beginCaptures":{"1":{"name":"punctuation.separator.period.java"},"2":{"name":"entity.name.function.java"},"3":{"name":"punctuation.definition.parameters.begin.bracket.round.java"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.parameters.end.bracket.round.java"}},"name":"meta.method-call.java","patterns":[{"include":"#code"}]},"methods":{"begin":"(?!new)(?=[<\\\\w].*\\\\s+)(?=([^/=]|/(?!/))+\\\\()","end":"(})|(?=;)","endCaptures":{"1":{"name":"punctuation.section.method.end.bracket.curly.java"}},"name":"meta.method.java","patterns":[{"include":"#storage-modifiers"},{"begin":"(\\\\w+)\\\\s*(\\\\()","beginCaptures":{"1":{"name":"entity.name.function.java"},"2":{"name":"punctuation.definition.parameters.begin.bracket.round.java"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.parameters.end.bracket.round.java"}},"name":"meta.method.identifier.java","patterns":[{"include":"#parameters"},{"include":"#parens"},{"include":"#comments"}]},{"include":"#generics"},{"begin":"(?=\\\\w.*\\\\s+\\\\w+\\\\s*\\\\()","end":"(?=\\\\s+\\\\w+\\\\s*\\\\()","name":"meta.method.return-type.java","patterns":[{"include":"#all-types"},{"include":"#parens"},{"include":"#comments"}]},{"include":"#throws"},{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.method.begin.bracket.curly.java"}},"contentName":"meta.method.body.java","end":"(?=})","patterns":[{"include":"#code"}]},{"include":"#comments"}]},"module":{"begin":"((open)\\\\s)?(module)\\\\s+(\\\\w+)","beginCaptures":{"1":{"name":"storage.modifier.java"},"3":{"name":"storage.modifier.java"},"4":{"name":"entity.name.type.module.java"}},"end":"}","endCaptures":{"0":{"name":"punctuation.section.module.end.bracket.curly.java"}},"name":"meta.module.java","patterns":[{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.module.begin.bracket.curly.java"}},"contentName":"meta.module.body.java","end":"(?=})","patterns":[{"include":"#comments"},{"include":"#comments-javadoc"},{"match":"\\\\b(requires|transitive|exports|opens|to|uses|provides|with)\\\\b","name":"keyword.module.java"}]}]},"numbers":{"patterns":[{"match":"\\\\b(?<!\\\\$)0([Xx])((?<!\\\\.)\\\\h([_\\\\h]*\\\\h)?[Ll]?(?!\\\\.)|(\\\\h([_\\\\h]*\\\\h)?\\\\.?|(\\\\h([_\\\\h]*\\\\h)?)?\\\\.\\\\h([_\\\\h]*\\\\h)?)[Pp][-+]?[0-9]([0-9_]*[0-9])?[DFdf]?)\\\\b(?!\\\\$)","name":"constant.numeric.hex.java"},{"match":"\\\\b(?<!\\\\$)0([Bb])[01]([01_]*[01])?[Ll]?\\\\b(?!\\\\$)","name":"constant.numeric.binary.java"},{"match":"\\\\b(?<!\\\\$)0[0-7]([0-7_]*[0-7])?[Ll]?\\\\b(?!\\\\$)","name":"constant.numeric.octal.java"},{"match":"(?<!\\\\$)(\\\\b[0-9]([0-9_]*[0-9])?\\\\.\\\\B(?!\\\\.)|\\\\b[0-9]([0-9_]*[0-9])?\\\\.([Ee][-+]?[0-9]([0-9_]*[0-9])?)[DFdf]?\\\\b|\\\\b[0-9]([0-9_]*[0-9])?\\\\.([Ee][-+]?[0-9]([0-9_]*[0-9])?)?[DFdf]\\\\b|\\\\b[0-9]([0-9_]*[0-9])?\\\\.([0-9]([0-9_]*[0-9])?)([Ee][-+]?[0-9]([0-9_]*[0-9])?)?[DFdf]?\\\\b|(?<!\\\\.)\\\\B\\\\.[0-9]([0-9_]*[0-9])?([Ee][-+]?[0-9]([0-9_]*[0-9])?)?[DFdf]?\\\\b|\\\\b[0-9]([0-9_]*[0-9])?([Ee][-+]?[0-9]([0-9_]*[0-9])?)[DFdf]?\\\\b|\\\\b[0-9]([0-9_]*[0-9])?([Ee][-+]?[0-9]([0-9_]*[0-9])?)?[DFdf]\\\\b|\\\\b(0|[1-9]([0-9_]*[0-9])?)(?!\\\\.)[Ll]?\\\\b)(?!\\\\$)","name":"constant.numeric.decimal.java"}]},"object-types":{"patterns":[{"include":"#generics"},{"begin":"\\\\b((?:[A-Z_a-z]\\\\w*\\\\s*\\\\.\\\\s*)*)([A-Z_]\\\\w*)\\\\s*(?=\\\\[)","beginCaptures":{"1":{"patterns":[{"match":"[A-Z_a-z]\\\\w*","name":"storage.type.java"},{"match":"\\\\.","name":"punctuation.separator.period.java"}]},"2":{"name":"storage.type.object.array.java"}},"end":"(?!\\\\s*\\\\[)","patterns":[{"include":"#comments"},{"include":"#parens"}]},{"captures":{"1":{"patterns":[{"match":"[A-Z_a-z]\\\\w*","name":"storage.type.java"},{"match":"\\\\.","name":"punctuation.separator.period.java"}]}},"match":"\\\\b((?:[A-Z_a-z]\\\\w*\\\\s*\\\\.\\\\s*)*[A-Z_]\\\\w*)\\\\s*(?=<)"},{"captures":{"1":{"patterns":[{"match":"[A-Z_a-z]\\\\w*","name":"storage.type.java"},{"match":"\\\\.","name":"punctuation.separator.period.java"}]}},"match":"\\\\b((?:[A-Z_a-z]\\\\w*\\\\s*\\\\.\\\\s*)*[A-Z_]\\\\w*)\\\\b((?=\\\\s*[\\\\n$A-Z_a-z])|(?=\\\\s*\\\\.\\\\.\\\\.))"}]},"object-types-inherited":{"patterns":[{"include":"#generics"},{"captures":{"1":{"name":"punctuation.separator.period.java"}},"match":"\\\\b(?:[A-Z]\\\\w*\\\\s*(\\\\.)\\\\s*)*[A-Z]\\\\w*\\\\b","name":"entity.other.inherited-class.java"},{"match":",","name":"punctuation.separator.delimiter.java"}]},"objects":{"match":"(?<![$\\\\w])[$A-Z_a-z][$\\\\w]*(?=\\\\s*\\\\.\\\\s*[$\\\\w]+)","name":"variable.other.object.java"},"parameters":{"patterns":[{"match":"\\\\bfinal\\\\b","name":"storage.modifier.java"},{"include":"#annotations"},{"include":"#all-types"},{"include":"#strings"},{"match":"\\\\w+","name":"variable.parameter.java"},{"match":",","name":"punctuation.separator.delimiter.java"},{"match":"\\\\.\\\\.\\\\.","name":"punctuation.definition.parameters.varargs.java"}]},"parens":{"patterns":[{"begin":"\\\\(","beginCaptures":{"0":{"name":"punctuation.bracket.round.java"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.bracket.round.java"}},"patterns":[{"include":"#code"}]},{"begin":"\\\\[","beginCaptures":{"0":{"name":"punctuation.bracket.square.java"}},"end":"]","endCaptures":{"0":{"name":"punctuation.bracket.square.java"}},"patterns":[{"include":"#code"}]},{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.bracket.curly.java"}},"end":"}","endCaptures":{"0":{"name":"punctuation.bracket.curly.java"}},"patterns":[{"include":"#code"}]}]},"primitive-arrays":{"patterns":[{"begin":"\\\\b(void|boolean|byte|char|short|int|float|long|double)\\\\b\\\\s*(?=\\\\[)","beginCaptures":{"1":{"name":"storage.type.primitive.array.java"}},"end":"(?!\\\\s*\\\\[)","patterns":[{"include":"#comments"},{"include":"#parens"}]}]},"primitive-types":{"match":"\\\\b(void|boolean|byte|char|short|int|float|long|double)\\\\b","name":"storage.type.primitive.java"},"properties":{"patterns":[{"captures":{"1":{"name":"punctuation.separator.period.java"},"2":{"name":"keyword.control.new.java"}},"match":"(\\\\.)\\\\s*(new)"},{"captures":{"1":{"name":"punctuation.separator.period.java"},"2":{"name":"variable.other.object.property.java"}},"match":"(\\\\.)\\\\s*([$A-Z_a-z][$\\\\w]*)(?=\\\\s*\\\\.\\\\s*[$A-Z_a-z][$\\\\w]*)"},{"captures":{"1":{"name":"punctuation.separator.period.java"},"2":{"name":"variable.other.object.property.java"}},"match":"(\\\\.)\\\\s*([$A-Z_a-z][$\\\\w]*)"},{"captures":{"1":{"name":"punctuation.separator.period.java"},"2":{"name":"invalid.illegal.identifier.java"}},"match":"(\\\\.)\\\\s*([0-9][$\\\\w]*)"}]},"record":{"begin":"(?=\\\\w?[\\\\w\\\\s]*\\\\brecord\\\\s+[$\\\\w]+)","end":"}","endCaptures":{"0":{"name":"punctuation.section.class.end.bracket.curly.java"}},"name":"meta.record.java","patterns":[{"include":"#storage-modifiers"},{"include":"#generics"},{"include":"#comments"},{"begin":"(record)\\\\s+([$\\\\w]+)(<[$\\\\w]+>)?(\\\\()","beginCaptures":{"1":{"name":"storage.modifier.java"},"2":{"name":"entity.name.type.record.java"},"3":{"patterns":[{"include":"#generics"}]},"4":{"name":"punctuation.definition.parameters.begin.bracket.round.java"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.parameters.end.bracket.round.java"}},"name":"meta.record.identifier.java","patterns":[{"include":"#code"}]},{"begin":"(implements)\\\\s","beginCaptures":{"1":{"name":"storage.modifier.implements.java"}},"end":"(?=\\\\s*\\\\{)","name":"meta.definition.class.implemented.interfaces.java","patterns":[{"include":"#object-types-inherited"},{"include":"#comments"}]},{"include":"#record-body"}]},"record-body":{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.class.begin.bracket.curly.java"}},"end":"(?=})","name":"meta.record.body.java","patterns":[{"include":"#record-constructor"},{"include":"#class-body"}]},"record-constructor":{"begin":"(?!new)(?=[<\\\\w].*\\\\s+)(?=([^(/=]|/(?!/))+(?=\\\\{))","end":"(})|(?=;)","endCaptures":{"1":{"name":"punctuation.section.method.end.bracket.curly.java"}},"name":"meta.method.java","patterns":[{"include":"#storage-modifiers"},{"begin":"(\\\\w+)","beginCaptures":{"1":{"name":"entity.name.function.java"}},"end":"(?=\\\\s*\\\\{)","name":"meta.method.identifier.java","patterns":[{"include":"#comments"}]},{"include":"#comments"},{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.method.begin.bracket.curly.java"}},"contentName":"meta.method.body.java","end":"(?=})","patterns":[{"include":"#code"}]}]},"static-initializer":{"patterns":[{"include":"#anonymous-block-and-instance-initializer"},{"match":"static","name":"storage.modifier.java"}]},"storage-modifiers":{"match":"\\\\b(public|private|protected|static|final|native|synchronized|abstract|threadsafe|transient|volatile|default|strictfp|sealed|non-sealed)\\\\b","name":"storage.modifier.java"},"strings":{"patterns":[{"begin":"\\"\\"\\"","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.java"}},"end":"\\"\\"\\"","endCaptures":{"0":{"name":"punctuation.definition.string.end.java"}},"name":"string.quoted.triple.java","patterns":[{"match":"(\\\\\\\\\\"\\"\\")(?!\\")|(\\\\\\\\.)","name":"constant.character.escape.java"}]},{"begin":"\\"","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.java"}},"end":"\\"","endCaptures":{"0":{"name":"punctuation.definition.string.end.java"}},"name":"string.quoted.double.java","patterns":[{"match":"\\\\\\\\.","name":"constant.character.escape.java"}]},{"begin":"'","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.java"}},"end":"'","endCaptures":{"0":{"name":"punctuation.definition.string.end.java"}},"name":"string.quoted.single.java","patterns":[{"match":"\\\\\\\\.","name":"constant.character.escape.java"}]}]},"throws":{"begin":"throws","beginCaptures":{"0":{"name":"storage.modifier.java"}},"end":"(?=[;{])","name":"meta.throwables.java","patterns":[{"match":",","name":"punctuation.separator.delimiter.java"},{"match":"[$A-Z_a-z][$.0-9A-Z_a-z]*","name":"storage.type.java"},{"include":"#comments"}]},"try-catch-finally":{"patterns":[{"begin":"\\\\btry\\\\b","beginCaptures":{"0":{"name":"keyword.control.try.java"}},"end":"}","endCaptures":{"0":{"name":"punctuation.section.try.end.bracket.curly.java"}},"name":"meta.try.java","patterns":[{"begin":"\\\\(","beginCaptures":{"0":{"name":"punctuation.section.try.resources.begin.bracket.round.java"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.section.try.resources.end.bracket.round.java"}},"name":"meta.try.resources.java","patterns":[{"include":"#code"}]},{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.try.begin.bracket.curly.java"}},"contentName":"meta.try.body.java","end":"(?=})","patterns":[{"include":"#code"}]}]},{"begin":"\\\\b(catch)\\\\b","beginCaptures":{"1":{"name":"keyword.control.catch.java"}},"end":"}","endCaptures":{"0":{"name":"punctuation.section.catch.end.bracket.curly.java"}},"name":"meta.catch.java","patterns":[{"include":"#comments"},{"begin":"\\\\(","beginCaptures":{"0":{"name":"punctuation.definition.parameters.begin.bracket.round.java"}},"contentName":"meta.catch.parameters.java","end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.parameters.end.bracket.round.java"}},"patterns":[{"include":"#comments"},{"include":"#storage-modifiers"},{"begin":"[$A-Z_a-z][$.0-9A-Z_a-z]*","beginCaptures":{"0":{"name":"storage.type.java"}},"end":"(\\\\|)|(?=\\\\))","endCaptures":{"1":{"name":"punctuation.catch.separator.java"}},"patterns":[{"include":"#comments"},{"captures":{"0":{"name":"variable.parameter.java"}},"match":"\\\\w+"}]}]},{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.catch.begin.bracket.curly.java"}},"contentName":"meta.catch.body.java","end":"(?=})","patterns":[{"include":"#code"}]}]},{"begin":"\\\\bfinally\\\\b","beginCaptures":{"0":{"name":"keyword.control.finally.java"}},"end":"}","endCaptures":{"0":{"name":"punctuation.section.finally.end.bracket.curly.java"}},"name":"meta.finally.java","patterns":[{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.finally.begin.bracket.curly.java"}},"contentName":"meta.finally.body.java","end":"(?=})","patterns":[{"include":"#code"}]}]}]},"variables":{"begin":"(?=\\\\b((void|boolean|byte|char|short|int|float|long|double)|(?>(\\\\w+\\\\.)*[A-Z_]+\\\\w*))\\\\b\\\\s*(<[],.<>?\\\\[\\\\w\\\\s]*>)?\\\\s*((\\\\[])*)?\\\\s+[$A-Z_a-z][$\\\\w]*([]$,\\\\[\\\\w][],\\\\[\\\\w\\\\s]*)?\\\\s*([:;=]))","end":"(?=[:;=])","name":"meta.definition.variable.java","patterns":[{"captures":{"1":{"name":"variable.other.definition.java"}},"match":"([$A-Z_a-z][$\\\\w]*)(?=\\\\s*(\\\\[])*\\\\s*([,:;=]))"},{"include":"#all-types"},{"include":"#code"}]},"variables-local":{"begin":"(?=\\\\b(var)\\\\b\\\\s+[$A-Z_a-z][$\\\\w]*\\\\s*([:;=]))","end":"(?=[:;=])","name":"meta.definition.variable.local.java","patterns":[{"match":"\\\\bvar\\\\b","name":"storage.type.local.java"},{"captures":{"1":{"name":"variable.other.definition.java"}},"match":"([$A-Z_a-z][$\\\\w]*)(?=\\\\s*(\\\\[])*\\\\s*([:;=]))"},{"include":"#code"}]}},"scopeName":"source.java"}`))];export{t as n,n as t};
|
|
|
|
| 1 |
+
import{t as e}from"./index-Qym19Dm5.js";var t=e({default:()=>n}),n=[Object.freeze(JSON.parse(`{"displayName":"Java","name":"java","patterns":[{"begin":"\\\\b(package)\\\\b\\\\s*","beginCaptures":{"1":{"name":"keyword.other.package.java"}},"contentName":"storage.modifier.package.java","end":"\\\\s*(;)","endCaptures":{"1":{"name":"punctuation.terminator.java"}},"name":"meta.package.java","patterns":[{"include":"#comments"},{"match":"(?<=\\\\.)\\\\s*\\\\.|\\\\.(?=\\\\s*;)","name":"invalid.illegal.character_not_allowed_here.java"},{"match":"(?<!_)_(?=\\\\s*([.;]))|\\\\b\\\\d+|-+","name":"invalid.illegal.character_not_allowed_here.java"},{"match":"[A-Z]+","name":"invalid.deprecated.package_name_not_lowercase.java"},{"match":"\\\\b(?<!\\\\$)(abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|native|new|non-sealed|package|permits|private|protected|public|return|sealed|short|static|strictfp|super|switch|syncronized|this|throws??|transient|try|void|volatile|while|yield|true|false|null)\\\\b","name":"invalid.illegal.character_not_allowed_here.java"},{"match":"\\\\.","name":"punctuation.separator.java"}]},{"begin":"\\\\b(import)\\\\b\\\\s*\\\\b(static)?\\\\b\\\\s","beginCaptures":{"1":{"name":"keyword.other.import.java"},"2":{"name":"storage.modifier.java"}},"contentName":"storage.modifier.import.java","end":"\\\\s*(;)","endCaptures":{"1":{"name":"punctuation.terminator.java"}},"name":"meta.import.java","patterns":[{"include":"#comments"},{"match":"(?<=\\\\.)\\\\s*\\\\.|\\\\.(?=\\\\s*;)","name":"invalid.illegal.character_not_allowed_here.java"},{"match":"(?<!\\\\.)\\\\s*\\\\*","name":"invalid.illegal.character_not_allowed_here.java"},{"match":"(?<!_)_(?=\\\\s*([.;]))|\\\\b\\\\d+|-+","name":"invalid.illegal.character_not_allowed_here.java"},{"match":"\\\\b(?<!\\\\$)(abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|native|new|non-sealed|package|permits|private|protected|public|return|sealed|short|static|strictfp|super|switch|syncronized|this|throws??|transient|try|void|volatile|while|yield|true|false|null)\\\\b","name":"invalid.illegal.character_not_allowed_here.java"},{"match":"\\\\.","name":"punctuation.separator.java"},{"match":"\\\\*","name":"variable.language.wildcard.java"}]},{"include":"#comments-javadoc"},{"include":"#code"},{"include":"#module"}],"repository":{"all-types":{"patterns":[{"include":"#primitive-arrays"},{"include":"#primitive-types"},{"include":"#object-types"}]},"annotations":{"patterns":[{"begin":"((@)\\\\s*([^(\\\\s]+))(\\\\()","beginCaptures":{"2":{"name":"punctuation.definition.annotation.java"},"3":{"name":"storage.type.annotation.java"},"4":{"name":"punctuation.definition.annotation-arguments.begin.bracket.round.java"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.annotation-arguments.end.bracket.round.java"}},"name":"meta.declaration.annotation.java","patterns":[{"captures":{"1":{"name":"constant.other.key.java"},"2":{"name":"keyword.operator.assignment.java"}},"match":"(\\\\w*)\\\\s*(=)"},{"include":"#code"}]},{"captures":{"1":{"name":"punctuation.definition.annotation.java"},"2":{"name":"storage.modifier.java"},"3":{"name":"storage.type.annotation.java"},"5":{"name":"punctuation.definition.annotation.java"},"6":{"name":"storage.type.annotation.java"}},"match":"(@)(interface)\\\\s+(\\\\w*)|((@)\\\\s*(\\\\w+))","name":"meta.declaration.annotation.java"}]},"anonymous-block-and-instance-initializer":{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.block.begin.bracket.curly.java"}},"end":"}","endCaptures":{"0":{"name":"punctuation.section.block.end.bracket.curly.java"}},"patterns":[{"include":"#code"}]},"anonymous-classes-and-new":{"begin":"\\\\bnew\\\\b","beginCaptures":{"0":{"name":"keyword.control.new.java"}},"end":"(?=[])-.:;?}]|/(?![*/])|[!%\\\\&=^|])","patterns":[{"include":"#comments"},{"include":"#function-call"},{"include":"#all-types"},{"begin":"(?<=\\\\))","end":"(?=[])-.:;?}]|/(?![*/])|[!%\\\\&=^|])","patterns":[{"include":"#comments"},{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.inner-class.begin.bracket.curly.java"}},"end":"}","endCaptures":{"0":{"name":"punctuation.section.inner-class.end.bracket.curly.java"}},"name":"meta.inner-class.java","patterns":[{"include":"#class-body"}]}]},{"begin":"(?<=])","end":"(?=[])-.:;?}]|/(?![*/])|[!%\\\\&=^|])","patterns":[{"include":"#comments"},{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.array-initializer.begin.bracket.curly.java"}},"end":"}","endCaptures":{"0":{"name":"punctuation.section.array-initializer.end.bracket.curly.java"}},"name":"meta.array-initializer.java","patterns":[{"include":"#code"}]}]},{"include":"#parens"}]},"assertions":{"patterns":[{"begin":"\\\\b(assert)\\\\s","beginCaptures":{"1":{"name":"keyword.control.assert.java"}},"end":"$","name":"meta.declaration.assertion.java","patterns":[{"match":":","name":"keyword.operator.assert.expression-separator.java"},{"include":"#code"}]}]},"class":{"begin":"(?=\\\\w?[-\\\\w\\\\s]*\\\\b(?:class|(?<!@)interface|enum)\\\\s+[$\\\\w]+)","end":"}","endCaptures":{"0":{"name":"punctuation.section.class.end.bracket.curly.java"}},"name":"meta.class.java","patterns":[{"include":"#storage-modifiers"},{"include":"#generics"},{"include":"#comments"},{"captures":{"1":{"name":"storage.modifier.java"},"2":{"name":"entity.name.type.class.java"}},"match":"(class|(?<!@)interface|enum)\\\\s+([$\\\\w]+)","name":"meta.class.identifier.java"},{"begin":"extends","beginCaptures":{"0":{"name":"storage.modifier.extends.java"}},"end":"(?=\\\\{|implements|permits)","name":"meta.definition.class.inherited.classes.java","patterns":[{"include":"#object-types-inherited"},{"include":"#comments"}]},{"begin":"(implements)\\\\s","beginCaptures":{"1":{"name":"storage.modifier.implements.java"}},"end":"(?=\\\\s*extends|permits|\\\\{)","name":"meta.definition.class.implemented.interfaces.java","patterns":[{"include":"#object-types-inherited"},{"include":"#comments"}]},{"begin":"(permits)\\\\s","beginCaptures":{"1":{"name":"storage.modifier.permits.java"}},"end":"(?=\\\\s*extends|implements|\\\\{)","name":"meta.definition.class.permits.classes.java","patterns":[{"include":"#object-types-inherited"},{"include":"#comments"}]},{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.class.begin.bracket.curly.java"}},"contentName":"meta.class.body.java","end":"(?=})","patterns":[{"include":"#class-body"}]}]},"class-body":{"patterns":[{"include":"#comments-javadoc"},{"include":"#comments"},{"include":"#enums"},{"include":"#class"},{"include":"#generics"},{"include":"#static-initializer"},{"include":"#class-fields-and-methods"},{"include":"#annotations"},{"include":"#storage-modifiers"},{"include":"#member-variables"},{"include":"#code"}]},"class-fields-and-methods":{"patterns":[{"begin":"(?==)","end":"(?=;)","patterns":[{"include":"#code"}]},{"include":"#methods"}]},"code":{"patterns":[{"include":"#annotations"},{"include":"#comments"},{"include":"#enums"},{"include":"#class"},{"include":"#record"},{"include":"#anonymous-block-and-instance-initializer"},{"include":"#try-catch-finally"},{"include":"#assertions"},{"include":"#parens"},{"include":"#constants-and-special-vars"},{"include":"#numbers"},{"include":"#anonymous-classes-and-new"},{"include":"#lambda-expression"},{"include":"#keywords"},{"include":"#storage-modifiers"},{"include":"#method-call"},{"include":"#function-call"},{"include":"#variables"},{"include":"#variables-local"},{"include":"#objects"},{"include":"#properties"},{"include":"#strings"},{"include":"#all-types"},{"match":",","name":"punctuation.separator.delimiter.java"},{"match":"\\\\.","name":"punctuation.separator.period.java"},{"match":";","name":"punctuation.terminator.java"}]},"comments":{"patterns":[{"captures":{"0":{"name":"punctuation.definition.comment.java"}},"match":"/\\\\*\\\\*/","name":"comment.block.empty.java"},{"include":"#comments-inline"}]},"comments-inline":{"patterns":[{"begin":"/\\\\*","captures":{"0":{"name":"punctuation.definition.comment.java"}},"end":"\\\\*/","name":"comment.block.java"},{"begin":"(^[\\\\t ]+)?(?=//)","beginCaptures":{"1":{"name":"punctuation.whitespace.comment.leading.java"}},"end":"(?!\\\\G)","patterns":[{"begin":"//","beginCaptures":{"0":{"name":"punctuation.definition.comment.java"}},"end":"\\\\n","name":"comment.line.double-slash.java"}]}]},"comments-javadoc":{"patterns":[{"begin":"^\\\\s*(/\\\\*\\\\*)(?!/)","beginCaptures":{"1":{"name":"punctuation.definition.comment.java"}},"end":"\\\\*/","endCaptures":{"0":{"name":"punctuation.definition.comment.java"}},"name":"comment.block.javadoc.java","patterns":[{"match":"@(author|deprecated|return|see|serial|since|version)\\\\b","name":"keyword.other.documentation.javadoc.java"},{"captures":{"1":{"name":"keyword.other.documentation.javadoc.java"},"2":{"name":"variable.parameter.java"}},"match":"(@param)\\\\s+(\\\\S+)"},{"captures":{"1":{"name":"keyword.other.documentation.javadoc.java"},"2":{"name":"entity.name.type.class.java"}},"match":"(@(?:exception|throws))\\\\s+(\\\\S+)"},{"captures":{"1":{"name":"keyword.other.documentation.javadoc.java"},"2":{"name":"entity.name.type.class.java"},"3":{"name":"variable.parameter.java"}},"match":"\\\\{(@link)\\\\s+(\\\\S+)?#([$\\\\w]+\\\\s*\\\\([^()]*\\\\)).*?}"}]}]},"constants-and-special-vars":{"patterns":[{"match":"\\\\b(true|false|null)\\\\b","name":"constant.language.java"},{"match":"\\\\bthis\\\\b","name":"variable.language.this.java"},{"match":"\\\\bsuper\\\\b","name":"variable.language.java"}]},"enums":{"begin":"^\\\\s*([\\\\w\\\\s]*)(enum)\\\\s+(\\\\w+)","beginCaptures":{"1":{"patterns":[{"include":"#storage-modifiers"}]},"2":{"name":"storage.modifier.java"},"3":{"name":"entity.name.type.enum.java"}},"end":"}","endCaptures":{"0":{"name":"punctuation.section.enum.end.bracket.curly.java"}},"name":"meta.enum.java","patterns":[{"begin":"\\\\b(extends)\\\\b","beginCaptures":{"1":{"name":"storage.modifier.extends.java"}},"end":"(?=\\\\{|\\\\bimplements\\\\b)","name":"meta.definition.class.inherited.classes.java","patterns":[{"include":"#object-types-inherited"},{"include":"#comments"}]},{"begin":"\\\\b(implements)\\\\b","beginCaptures":{"1":{"name":"storage.modifier.implements.java"}},"end":"(?=\\\\{|\\\\bextends\\\\b)","name":"meta.definition.class.implemented.interfaces.java","patterns":[{"include":"#object-types-inherited"},{"include":"#comments"}]},{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.enum.begin.bracket.curly.java"}},"end":"(?=})","patterns":[{"begin":"(?<=\\\\{)","end":"(?=[;}])","patterns":[{"include":"#comments-javadoc"},{"include":"#comments"},{"begin":"\\\\b(\\\\w+)\\\\b","beginCaptures":{"1":{"name":"constant.other.enum.java"}},"end":"(,)|(?=[;}])","endCaptures":{"1":{"name":"punctuation.separator.delimiter.java"}},"patterns":[{"include":"#comments-javadoc"},{"include":"#comments"},{"begin":"\\\\(","beginCaptures":{"0":{"name":"punctuation.bracket.round.java"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.bracket.round.java"}},"patterns":[{"include":"#code"}]},{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.bracket.curly.java"}},"end":"}","endCaptures":{"0":{"name":"punctuation.bracket.curly.java"}},"patterns":[{"include":"#class-body"}]}]}]},{"include":"#class-body"}]}]},"function-call":{"begin":"([$A-Z_a-z][$\\\\w]*)\\\\s*(\\\\()","beginCaptures":{"1":{"name":"entity.name.function.java"},"2":{"name":"punctuation.definition.parameters.begin.bracket.round.java"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.parameters.end.bracket.round.java"}},"name":"meta.function-call.java","patterns":[{"include":"#code"}]},"generics":{"begin":"<","beginCaptures":{"0":{"name":"punctuation.bracket.angle.java"}},"end":">","endCaptures":{"0":{"name":"punctuation.bracket.angle.java"}},"patterns":[{"match":"\\\\b(extends|super)\\\\b","name":"storage.modifier.$1.java"},{"captures":{"1":{"name":"storage.type.java"}},"match":"(?<!\\\\.)([$A-Z_a-z][$0-9A-Z_a-z]*)(?=\\\\s*<)"},{"include":"#primitive-arrays"},{"match":"[$A-Z_a-z][$0-9A-Z_a-z]*","name":"storage.type.generic.java"},{"match":"\\\\?","name":"storage.type.generic.wildcard.java"},{"match":"&","name":"punctuation.separator.types.java"},{"match":",","name":"punctuation.separator.delimiter.java"},{"match":"\\\\.","name":"punctuation.separator.period.java"},{"include":"#parens"},{"include":"#generics"},{"include":"#comments"}]},"keywords":{"patterns":[{"match":"\\\\bthrow\\\\b","name":"keyword.control.throw.java"},{"match":"[:?]","name":"keyword.control.ternary.java"},{"match":"\\\\b(return|yield|break|case|continue|default|do|while|for|switch|if|else)\\\\b","name":"keyword.control.java"},{"match":"\\\\b(instanceof)\\\\b","name":"keyword.operator.instanceof.java"},{"match":"(<<|>>>?|[\\\\^~])","name":"keyword.operator.bitwise.java"},{"match":"(([\\\\&^|]|<<|>>>?)=)","name":"keyword.operator.assignment.bitwise.java"},{"match":"(===?|!=|<=|>=|<>|[<>])","name":"keyword.operator.comparison.java"},{"match":"([-%*+/]=)","name":"keyword.operator.assignment.arithmetic.java"},{"match":"(=)","name":"keyword.operator.assignment.java"},{"match":"(--|\\\\+\\\\+)","name":"keyword.operator.increment-decrement.java"},{"match":"([-%*+/])","name":"keyword.operator.arithmetic.java"},{"match":"(!|&&|\\\\|\\\\|)","name":"keyword.operator.logical.java"},{"match":"([\\\\&|])","name":"keyword.operator.bitwise.java"},{"match":"\\\\b(const|goto)\\\\b","name":"keyword.reserved.java"}]},"lambda-expression":{"patterns":[{"match":"->","name":"storage.type.function.arrow.java"}]},"member-variables":{"begin":"(?=private|protected|public|native|synchronized|abstract|threadsafe|transient|static|final)","end":"(?=[;=])","patterns":[{"include":"#storage-modifiers"},{"include":"#variables"},{"include":"#primitive-arrays"},{"include":"#object-types"}]},"method-call":{"begin":"(\\\\.)\\\\s*([$A-Z_a-z][$\\\\w]*)\\\\s*(\\\\()","beginCaptures":{"1":{"name":"punctuation.separator.period.java"},"2":{"name":"entity.name.function.java"},"3":{"name":"punctuation.definition.parameters.begin.bracket.round.java"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.parameters.end.bracket.round.java"}},"name":"meta.method-call.java","patterns":[{"include":"#code"}]},"methods":{"begin":"(?!new)(?=[<\\\\w].*\\\\s+)(?=([^/=]|/(?!/))+\\\\()","end":"(})|(?=;)","endCaptures":{"1":{"name":"punctuation.section.method.end.bracket.curly.java"}},"name":"meta.method.java","patterns":[{"include":"#storage-modifiers"},{"begin":"(\\\\w+)\\\\s*(\\\\()","beginCaptures":{"1":{"name":"entity.name.function.java"},"2":{"name":"punctuation.definition.parameters.begin.bracket.round.java"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.parameters.end.bracket.round.java"}},"name":"meta.method.identifier.java","patterns":[{"include":"#parameters"},{"include":"#parens"},{"include":"#comments"}]},{"include":"#generics"},{"begin":"(?=\\\\w.*\\\\s+\\\\w+\\\\s*\\\\()","end":"(?=\\\\s+\\\\w+\\\\s*\\\\()","name":"meta.method.return-type.java","patterns":[{"include":"#all-types"},{"include":"#parens"},{"include":"#comments"}]},{"include":"#throws"},{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.method.begin.bracket.curly.java"}},"contentName":"meta.method.body.java","end":"(?=})","patterns":[{"include":"#code"}]},{"include":"#comments"}]},"module":{"begin":"((open)\\\\s)?(module)\\\\s+(\\\\w+)","beginCaptures":{"1":{"name":"storage.modifier.java"},"3":{"name":"storage.modifier.java"},"4":{"name":"entity.name.type.module.java"}},"end":"}","endCaptures":{"0":{"name":"punctuation.section.module.end.bracket.curly.java"}},"name":"meta.module.java","patterns":[{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.module.begin.bracket.curly.java"}},"contentName":"meta.module.body.java","end":"(?=})","patterns":[{"include":"#comments"},{"include":"#comments-javadoc"},{"match":"\\\\b(requires|transitive|exports|opens|to|uses|provides|with)\\\\b","name":"keyword.module.java"}]}]},"numbers":{"patterns":[{"match":"\\\\b(?<!\\\\$)0([Xx])((?<!\\\\.)\\\\h([_\\\\h]*\\\\h)?[Ll]?(?!\\\\.)|(\\\\h([_\\\\h]*\\\\h)?\\\\.?|(\\\\h([_\\\\h]*\\\\h)?)?\\\\.\\\\h([_\\\\h]*\\\\h)?)[Pp][-+]?[0-9]([0-9_]*[0-9])?[DFdf]?)\\\\b(?!\\\\$)","name":"constant.numeric.hex.java"},{"match":"\\\\b(?<!\\\\$)0([Bb])[01]([01_]*[01])?[Ll]?\\\\b(?!\\\\$)","name":"constant.numeric.binary.java"},{"match":"\\\\b(?<!\\\\$)0[0-7]([0-7_]*[0-7])?[Ll]?\\\\b(?!\\\\$)","name":"constant.numeric.octal.java"},{"match":"(?<!\\\\$)(\\\\b[0-9]([0-9_]*[0-9])?\\\\.\\\\B(?!\\\\.)|\\\\b[0-9]([0-9_]*[0-9])?\\\\.([Ee][-+]?[0-9]([0-9_]*[0-9])?)[DFdf]?\\\\b|\\\\b[0-9]([0-9_]*[0-9])?\\\\.([Ee][-+]?[0-9]([0-9_]*[0-9])?)?[DFdf]\\\\b|\\\\b[0-9]([0-9_]*[0-9])?\\\\.([0-9]([0-9_]*[0-9])?)([Ee][-+]?[0-9]([0-9_]*[0-9])?)?[DFdf]?\\\\b|(?<!\\\\.)\\\\B\\\\.[0-9]([0-9_]*[0-9])?([Ee][-+]?[0-9]([0-9_]*[0-9])?)?[DFdf]?\\\\b|\\\\b[0-9]([0-9_]*[0-9])?([Ee][-+]?[0-9]([0-9_]*[0-9])?)[DFdf]?\\\\b|\\\\b[0-9]([0-9_]*[0-9])?([Ee][-+]?[0-9]([0-9_]*[0-9])?)?[DFdf]\\\\b|\\\\b(0|[1-9]([0-9_]*[0-9])?)(?!\\\\.)[Ll]?\\\\b)(?!\\\\$)","name":"constant.numeric.decimal.java"}]},"object-types":{"patterns":[{"include":"#generics"},{"begin":"\\\\b((?:[A-Z_a-z]\\\\w*\\\\s*\\\\.\\\\s*)*)([A-Z_]\\\\w*)\\\\s*(?=\\\\[)","beginCaptures":{"1":{"patterns":[{"match":"[A-Z_a-z]\\\\w*","name":"storage.type.java"},{"match":"\\\\.","name":"punctuation.separator.period.java"}]},"2":{"name":"storage.type.object.array.java"}},"end":"(?!\\\\s*\\\\[)","patterns":[{"include":"#comments"},{"include":"#parens"}]},{"captures":{"1":{"patterns":[{"match":"[A-Z_a-z]\\\\w*","name":"storage.type.java"},{"match":"\\\\.","name":"punctuation.separator.period.java"}]}},"match":"\\\\b((?:[A-Z_a-z]\\\\w*\\\\s*\\\\.\\\\s*)*[A-Z_]\\\\w*)\\\\s*(?=<)"},{"captures":{"1":{"patterns":[{"match":"[A-Z_a-z]\\\\w*","name":"storage.type.java"},{"match":"\\\\.","name":"punctuation.separator.period.java"}]}},"match":"\\\\b((?:[A-Z_a-z]\\\\w*\\\\s*\\\\.\\\\s*)*[A-Z_]\\\\w*)\\\\b((?=\\\\s*[\\\\n$A-Z_a-z])|(?=\\\\s*\\\\.\\\\.\\\\.))"}]},"object-types-inherited":{"patterns":[{"include":"#generics"},{"captures":{"1":{"name":"punctuation.separator.period.java"}},"match":"\\\\b(?:[A-Z]\\\\w*\\\\s*(\\\\.)\\\\s*)*[A-Z]\\\\w*\\\\b","name":"entity.other.inherited-class.java"},{"match":",","name":"punctuation.separator.delimiter.java"}]},"objects":{"match":"(?<![$\\\\w])[$A-Z_a-z][$\\\\w]*(?=\\\\s*\\\\.\\\\s*[$\\\\w]+)","name":"variable.other.object.java"},"parameters":{"patterns":[{"match":"\\\\bfinal\\\\b","name":"storage.modifier.java"},{"include":"#annotations"},{"include":"#all-types"},{"include":"#strings"},{"match":"\\\\w+","name":"variable.parameter.java"},{"match":",","name":"punctuation.separator.delimiter.java"},{"match":"\\\\.\\\\.\\\\.","name":"punctuation.definition.parameters.varargs.java"}]},"parens":{"patterns":[{"begin":"\\\\(","beginCaptures":{"0":{"name":"punctuation.bracket.round.java"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.bracket.round.java"}},"patterns":[{"include":"#code"}]},{"begin":"\\\\[","beginCaptures":{"0":{"name":"punctuation.bracket.square.java"}},"end":"]","endCaptures":{"0":{"name":"punctuation.bracket.square.java"}},"patterns":[{"include":"#code"}]},{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.bracket.curly.java"}},"end":"}","endCaptures":{"0":{"name":"punctuation.bracket.curly.java"}},"patterns":[{"include":"#code"}]}]},"primitive-arrays":{"patterns":[{"begin":"\\\\b(void|boolean|byte|char|short|int|float|long|double)\\\\b\\\\s*(?=\\\\[)","beginCaptures":{"1":{"name":"storage.type.primitive.array.java"}},"end":"(?!\\\\s*\\\\[)","patterns":[{"include":"#comments"},{"include":"#parens"}]}]},"primitive-types":{"match":"\\\\b(void|boolean|byte|char|short|int|float|long|double)\\\\b","name":"storage.type.primitive.java"},"properties":{"patterns":[{"captures":{"1":{"name":"punctuation.separator.period.java"},"2":{"name":"keyword.control.new.java"}},"match":"(\\\\.)\\\\s*(new)"},{"captures":{"1":{"name":"punctuation.separator.period.java"},"2":{"name":"variable.other.object.property.java"}},"match":"(\\\\.)\\\\s*([$A-Z_a-z][$\\\\w]*)(?=\\\\s*\\\\.\\\\s*[$A-Z_a-z][$\\\\w]*)"},{"captures":{"1":{"name":"punctuation.separator.period.java"},"2":{"name":"variable.other.object.property.java"}},"match":"(\\\\.)\\\\s*([$A-Z_a-z][$\\\\w]*)"},{"captures":{"1":{"name":"punctuation.separator.period.java"},"2":{"name":"invalid.illegal.identifier.java"}},"match":"(\\\\.)\\\\s*([0-9][$\\\\w]*)"}]},"record":{"begin":"(?=\\\\w?[\\\\w\\\\s]*\\\\brecord\\\\s+[$\\\\w]+)","end":"}","endCaptures":{"0":{"name":"punctuation.section.class.end.bracket.curly.java"}},"name":"meta.record.java","patterns":[{"include":"#storage-modifiers"},{"include":"#generics"},{"include":"#comments"},{"begin":"(record)\\\\s+([$\\\\w]+)(<[$\\\\w]+>)?(\\\\()","beginCaptures":{"1":{"name":"storage.modifier.java"},"2":{"name":"entity.name.type.record.java"},"3":{"patterns":[{"include":"#generics"}]},"4":{"name":"punctuation.definition.parameters.begin.bracket.round.java"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.parameters.end.bracket.round.java"}},"name":"meta.record.identifier.java","patterns":[{"include":"#code"}]},{"begin":"(implements)\\\\s","beginCaptures":{"1":{"name":"storage.modifier.implements.java"}},"end":"(?=\\\\s*\\\\{)","name":"meta.definition.class.implemented.interfaces.java","patterns":[{"include":"#object-types-inherited"},{"include":"#comments"}]},{"include":"#record-body"}]},"record-body":{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.class.begin.bracket.curly.java"}},"end":"(?=})","name":"meta.record.body.java","patterns":[{"include":"#record-constructor"},{"include":"#class-body"}]},"record-constructor":{"begin":"(?!new)(?=[<\\\\w].*\\\\s+)(?=([^(/=]|/(?!/))+(?=\\\\{))","end":"(})|(?=;)","endCaptures":{"1":{"name":"punctuation.section.method.end.bracket.curly.java"}},"name":"meta.method.java","patterns":[{"include":"#storage-modifiers"},{"begin":"(\\\\w+)","beginCaptures":{"1":{"name":"entity.name.function.java"}},"end":"(?=\\\\s*\\\\{)","name":"meta.method.identifier.java","patterns":[{"include":"#comments"}]},{"include":"#comments"},{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.method.begin.bracket.curly.java"}},"contentName":"meta.method.body.java","end":"(?=})","patterns":[{"include":"#code"}]}]},"static-initializer":{"patterns":[{"include":"#anonymous-block-and-instance-initializer"},{"match":"static","name":"storage.modifier.java"}]},"storage-modifiers":{"match":"\\\\b(public|private|protected|static|final|native|synchronized|abstract|threadsafe|transient|volatile|default|strictfp|sealed|non-sealed)\\\\b","name":"storage.modifier.java"},"strings":{"patterns":[{"begin":"\\"\\"\\"","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.java"}},"end":"\\"\\"\\"","endCaptures":{"0":{"name":"punctuation.definition.string.end.java"}},"name":"string.quoted.triple.java","patterns":[{"match":"(\\\\\\\\\\"\\"\\")(?!\\")|(\\\\\\\\.)","name":"constant.character.escape.java"}]},{"begin":"\\"","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.java"}},"end":"\\"","endCaptures":{"0":{"name":"punctuation.definition.string.end.java"}},"name":"string.quoted.double.java","patterns":[{"match":"\\\\\\\\.","name":"constant.character.escape.java"}]},{"begin":"'","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.java"}},"end":"'","endCaptures":{"0":{"name":"punctuation.definition.string.end.java"}},"name":"string.quoted.single.java","patterns":[{"match":"\\\\\\\\.","name":"constant.character.escape.java"}]}]},"throws":{"begin":"throws","beginCaptures":{"0":{"name":"storage.modifier.java"}},"end":"(?=[;{])","name":"meta.throwables.java","patterns":[{"match":",","name":"punctuation.separator.delimiter.java"},{"match":"[$A-Z_a-z][$.0-9A-Z_a-z]*","name":"storage.type.java"},{"include":"#comments"}]},"try-catch-finally":{"patterns":[{"begin":"\\\\btry\\\\b","beginCaptures":{"0":{"name":"keyword.control.try.java"}},"end":"}","endCaptures":{"0":{"name":"punctuation.section.try.end.bracket.curly.java"}},"name":"meta.try.java","patterns":[{"begin":"\\\\(","beginCaptures":{"0":{"name":"punctuation.section.try.resources.begin.bracket.round.java"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.section.try.resources.end.bracket.round.java"}},"name":"meta.try.resources.java","patterns":[{"include":"#code"}]},{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.try.begin.bracket.curly.java"}},"contentName":"meta.try.body.java","end":"(?=})","patterns":[{"include":"#code"}]}]},{"begin":"\\\\b(catch)\\\\b","beginCaptures":{"1":{"name":"keyword.control.catch.java"}},"end":"}","endCaptures":{"0":{"name":"punctuation.section.catch.end.bracket.curly.java"}},"name":"meta.catch.java","patterns":[{"include":"#comments"},{"begin":"\\\\(","beginCaptures":{"0":{"name":"punctuation.definition.parameters.begin.bracket.round.java"}},"contentName":"meta.catch.parameters.java","end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.parameters.end.bracket.round.java"}},"patterns":[{"include":"#comments"},{"include":"#storage-modifiers"},{"begin":"[$A-Z_a-z][$.0-9A-Z_a-z]*","beginCaptures":{"0":{"name":"storage.type.java"}},"end":"(\\\\|)|(?=\\\\))","endCaptures":{"1":{"name":"punctuation.catch.separator.java"}},"patterns":[{"include":"#comments"},{"captures":{"0":{"name":"variable.parameter.java"}},"match":"\\\\w+"}]}]},{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.catch.begin.bracket.curly.java"}},"contentName":"meta.catch.body.java","end":"(?=})","patterns":[{"include":"#code"}]}]},{"begin":"\\\\bfinally\\\\b","beginCaptures":{"0":{"name":"keyword.control.finally.java"}},"end":"}","endCaptures":{"0":{"name":"punctuation.section.finally.end.bracket.curly.java"}},"name":"meta.finally.java","patterns":[{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.section.finally.begin.bracket.curly.java"}},"contentName":"meta.finally.body.java","end":"(?=})","patterns":[{"include":"#code"}]}]}]},"variables":{"begin":"(?=\\\\b((void|boolean|byte|char|short|int|float|long|double)|(?>(\\\\w+\\\\.)*[A-Z_]+\\\\w*))\\\\b\\\\s*(<[],.<>?\\\\[\\\\w\\\\s]*>)?\\\\s*((\\\\[])*)?\\\\s+[$A-Z_a-z][$\\\\w]*([]$,\\\\[\\\\w][],\\\\[\\\\w\\\\s]*)?\\\\s*([:;=]))","end":"(?=[:;=])","name":"meta.definition.variable.java","patterns":[{"captures":{"1":{"name":"variable.other.definition.java"}},"match":"([$A-Z_a-z][$\\\\w]*)(?=\\\\s*(\\\\[])*\\\\s*([,:;=]))"},{"include":"#all-types"},{"include":"#code"}]},"variables-local":{"begin":"(?=\\\\b(var)\\\\b\\\\s+[$A-Z_a-z][$\\\\w]*\\\\s*([:;=]))","end":"(?=[:;=])","name":"meta.definition.variable.local.java","patterns":[{"match":"\\\\bvar\\\\b","name":"storage.type.local.java"},{"captures":{"1":{"name":"variable.other.definition.java"}},"match":"([$A-Z_a-z][$\\\\w]*)(?=\\\\s*(\\\\[])*\\\\s*([:;=]))"},{"include":"#code"}]}},"scopeName":"source.java"}`))];export{t as n,n as t};
|
dist/assets/{jsx-CtOK3bhZ.js → jsx-7UQWTecr.js}
RENAMED
|
The diff for this file is too large to render.
See raw diff
|
|
|
dist/assets/{lua-CUc9ktct.js → lua-DNHyM1z9.js}
RENAMED
|
@@ -1 +1 @@
|
|
| 1 |
-
import{t as e}from"./c-DwI-mMi7.js";var t=Object.freeze(JSON.parse(`{"displayName":"Lua","name":"lua","patterns":[{"begin":"\\\\b(?:(local)\\\\s+)?(function)\\\\b(?![,:])","beginCaptures":{"1":{"name":"keyword.local.lua"},"2":{"name":"keyword.control.lua"}},"end":"(?<=[-\\\\]\\"')\\\\[{}])","name":"meta.function.lua","patterns":[{"include":"#comment"},{"begin":"(\\\\()","beginCaptures":{"1":{"name":"punctuation.definition.parameters.begin.lua"}},"end":"(\\\\))|(?=[-\\\\]\\"'\\\\[{}])|(?<!\\\\.)\\\\.(?!\\\\.)","endCaptures":{"1":{"name":"punctuation.definition.parameters.finish.lua"}},"name":"meta.parameter.lua","patterns":[{"include":"#comment"},{"captures":{"1":{"name":"constant.language.lua"},"2":{"name":"variable.parameter.function.lua"}},"match":"(\\\\.{3})\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)"},{"match":"[A-Z_a-z][0-9A-Z_a-z]*","name":"variable.parameter.function.lua"},{"match":",","name":"punctuation.separator.arguments.lua"},{"begin":":","beginCaptures":{"0":{"name":"punctuation.separator.arguments.lua"}},"end":"(?=[),])","patterns":[{"include":"#emmydoc.type"}]}]},{"match":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b\\\\s*(?=:)","name":"entity.name.class.lua"},{"match":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b","name":"entity.name.function.lua"}]},{"match":"(?<![.\\\\w\\\\d])0[Xx]\\\\h+(\\\\.\\\\h*)?([Ee]-?\\\\d*)?([Pp][-+]\\\\d+)?","name":"constant.numeric.float.hexadecimal.lua"},{"match":"(?<![.\\\\w\\\\d])0[Xx]\\\\.\\\\h+([Ee]-?\\\\d*)?([Pp][-+]\\\\d+)?","name":"constant.numeric.float.hexadecimal.lua"},{"match":"(?<![.\\\\w\\\\d])0[Xx]\\\\h+(?![.0-9EPep])","name":"constant.numeric.integer.hexadecimal.lua"},{"match":"(?<![.\\\\w\\\\d])\\\\d+(\\\\.\\\\d*)?([Ee]-?\\\\d*)?","name":"constant.numeric.float.lua"},{"match":"(?<![.\\\\w\\\\d])\\\\.\\\\d+([Ee]-?\\\\d*)?","name":"constant.numeric.float.lua"},{"match":"(?<![.\\\\w\\\\d])\\\\d+(?![.0-9EPep])","name":"constant.numeric.integer.lua"},{"include":"#string"},{"captures":{"1":{"name":"punctuation.definition.comment.lua"}},"match":"\\\\A(#!).*$\\\\n?","name":"comment.line.shebang.lua"},{"include":"#comment"},{"captures":{"1":{"name":"keyword.control.goto.lua"},"2":{"name":"string.tag.lua"}},"match":"\\\\b(goto)\\\\s+([A-Z_a-z][0-9A-Z_a-z]*)"},{"captures":{"1":{"name":"punctuation.section.embedded.begin.lua"},"2":{"name":"punctuation.section.embedded.end.lua"}},"match":"(::)\\\\s*[A-Z_a-z][0-9A-Z_a-z]*\\\\s*(::)","name":"string.tag.lua"},{"captures":{"0":{"name":"storage.type.attribute.lua"}},"match":"<\\\\s*(c(?:onst|lose))\\\\s*>"},{"match":"<[*A-Z_a-z][-*.0-9A-Z_a-z]*>","name":"storage.type.generic.lua"},{"match":"\\\\b(break|do|else|for|if|elseif|goto|return|then|repeat|while|until|end|in)\\\\b","name":"keyword.control.lua"},{"match":"\\\\b(local)\\\\b","name":"keyword.local.lua"},{"captures":{"1":{"name":"keyword.global.lua"}},"match":"^\\\\s*(global)\\\\b(?!\\\\s*=)"},{"match":"\\\\b(function)\\\\b(?![,:])","name":"keyword.control.lua"},{"match":"(?<![^.]\\\\.|:)\\\\b(false|nil(?!:)|true|_ENV|_G|_VERSION|math\\\\.(pi|huge|maxinteger|mininteger)|utf8\\\\.charpattern|io\\\\.(std(?:in|out|err))|package\\\\.(config|cpath|loaded|loaders|path|preload|searchers))\\\\b|(?<!\\\\.)\\\\.{3}(?!\\\\.)","name":"constant.language.lua"},{"match":"(?<![^.]\\\\.|:)\\\\b(self)\\\\b","name":"variable.language.self.lua"},{"match":"(?<![^.]\\\\.|:)\\\\b(assert|collectgarbage|dofile|error|getfenv|getmetatable|ipairs|load|loadfile|loadstring|module|next|pairs|pcall|print|rawequal|rawget|rawlen|rawset|require|select|setfenv|setmetatable|tonumber|tostring|type|unpack|xpcall)\\\\b(?!\\\\s*=(?!=))","name":"support.function.lua"},{"match":"(?<![^.]\\\\.|:)\\\\b(async)\\\\b(?!\\\\s*=(?!=))","name":"entity.name.tag.lua"},{"match":"(?<![^.]\\\\.|:)\\\\b(coroutine\\\\.(create|isyieldable|close|resume|running|status|wrap|yield)|string\\\\.(byte|char|dump|find|format|gmatch|gsub|len|lower|match|pack|packsize|rep|reverse|sub|unpack|upper)|table\\\\.(concat|create|insert|maxn|move|pack|remove|sort|unpack)|math\\\\.(abs|acos|asin|atan2?|ceil|cosh?|deg|exp|floor|fmod|frexp|ldexp|log|log10|max|min|modf|pow|rad|random|randomseed|sinh?|sqrt|tanh?|tointeger|type)|io\\\\.(close|flush|input|lines|open|output|popen|read|tmpfile|type|write)|os\\\\.(clock|date|difftime|execute|exit|getenv|remove|rename|setlocale|time|tmpname)|package\\\\.(loadlib|seeall|searchpath)|debug\\\\.(debug|[gs]etfenv|[gs]ethook|getinfo|[gs]etlocal|[gs]etmetatable|getregistry|[gs]etupvalue|[gs]etuservalue|set[Cc]stacklimit|traceback|upvalueid|upvaluejoin)|bit32\\\\.(arshift|band|bnot|bor|btest|bxor|extract|replace|lrotate|lshift|rrotate|rshift)|utf8\\\\.(char|codes|codepoint|len|offset))\\\\b(?!\\\\s*=(?!=))","name":"support.function.library.lua"},{"match":"\\\\b(\\\\|\\\\||&&|!)\\\\b","name":"keyword.operator.lua"},{"match":"\\\\b(and|or|not)\\\\b","name":"keyword.operator.logical.lua"},{"match":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b(?=\\\\s*(?:[\\"'({]|\\\\[\\\\[))","name":"support.function.any-method.lua"},{"match":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b(?=\\\\s*\\\\??:)","name":"entity.name.class.lua"},{"match":"(?<=[^.]\\\\.|:)\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b(?!\\\\s*=\\\\s*\\\\b(function)\\\\b)","name":"entity.other.attribute.lua"},{"match":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b(?!\\\\s*=\\\\s*\\\\b(function)\\\\b)","name":"variable.other.lua"},{"match":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b(?=\\\\s*=\\\\s*\\\\b(function)\\\\b)","name":"entity.name.function.lua"},{"match":"[-#%*+/^]|==?|~=|!=|<=?|>=?|(?<!\\\\.)\\\\.{2}(?!\\\\.)","name":"keyword.operator.lua"}],"repository":{"comment":{"patterns":[{"begin":"(^[\\\\t ]+)?(?=--)","beginCaptures":{"1":{"name":"punctuation.whitespace.comment.leading.lua"}},"end":"(?!\\\\G)((?!^)[\\\\t ]+\\\\n)?","endCaptures":{"1":{"name":"punctuation.whitespace.comment.trailing.lua"}},"patterns":[{"begin":"--\\\\[(=*)\\\\[@@@","beginCaptures":{"0":{"name":"punctuation.definition.comment.begin.lua"}},"end":"(--)?]\\\\1]","endCaptures":{"0":{"name":"punctuation.definition.comment.end.lua"}},"name":"","patterns":[{"include":"source.lua"}]},{"begin":"--\\\\[(=*)\\\\[","beginCaptures":{"0":{"name":"punctuation.definition.comment.begin.lua"}},"end":"(--)?]\\\\1]","endCaptures":{"0":{"name":"punctuation.definition.comment.end.lua"}},"name":"comment.block.lua","patterns":[{"include":"#emmydoc"},{"include":"#ldoc_tag"}]},{"begin":"----","beginCaptures":{"0":{"name":"punctuation.definition.comment.lua"}},"end":"\\\\n","name":"comment.line.double-dash.lua"},{"begin":"---","beginCaptures":{"0":{"name":"punctuation.definition.comment.lua"}},"end":"\\\\n","name":"comment.line.double-dash.documentation.lua","patterns":[{"include":"#emmydoc"},{"include":"#ldoc_tag"}]},{"begin":"--","beginCaptures":{"0":{"name":"punctuation.definition.comment.lua"}},"end":"\\\\n","name":"comment.line.double-dash.lua","patterns":[{"include":"#ldoc_tag"}]}]},{"begin":"/\\\\*","beginCaptures":{"0":{"name":"punctuation.definition.comment.begin.lua"}},"end":"\\\\*/","endCaptures":{"0":{"name":"punctuation.definition.comment.end.lua"}},"name":"comment.block.lua","patterns":[{"include":"#emmydoc"},{"include":"#ldoc_tag"}]}]},"emmydoc":{"patterns":[{"begin":"(?<=---)[\\\\t ]*@class","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"match":"\\\\b([*A-Z_a-z][-*.0-9A-Z_a-z]*)","name":"support.class.lua"},{"match":"[,:]","name":"keyword.operator.lua"}]},{"begin":"(?<=---)[\\\\t ]*@enum","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"begin":"\\\\b([*A-Z_a-z][-*.0-9A-Z_a-z]*)","beginCaptures":{"0":{"name":"variable.lua"}},"end":"(?=\\\\n)"}]},{"begin":"(?<=---)[\\\\t ]*@type","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"include":"#emmydoc.type"}]},{"begin":"(?<=---)[\\\\t ]*@alias","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"begin":"\\\\b([*A-Z_a-z][-*.0-9A-Z_a-z]*)","beginCaptures":{"0":{"name":"variable.lua"}},"end":"(?=[\\\\n#])","patterns":[{"include":"#emmydoc.type"}]}]},{"begin":"(?<=---)[\\\\t ]*(@operator)\\\\s*(\\\\b[a-z]+)?","beginCaptures":{"1":{"name":"storage.type.annotation.lua"},"2":{"name":"support.function.library.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"include":"#emmydoc.type"}]},{"begin":"(?<=---)[\\\\t ]*@cast","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"begin":"\\\\b([*A-Z_a-z][-*.0-9A-Z_a-z]*)","beginCaptures":{"0":{"name":"variable.other.lua"}},"end":"(?=\\\\n)","patterns":[{"include":"#emmydoc.type"},{"match":"([+-|])","name":"keyword.operator.lua"}]}]},{"begin":"(?<=---)[\\\\t ]*@param","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"begin":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b(\\\\??)","beginCaptures":{"1":{"name":"entity.name.variable.lua"},"2":{"name":"keyword.operator.lua"}},"end":"(?=[\\\\n#])","patterns":[{"include":"#emmydoc.type"}]}]},{"begin":"(?<=---)[\\\\t ]*@return","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"match":"\\\\?","name":"keyword.operator.lua"},{"include":"#emmydoc.type"}]},{"begin":"(?<=---)[\\\\t ]*@field","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"begin":"(\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b|(\\\\[))(\\\\??)","beginCaptures":{"2":{"name":"entity.name.variable.lua"},"3":{"name":"keyword.operator.lua"}},"end":"(?=[\\\\n#])","patterns":[{"include":"#string"},{"include":"#emmydoc.type"},{"match":"]","name":"keyword.operator.lua"}]}]},{"begin":"(?<=---)[\\\\t ]*@generic","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"begin":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b","beginCaptures":{"0":{"name":"storage.type.generic.lua"}},"end":"(?=\\\\n)|(,)","endCaptures":{"0":{"name":"keyword.operator.lua"}},"patterns":[{"match":":","name":"keyword.operator.lua"},{"include":"#emmydoc.type"}]}]},{"begin":"(?<=---)[\\\\t ]*@vararg","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"include":"#emmydoc.type"}]},{"begin":"(?<=---)[\\\\t ]*@overload","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"include":"#emmydoc.type"}]},{"begin":"(?<=---)[\\\\t ]*@deprecated","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])"},{"begin":"(?<=---)[\\\\t ]*@meta","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])"},{"begin":"(?<=---)[\\\\t ]*@private","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])"},{"begin":"(?<=---)[\\\\t ]*@protected","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])"},{"begin":"(?<=---)[\\\\t ]*@package","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])"},{"begin":"(?<=---)[\\\\t ]*@version","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"match":"\\\\b(5\\\\.1|5\\\\.2|5\\\\.3|5\\\\.4|JIT)\\\\b","name":"support.class.lua"},{"match":"[,<>]","name":"keyword.operator.lua"}]},{"begin":"(?<=---)[\\\\t ]*@see","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"match":"\\\\b([*A-Z_a-z][-*.0-9A-Z_a-z]*)","name":"support.class.lua"},{"match":"#","name":"keyword.operator.lua"}]},{"begin":"(?<=---)[\\\\t ]*@diagnostic","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"begin":"([-0-9A-Z_a-z]+)[\\\\t ]*(:)?","beginCaptures":{"1":{"name":"keyword.other.unit"},"2":{"name":"keyword.operator.unit"}},"end":"(?=\\\\n)","patterns":[{"match":"\\\\b([*A-Z_a-z][-0-9A-Z_a-z]*)","name":"support.class.lua"},{"match":",","name":"keyword.operator.lua"}]}]},{"begin":"(?<=---)[\\\\t ]*@module","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"include":"#string"}]},{"match":"(?<=---)[\\\\t ]*@(async|nodiscard)","name":"storage.type.annotation.lua"},{"begin":"(?<=---)\\\\|\\\\s*[+>]?","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"include":"#string"}]}]},"emmydoc.type":{"patterns":[{"begin":"\\\\bfun\\\\b","beginCaptures":{"0":{"name":"keyword.control.lua"}},"end":"(?=[#\\\\s])","patterns":[{"match":"[](),:<>?\\\\[][\\\\t ]*","name":"keyword.operator.lua"},{"match":"([A-Z_a-z][-*.0-9A-Z_a-z]*)(?<!,)[\\\\t ]*(?=\\\\??:)","name":"entity.name.variable.lua"},{"include":"#emmydoc.type"},{"include":"#string"}]},{"match":"<[*A-Z_a-z][-*.0-9A-Z_a-z]*>","name":"storage.type.generic.lua"},{"match":"\\\\basync\\\\b","name":"entity.name.tag.lua"},{"match":"[,:?\`{|}][\\\\t ]*","name":"keyword.operator.lua"},{"begin":"(?=[\\"'*.A-\\\\[_a-z])","end":"(?=[#),:?|}\\\\s])","patterns":[{"match":"([-\\\\]*,.0-9<>A-\\\\[_a-z]+)(?<!,)[\\\\t ]*","name":"support.type.lua"},{"match":"(\\\\.\\\\.\\\\.)[\\\\t ]*","name":"constant.language.lua"},{"include":"#string"}]}]},"escaped_char":{"patterns":[{"match":"\\\\\\\\[\\\\n\\"'\\\\\\\\abfnrtv]","name":"constant.character.escape.lua"},{"match":"\\\\\\\\z[\\\\t\\\\n ]*","name":"constant.character.escape.lua"},{"match":"\\\\\\\\\\\\d{1,3}","name":"constant.character.escape.byte.lua"},{"match":"\\\\\\\\x\\\\h\\\\h","name":"constant.character.escape.byte.lua"},{"match":"\\\\\\\\u\\\\{\\\\h+}","name":"constant.character.escape.unicode.lua"},{"match":"\\\\\\\\.","name":"invalid.illegal.character.escape.lua"}]},"ldoc_tag":{"captures":{"1":{"name":"punctuation.definition.block.tag.ldoc"},"2":{"name":"storage.type.class.ldoc"}},"match":"\\\\G[\\\\t ]*(@)(alias|annotation|author|charset|class|classmod|comment|constructor|copyright|description|example|export|factory|field|file|fixme|function|include|lfunction|license|local|module|name|param|pragma|private|raise|release|return|script|section|see|set|static|submodule|summary|tfield|thread|tparam|treturn|todo|topic|type|usage|warning|within)\\\\b"},"string":{"patterns":[{"begin":"'","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.lua"}},"end":"'[\\\\t ]*|(?=\\\\n)","endCaptures":{"0":{"name":"punctuation.definition.string.end.lua"}},"name":"string.quoted.single.lua","patterns":[{"include":"#escaped_char"}]},{"begin":"\\"","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.lua"}},"end":"\\"[\\\\t ]*|(?=\\\\n)","endCaptures":{"0":{"name":"punctuation.definition.string.end.lua"}},"name":"string.quoted.double.lua","patterns":[{"include":"#escaped_char"}]},{"begin":"\`","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.lua"}},"end":"\`[\\\\t ]*|(?=\\\\n)","endCaptures":{"0":{"name":"punctuation.definition.string.end.lua"}},"name":"string.quoted.double.lua"},{"begin":"(?<=\\\\.cdef)\\\\s*(\\\\[(=*)\\\\[)","beginCaptures":{"0":{"name":"string.quoted.other.multiline.lua"},"1":{"name":"punctuation.definition.string.begin.lua"}},"contentName":"meta.embedded.lua","end":"(]\\\\2])[\\\\t ]*","endCaptures":{"0":{"name":"string.quoted.other.multiline.lua"},"1":{"name":"punctuation.definition.string.end.lua"}},"patterns":[{"include":"source.c"}]},{"begin":"(?<!--)\\\\[(=*)\\\\[","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.lua"}},"end":"]\\\\1][\\\\t ]*","endCaptures":{"0":{"name":"punctuation.definition.string.end.lua"}},"name":"string.quoted.other.multiline.lua"}]}},"scopeName":"source.lua","embeddedLangs":["c"]}`)),n=[...e,t];export{n as default};
|
|
|
|
| 1 |
+
import{t as e}from"./c-DU7sDOfO.js";var t=Object.freeze(JSON.parse(`{"displayName":"Lua","name":"lua","patterns":[{"begin":"\\\\b(?:(local)\\\\s+)?(function)\\\\b(?![,:])","beginCaptures":{"1":{"name":"keyword.local.lua"},"2":{"name":"keyword.control.lua"}},"end":"(?<=[-\\\\]\\"')\\\\[{}])","name":"meta.function.lua","patterns":[{"include":"#comment"},{"begin":"(\\\\()","beginCaptures":{"1":{"name":"punctuation.definition.parameters.begin.lua"}},"end":"(\\\\))|(?=[-\\\\]\\"'\\\\[{}])|(?<!\\\\.)\\\\.(?!\\\\.)","endCaptures":{"1":{"name":"punctuation.definition.parameters.finish.lua"}},"name":"meta.parameter.lua","patterns":[{"include":"#comment"},{"captures":{"1":{"name":"constant.language.lua"},"2":{"name":"variable.parameter.function.lua"}},"match":"(\\\\.{3})\\\\s*([A-Z_a-z][0-9A-Z_a-z]*)"},{"match":"[A-Z_a-z][0-9A-Z_a-z]*","name":"variable.parameter.function.lua"},{"match":",","name":"punctuation.separator.arguments.lua"},{"begin":":","beginCaptures":{"0":{"name":"punctuation.separator.arguments.lua"}},"end":"(?=[),])","patterns":[{"include":"#emmydoc.type"}]}]},{"match":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b\\\\s*(?=:)","name":"entity.name.class.lua"},{"match":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b","name":"entity.name.function.lua"}]},{"match":"(?<![.\\\\w\\\\d])0[Xx]\\\\h+(\\\\.\\\\h*)?([Ee]-?\\\\d*)?([Pp][-+]\\\\d+)?","name":"constant.numeric.float.hexadecimal.lua"},{"match":"(?<![.\\\\w\\\\d])0[Xx]\\\\.\\\\h+([Ee]-?\\\\d*)?([Pp][-+]\\\\d+)?","name":"constant.numeric.float.hexadecimal.lua"},{"match":"(?<![.\\\\w\\\\d])0[Xx]\\\\h+(?![.0-9EPep])","name":"constant.numeric.integer.hexadecimal.lua"},{"match":"(?<![.\\\\w\\\\d])\\\\d+(\\\\.\\\\d*)?([Ee]-?\\\\d*)?","name":"constant.numeric.float.lua"},{"match":"(?<![.\\\\w\\\\d])\\\\.\\\\d+([Ee]-?\\\\d*)?","name":"constant.numeric.float.lua"},{"match":"(?<![.\\\\w\\\\d])\\\\d+(?![.0-9EPep])","name":"constant.numeric.integer.lua"},{"include":"#string"},{"captures":{"1":{"name":"punctuation.definition.comment.lua"}},"match":"\\\\A(#!).*$\\\\n?","name":"comment.line.shebang.lua"},{"include":"#comment"},{"captures":{"1":{"name":"keyword.control.goto.lua"},"2":{"name":"string.tag.lua"}},"match":"\\\\b(goto)\\\\s+([A-Z_a-z][0-9A-Z_a-z]*)"},{"captures":{"1":{"name":"punctuation.section.embedded.begin.lua"},"2":{"name":"punctuation.section.embedded.end.lua"}},"match":"(::)\\\\s*[A-Z_a-z][0-9A-Z_a-z]*\\\\s*(::)","name":"string.tag.lua"},{"captures":{"0":{"name":"storage.type.attribute.lua"}},"match":"<\\\\s*(c(?:onst|lose))\\\\s*>"},{"match":"<[*A-Z_a-z][-*.0-9A-Z_a-z]*>","name":"storage.type.generic.lua"},{"match":"\\\\b(break|do|else|for|if|elseif|goto|return|then|repeat|while|until|end|in)\\\\b","name":"keyword.control.lua"},{"match":"\\\\b(local)\\\\b","name":"keyword.local.lua"},{"captures":{"1":{"name":"keyword.global.lua"}},"match":"^\\\\s*(global)\\\\b(?!\\\\s*=)"},{"match":"\\\\b(function)\\\\b(?![,:])","name":"keyword.control.lua"},{"match":"(?<![^.]\\\\.|:)\\\\b(false|nil(?!:)|true|_ENV|_G|_VERSION|math\\\\.(pi|huge|maxinteger|mininteger)|utf8\\\\.charpattern|io\\\\.(std(?:in|out|err))|package\\\\.(config|cpath|loaded|loaders|path|preload|searchers))\\\\b|(?<!\\\\.)\\\\.{3}(?!\\\\.)","name":"constant.language.lua"},{"match":"(?<![^.]\\\\.|:)\\\\b(self)\\\\b","name":"variable.language.self.lua"},{"match":"(?<![^.]\\\\.|:)\\\\b(assert|collectgarbage|dofile|error|getfenv|getmetatable|ipairs|load|loadfile|loadstring|module|next|pairs|pcall|print|rawequal|rawget|rawlen|rawset|require|select|setfenv|setmetatable|tonumber|tostring|type|unpack|xpcall)\\\\b(?!\\\\s*=(?!=))","name":"support.function.lua"},{"match":"(?<![^.]\\\\.|:)\\\\b(async)\\\\b(?!\\\\s*=(?!=))","name":"entity.name.tag.lua"},{"match":"(?<![^.]\\\\.|:)\\\\b(coroutine\\\\.(create|isyieldable|close|resume|running|status|wrap|yield)|string\\\\.(byte|char|dump|find|format|gmatch|gsub|len|lower|match|pack|packsize|rep|reverse|sub|unpack|upper)|table\\\\.(concat|create|insert|maxn|move|pack|remove|sort|unpack)|math\\\\.(abs|acos|asin|atan2?|ceil|cosh?|deg|exp|floor|fmod|frexp|ldexp|log|log10|max|min|modf|pow|rad|random|randomseed|sinh?|sqrt|tanh?|tointeger|type)|io\\\\.(close|flush|input|lines|open|output|popen|read|tmpfile|type|write)|os\\\\.(clock|date|difftime|execute|exit|getenv|remove|rename|setlocale|time|tmpname)|package\\\\.(loadlib|seeall|searchpath)|debug\\\\.(debug|[gs]etfenv|[gs]ethook|getinfo|[gs]etlocal|[gs]etmetatable|getregistry|[gs]etupvalue|[gs]etuservalue|set[Cc]stacklimit|traceback|upvalueid|upvaluejoin)|bit32\\\\.(arshift|band|bnot|bor|btest|bxor|extract|replace|lrotate|lshift|rrotate|rshift)|utf8\\\\.(char|codes|codepoint|len|offset))\\\\b(?!\\\\s*=(?!=))","name":"support.function.library.lua"},{"match":"\\\\b(\\\\|\\\\||&&|!)\\\\b","name":"keyword.operator.lua"},{"match":"\\\\b(and|or|not)\\\\b","name":"keyword.operator.logical.lua"},{"match":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b(?=\\\\s*(?:[\\"'({]|\\\\[\\\\[))","name":"support.function.any-method.lua"},{"match":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b(?=\\\\s*\\\\??:)","name":"entity.name.class.lua"},{"match":"(?<=[^.]\\\\.|:)\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b(?!\\\\s*=\\\\s*\\\\b(function)\\\\b)","name":"entity.other.attribute.lua"},{"match":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b(?!\\\\s*=\\\\s*\\\\b(function)\\\\b)","name":"variable.other.lua"},{"match":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b(?=\\\\s*=\\\\s*\\\\b(function)\\\\b)","name":"entity.name.function.lua"},{"match":"[-#%*+/^]|==?|~=|!=|<=?|>=?|(?<!\\\\.)\\\\.{2}(?!\\\\.)","name":"keyword.operator.lua"}],"repository":{"comment":{"patterns":[{"begin":"(^[\\\\t ]+)?(?=--)","beginCaptures":{"1":{"name":"punctuation.whitespace.comment.leading.lua"}},"end":"(?!\\\\G)((?!^)[\\\\t ]+\\\\n)?","endCaptures":{"1":{"name":"punctuation.whitespace.comment.trailing.lua"}},"patterns":[{"begin":"--\\\\[(=*)\\\\[@@@","beginCaptures":{"0":{"name":"punctuation.definition.comment.begin.lua"}},"end":"(--)?]\\\\1]","endCaptures":{"0":{"name":"punctuation.definition.comment.end.lua"}},"name":"","patterns":[{"include":"source.lua"}]},{"begin":"--\\\\[(=*)\\\\[","beginCaptures":{"0":{"name":"punctuation.definition.comment.begin.lua"}},"end":"(--)?]\\\\1]","endCaptures":{"0":{"name":"punctuation.definition.comment.end.lua"}},"name":"comment.block.lua","patterns":[{"include":"#emmydoc"},{"include":"#ldoc_tag"}]},{"begin":"----","beginCaptures":{"0":{"name":"punctuation.definition.comment.lua"}},"end":"\\\\n","name":"comment.line.double-dash.lua"},{"begin":"---","beginCaptures":{"0":{"name":"punctuation.definition.comment.lua"}},"end":"\\\\n","name":"comment.line.double-dash.documentation.lua","patterns":[{"include":"#emmydoc"},{"include":"#ldoc_tag"}]},{"begin":"--","beginCaptures":{"0":{"name":"punctuation.definition.comment.lua"}},"end":"\\\\n","name":"comment.line.double-dash.lua","patterns":[{"include":"#ldoc_tag"}]}]},{"begin":"/\\\\*","beginCaptures":{"0":{"name":"punctuation.definition.comment.begin.lua"}},"end":"\\\\*/","endCaptures":{"0":{"name":"punctuation.definition.comment.end.lua"}},"name":"comment.block.lua","patterns":[{"include":"#emmydoc"},{"include":"#ldoc_tag"}]}]},"emmydoc":{"patterns":[{"begin":"(?<=---)[\\\\t ]*@class","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"match":"\\\\b([*A-Z_a-z][-*.0-9A-Z_a-z]*)","name":"support.class.lua"},{"match":"[,:]","name":"keyword.operator.lua"}]},{"begin":"(?<=---)[\\\\t ]*@enum","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"begin":"\\\\b([*A-Z_a-z][-*.0-9A-Z_a-z]*)","beginCaptures":{"0":{"name":"variable.lua"}},"end":"(?=\\\\n)"}]},{"begin":"(?<=---)[\\\\t ]*@type","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"include":"#emmydoc.type"}]},{"begin":"(?<=---)[\\\\t ]*@alias","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"begin":"\\\\b([*A-Z_a-z][-*.0-9A-Z_a-z]*)","beginCaptures":{"0":{"name":"variable.lua"}},"end":"(?=[\\\\n#])","patterns":[{"include":"#emmydoc.type"}]}]},{"begin":"(?<=---)[\\\\t ]*(@operator)\\\\s*(\\\\b[a-z]+)?","beginCaptures":{"1":{"name":"storage.type.annotation.lua"},"2":{"name":"support.function.library.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"include":"#emmydoc.type"}]},{"begin":"(?<=---)[\\\\t ]*@cast","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"begin":"\\\\b([*A-Z_a-z][-*.0-9A-Z_a-z]*)","beginCaptures":{"0":{"name":"variable.other.lua"}},"end":"(?=\\\\n)","patterns":[{"include":"#emmydoc.type"},{"match":"([+-|])","name":"keyword.operator.lua"}]}]},{"begin":"(?<=---)[\\\\t ]*@param","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"begin":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b(\\\\??)","beginCaptures":{"1":{"name":"entity.name.variable.lua"},"2":{"name":"keyword.operator.lua"}},"end":"(?=[\\\\n#])","patterns":[{"include":"#emmydoc.type"}]}]},{"begin":"(?<=---)[\\\\t ]*@return","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"match":"\\\\?","name":"keyword.operator.lua"},{"include":"#emmydoc.type"}]},{"begin":"(?<=---)[\\\\t ]*@field","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"begin":"(\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b|(\\\\[))(\\\\??)","beginCaptures":{"2":{"name":"entity.name.variable.lua"},"3":{"name":"keyword.operator.lua"}},"end":"(?=[\\\\n#])","patterns":[{"include":"#string"},{"include":"#emmydoc.type"},{"match":"]","name":"keyword.operator.lua"}]}]},{"begin":"(?<=---)[\\\\t ]*@generic","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"begin":"\\\\b([A-Z_a-z][0-9A-Z_a-z]*)\\\\b","beginCaptures":{"0":{"name":"storage.type.generic.lua"}},"end":"(?=\\\\n)|(,)","endCaptures":{"0":{"name":"keyword.operator.lua"}},"patterns":[{"match":":","name":"keyword.operator.lua"},{"include":"#emmydoc.type"}]}]},{"begin":"(?<=---)[\\\\t ]*@vararg","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"include":"#emmydoc.type"}]},{"begin":"(?<=---)[\\\\t ]*@overload","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"include":"#emmydoc.type"}]},{"begin":"(?<=---)[\\\\t ]*@deprecated","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])"},{"begin":"(?<=---)[\\\\t ]*@meta","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])"},{"begin":"(?<=---)[\\\\t ]*@private","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])"},{"begin":"(?<=---)[\\\\t ]*@protected","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])"},{"begin":"(?<=---)[\\\\t ]*@package","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])"},{"begin":"(?<=---)[\\\\t ]*@version","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"match":"\\\\b(5\\\\.1|5\\\\.2|5\\\\.3|5\\\\.4|JIT)\\\\b","name":"support.class.lua"},{"match":"[,<>]","name":"keyword.operator.lua"}]},{"begin":"(?<=---)[\\\\t ]*@see","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"match":"\\\\b([*A-Z_a-z][-*.0-9A-Z_a-z]*)","name":"support.class.lua"},{"match":"#","name":"keyword.operator.lua"}]},{"begin":"(?<=---)[\\\\t ]*@diagnostic","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"begin":"([-0-9A-Z_a-z]+)[\\\\t ]*(:)?","beginCaptures":{"1":{"name":"keyword.other.unit"},"2":{"name":"keyword.operator.unit"}},"end":"(?=\\\\n)","patterns":[{"match":"\\\\b([*A-Z_a-z][-0-9A-Z_a-z]*)","name":"support.class.lua"},{"match":",","name":"keyword.operator.lua"}]}]},{"begin":"(?<=---)[\\\\t ]*@module","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"include":"#string"}]},{"match":"(?<=---)[\\\\t ]*@(async|nodiscard)","name":"storage.type.annotation.lua"},{"begin":"(?<=---)\\\\|\\\\s*[+>]?","beginCaptures":{"0":{"name":"storage.type.annotation.lua"}},"end":"(?=[\\\\n#@])","patterns":[{"include":"#string"}]}]},"emmydoc.type":{"patterns":[{"begin":"\\\\bfun\\\\b","beginCaptures":{"0":{"name":"keyword.control.lua"}},"end":"(?=[#\\\\s])","patterns":[{"match":"[](),:<>?\\\\[][\\\\t ]*","name":"keyword.operator.lua"},{"match":"([A-Z_a-z][-*.0-9A-Z_a-z]*)(?<!,)[\\\\t ]*(?=\\\\??:)","name":"entity.name.variable.lua"},{"include":"#emmydoc.type"},{"include":"#string"}]},{"match":"<[*A-Z_a-z][-*.0-9A-Z_a-z]*>","name":"storage.type.generic.lua"},{"match":"\\\\basync\\\\b","name":"entity.name.tag.lua"},{"match":"[,:?\`{|}][\\\\t ]*","name":"keyword.operator.lua"},{"begin":"(?=[\\"'*.A-\\\\[_a-z])","end":"(?=[#),:?|}\\\\s])","patterns":[{"match":"([-\\\\]*,.0-9<>A-\\\\[_a-z]+)(?<!,)[\\\\t ]*","name":"support.type.lua"},{"match":"(\\\\.\\\\.\\\\.)[\\\\t ]*","name":"constant.language.lua"},{"include":"#string"}]}]},"escaped_char":{"patterns":[{"match":"\\\\\\\\[\\\\n\\"'\\\\\\\\abfnrtv]","name":"constant.character.escape.lua"},{"match":"\\\\\\\\z[\\\\t\\\\n ]*","name":"constant.character.escape.lua"},{"match":"\\\\\\\\\\\\d{1,3}","name":"constant.character.escape.byte.lua"},{"match":"\\\\\\\\x\\\\h\\\\h","name":"constant.character.escape.byte.lua"},{"match":"\\\\\\\\u\\\\{\\\\h+}","name":"constant.character.escape.unicode.lua"},{"match":"\\\\\\\\.","name":"invalid.illegal.character.escape.lua"}]},"ldoc_tag":{"captures":{"1":{"name":"punctuation.definition.block.tag.ldoc"},"2":{"name":"storage.type.class.ldoc"}},"match":"\\\\G[\\\\t ]*(@)(alias|annotation|author|charset|class|classmod|comment|constructor|copyright|description|example|export|factory|field|file|fixme|function|include|lfunction|license|local|module|name|param|pragma|private|raise|release|return|script|section|see|set|static|submodule|summary|tfield|thread|tparam|treturn|todo|topic|type|usage|warning|within)\\\\b"},"string":{"patterns":[{"begin":"'","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.lua"}},"end":"'[\\\\t ]*|(?=\\\\n)","endCaptures":{"0":{"name":"punctuation.definition.string.end.lua"}},"name":"string.quoted.single.lua","patterns":[{"include":"#escaped_char"}]},{"begin":"\\"","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.lua"}},"end":"\\"[\\\\t ]*|(?=\\\\n)","endCaptures":{"0":{"name":"punctuation.definition.string.end.lua"}},"name":"string.quoted.double.lua","patterns":[{"include":"#escaped_char"}]},{"begin":"\`","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.lua"}},"end":"\`[\\\\t ]*|(?=\\\\n)","endCaptures":{"0":{"name":"punctuation.definition.string.end.lua"}},"name":"string.quoted.double.lua"},{"begin":"(?<=\\\\.cdef)\\\\s*(\\\\[(=*)\\\\[)","beginCaptures":{"0":{"name":"string.quoted.other.multiline.lua"},"1":{"name":"punctuation.definition.string.begin.lua"}},"contentName":"meta.embedded.lua","end":"(]\\\\2])[\\\\t ]*","endCaptures":{"0":{"name":"string.quoted.other.multiline.lua"},"1":{"name":"punctuation.definition.string.end.lua"}},"patterns":[{"include":"source.c"}]},{"begin":"(?<!--)\\\\[(=*)\\\\[","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.lua"}},"end":"]\\\\1][\\\\t ]*","endCaptures":{"0":{"name":"punctuation.definition.string.end.lua"}},"name":"string.quoted.other.multiline.lua"}]}},"scopeName":"source.lua","embeddedLangs":["c"]}`)),n=[...e,t];export{n as default};
|
dist/assets/{nginx-DUHU2Dqn.js → nginx-D7gToQuB.js}
RENAMED
|
@@ -1 +1 @@
|
|
| 1 |
-
import e from"./lua-CUc9ktct.js";var t=Object.freeze(JSON.parse(`{"displayName":"Nginx","fileTypes":["conf.erb","conf","ngx","nginx.conf","mime.types","fastcgi_params","scgi_params","uwsgi_params"],"foldingStartMarker":"\\\\{\\\\s*$","foldingStopMarker":"^\\\\s*}","name":"nginx","patterns":[{"match":"#.*","name":"comment.line.number-sign"},{"begin":"\\\\b((?:content|rewrite|access|init_worker|init|set|log|balancer|ssl_(?:client_hello|session_fetch|certificate))_by_lua(?:_block)?)\\\\s*\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"}},"contentName":"meta.embedded.block.lua","end":"}","name":"meta.context.lua.nginx","patterns":[{"include":"source.lua"}]},{"begin":"\\\\b((?:content|rewrite|access|init_worker|init|set|log|balancer|ssl_(?:client_hello|session_fetch|certificate))_by_lua)\\\\s*'","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"}},"contentName":"meta.embedded.block.lua","end":"'","name":"meta.context.lua.nginx","patterns":[{"include":"source.lua"}]},{"begin":"\\\\b(events) +\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"}},"end":"}","name":"meta.context.events.nginx","patterns":[{"include":"$self"}]},{"begin":"\\\\b(http) +\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"}},"end":"}","name":"meta.context.http.nginx","patterns":[{"include":"$self"}]},{"begin":"\\\\b(mail) +\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"}},"end":"}","name":"meta.context.mail.nginx","patterns":[{"include":"$self"}]},{"begin":"\\\\b(stream) +\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"}},"end":"}","name":"meta.context.stream.nginx","patterns":[{"include":"$self"}]},{"begin":"\\\\b(server) +\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"}},"end":"}","name":"meta.context.server.nginx","patterns":[{"include":"$self"}]},{"begin":"\\\\b(location) +(\\\\^?~\\\\*?|=) +(.*?)\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"},"2":{"name":"keyword.operator.nginx"},"3":{"name":"string.regexp.nginx"}},"end":"}","name":"meta.context.location.nginx","patterns":[{"include":"$self"}]},{"begin":"\\\\b(location) +(.*?)\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"},"2":{"name":"entity.name.context.location.nginx"}},"end":"}","name":"meta.context.location.nginx","patterns":[{"include":"$self"}]},{"begin":"\\\\b(limit_except) +\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"}},"end":"}","name":"meta.context.limit_except.nginx","patterns":[{"include":"$self"}]},{"begin":"\\\\b(if) +\\\\(","beginCaptures":{"1":{"name":"keyword.control.nginx"}},"end":"\\\\)","name":"meta.context.if.nginx","patterns":[{"include":"#if_condition"}]},{"begin":"\\\\b(upstream) +(.*?)\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"},"2":{"name":"entity.name.context.location.nginx"}},"end":"}","name":"meta.context.upstream.nginx","patterns":[{"include":"$self"}]},{"begin":"\\\\b(types) +\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"}},"end":"}","name":"meta.context.types.nginx","patterns":[{"include":"$self"}]},{"begin":"\\\\b(map) +(\\\\$)([0-9A-Z_a-z]+) +(\\\\$)([0-9A-Z_a-z]+) *\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"},"2":{"name":"punctuation.definition.variable.nginx"},"3":{"name":"variable.parameter.nginx"},"4":{"name":"punctuation.definition.variable.nginx"},"5":{"name":"variable.other.nginx"}},"end":"}","name":"meta.context.map.nginx","patterns":[{"include":"#values"},{"match":";","name":"punctuation.terminator.nginx"},{"match":"#.*","name":"comment.line.number-sign"}]},{"begin":"\\\\{","end":"}","name":"meta.block.nginx","patterns":[{"include":"$self"}]},{"begin":"\\\\b(return)\\\\b","beginCaptures":{"1":{"name":"keyword.control.nginx"}},"end":";","patterns":[{"include":"#values"}]},{"begin":"\\\\b(rewrite)\\\\s+","beginCaptures":{"1":{"name":"keyword.directive.nginx"}},"end":"(last|break|redirect|permanent)?(;)","endCaptures":{"1":{"name":"keyword.other.nginx"},"2":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"\\\\b(server)\\\\s+","beginCaptures":{"1":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"1":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#server_parameters"}]},{"begin":"\\\\b(internal|empty_gif|f4f|flv|hls|mp4|break|status|stub_status|ip_hash|ntlm|least_conn|upstream_conf|least_conn|zone_sync)\\\\b","beginCaptures":{"1":{"name":"keyword.directive.nginx"}},"end":"(;|$)","endCaptures":{"1":{"name":"punctuation.terminator.nginx"}}},{"begin":"([\\"'\\\\s]|^)(accept_)(mutex(?:|_delay))([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(debug_)(connection|points)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(error_)(log|page)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(ssl_)(engine|buffer_size|certificate|certificate_key|ciphers|client_certificate|conf_command|crl|dhparam|early_data|ecdh_curve|ocsp|ocsp_cache|ocsp_responder|password_file|prefer_server_ciphers|protocols|reject_handshake|session_cache|session_ticket_key|session_tickets|session_timeout|stapling|stapling_file|stapling_responder|stapling_verify|trusted_certificate|verify_client|verify_depth|alpn|handshake_timeout|preread)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(worker_)(aio_requests|connections|cpu_affinity|priority|processes|rlimit_core|rlimit_nofile|shutdown_timeout)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(auth_)(delay|basic|basic_user_file|jwt|jwt_claim_set|jwt_header_set|jwt_key_cache|jwt_key_file|jwt_key_request|jwt_leeway|jwt_type|jwt_require|request|request_set|http|http_header|http_pass_client_cert|http_timeout)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(client_)(body_buffer_size|body_in_file_only|body_in_single_buffer|body_temp_path|body_timeout|header_buffer_size|header_timeout|max_body_size)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(keepalive_)(disable|requests|time|timeout)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(limit_)(rate|rate_after|conn|conn_dry_run|conn_log_level|conn_status|conn_zone|zone|req|req_dry_run|req_log_level|req_status|req_zone)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(lingering_)(close|time|timeout)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(log_)(not_found|subrequest|format)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(max_)(ranges|errors)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(msie_)(padding|refresh)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(open_)(file_cache|file_cache_errors|file_cache_min_uses|file_cache_valid|log_file_cache)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(send_)(lowat|timeout)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(server_)(name|name_in_redirect|names_hash_bucket_size|names_hash_max_size|tokens)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(tcp_)(no(?:delay|push))([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(types_)(hash_(?:bucket|max)_size)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(variables_)(hash_(?:bucket|max)_size)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(add_)(before_body|after_body|header|trailer)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(status_)(zone|format)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(autoindex_)(exact_size|format|localtime)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(ancient_)(browser(?:|_value))([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(modern_)(browser(?:|_value))([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(charset_)(map|types)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(dav_)(access|methods)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(fastcgi_)(bind|buffer_size|buffering|buffers|busy_buffers_size|cache|cache_background_update|cache_bypass|cache_key|cache_lock|cache_lock_age|cache_lock_timeout|cache_max_range_offset|cache_methods|cache_min_uses|cache_path|cache_purge|cache_revalidate|cache_use_stale|cache_valid|catch_stderr|connect_timeout|force_ranges|hide_header|ignore_client_abort|ignore_headers|index|intercept_errors|keep_conn|limit_rate|max_temp_file_size|next_upstream|next_upstream_timeout|next_upstream_tries|no_cache|param|pass|pass_header|pass_request_body|pass_request_headers|read_timeout|request_buffering|send_lowat|send_timeout|socket_keepalive|split_path_info|store|store_access|temp_file_write_size|temp_path)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(geoip_)(country|city|org|proxy|proxy_recursive)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(grpc_)(bind|buffer_size|connect_timeout|hide_header|ignore_headers|intercept_errors|next_upstream|next_upstream_timeout|next_upstream_tries|pass|pass_header|read_timeout|send_timeout|set_header|socket_keepalive|ssl_certificate|ssl_certificate_key|ssl_ciphers|ssl_conf_command|ssl_crl|ssl_name|ssl_password_file|ssl_protocols|ssl_server_name|ssl_session_reuse|ssl_trusted_certificate|ssl_verify|ssl_verify_depth)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(gzip_)(buffers|comp_level|disable|http_version|min_length|proxied|types|vary|static)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(hls_)(buffers|forward_args|fragment|mp4_buffer_size|mp4_max_buffer_size)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(image_)(filter(?:|_buffer|_interlace|_jpeg_quality|_sharpen|_transparency|_webp_quality))([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(map_)(hash_(?:bucket|max)_size)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(memcached_)(bind|buffer_size|connect_timeout|gzip_flag|next_upstream|next_upstream_timeout|next_upstream_tries|pass|read_timeout|send_timeout|socket_keepalive)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(mp4_)(buffer_size|max_buffer_size|limit_rate|limit_rate_after|start_key_frame)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(perl_)(modules|require|set)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(proxy_)(bind|buffer_size|buffering|buffers|busy_buffers_size|cache|cache_background_update|cache_bypass|cache_convert_head|cache_key|cache_lock|cache_lock_age|cache_lock_timeout|cache_max_range_offset|cache_methods|cache_min_uses|cache_path|cache_purge|cache_revalidate|cache_use_stale|cache_valid|connect_timeout|cookie_domain|cookie_flags|cookie_path|force_ranges|headers_hash_bucket_size|headers_hash_max_size|hide_header|http_version|ignore_client_abort|ignore_headers|intercept_errors|limit_rate|max_temp_file_size|method|next_upstream|next_upstream_timeout|next_upstream_tries|no_cache|pass|pass_header|pass_request_body|pass_request_headers|read_timeout|redirect|request_buffering|send_lowat|send_timeout|set_body|set_header|socket_keepalive|ssl_certificate|ssl_certificate_key|ssl_ciphers|ssl_conf_command|ssl_crl|ssl_name|ssl_password_file|ssl_protocols|ssl_server_name|ssl_session_reuse|ssl_trusted_certificate|ssl_verify|ssl_verify_depth|store|store_access|temp_file_write_size|temp_path|buffer|pass_error_message|protocol|smtp_auth|timeout|protocol_timeout|download_rate|half_close|requests|responses|session_drop|ssl|upload_rate)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(real_)(ip_(?:header|recursive))([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(referer_)(hash_(?:bucket|max)_size)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(scgi_)(bind|buffer_size|buffering|buffers|busy_buffers_size|cache|cache_background_update|cache_bypass|cache_key|cache_lock|cache_lock_age|cache_lock_timeout|cache_max_range_offset|cache_methods|cache_min_uses|cache_path|cache_purge|cache_revalidate|cache_use_stale|cache_valid|connect_timeout|force_ranges|hide_header|ignore_client_abort|ignore_headers|intercept_errors|limit_rate|max_temp_file_size|next_upstream|next_upstream_timeout|next_upstream_tries|no_cache|param|pass|pass_header|pass_request_body|pass_request_headers|read_timeout|request_buffering|send_timeout|socket_keepalive|store|store_access|temp_file_write_size|temp_path)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(secure_)(link(?:|_md5|_secret))([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(session_)(log(?:|_format|_zone))([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(ssi_)(last_modified|min_file_chunk|silent_errors|types|value_length)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(sub_)(filter(?:|_last_modified|_once|_types))([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(health_)(check(?:|_timeout))([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(userid_)(domain|expires|flags|mark|name|p3p|path|service)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(uwsgi_)(bind|buffer_size|buffering|buffers|busy_buffers_size|cache|cache_background_update|cache_bypass|cache_key|cache_lock|cache_lock_age|cache_lock_timeout|cache_max_range_offset|cache_methods|cache_min_uses|cache_path|cache_purge|cache_revalidate|cache_use_stale|cache_valid|connect_timeout|force_ranges|hide_header|ignore_client_abort|ignore_headers|intercept_errors|limit_rate|max_temp_file_size|modifier1|modifier2|next_upstream|next_upstream_timeout|next_upstream_tries|no_cache|param|pass|pass_header|pass_request_body|pass_request_headers|read_timeout|request_buffering|send_timeout|socket_keepalive|ssl_certificate|ssl_certificate_key|ssl_ciphers|ssl_conf_command|ssl_crl|ssl_name|ssl_password_file|ssl_protocols|ssl_server_name|ssl_session_reuse|ssl_trusted_certificate|ssl_verify|ssl_verify_depth|store|store_access|temp_file_write_size|temp_path)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(http2_)(body_preread_size|chunk_size|idle_timeout|max_concurrent_pushes|max_concurrent_streams|max_field_size|max_header_size|max_requests|push|push_preload|recv_buffer_size|recv_timeout)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(http3_)(hq|max_concurrent_streams|stream_buffer_size)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(quic_)(active_connection_id_limit|bpf|gso|host_key|retry)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(xslt_)(last_modified|param|string_param|stylesheet|types)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(imap_)(auth|capabilities|client_buffer)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(pop3_)(auth|capabilities)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(smtp_)(auth|capabilities|client_buffer|greeting_delay)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(preread_)(buffer_size|timeout)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(mqtt_)(preread|buffers|rewrite_buffer_size|set_connect)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(zone_)(sync_(?:buffers|connect_retry_interval|connect_timeout|interval|recv_buffer_size|server|ssl|ssl_certificate|ssl_certificate_key|ssl_ciphers|ssl_conf_command|ssl_crl|ssl_name|ssl_password_file|ssl_protocols|ssl_server_name|ssl_trusted_certificate|ssl_verify|ssl_verify_depth|timeout))([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(otel_)(exporter|service_name|trace|trace_context|span_name|span_attr)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(js_)(body_filter|content|fetch_buffer_size|fetch_ciphers|fetch_max_response_buffer_size|fetch_protocols|fetch_timeout|fetch_trusted_certificate|fetch_verify|fetch_verify_depth|header_filter|import|include|path|periodic|preload_object|set|shared_dict_zone|var|access|filter|preread)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(daemon|env|include|pid|user??|aio|alias|directio|etag|listen|resolver|root|satisfy|sendfile|allow|deny|api|autoindex|charset|geo|gunzip|gzip|expires|index|keyval|mirror|perl|set|slice|ssi|ssl|zone|state|hash|keepalive|queue|random|sticky|match|userid|http2|http3|protocol|timeout|xclient|starttls|mqtt|load_module|lock_file|master_process|multi_accept|pcre_jit|thread_pool|timer_resolution|working_directory|absolute_redirect|aio_write|chunked_transfer_encoding|connection_pool_size|default_type|directio_alignment|disable_symlinks|if_modified_since|ignore_invalid_headers|large_client_header_buffers|merge_slashes|output_buffers|port_in_redirect|postpone_output|read_ahead|recursive_error_pages|request_pool_size|reset_timedout_connection|resolver_timeout|sendfile_max_chunk|subrequest_output_buffer_size|try_files|underscores_in_headers|addition_types|override_charset|source_charset|create_full_put_path|min_delete_depth|f4f_buffer_size|gunzip_buffers|internal_redirect|keyval_zone|access_log|mirror_request_body|random_index|set_real_ip_from|valid_referers|rewrite_log|uninitialized_variable_warn|split_clients|least_time|sticky_cookie_insert|xml_entities|google_perftools_profiles)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"\\\\b([0-9A-Z_a-z]+)\\\\s+","beginCaptures":{"1":{"name":"keyword.directive.unknown.nginx"}},"end":"(;|$)","endCaptures":{"1":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"\\\\b([a-z]+/[-+.0-9A-Za-z]+)\\\\b","beginCaptures":{"1":{"name":"constant.other.mediatype.nginx"}},"end":"(;)","endCaptures":{"1":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]}],"repository":{"if_condition":{"patterns":[{"include":"#variables"},{"match":"!?~\\\\*?\\\\s","name":"keyword.operator.nginx"},{"match":"!?-[defx]\\\\s","name":"keyword.operator.nginx"},{"match":"!?=[^=]","name":"keyword.operator.nginx"},{"include":"#regexp_and_string"}]},"regexp_and_string":{"patterns":[{"match":"\\\\^.*?\\\\$","name":"string.regexp.nginx"},{"begin":"\\"","end":"\\"","name":"string.quoted.double.nginx","patterns":[{"match":"\\\\\\\\[\\"'\\\\\\\\nt]","name":"constant.character.escape.nginx"},{"include":"#variables"}]},{"begin":"'","end":"'","name":"string.quoted.single.nginx","patterns":[{"match":"\\\\\\\\[\\"'\\\\\\\\nt]","name":"constant.character.escape.nginx"},{"include":"#variables"}]}]},"server_parameters":{"patterns":[{"captures":{"1":{"name":"variable.parameter.nginx"},"2":{"name":"keyword.operator.nginx"},"3":{"name":"constant.numeric.nginx"}},"match":"(?:^|\\\\s)(weight|max_conn|max_fails|fail_timeout|slow_start)(=)(\\\\d[.\\\\d]*[BDGHKMSTbdghkmst]?)(?:[;\\\\s]|$)"},{"include":"#values"}]},"values":{"patterns":[{"include":"#variables"},{"match":"#.*","name":"comment.line.number-sign"},{"captures":{"1":{"name":"constant.numeric.nginx"}},"match":"(?<=\\\\G|\\\\s)(=?[0-9][.0-9]*[BDGHKMSTbdghkmst]?)(?=[\\\\t ;])"},{"match":"(?<=\\\\G|\\\\s)(on|off|true|false)(?=[\\\\t ;])","name":"constant.language.nginx"},{"match":"(?<=\\\\G|\\\\s)(kqueue|rtsig|epoll|/dev/poll|select|poll|eventport|max|all|default_server|default|main|crit|error|debug|warn|notice|last)(?=[\\\\t ;])","name":"constant.language.nginx"},{"match":"\\\\\\\\.* |~\\\\*?|!~\\\\*?","name":"keyword.operator.nginx"},{"include":"#regexp_and_string"}]},"variables":{"patterns":[{"captures":{"1":{"name":"punctuation.definition.variable.nginx"},"2":{"name":"variable.other.nginx"}},"match":"(\\\\$)([0-9A-Z_a-z]+)\\\\b"},{"captures":{"1":{"name":"punctuation.definition.variable.nginx"},"2":{"name":"variable.other.nginx"},"3":{"name":"punctuation.definition.variable.nginx"}},"match":"(\\\\$\\\\{)([0-9A-Z_a-z]+)(})"}]}},"scopeName":"source.nginx","embeddedLangs":["lua"]}`)),n=[...e,t];export{n as default};
|
|
|
|
| 1 |
+
import e from"./lua-DNHyM1z9.js";var t=Object.freeze(JSON.parse(`{"displayName":"Nginx","fileTypes":["conf.erb","conf","ngx","nginx.conf","mime.types","fastcgi_params","scgi_params","uwsgi_params"],"foldingStartMarker":"\\\\{\\\\s*$","foldingStopMarker":"^\\\\s*}","name":"nginx","patterns":[{"match":"#.*","name":"comment.line.number-sign"},{"begin":"\\\\b((?:content|rewrite|access|init_worker|init|set|log|balancer|ssl_(?:client_hello|session_fetch|certificate))_by_lua(?:_block)?)\\\\s*\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"}},"contentName":"meta.embedded.block.lua","end":"}","name":"meta.context.lua.nginx","patterns":[{"include":"source.lua"}]},{"begin":"\\\\b((?:content|rewrite|access|init_worker|init|set|log|balancer|ssl_(?:client_hello|session_fetch|certificate))_by_lua)\\\\s*'","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"}},"contentName":"meta.embedded.block.lua","end":"'","name":"meta.context.lua.nginx","patterns":[{"include":"source.lua"}]},{"begin":"\\\\b(events) +\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"}},"end":"}","name":"meta.context.events.nginx","patterns":[{"include":"$self"}]},{"begin":"\\\\b(http) +\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"}},"end":"}","name":"meta.context.http.nginx","patterns":[{"include":"$self"}]},{"begin":"\\\\b(mail) +\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"}},"end":"}","name":"meta.context.mail.nginx","patterns":[{"include":"$self"}]},{"begin":"\\\\b(stream) +\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"}},"end":"}","name":"meta.context.stream.nginx","patterns":[{"include":"$self"}]},{"begin":"\\\\b(server) +\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"}},"end":"}","name":"meta.context.server.nginx","patterns":[{"include":"$self"}]},{"begin":"\\\\b(location) +(\\\\^?~\\\\*?|=) +(.*?)\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"},"2":{"name":"keyword.operator.nginx"},"3":{"name":"string.regexp.nginx"}},"end":"}","name":"meta.context.location.nginx","patterns":[{"include":"$self"}]},{"begin":"\\\\b(location) +(.*?)\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"},"2":{"name":"entity.name.context.location.nginx"}},"end":"}","name":"meta.context.location.nginx","patterns":[{"include":"$self"}]},{"begin":"\\\\b(limit_except) +\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"}},"end":"}","name":"meta.context.limit_except.nginx","patterns":[{"include":"$self"}]},{"begin":"\\\\b(if) +\\\\(","beginCaptures":{"1":{"name":"keyword.control.nginx"}},"end":"\\\\)","name":"meta.context.if.nginx","patterns":[{"include":"#if_condition"}]},{"begin":"\\\\b(upstream) +(.*?)\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"},"2":{"name":"entity.name.context.location.nginx"}},"end":"}","name":"meta.context.upstream.nginx","patterns":[{"include":"$self"}]},{"begin":"\\\\b(types) +\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"}},"end":"}","name":"meta.context.types.nginx","patterns":[{"include":"$self"}]},{"begin":"\\\\b(map) +(\\\\$)([0-9A-Z_a-z]+) +(\\\\$)([0-9A-Z_a-z]+) *\\\\{","beginCaptures":{"1":{"name":"storage.type.directive.context.nginx"},"2":{"name":"punctuation.definition.variable.nginx"},"3":{"name":"variable.parameter.nginx"},"4":{"name":"punctuation.definition.variable.nginx"},"5":{"name":"variable.other.nginx"}},"end":"}","name":"meta.context.map.nginx","patterns":[{"include":"#values"},{"match":";","name":"punctuation.terminator.nginx"},{"match":"#.*","name":"comment.line.number-sign"}]},{"begin":"\\\\{","end":"}","name":"meta.block.nginx","patterns":[{"include":"$self"}]},{"begin":"\\\\b(return)\\\\b","beginCaptures":{"1":{"name":"keyword.control.nginx"}},"end":";","patterns":[{"include":"#values"}]},{"begin":"\\\\b(rewrite)\\\\s+","beginCaptures":{"1":{"name":"keyword.directive.nginx"}},"end":"(last|break|redirect|permanent)?(;)","endCaptures":{"1":{"name":"keyword.other.nginx"},"2":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"\\\\b(server)\\\\s+","beginCaptures":{"1":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"1":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#server_parameters"}]},{"begin":"\\\\b(internal|empty_gif|f4f|flv|hls|mp4|break|status|stub_status|ip_hash|ntlm|least_conn|upstream_conf|least_conn|zone_sync)\\\\b","beginCaptures":{"1":{"name":"keyword.directive.nginx"}},"end":"(;|$)","endCaptures":{"1":{"name":"punctuation.terminator.nginx"}}},{"begin":"([\\"'\\\\s]|^)(accept_)(mutex(?:|_delay))([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(debug_)(connection|points)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(error_)(log|page)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(ssl_)(engine|buffer_size|certificate|certificate_key|ciphers|client_certificate|conf_command|crl|dhparam|early_data|ecdh_curve|ocsp|ocsp_cache|ocsp_responder|password_file|prefer_server_ciphers|protocols|reject_handshake|session_cache|session_ticket_key|session_tickets|session_timeout|stapling|stapling_file|stapling_responder|stapling_verify|trusted_certificate|verify_client|verify_depth|alpn|handshake_timeout|preread)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(worker_)(aio_requests|connections|cpu_affinity|priority|processes|rlimit_core|rlimit_nofile|shutdown_timeout)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(auth_)(delay|basic|basic_user_file|jwt|jwt_claim_set|jwt_header_set|jwt_key_cache|jwt_key_file|jwt_key_request|jwt_leeway|jwt_type|jwt_require|request|request_set|http|http_header|http_pass_client_cert|http_timeout)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(client_)(body_buffer_size|body_in_file_only|body_in_single_buffer|body_temp_path|body_timeout|header_buffer_size|header_timeout|max_body_size)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(keepalive_)(disable|requests|time|timeout)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(limit_)(rate|rate_after|conn|conn_dry_run|conn_log_level|conn_status|conn_zone|zone|req|req_dry_run|req_log_level|req_status|req_zone)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(lingering_)(close|time|timeout)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(log_)(not_found|subrequest|format)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(max_)(ranges|errors)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(msie_)(padding|refresh)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(open_)(file_cache|file_cache_errors|file_cache_min_uses|file_cache_valid|log_file_cache)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(send_)(lowat|timeout)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(server_)(name|name_in_redirect|names_hash_bucket_size|names_hash_max_size|tokens)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(tcp_)(no(?:delay|push))([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(types_)(hash_(?:bucket|max)_size)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(variables_)(hash_(?:bucket|max)_size)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(add_)(before_body|after_body|header|trailer)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(status_)(zone|format)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(autoindex_)(exact_size|format|localtime)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(ancient_)(browser(?:|_value))([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(modern_)(browser(?:|_value))([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(charset_)(map|types)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(dav_)(access|methods)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(fastcgi_)(bind|buffer_size|buffering|buffers|busy_buffers_size|cache|cache_background_update|cache_bypass|cache_key|cache_lock|cache_lock_age|cache_lock_timeout|cache_max_range_offset|cache_methods|cache_min_uses|cache_path|cache_purge|cache_revalidate|cache_use_stale|cache_valid|catch_stderr|connect_timeout|force_ranges|hide_header|ignore_client_abort|ignore_headers|index|intercept_errors|keep_conn|limit_rate|max_temp_file_size|next_upstream|next_upstream_timeout|next_upstream_tries|no_cache|param|pass|pass_header|pass_request_body|pass_request_headers|read_timeout|request_buffering|send_lowat|send_timeout|socket_keepalive|split_path_info|store|store_access|temp_file_write_size|temp_path)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(geoip_)(country|city|org|proxy|proxy_recursive)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(grpc_)(bind|buffer_size|connect_timeout|hide_header|ignore_headers|intercept_errors|next_upstream|next_upstream_timeout|next_upstream_tries|pass|pass_header|read_timeout|send_timeout|set_header|socket_keepalive|ssl_certificate|ssl_certificate_key|ssl_ciphers|ssl_conf_command|ssl_crl|ssl_name|ssl_password_file|ssl_protocols|ssl_server_name|ssl_session_reuse|ssl_trusted_certificate|ssl_verify|ssl_verify_depth)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(gzip_)(buffers|comp_level|disable|http_version|min_length|proxied|types|vary|static)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(hls_)(buffers|forward_args|fragment|mp4_buffer_size|mp4_max_buffer_size)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(image_)(filter(?:|_buffer|_interlace|_jpeg_quality|_sharpen|_transparency|_webp_quality))([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(map_)(hash_(?:bucket|max)_size)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(memcached_)(bind|buffer_size|connect_timeout|gzip_flag|next_upstream|next_upstream_timeout|next_upstream_tries|pass|read_timeout|send_timeout|socket_keepalive)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(mp4_)(buffer_size|max_buffer_size|limit_rate|limit_rate_after|start_key_frame)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(perl_)(modules|require|set)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(proxy_)(bind|buffer_size|buffering|buffers|busy_buffers_size|cache|cache_background_update|cache_bypass|cache_convert_head|cache_key|cache_lock|cache_lock_age|cache_lock_timeout|cache_max_range_offset|cache_methods|cache_min_uses|cache_path|cache_purge|cache_revalidate|cache_use_stale|cache_valid|connect_timeout|cookie_domain|cookie_flags|cookie_path|force_ranges|headers_hash_bucket_size|headers_hash_max_size|hide_header|http_version|ignore_client_abort|ignore_headers|intercept_errors|limit_rate|max_temp_file_size|method|next_upstream|next_upstream_timeout|next_upstream_tries|no_cache|pass|pass_header|pass_request_body|pass_request_headers|read_timeout|redirect|request_buffering|send_lowat|send_timeout|set_body|set_header|socket_keepalive|ssl_certificate|ssl_certificate_key|ssl_ciphers|ssl_conf_command|ssl_crl|ssl_name|ssl_password_file|ssl_protocols|ssl_server_name|ssl_session_reuse|ssl_trusted_certificate|ssl_verify|ssl_verify_depth|store|store_access|temp_file_write_size|temp_path|buffer|pass_error_message|protocol|smtp_auth|timeout|protocol_timeout|download_rate|half_close|requests|responses|session_drop|ssl|upload_rate)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(real_)(ip_(?:header|recursive))([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(referer_)(hash_(?:bucket|max)_size)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(scgi_)(bind|buffer_size|buffering|buffers|busy_buffers_size|cache|cache_background_update|cache_bypass|cache_key|cache_lock|cache_lock_age|cache_lock_timeout|cache_max_range_offset|cache_methods|cache_min_uses|cache_path|cache_purge|cache_revalidate|cache_use_stale|cache_valid|connect_timeout|force_ranges|hide_header|ignore_client_abort|ignore_headers|intercept_errors|limit_rate|max_temp_file_size|next_upstream|next_upstream_timeout|next_upstream_tries|no_cache|param|pass|pass_header|pass_request_body|pass_request_headers|read_timeout|request_buffering|send_timeout|socket_keepalive|store|store_access|temp_file_write_size|temp_path)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(secure_)(link(?:|_md5|_secret))([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(session_)(log(?:|_format|_zone))([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(ssi_)(last_modified|min_file_chunk|silent_errors|types|value_length)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(sub_)(filter(?:|_last_modified|_once|_types))([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(health_)(check(?:|_timeout))([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(userid_)(domain|expires|flags|mark|name|p3p|path|service)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(uwsgi_)(bind|buffer_size|buffering|buffers|busy_buffers_size|cache|cache_background_update|cache_bypass|cache_key|cache_lock|cache_lock_age|cache_lock_timeout|cache_max_range_offset|cache_methods|cache_min_uses|cache_path|cache_purge|cache_revalidate|cache_use_stale|cache_valid|connect_timeout|force_ranges|hide_header|ignore_client_abort|ignore_headers|intercept_errors|limit_rate|max_temp_file_size|modifier1|modifier2|next_upstream|next_upstream_timeout|next_upstream_tries|no_cache|param|pass|pass_header|pass_request_body|pass_request_headers|read_timeout|request_buffering|send_timeout|socket_keepalive|ssl_certificate|ssl_certificate_key|ssl_ciphers|ssl_conf_command|ssl_crl|ssl_name|ssl_password_file|ssl_protocols|ssl_server_name|ssl_session_reuse|ssl_trusted_certificate|ssl_verify|ssl_verify_depth|store|store_access|temp_file_write_size|temp_path)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(http2_)(body_preread_size|chunk_size|idle_timeout|max_concurrent_pushes|max_concurrent_streams|max_field_size|max_header_size|max_requests|push|push_preload|recv_buffer_size|recv_timeout)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(http3_)(hq|max_concurrent_streams|stream_buffer_size)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(quic_)(active_connection_id_limit|bpf|gso|host_key|retry)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(xslt_)(last_modified|param|string_param|stylesheet|types)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(imap_)(auth|capabilities|client_buffer)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(pop3_)(auth|capabilities)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(smtp_)(auth|capabilities|client_buffer|greeting_delay)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(preread_)(buffer_size|timeout)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(mqtt_)(preread|buffers|rewrite_buffer_size|set_connect)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(zone_)(sync_(?:buffers|connect_retry_interval|connect_timeout|interval|recv_buffer_size|server|ssl|ssl_certificate|ssl_certificate_key|ssl_ciphers|ssl_conf_command|ssl_crl|ssl_name|ssl_password_file|ssl_protocols|ssl_server_name|ssl_trusted_certificate|ssl_verify|ssl_verify_depth|timeout))([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(otel_)(exporter|service_name|trace|trace_context|span_name|span_attr)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(js_)(body_filter|content|fetch_buffer_size|fetch_ciphers|fetch_max_response_buffer_size|fetch_protocols|fetch_timeout|fetch_trusted_certificate|fetch_verify|fetch_verify_depth|header_filter|import|include|path|periodic|preload_object|set|shared_dict_zone|var|access|filter|preread)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"},"4":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"([\\"'\\\\s]|^)(daemon|env|include|pid|user??|aio|alias|directio|etag|listen|resolver|root|satisfy|sendfile|allow|deny|api|autoindex|charset|geo|gunzip|gzip|expires|index|keyval|mirror|perl|set|slice|ssi|ssl|zone|state|hash|keepalive|queue|random|sticky|match|userid|http2|http3|protocol|timeout|xclient|starttls|mqtt|load_module|lock_file|master_process|multi_accept|pcre_jit|thread_pool|timer_resolution|working_directory|absolute_redirect|aio_write|chunked_transfer_encoding|connection_pool_size|default_type|directio_alignment|disable_symlinks|if_modified_since|ignore_invalid_headers|large_client_header_buffers|merge_slashes|output_buffers|port_in_redirect|postpone_output|read_ahead|recursive_error_pages|request_pool_size|reset_timedout_connection|resolver_timeout|sendfile_max_chunk|subrequest_output_buffer_size|try_files|underscores_in_headers|addition_types|override_charset|source_charset|create_full_put_path|min_delete_depth|f4f_buffer_size|gunzip_buffers|internal_redirect|keyval_zone|access_log|mirror_request_body|random_index|set_real_ip_from|valid_referers|rewrite_log|uninitialized_variable_warn|split_clients|least_time|sticky_cookie_insert|xml_entities|google_perftools_profiles)([\\"'\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.directive.nginx"},"2":{"name":"keyword.directive.nginx"},"3":{"name":"keyword.directive.nginx"}},"end":";","endCaptures":{"0":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"\\\\b([0-9A-Z_a-z]+)\\\\s+","beginCaptures":{"1":{"name":"keyword.directive.unknown.nginx"}},"end":"(;|$)","endCaptures":{"1":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]},{"begin":"\\\\b([a-z]+/[-+.0-9A-Za-z]+)\\\\b","beginCaptures":{"1":{"name":"constant.other.mediatype.nginx"}},"end":"(;)","endCaptures":{"1":{"name":"punctuation.terminator.nginx"}},"patterns":[{"include":"#values"}]}],"repository":{"if_condition":{"patterns":[{"include":"#variables"},{"match":"!?~\\\\*?\\\\s","name":"keyword.operator.nginx"},{"match":"!?-[defx]\\\\s","name":"keyword.operator.nginx"},{"match":"!?=[^=]","name":"keyword.operator.nginx"},{"include":"#regexp_and_string"}]},"regexp_and_string":{"patterns":[{"match":"\\\\^.*?\\\\$","name":"string.regexp.nginx"},{"begin":"\\"","end":"\\"","name":"string.quoted.double.nginx","patterns":[{"match":"\\\\\\\\[\\"'\\\\\\\\nt]","name":"constant.character.escape.nginx"},{"include":"#variables"}]},{"begin":"'","end":"'","name":"string.quoted.single.nginx","patterns":[{"match":"\\\\\\\\[\\"'\\\\\\\\nt]","name":"constant.character.escape.nginx"},{"include":"#variables"}]}]},"server_parameters":{"patterns":[{"captures":{"1":{"name":"variable.parameter.nginx"},"2":{"name":"keyword.operator.nginx"},"3":{"name":"constant.numeric.nginx"}},"match":"(?:^|\\\\s)(weight|max_conn|max_fails|fail_timeout|slow_start)(=)(\\\\d[.\\\\d]*[BDGHKMSTbdghkmst]?)(?:[;\\\\s]|$)"},{"include":"#values"}]},"values":{"patterns":[{"include":"#variables"},{"match":"#.*","name":"comment.line.number-sign"},{"captures":{"1":{"name":"constant.numeric.nginx"}},"match":"(?<=\\\\G|\\\\s)(=?[0-9][.0-9]*[BDGHKMSTbdghkmst]?)(?=[\\\\t ;])"},{"match":"(?<=\\\\G|\\\\s)(on|off|true|false)(?=[\\\\t ;])","name":"constant.language.nginx"},{"match":"(?<=\\\\G|\\\\s)(kqueue|rtsig|epoll|/dev/poll|select|poll|eventport|max|all|default_server|default|main|crit|error|debug|warn|notice|last)(?=[\\\\t ;])","name":"constant.language.nginx"},{"match":"\\\\\\\\.* |~\\\\*?|!~\\\\*?","name":"keyword.operator.nginx"},{"include":"#regexp_and_string"}]},"variables":{"patterns":[{"captures":{"1":{"name":"punctuation.definition.variable.nginx"},"2":{"name":"variable.other.nginx"}},"match":"(\\\\$)([0-9A-Z_a-z]+)\\\\b"},{"captures":{"1":{"name":"punctuation.definition.variable.nginx"},"2":{"name":"variable.other.nginx"},"3":{"name":"punctuation.definition.variable.nginx"}},"match":"(\\\\$\\\\{)([0-9A-Z_a-z]+)(})"}]}},"scopeName":"source.nginx","embeddedLangs":["lua"]}`)),n=[...e,t];export{n as default};
|
dist/assets/{perl-DCcfytl_.js → perl-jST4v011.js}
RENAMED
|
@@ -1 +1 @@
|
|
| 1 |
-
import e from"./sql-BsFa4tDR.js";import t from"./css-BsVw1vtW.js";import n from"./javascript-BgS3c2Ky.js";import r from"./html-BY76lXLH.js";import i from"./xml-CkTAj7zh.js";var a=Object.freeze(JSON.parse(`{"displayName":"Perl","name":"perl","patterns":[{"include":"#line_comment"},{"begin":"^(?==[A-Za-z]+)","end":"^(=cut\\\\b.*)$","endCaptures":{"1":{"patterns":[{"include":"#pod"}]}},"name":"comment.block.documentation.perl","patterns":[{"include":"#pod"}]},{"include":"#variable"},{"applyEndPatternLast":1,"begin":"\\\\b(?=qr\\\\s*[^\\\\s\\\\w])","end":"((([acdegil-prsux]*)))(?=(\\\\s+\\\\S|\\\\s*[#),;{}]|\\\\s*$))","endCaptures":{"1":{"name":"string.regexp.compile.perl"},"2":{"name":"punctuation.definition.string.perl"},"3":{"name":"keyword.control.regexp-option.perl"}},"patterns":[{"begin":"(qr)\\\\s*\\\\{","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"}","name":"string.regexp.compile.nested_braces.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_braces_interpolated"}]},{"begin":"(qr)\\\\s*\\\\[","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"]","name":"string.regexp.compile.nested_brackets.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_brackets_interpolated"}]},{"begin":"(qr)\\\\s*<","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":">","name":"string.regexp.compile.nested_ltgt.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_ltgt_interpolated"}]},{"begin":"(qr)\\\\s*\\\\(","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"\\\\)","name":"string.regexp.compile.nested_parens.perl","patterns":[{"match":"\\\\$(?=[^'(<\\\\[\\\\\\\\{\\\\s\\\\w])"},{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_parens_interpolated"}]},{"begin":"(qr)\\\\s*'","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"'","name":"string.regexp.compile.single-quote.perl","patterns":[{"include":"#escaped_char"}]},{"begin":"(qr)\\\\s*([^'(<\\\\[{\\\\s\\\\w])","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"\\\\2","name":"string.regexp.compile.simple-delimiter.perl","patterns":[{"match":"\\\\$(?=[^'(<\\\\[{\\\\s\\\\w])","name":"keyword.control.anchor.perl"},{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_parens_interpolated"}]}]},{"applyEndPatternLast":1,"begin":"(?<![-+{])\\\\b(?=m\\\\s*[^0-9A-Za-z\\\\s])","end":"((([acdegil-prsux]*)))(?=(\\\\s+\\\\S|\\\\s*[#),;{}]|\\\\s*$))","endCaptures":{"1":{"name":"string.regexp.find-m.perl"},"2":{"name":"punctuation.definition.string.perl"},"3":{"name":"keyword.control.regexp-option.perl"}},"patterns":[{"begin":"(m)\\\\s*\\\\{","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"}","name":"string.regexp.find-m.nested_braces.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_braces_interpolated"}]},{"begin":"(m)\\\\s*\\\\[","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"]","name":"string.regexp.find-m.nested_brackets.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_brackets_interpolated"}]},{"begin":"(m)\\\\s*<","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":">","name":"string.regexp.find-m.nested_ltgt.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_ltgt_interpolated"}]},{"begin":"(m)\\\\s*\\\\(","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"\\\\)","name":"string.regexp.find-m.nested_parens.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_parens_interpolated"}]},{"begin":"(m)\\\\s*'","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"'","name":"string.regexp.find-m.single-quote.perl","patterns":[{"include":"#escaped_char"}]},{"begin":"\\\\G(?<![-+{])(m)(?!_)\\\\s*([^'(0-9<A-\\\\[a-{\\\\s])","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"\\\\2","name":"string.regexp.find-m.simple-delimiter.perl","patterns":[{"match":"\\\\$(?=[^'(0-9<A-\\\\[a-{\\\\s])","name":"keyword.control.anchor.perl"},{"include":"#escaped_char"},{"include":"#variable"},{"begin":"\\\\[","beginCaptures":{"1":{"name":"punctuation.definition.character-class.begin.perl"}},"end":"]","endCaptures":{"1":{"name":"punctuation.definition.character-class.end.perl"}},"name":"constant.other.character-class.set.perl","patterns":[{"match":"\\\\$(?=[^'(<\\\\[{\\\\s\\\\w])","name":"keyword.control.anchor.perl"},{"include":"#escaped_char"}]},{"include":"#nested_parens_interpolated"}]}]},{"applyEndPatternLast":1,"begin":"\\\\b(?=(?<!&)(s)(\\\\s+\\\\S|\\\\s*[(),;<\\\\[{}]|$))","end":"((([acdegil-prsux]*)))(?=(\\\\s+\\\\S|\\\\s*[]),;>{}]|\\\\s*$))","endCaptures":{"1":{"name":"string.regexp.replace.perl"},"2":{"name":"punctuation.definition.string.perl"},"3":{"name":"keyword.control.regexp-option.perl"}},"patterns":[{"begin":"(s)\\\\s*\\\\{","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"}","name":"string.regexp.nested_braces.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_braces"}]},{"begin":"(s)\\\\s*\\\\[","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"]","name":"string.regexp.nested_brackets.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_brackets"}]},{"begin":"(s)\\\\s*<","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":">","name":"string.regexp.nested_ltgt.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_ltgt"}]},{"begin":"(s)\\\\s*\\\\(","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"\\\\)","name":"string.regexp.nested_parens.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_parens"}]},{"begin":"\\\\{","captures":{"0":{"name":"punctuation.definition.string.perl"}},"end":"}","name":"string.regexp.format.nested_braces.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_braces_interpolated"}]},{"begin":"\\\\[","captures":{"0":{"name":"punctuation.definition.string.perl"}},"end":"]","name":"string.regexp.format.nested_brackets.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_brackets_interpolated"}]},{"begin":"<","captures":{"0":{"name":"punctuation.definition.string.perl"}},"end":">","name":"string.regexp.format.nested_ltgt.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_ltgt_interpolated"}]},{"begin":"\\\\(","captures":{"0":{"name":"punctuation.definition.string.perl"}},"end":"\\\\)","name":"string.regexp.format.nested_parens.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_parens_interpolated"}]},{"begin":"'","captures":{"0":{"name":"punctuation.definition.string.perl"}},"end":"'","name":"string.regexp.format.single_quote.perl","patterns":[{"match":"\\\\\\\\['\\\\\\\\]","name":"constant.character.escape.perl"}]},{"begin":"([^(;<\\\\[{\\\\s\\\\w])","captures":{"0":{"name":"punctuation.definition.string.perl"}},"end":"\\\\1","name":"string.regexp.format.simple_delimiter.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"}]},{"match":"\\\\s+"}]},{"begin":"\\\\b(?=s([^(0-9<A-\\\\[a-{\\\\s]).*\\\\1([acdegil-prsux]*)([),;}]|\\\\s+))","end":"((([acdegil-prsux]*)))(?=([),;}]|\\\\s+|\\\\s*$))","endCaptures":{"1":{"name":"string.regexp.replace.perl"},"2":{"name":"punctuation.definition.string.perl"},"3":{"name":"keyword.control.regexp-option.perl"}},"patterns":[{"begin":"(s\\\\s*)([^(0-9<A-\\\\[a-{\\\\s])","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"(?=\\\\2)","name":"string.regexp.replaceXXX.simple_delimiter.perl","patterns":[{"include":"#escaped_char"}]},{"begin":"'","captures":{"0":{"name":"punctuation.definition.string.perl"}},"end":"'","name":"string.regexp.replaceXXX.format.single_quote.perl","patterns":[{"match":"\\\\\\\\['\\\\\\\\]","name":"constant.character.escape.perl.perl"}]},{"begin":"([^(0-9<A-\\\\[a-{\\\\s])","captures":{"0":{"name":"punctuation.definition.string.perl"}},"end":"\\\\1","name":"string.regexp.replaceXXX.format.simple_delimiter.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"}]}]},{"begin":"\\\\b(?=(?<!\\\\\\\\)s\\\\s*([^(<>\\\\[{\\\\s\\\\w]))","end":"((([acdegilmoprsu]*x[acdegilmoprsu]*)))\\\\b","endCaptures":{"1":{"name":"string.regexp.replace.perl"},"2":{"name":"punctuation.definition.string.perl"},"3":{"name":"keyword.control.regexp-option.perl"}},"patterns":[{"begin":"(s)\\\\s*(.)","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"(?=\\\\2)","name":"string.regexp.replace.extended.simple_delimiter.perl","patterns":[{"include":"#escaped_char"}]},{"begin":"'","captures":{"0":{"name":"punctuation.definition.string.perl"}},"end":"'(?=[acdegilmoprsu]*x[acdegilmoprsu]*)\\\\b","name":"string.regexp.replace.extended.simple_delimiter.perl","patterns":[{"include":"#escaped_char"}]},{"begin":"(.)","captures":{"0":{"name":"punctuation.definition.string.perl"}},"end":"\\\\1(?=[acdegilmoprsu]*x[acdegilmoprsu]*)\\\\b","name":"string.regexp.replace.extended.simple_delimiter.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"}]}]},{"begin":"(?<=[\\\\&({|~]|if|unless|^)\\\\s*((/))","beginCaptures":{"1":{"name":"string.regexp.find.perl"},"2":{"name":"punctuation.definition.string.perl"}},"contentName":"string.regexp.find.perl","end":"((\\\\1([acdegil-prsux]*)))(?=(\\\\s+\\\\S|\\\\s*[#),;{}]|\\\\s*$))","endCaptures":{"1":{"name":"string.regexp.find.perl"},"2":{"name":"punctuation.definition.string.perl"},"3":{"name":"keyword.control.regexp-option.perl"}},"patterns":[{"match":"\\\\$(?=/)","name":"keyword.control.anchor.perl"},{"include":"#escaped_char"},{"include":"#variable"}]},{"captures":{"1":{"name":"constant.other.key.perl"}},"match":"\\\\b(\\\\w+)\\\\s*(?==>)"},{"match":"(?<=\\\\{)\\\\s*\\\\w+\\\\s*(?=})","name":"constant.other.bareword.perl"},{"captures":{"1":{"name":"keyword.control.perl"},"2":{"name":"entity.name.type.class.perl"}},"match":"^\\\\s*(package)\\\\s+([^;\\\\s]+)","name":"meta.class.perl"},{"captures":{"1":{"name":"storage.type.sub.perl"},"2":{"name":"entity.name.function.perl"},"3":{"name":"storage.type.method.perl"}},"match":"\\\\b(sub)(?:\\\\s+([-0-9A-Z_a-z]+))?\\\\s*(?:\\\\([$*;@]*\\\\))?[^{\\\\w]","name":"meta.function.perl"},{"captures":{"1":{"name":"entity.name.function.perl"},"2":{"name":"punctuation.definition.parameters.perl"},"3":{"name":"variable.parameter.function.perl"}},"match":"^\\\\s*(BEGIN|UNITCHECK|CHECK|INIT|END|DESTROY)\\\\b","name":"meta.function.perl"},{"begin":"^(?=(\\\\t| {4}))","end":"(?=[^\\\\t\\\\s])","name":"meta.leading-tabs","patterns":[{"captures":{"1":{"name":"meta.odd-tab"},"2":{"name":"meta.even-tab"}},"match":"(\\\\t| {4})(\\\\t| {4})?"}]},{"captures":{"1":{"name":"support.function.perl"},"2":{"name":"punctuation.definition.string.perl"},"5":{"name":"punctuation.definition.string.perl"},"8":{"name":"punctuation.definition.string.perl"}},"match":"\\\\b(tr|y)\\\\s*([^0-9A-Za-z\\\\s])(.*?)(?<!\\\\\\\\)(\\\\\\\\{2})*(\\\\2)(.*?)(?<!\\\\\\\\)(\\\\\\\\{2})*(\\\\2)","name":"string.regexp.replace.perl"},{"match":"\\\\b(__(?:FILE|LINE|PACKAGE|SUB)__)\\\\b","name":"constant.language.perl"},{"begin":"\\\\b(__(?:DATA__|END__))\\\\n?","beginCaptures":{"1":{"name":"constant.language.perl"}},"contentName":"comment.block.documentation.perl","end":"\\\\z","patterns":[{"include":"#pod"}]},{"match":"(?<!->)\\\\b(continue|default|die|do|else|elsif|exit|for|foreach|given|goto|if|last|next|redo|return|select|unless|until|wait|when|while|switch|case|require|use|eval)\\\\b","name":"keyword.control.perl"},{"match":"\\\\b(my|our|local)\\\\b","name":"storage.modifier.perl"},{"match":"(?<!\\\\w)-[ABCMORSTWXb-gklopr-uwxz]\\\\b","name":"keyword.operator.filetest.perl"},{"match":"\\\\b(and|or|xor|as|not)\\\\b","name":"keyword.operator.logical.perl"},{"match":"((?:<=|[-=])>)","name":"keyword.operator.comparison.perl"},{"include":"#heredoc"},{"begin":"\\\\bqq\\\\s*([^(<\\\\[{\\\\w\\\\s])","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"\\\\1","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.other.qq.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"}]},{"begin":"\\\\bqx\\\\s*([^'(<\\\\[{\\\\w\\\\s])","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"\\\\1","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.interpolated.qx.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"}]},{"begin":"\\\\bqx\\\\s*'","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"'","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.interpolated.qx.single-quote.perl","patterns":[{"include":"#escaped_char"}]},{"begin":"\\"","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"\\"","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.double.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"}]},{"begin":"(?<!->)\\\\bqw?\\\\s*([^(<\\\\[{\\\\w\\\\s])","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"\\\\1","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.other.q.perl"},{"begin":"'","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"'","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.single.perl","patterns":[{"match":"\\\\\\\\['\\\\\\\\]","name":"constant.character.escape.perl"}]},{"begin":"\`","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"\`","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.interpolated.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"}]},{"begin":"(?<!->)\\\\bqq\\\\s*\\\\(","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.other.qq-paren.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_parens_interpolated"},{"include":"#variable"}]},{"begin":"\\\\bqq\\\\s*\\\\{","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"}","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.other.qq-brace.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_braces_interpolated"},{"include":"#variable"}]},{"begin":"\\\\bqq\\\\s*\\\\[","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"]","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.other.qq-bracket.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_brackets_interpolated"},{"include":"#variable"}]},{"begin":"\\\\bqq\\\\s*<","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":">","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.other.qq-ltgt.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_ltgt_interpolated"},{"include":"#variable"}]},{"begin":"(?<!->)\\\\bqx\\\\s*\\\\(","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.interpolated.qx-paren.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_parens_interpolated"},{"include":"#variable"}]},{"begin":"\\\\bqx\\\\s*\\\\{","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"}","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.interpolated.qx-brace.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_braces_interpolated"},{"include":"#variable"}]},{"begin":"\\\\bqx\\\\s*\\\\[","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"]","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.interpolated.qx-bracket.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_brackets_interpolated"},{"include":"#variable"}]},{"begin":"\\\\bqx\\\\s*<","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":">","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.interpolated.qx-ltgt.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_ltgt_interpolated"},{"include":"#variable"}]},{"begin":"(?<!->)\\\\bqw?\\\\s*\\\\(","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.other.q-paren.perl","patterns":[{"include":"#nested_parens"}]},{"begin":"\\\\bqw?\\\\s*\\\\{","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"}","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.other.q-brace.perl","patterns":[{"include":"#nested_braces"}]},{"begin":"\\\\bqw?\\\\s*\\\\[","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"]","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.other.q-bracket.perl","patterns":[{"include":"#nested_brackets"}]},{"begin":"\\\\bqw?\\\\s*<","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":">","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.other.q-ltgt.perl","patterns":[{"include":"#nested_ltgt"}]},{"begin":"^__\\\\w+__","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"$","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.unquoted.program-block.perl"},{"begin":"\\\\b(format)\\\\s+(\\\\w+)\\\\s*=","beginCaptures":{"1":{"name":"support.function.perl"},"2":{"name":"entity.name.function.format.perl"}},"end":"^\\\\.\\\\s*$","name":"meta.format.perl","patterns":[{"include":"#line_comment"},{"include":"#variable"}]},{"captures":{"1":{"name":"support.function.perl"},"2":{"name":"entity.name.function.perl"}},"match":"\\\\b(x)\\\\s*(\\\\d+)\\\\b"},{"match":"\\\\b(ARGV|DATA|ENV|SIG|STDERR|STDIN|STDOUT|atan2|bind|binmode|bless|caller|chdir|chmod|chomp|chop|chown|chr|chroot|close|closedir|cmp|connect|cos|crypt|dbmclose|dbmopen|defined|delete|dump|each|endgrent|endhostent|endnetent|endprotoent|endpwent|endservent|eof|eq|eval|exec|exists|exp|fcntl|fileno|flock|fork|formline|ge|getc|getgrent|getgrgid|getgrnam|gethostbyaddr|gethostbyname|gethostent|getlogin|getnetbyaddr|getnetbyname|getnetent|getpeername|getpgrp|getppid|getpriority|getprotobyname|getprotobynumber|getprotoent|getpwent|getpwnam|getpwuid|getservbyname|getservbyport|getservent|getsockname|getsockopt|glob|gmtime|grep|gt|hex|import|index|int|ioctl|join|keys|kill|lc|lcfirst|le|length|link|listen|local|localtime|log|lstat|lt|m|map|mkdir|msgctl|msgget|msgrcv|msgsnd|ne|no|oct|open|opendir|ord|pack|pipe|pop|pos|printf??|push|quotemeta|rand|read|readdir|readlink|recv|ref|rename|reset|reverse|rewinddir|rindex|rmdir|s|say|scalar|seek|seekdir|semctl|semget|semop|send|setgrent|sethostent|setnetent|setpgrp|setpriority|setprotoent|setpwent|setservent|setsockopt|shift|shmctl|shmget|shmread|shmwrite|shutdown|sin|sleep|socket|socketpair|sort|splice|split|sprintf|sqrt|srand|stat|study|substr|symlink|syscall|sysopen|sysread|system|syswrite|tell|telldir|tied??|times??|tr|truncate|uc|ucfirst|umask|undef|unlink|unpack|unshift|untie|utime|values|vec|waitpid|wantarray|warn|write|y)\\\\b","name":"support.function.perl"},{"captures":{"1":{"name":"punctuation.section.scope.begin.perl"},"2":{"name":"punctuation.section.scope.end.perl"}},"match":"(\\\\{)(})"},{"captures":{"1":{"name":"punctuation.section.scope.begin.perl"},"2":{"name":"punctuation.section.scope.end.perl"}},"match":"(\\\\()(\\\\))"}],"repository":{"escaped_char":{"patterns":[{"match":"\\\\\\\\\\\\d+","name":"constant.character.escape.perl"},{"match":"\\\\\\\\c[^\\\\\\\\\\\\s]","name":"constant.character.escape.perl"},{"match":"\\\\\\\\g(?:\\\\{(?:\\\\w*|-\\\\d+)}|\\\\d+)","name":"constant.character.escape.perl"},{"match":"\\\\\\\\k(?:\\\\{\\\\w*}|<\\\\w*>|'\\\\w*')","name":"constant.character.escape.perl"},{"match":"\\\\\\\\N\\\\{[^}]*}","name":"constant.character.escape.perl"},{"match":"\\\\\\\\o\\\\{\\\\d*}","name":"constant.character.escape.perl"},{"match":"\\\\\\\\[Pp](?:\\\\{\\\\w*}|P)","name":"constant.character.escape.perl"},{"match":"\\\\\\\\x(?:[0-9A-Za-z]{2}|\\\\{\\\\w*})?","name":"constant.character.escape.perl"},{"match":"\\\\\\\\.","name":"constant.character.escape.perl"}]},"heredoc":{"patterns":[{"begin":"((((<<(~)?) *')(HTML)(')))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.raw.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.raw.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.raw.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.html","patterns":[{"begin":"^","end":"\\\\n","name":"text.html.basic","patterns":[{"include":"text.html.basic"}]}]},{"begin":"((((<<(~)?) *')(XML)(')))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.raw.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.raw.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.raw.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.xml","patterns":[{"begin":"^","end":"\\\\n","name":"text.xml","patterns":[{"include":"text.xml"}]}]},{"begin":"((((<<(~)?) *')(CSS)(')))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.raw.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.raw.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.raw.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.css","patterns":[{"begin":"^","end":"\\\\n","name":"source.css","patterns":[{"include":"source.css"}]}]},{"begin":"((((<<(~)?) *')(JAVASCRIPT)(')))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.raw.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.raw.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.raw.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.js","patterns":[{"begin":"^","end":"\\\\n","name":"source.js","patterns":[{"include":"source.js"}]}]},{"begin":"((((<<(~)?) *')(SQL)(')))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.raw.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.raw.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.raw.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.sql","patterns":[{"begin":"^","end":"\\\\n","name":"source.sql","patterns":[{"include":"source.sql"}]}]},{"begin":"((((<<(~)?) *')(POSTSCRIPT)(')))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.raw.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.raw.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.raw.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.postscript","patterns":[{"begin":"^","end":"\\\\n","name":"source.postscript","patterns":[{"include":"source.postscript"}]}]},{"begin":"((((<<(~)?) *')([^']*)(')))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.raw.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.raw.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.raw.perl"},"3":{"name":"punctuation.definition.string.end.perl"}}},{"begin":"((((<<(~)?) *\\\\\\\\)((?![ $(=\\\\d])[^\\"'),;\`\\\\s]*)()))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.raw.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.raw.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.raw.perl"},"3":{"name":"punctuation.definition.string.end.perl"}}},{"begin":"((((<<(~)?) *\\")(HTML)(\\")))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.html","patterns":[{"begin":"^","end":"\\\\n","name":"text.html.basic","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"text.html.basic"}]}]},{"begin":"((((<<(~)?) *\\")(XML)(\\")))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.xml","patterns":[{"begin":"^","end":"\\\\n","name":"text.xml","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"text.xml"}]}]},{"begin":"((((<<(~)?) *\\")(CSS)(\\")))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.css","patterns":[{"begin":"^","end":"\\\\n","name":"source.css","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"source.css"}]}]},{"begin":"((((<<(~)?) *\\")(JAVASCRIPT)(\\")))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.js","patterns":[{"begin":"^","end":"\\\\n","name":"source.js","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"source.js"}]}]},{"begin":"((((<<(~)?) *\\")(SQL)(\\")))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.sql","patterns":[{"begin":"^","end":"\\\\n","name":"source.sql","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"source.sql"}]}]},{"begin":"((((<<(~)?) *\\")(POSTSCRIPT)(\\")))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.postscript","patterns":[{"begin":"^","end":"\\\\n","name":"source.postscript","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"source.postscript"}]}]},{"begin":"((((<<(~)?) *\\")([^\\"]*)(\\")))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"patterns":[{"include":"#escaped_char"},{"include":"#variable"}]},{"begin":"((((<<(~)?) *)(HTML)()))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.html","patterns":[{"begin":"^","end":"\\\\n","name":"text.html.basic","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"text.html.basic"}]}]},{"begin":"((((<<(~)?) *)(XML)()))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.xml","patterns":[{"begin":"^","end":"\\\\n","name":"text.xml","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"text.xml"}]}]},{"begin":"((((<<(~)?) *)(CSS)()))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.css","patterns":[{"begin":"^","end":"\\\\n","name":"source.css","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"source.css"}]}]},{"begin":"((((<<(~)?) *)(JAVASCRIPT)()))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.js","patterns":[{"begin":"^","end":"\\\\n","name":"source.js","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"source.js"}]}]},{"begin":"((((<<(~)?) *)(SQL)()))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.sql","patterns":[{"begin":"^","end":"\\\\n","name":"source.sql","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"source.sql"}]}]},{"begin":"((((<<(~)?) *)(POSTSCRIPT)()))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.postscript","patterns":[{"begin":"^","end":"\\\\n","name":"source.postscript","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"source.postscript"}]}]},{"begin":"((((<<(~)?) *)((?![ $(=\\\\d])[^\\"'),;\`\\\\s]*)()))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"patterns":[{"include":"#escaped_char"},{"include":"#variable"}]},{"begin":"((((<<(~)?) *\`)([^\`]*)(\`)))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.shell.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"patterns":[{"include":"#escaped_char"},{"include":"#variable"}]}]},"line_comment":{"patterns":[{"begin":"(^[\\\\t ]+)?(?=#)","beginCaptures":{"1":{"name":"punctuation.whitespace.comment.leading.perl"}},"end":"(?!\\\\G)","patterns":[{"begin":"#","beginCaptures":{"0":{"name":"punctuation.definition.comment.perl"}},"end":"\\\\n","name":"comment.line.number-sign.perl"}]}]},"nested_braces":{"begin":"\\\\{","captures":{"1":{"name":"punctuation.section.scope.perl"}},"end":"}","patterns":[{"include":"#escaped_char"},{"include":"#nested_braces"}]},"nested_braces_interpolated":{"begin":"\\\\{","captures":{"1":{"name":"punctuation.section.scope.perl"}},"end":"}","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_braces_interpolated"}]},"nested_brackets":{"begin":"\\\\[","captures":{"1":{"name":"punctuation.section.scope.perl"}},"end":"]","patterns":[{"include":"#escaped_char"},{"include":"#nested_brackets"}]},"nested_brackets_interpolated":{"begin":"\\\\[","captures":{"1":{"name":"punctuation.section.scope.perl"}},"end":"]","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_brackets_interpolated"}]},"nested_ltgt":{"begin":"<","captures":{"1":{"name":"punctuation.section.scope.perl"}},"end":">","patterns":[{"include":"#nested_ltgt"}]},"nested_ltgt_interpolated":{"begin":"<","captures":{"1":{"name":"punctuation.section.scope.perl"}},"end":">","patterns":[{"include":"#variable"},{"include":"#nested_ltgt_interpolated"}]},"nested_parens":{"begin":"\\\\(","captures":{"1":{"name":"punctuation.section.scope.perl"}},"end":"\\\\)","patterns":[{"include":"#escaped_char"},{"include":"#nested_parens"}]},"nested_parens_interpolated":{"begin":"\\\\(","captures":{"1":{"name":"punctuation.section.scope.perl"}},"end":"\\\\)","patterns":[{"match":"\\\\$(?=[^'(<\\\\[{\\\\s\\\\w])","name":"keyword.control.anchor.perl"},{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_parens_interpolated"}]},"pod":{"patterns":[{"match":"^=(pod|back|cut)\\\\b","name":"storage.type.class.pod.perl"},{"begin":"^(=begin)\\\\s+(html)\\\\s*$","beginCaptures":{"1":{"name":"storage.type.class.pod.perl"},"2":{"name":"variable.other.pod.perl"}},"contentName":"text.embedded.html.basic","end":"^(?:(=end)\\\\s+(html)|(?==cut))","endCaptures":{"1":{"name":"storage.type.class.pod.perl"},"2":{"name":"variable.other.pod.perl"}},"name":"meta.embedded.pod.perl","patterns":[{"include":"text.html.basic"}]},{"captures":{"1":{"name":"storage.type.class.pod.perl"},"2":{"name":"variable.other.pod.perl","patterns":[{"include":"#pod-formatting"}]}},"match":"^(=(?:head[1-4]|item|over|encoding|begin|end|for))\\\\b\\\\s*(.*)"},{"include":"#pod-formatting"}]},"pod-formatting":{"patterns":[{"captures":{"1":{"name":"markup.italic.pod.perl"},"2":{"name":"markup.italic.pod.perl"}},"match":"I(?:<([^<>]+)>|<+(\\\\s+(?:(?<!\\\\s)>|[^>])+\\\\s+)>+)","name":"entity.name.type.instance.pod.perl"},{"captures":{"1":{"name":"markup.bold.pod.perl"},"2":{"name":"markup.bold.pod.perl"}},"match":"B(?:<([^<>]+)>|<+(\\\\s+(?:(?<!\\\\s)>|[^>])+\\\\s+)>+)","name":"entity.name.type.instance.pod.perl"},{"captures":{"1":{"name":"markup.raw.pod.perl"},"2":{"name":"markup.raw.pod.perl"}},"match":"C(?:<([^<>]+)>|<+(\\\\\\\\s+(?:(?<!\\\\\\\\s)>|[^>])+\\\\\\\\s+)>+)","name":"entity.name.type.instance.pod.perl"},{"captures":{"1":{"name":"markup.underline.link.hyperlink.pod.perl"}},"match":"L<([^>]+)>","name":"entity.name.type.instance.pod.perl"},{"match":"[EFSXZ]<[^>]*>","name":"entity.name.type.instance.pod.perl"}]},"variable":{"patterns":[{"captures":{"1":{"name":"punctuation.definition.variable.perl"}},"match":"(\\\\$)&(?![0-9A-Z_a-z])","name":"variable.other.regexp.match.perl"},{"captures":{"1":{"name":"punctuation.definition.variable.perl"}},"match":"(\\\\$)\`(?![0-9A-Z_a-z])","name":"variable.other.regexp.pre-match.perl"},{"captures":{"1":{"name":"punctuation.definition.variable.perl"}},"match":"(\\\\$)'(?![0-9A-Z_a-z])","name":"variable.other.regexp.post-match.perl"},{"captures":{"1":{"name":"punctuation.definition.variable.perl"}},"match":"(\\\\$)\\\\+(?![0-9A-Z_a-z])","name":"variable.other.regexp.last-paren-match.perl"},{"captures":{"1":{"name":"punctuation.definition.variable.perl"}},"match":"(\\\\$)\\"(?![0-9A-Z_a-z])","name":"variable.other.readwrite.list-separator.perl"},{"captures":{"1":{"name":"punctuation.definition.variable.perl"}},"match":"(\\\\$)0(?![0-9A-Z_a-z])","name":"variable.other.predefined.program-name.perl"},{"captures":{"1":{"name":"punctuation.definition.variable.perl"}},"match":"(\\\\$)[!#$%()*,-/:-@\\\\[-_ab|~](?![0-9A-Z_a-z])","name":"variable.other.predefined.perl"},{"captures":{"1":{"name":"punctuation.definition.variable.perl"}},"match":"(\\\\$)[0-9]+(?![0-9A-Z_a-z])","name":"variable.other.subpattern.perl"},{"captures":{"1":{"name":"punctuation.definition.variable.perl"}},"match":"([$%@](#)?)([$7A-Za-z]|::)([$0-9A-Z_a-z]|::)*\\\\b","name":"variable.other.readwrite.global.perl"},{"captures":{"1":{"name":"punctuation.definition.variable.perl"},"2":{"name":"punctuation.definition.variable.perl"}},"match":"(\\\\$\\\\{)(?:[$7A-Za-z]|::)(?:[$0-9A-Z_a-z]|::)*(})","name":"variable.other.readwrite.global.perl"},{"captures":{"1":{"name":"punctuation.definition.variable.perl"}},"match":"([$%@](#)?)[0-9_]\\\\b","name":"variable.other.readwrite.global.special.perl"}]}},"scopeName":"source.perl","embeddedLangs":["html","xml","css","javascript","sql"]}`)),o=[...r,...i,...t,...n,...e,a];export{o as default};
|
|
|
|
| 1 |
+
import e from"./sql-BsFa4tDR.js";import t from"./css-BsVw1vtW.js";import n from"./javascript-BgS3c2Ky.js";import r from"./html-BY76lXLH.js";import i from"./xml-DoonlvgL.js";var a=Object.freeze(JSON.parse(`{"displayName":"Perl","name":"perl","patterns":[{"include":"#line_comment"},{"begin":"^(?==[A-Za-z]+)","end":"^(=cut\\\\b.*)$","endCaptures":{"1":{"patterns":[{"include":"#pod"}]}},"name":"comment.block.documentation.perl","patterns":[{"include":"#pod"}]},{"include":"#variable"},{"applyEndPatternLast":1,"begin":"\\\\b(?=qr\\\\s*[^\\\\s\\\\w])","end":"((([acdegil-prsux]*)))(?=(\\\\s+\\\\S|\\\\s*[#),;{}]|\\\\s*$))","endCaptures":{"1":{"name":"string.regexp.compile.perl"},"2":{"name":"punctuation.definition.string.perl"},"3":{"name":"keyword.control.regexp-option.perl"}},"patterns":[{"begin":"(qr)\\\\s*\\\\{","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"}","name":"string.regexp.compile.nested_braces.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_braces_interpolated"}]},{"begin":"(qr)\\\\s*\\\\[","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"]","name":"string.regexp.compile.nested_brackets.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_brackets_interpolated"}]},{"begin":"(qr)\\\\s*<","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":">","name":"string.regexp.compile.nested_ltgt.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_ltgt_interpolated"}]},{"begin":"(qr)\\\\s*\\\\(","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"\\\\)","name":"string.regexp.compile.nested_parens.perl","patterns":[{"match":"\\\\$(?=[^'(<\\\\[\\\\\\\\{\\\\s\\\\w])"},{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_parens_interpolated"}]},{"begin":"(qr)\\\\s*'","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"'","name":"string.regexp.compile.single-quote.perl","patterns":[{"include":"#escaped_char"}]},{"begin":"(qr)\\\\s*([^'(<\\\\[{\\\\s\\\\w])","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"\\\\2","name":"string.regexp.compile.simple-delimiter.perl","patterns":[{"match":"\\\\$(?=[^'(<\\\\[{\\\\s\\\\w])","name":"keyword.control.anchor.perl"},{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_parens_interpolated"}]}]},{"applyEndPatternLast":1,"begin":"(?<![-+{])\\\\b(?=m\\\\s*[^0-9A-Za-z\\\\s])","end":"((([acdegil-prsux]*)))(?=(\\\\s+\\\\S|\\\\s*[#),;{}]|\\\\s*$))","endCaptures":{"1":{"name":"string.regexp.find-m.perl"},"2":{"name":"punctuation.definition.string.perl"},"3":{"name":"keyword.control.regexp-option.perl"}},"patterns":[{"begin":"(m)\\\\s*\\\\{","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"}","name":"string.regexp.find-m.nested_braces.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_braces_interpolated"}]},{"begin":"(m)\\\\s*\\\\[","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"]","name":"string.regexp.find-m.nested_brackets.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_brackets_interpolated"}]},{"begin":"(m)\\\\s*<","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":">","name":"string.regexp.find-m.nested_ltgt.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_ltgt_interpolated"}]},{"begin":"(m)\\\\s*\\\\(","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"\\\\)","name":"string.regexp.find-m.nested_parens.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_parens_interpolated"}]},{"begin":"(m)\\\\s*'","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"'","name":"string.regexp.find-m.single-quote.perl","patterns":[{"include":"#escaped_char"}]},{"begin":"\\\\G(?<![-+{])(m)(?!_)\\\\s*([^'(0-9<A-\\\\[a-{\\\\s])","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"\\\\2","name":"string.regexp.find-m.simple-delimiter.perl","patterns":[{"match":"\\\\$(?=[^'(0-9<A-\\\\[a-{\\\\s])","name":"keyword.control.anchor.perl"},{"include":"#escaped_char"},{"include":"#variable"},{"begin":"\\\\[","beginCaptures":{"1":{"name":"punctuation.definition.character-class.begin.perl"}},"end":"]","endCaptures":{"1":{"name":"punctuation.definition.character-class.end.perl"}},"name":"constant.other.character-class.set.perl","patterns":[{"match":"\\\\$(?=[^'(<\\\\[{\\\\s\\\\w])","name":"keyword.control.anchor.perl"},{"include":"#escaped_char"}]},{"include":"#nested_parens_interpolated"}]}]},{"applyEndPatternLast":1,"begin":"\\\\b(?=(?<!&)(s)(\\\\s+\\\\S|\\\\s*[(),;<\\\\[{}]|$))","end":"((([acdegil-prsux]*)))(?=(\\\\s+\\\\S|\\\\s*[]),;>{}]|\\\\s*$))","endCaptures":{"1":{"name":"string.regexp.replace.perl"},"2":{"name":"punctuation.definition.string.perl"},"3":{"name":"keyword.control.regexp-option.perl"}},"patterns":[{"begin":"(s)\\\\s*\\\\{","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"}","name":"string.regexp.nested_braces.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_braces"}]},{"begin":"(s)\\\\s*\\\\[","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"]","name":"string.regexp.nested_brackets.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_brackets"}]},{"begin":"(s)\\\\s*<","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":">","name":"string.regexp.nested_ltgt.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_ltgt"}]},{"begin":"(s)\\\\s*\\\\(","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"\\\\)","name":"string.regexp.nested_parens.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_parens"}]},{"begin":"\\\\{","captures":{"0":{"name":"punctuation.definition.string.perl"}},"end":"}","name":"string.regexp.format.nested_braces.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_braces_interpolated"}]},{"begin":"\\\\[","captures":{"0":{"name":"punctuation.definition.string.perl"}},"end":"]","name":"string.regexp.format.nested_brackets.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_brackets_interpolated"}]},{"begin":"<","captures":{"0":{"name":"punctuation.definition.string.perl"}},"end":">","name":"string.regexp.format.nested_ltgt.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_ltgt_interpolated"}]},{"begin":"\\\\(","captures":{"0":{"name":"punctuation.definition.string.perl"}},"end":"\\\\)","name":"string.regexp.format.nested_parens.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_parens_interpolated"}]},{"begin":"'","captures":{"0":{"name":"punctuation.definition.string.perl"}},"end":"'","name":"string.regexp.format.single_quote.perl","patterns":[{"match":"\\\\\\\\['\\\\\\\\]","name":"constant.character.escape.perl"}]},{"begin":"([^(;<\\\\[{\\\\s\\\\w])","captures":{"0":{"name":"punctuation.definition.string.perl"}},"end":"\\\\1","name":"string.regexp.format.simple_delimiter.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"}]},{"match":"\\\\s+"}]},{"begin":"\\\\b(?=s([^(0-9<A-\\\\[a-{\\\\s]).*\\\\1([acdegil-prsux]*)([),;}]|\\\\s+))","end":"((([acdegil-prsux]*)))(?=([),;}]|\\\\s+|\\\\s*$))","endCaptures":{"1":{"name":"string.regexp.replace.perl"},"2":{"name":"punctuation.definition.string.perl"},"3":{"name":"keyword.control.regexp-option.perl"}},"patterns":[{"begin":"(s\\\\s*)([^(0-9<A-\\\\[a-{\\\\s])","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"(?=\\\\2)","name":"string.regexp.replaceXXX.simple_delimiter.perl","patterns":[{"include":"#escaped_char"}]},{"begin":"'","captures":{"0":{"name":"punctuation.definition.string.perl"}},"end":"'","name":"string.regexp.replaceXXX.format.single_quote.perl","patterns":[{"match":"\\\\\\\\['\\\\\\\\]","name":"constant.character.escape.perl.perl"}]},{"begin":"([^(0-9<A-\\\\[a-{\\\\s])","captures":{"0":{"name":"punctuation.definition.string.perl"}},"end":"\\\\1","name":"string.regexp.replaceXXX.format.simple_delimiter.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"}]}]},{"begin":"\\\\b(?=(?<!\\\\\\\\)s\\\\s*([^(<>\\\\[{\\\\s\\\\w]))","end":"((([acdegilmoprsu]*x[acdegilmoprsu]*)))\\\\b","endCaptures":{"1":{"name":"string.regexp.replace.perl"},"2":{"name":"punctuation.definition.string.perl"},"3":{"name":"keyword.control.regexp-option.perl"}},"patterns":[{"begin":"(s)\\\\s*(.)","captures":{"0":{"name":"punctuation.definition.string.perl"},"1":{"name":"support.function.perl"}},"end":"(?=\\\\2)","name":"string.regexp.replace.extended.simple_delimiter.perl","patterns":[{"include":"#escaped_char"}]},{"begin":"'","captures":{"0":{"name":"punctuation.definition.string.perl"}},"end":"'(?=[acdegilmoprsu]*x[acdegilmoprsu]*)\\\\b","name":"string.regexp.replace.extended.simple_delimiter.perl","patterns":[{"include":"#escaped_char"}]},{"begin":"(.)","captures":{"0":{"name":"punctuation.definition.string.perl"}},"end":"\\\\1(?=[acdegilmoprsu]*x[acdegilmoprsu]*)\\\\b","name":"string.regexp.replace.extended.simple_delimiter.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"}]}]},{"begin":"(?<=[\\\\&({|~]|if|unless|^)\\\\s*((/))","beginCaptures":{"1":{"name":"string.regexp.find.perl"},"2":{"name":"punctuation.definition.string.perl"}},"contentName":"string.regexp.find.perl","end":"((\\\\1([acdegil-prsux]*)))(?=(\\\\s+\\\\S|\\\\s*[#),;{}]|\\\\s*$))","endCaptures":{"1":{"name":"string.regexp.find.perl"},"2":{"name":"punctuation.definition.string.perl"},"3":{"name":"keyword.control.regexp-option.perl"}},"patterns":[{"match":"\\\\$(?=/)","name":"keyword.control.anchor.perl"},{"include":"#escaped_char"},{"include":"#variable"}]},{"captures":{"1":{"name":"constant.other.key.perl"}},"match":"\\\\b(\\\\w+)\\\\s*(?==>)"},{"match":"(?<=\\\\{)\\\\s*\\\\w+\\\\s*(?=})","name":"constant.other.bareword.perl"},{"captures":{"1":{"name":"keyword.control.perl"},"2":{"name":"entity.name.type.class.perl"}},"match":"^\\\\s*(package)\\\\s+([^;\\\\s]+)","name":"meta.class.perl"},{"captures":{"1":{"name":"storage.type.sub.perl"},"2":{"name":"entity.name.function.perl"},"3":{"name":"storage.type.method.perl"}},"match":"\\\\b(sub)(?:\\\\s+([-0-9A-Z_a-z]+))?\\\\s*(?:\\\\([$*;@]*\\\\))?[^{\\\\w]","name":"meta.function.perl"},{"captures":{"1":{"name":"entity.name.function.perl"},"2":{"name":"punctuation.definition.parameters.perl"},"3":{"name":"variable.parameter.function.perl"}},"match":"^\\\\s*(BEGIN|UNITCHECK|CHECK|INIT|END|DESTROY)\\\\b","name":"meta.function.perl"},{"begin":"^(?=(\\\\t| {4}))","end":"(?=[^\\\\t\\\\s])","name":"meta.leading-tabs","patterns":[{"captures":{"1":{"name":"meta.odd-tab"},"2":{"name":"meta.even-tab"}},"match":"(\\\\t| {4})(\\\\t| {4})?"}]},{"captures":{"1":{"name":"support.function.perl"},"2":{"name":"punctuation.definition.string.perl"},"5":{"name":"punctuation.definition.string.perl"},"8":{"name":"punctuation.definition.string.perl"}},"match":"\\\\b(tr|y)\\\\s*([^0-9A-Za-z\\\\s])(.*?)(?<!\\\\\\\\)(\\\\\\\\{2})*(\\\\2)(.*?)(?<!\\\\\\\\)(\\\\\\\\{2})*(\\\\2)","name":"string.regexp.replace.perl"},{"match":"\\\\b(__(?:FILE|LINE|PACKAGE|SUB)__)\\\\b","name":"constant.language.perl"},{"begin":"\\\\b(__(?:DATA__|END__))\\\\n?","beginCaptures":{"1":{"name":"constant.language.perl"}},"contentName":"comment.block.documentation.perl","end":"\\\\z","patterns":[{"include":"#pod"}]},{"match":"(?<!->)\\\\b(continue|default|die|do|else|elsif|exit|for|foreach|given|goto|if|last|next|redo|return|select|unless|until|wait|when|while|switch|case|require|use|eval)\\\\b","name":"keyword.control.perl"},{"match":"\\\\b(my|our|local)\\\\b","name":"storage.modifier.perl"},{"match":"(?<!\\\\w)-[ABCMORSTWXb-gklopr-uwxz]\\\\b","name":"keyword.operator.filetest.perl"},{"match":"\\\\b(and|or|xor|as|not)\\\\b","name":"keyword.operator.logical.perl"},{"match":"((?:<=|[-=])>)","name":"keyword.operator.comparison.perl"},{"include":"#heredoc"},{"begin":"\\\\bqq\\\\s*([^(<\\\\[{\\\\w\\\\s])","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"\\\\1","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.other.qq.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"}]},{"begin":"\\\\bqx\\\\s*([^'(<\\\\[{\\\\w\\\\s])","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"\\\\1","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.interpolated.qx.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"}]},{"begin":"\\\\bqx\\\\s*'","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"'","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.interpolated.qx.single-quote.perl","patterns":[{"include":"#escaped_char"}]},{"begin":"\\"","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"\\"","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.double.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"}]},{"begin":"(?<!->)\\\\bqw?\\\\s*([^(<\\\\[{\\\\w\\\\s])","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"\\\\1","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.other.q.perl"},{"begin":"'","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"'","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.single.perl","patterns":[{"match":"\\\\\\\\['\\\\\\\\]","name":"constant.character.escape.perl"}]},{"begin":"\`","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"\`","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.interpolated.perl","patterns":[{"include":"#escaped_char"},{"include":"#variable"}]},{"begin":"(?<!->)\\\\bqq\\\\s*\\\\(","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.other.qq-paren.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_parens_interpolated"},{"include":"#variable"}]},{"begin":"\\\\bqq\\\\s*\\\\{","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"}","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.other.qq-brace.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_braces_interpolated"},{"include":"#variable"}]},{"begin":"\\\\bqq\\\\s*\\\\[","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"]","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.other.qq-bracket.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_brackets_interpolated"},{"include":"#variable"}]},{"begin":"\\\\bqq\\\\s*<","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":">","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.other.qq-ltgt.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_ltgt_interpolated"},{"include":"#variable"}]},{"begin":"(?<!->)\\\\bqx\\\\s*\\\\(","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.interpolated.qx-paren.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_parens_interpolated"},{"include":"#variable"}]},{"begin":"\\\\bqx\\\\s*\\\\{","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"}","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.interpolated.qx-brace.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_braces_interpolated"},{"include":"#variable"}]},{"begin":"\\\\bqx\\\\s*\\\\[","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"]","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.interpolated.qx-bracket.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_brackets_interpolated"},{"include":"#variable"}]},{"begin":"\\\\bqx\\\\s*<","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":">","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.interpolated.qx-ltgt.perl","patterns":[{"include":"#escaped_char"},{"include":"#nested_ltgt_interpolated"},{"include":"#variable"}]},{"begin":"(?<!->)\\\\bqw?\\\\s*\\\\(","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.other.q-paren.perl","patterns":[{"include":"#nested_parens"}]},{"begin":"\\\\bqw?\\\\s*\\\\{","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"}","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.other.q-brace.perl","patterns":[{"include":"#nested_braces"}]},{"begin":"\\\\bqw?\\\\s*\\\\[","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"]","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.other.q-bracket.perl","patterns":[{"include":"#nested_brackets"}]},{"begin":"\\\\bqw?\\\\s*<","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":">","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.quoted.other.q-ltgt.perl","patterns":[{"include":"#nested_ltgt"}]},{"begin":"^__\\\\w+__","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.perl"}},"end":"$","endCaptures":{"0":{"name":"punctuation.definition.string.end.perl"}},"name":"string.unquoted.program-block.perl"},{"begin":"\\\\b(format)\\\\s+(\\\\w+)\\\\s*=","beginCaptures":{"1":{"name":"support.function.perl"},"2":{"name":"entity.name.function.format.perl"}},"end":"^\\\\.\\\\s*$","name":"meta.format.perl","patterns":[{"include":"#line_comment"},{"include":"#variable"}]},{"captures":{"1":{"name":"support.function.perl"},"2":{"name":"entity.name.function.perl"}},"match":"\\\\b(x)\\\\s*(\\\\d+)\\\\b"},{"match":"\\\\b(ARGV|DATA|ENV|SIG|STDERR|STDIN|STDOUT|atan2|bind|binmode|bless|caller|chdir|chmod|chomp|chop|chown|chr|chroot|close|closedir|cmp|connect|cos|crypt|dbmclose|dbmopen|defined|delete|dump|each|endgrent|endhostent|endnetent|endprotoent|endpwent|endservent|eof|eq|eval|exec|exists|exp|fcntl|fileno|flock|fork|formline|ge|getc|getgrent|getgrgid|getgrnam|gethostbyaddr|gethostbyname|gethostent|getlogin|getnetbyaddr|getnetbyname|getnetent|getpeername|getpgrp|getppid|getpriority|getprotobyname|getprotobynumber|getprotoent|getpwent|getpwnam|getpwuid|getservbyname|getservbyport|getservent|getsockname|getsockopt|glob|gmtime|grep|gt|hex|import|index|int|ioctl|join|keys|kill|lc|lcfirst|le|length|link|listen|local|localtime|log|lstat|lt|m|map|mkdir|msgctl|msgget|msgrcv|msgsnd|ne|no|oct|open|opendir|ord|pack|pipe|pop|pos|printf??|push|quotemeta|rand|read|readdir|readlink|recv|ref|rename|reset|reverse|rewinddir|rindex|rmdir|s|say|scalar|seek|seekdir|semctl|semget|semop|send|setgrent|sethostent|setnetent|setpgrp|setpriority|setprotoent|setpwent|setservent|setsockopt|shift|shmctl|shmget|shmread|shmwrite|shutdown|sin|sleep|socket|socketpair|sort|splice|split|sprintf|sqrt|srand|stat|study|substr|symlink|syscall|sysopen|sysread|system|syswrite|tell|telldir|tied??|times??|tr|truncate|uc|ucfirst|umask|undef|unlink|unpack|unshift|untie|utime|values|vec|waitpid|wantarray|warn|write|y)\\\\b","name":"support.function.perl"},{"captures":{"1":{"name":"punctuation.section.scope.begin.perl"},"2":{"name":"punctuation.section.scope.end.perl"}},"match":"(\\\\{)(})"},{"captures":{"1":{"name":"punctuation.section.scope.begin.perl"},"2":{"name":"punctuation.section.scope.end.perl"}},"match":"(\\\\()(\\\\))"}],"repository":{"escaped_char":{"patterns":[{"match":"\\\\\\\\\\\\d+","name":"constant.character.escape.perl"},{"match":"\\\\\\\\c[^\\\\\\\\\\\\s]","name":"constant.character.escape.perl"},{"match":"\\\\\\\\g(?:\\\\{(?:\\\\w*|-\\\\d+)}|\\\\d+)","name":"constant.character.escape.perl"},{"match":"\\\\\\\\k(?:\\\\{\\\\w*}|<\\\\w*>|'\\\\w*')","name":"constant.character.escape.perl"},{"match":"\\\\\\\\N\\\\{[^}]*}","name":"constant.character.escape.perl"},{"match":"\\\\\\\\o\\\\{\\\\d*}","name":"constant.character.escape.perl"},{"match":"\\\\\\\\[Pp](?:\\\\{\\\\w*}|P)","name":"constant.character.escape.perl"},{"match":"\\\\\\\\x(?:[0-9A-Za-z]{2}|\\\\{\\\\w*})?","name":"constant.character.escape.perl"},{"match":"\\\\\\\\.","name":"constant.character.escape.perl"}]},"heredoc":{"patterns":[{"begin":"((((<<(~)?) *')(HTML)(')))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.raw.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.raw.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.raw.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.html","patterns":[{"begin":"^","end":"\\\\n","name":"text.html.basic","patterns":[{"include":"text.html.basic"}]}]},{"begin":"((((<<(~)?) *')(XML)(')))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.raw.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.raw.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.raw.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.xml","patterns":[{"begin":"^","end":"\\\\n","name":"text.xml","patterns":[{"include":"text.xml"}]}]},{"begin":"((((<<(~)?) *')(CSS)(')))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.raw.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.raw.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.raw.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.css","patterns":[{"begin":"^","end":"\\\\n","name":"source.css","patterns":[{"include":"source.css"}]}]},{"begin":"((((<<(~)?) *')(JAVASCRIPT)(')))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.raw.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.raw.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.raw.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.js","patterns":[{"begin":"^","end":"\\\\n","name":"source.js","patterns":[{"include":"source.js"}]}]},{"begin":"((((<<(~)?) *')(SQL)(')))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.raw.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.raw.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.raw.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.sql","patterns":[{"begin":"^","end":"\\\\n","name":"source.sql","patterns":[{"include":"source.sql"}]}]},{"begin":"((((<<(~)?) *')(POSTSCRIPT)(')))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.raw.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.raw.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.raw.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.postscript","patterns":[{"begin":"^","end":"\\\\n","name":"source.postscript","patterns":[{"include":"source.postscript"}]}]},{"begin":"((((<<(~)?) *')([^']*)(')))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.raw.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.raw.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.raw.perl"},"3":{"name":"punctuation.definition.string.end.perl"}}},{"begin":"((((<<(~)?) *\\\\\\\\)((?![ $(=\\\\d])[^\\"'),;\`\\\\s]*)()))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.raw.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.raw.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.raw.perl"},"3":{"name":"punctuation.definition.string.end.perl"}}},{"begin":"((((<<(~)?) *\\")(HTML)(\\")))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.html","patterns":[{"begin":"^","end":"\\\\n","name":"text.html.basic","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"text.html.basic"}]}]},{"begin":"((((<<(~)?) *\\")(XML)(\\")))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.xml","patterns":[{"begin":"^","end":"\\\\n","name":"text.xml","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"text.xml"}]}]},{"begin":"((((<<(~)?) *\\")(CSS)(\\")))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.css","patterns":[{"begin":"^","end":"\\\\n","name":"source.css","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"source.css"}]}]},{"begin":"((((<<(~)?) *\\")(JAVASCRIPT)(\\")))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.js","patterns":[{"begin":"^","end":"\\\\n","name":"source.js","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"source.js"}]}]},{"begin":"((((<<(~)?) *\\")(SQL)(\\")))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.sql","patterns":[{"begin":"^","end":"\\\\n","name":"source.sql","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"source.sql"}]}]},{"begin":"((((<<(~)?) *\\")(POSTSCRIPT)(\\")))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.postscript","patterns":[{"begin":"^","end":"\\\\n","name":"source.postscript","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"source.postscript"}]}]},{"begin":"((((<<(~)?) *\\")([^\\"]*)(\\")))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"patterns":[{"include":"#escaped_char"},{"include":"#variable"}]},{"begin":"((((<<(~)?) *)(HTML)()))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.html","patterns":[{"begin":"^","end":"\\\\n","name":"text.html.basic","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"text.html.basic"}]}]},{"begin":"((((<<(~)?) *)(XML)()))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.xml","patterns":[{"begin":"^","end":"\\\\n","name":"text.xml","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"text.xml"}]}]},{"begin":"((((<<(~)?) *)(CSS)()))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.css","patterns":[{"begin":"^","end":"\\\\n","name":"source.css","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"source.css"}]}]},{"begin":"((((<<(~)?) *)(JAVASCRIPT)()))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.js","patterns":[{"begin":"^","end":"\\\\n","name":"source.js","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"source.js"}]}]},{"begin":"((((<<(~)?) *)(SQL)()))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.sql","patterns":[{"begin":"^","end":"\\\\n","name":"source.sql","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"source.sql"}]}]},{"begin":"((((<<(~)?) *)(POSTSCRIPT)()))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"name":"meta.embedded.block.postscript","patterns":[{"begin":"^","end":"\\\\n","name":"source.postscript","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"source.postscript"}]}]},{"begin":"((((<<(~)?) *)((?![ $(=\\\\d])[^\\"'),;\`\\\\s]*)()))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.interpolated.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"patterns":[{"include":"#escaped_char"},{"include":"#variable"}]},{"begin":"((((<<(~)?) *\`)([^\`]*)(\`)))(.*)\\\\n?","beginCaptures":{"1":{"name":"string.unquoted.heredoc.interpolated.perl"},"2":{"name":"punctuation.definition.string.begin.perl"},"3":{"name":"punctuation.definition.delimiter.begin.perl"},"7":{"name":"punctuation.definition.delimiter.end.perl"},"8":{"patterns":[{"include":"$self"}]}},"contentName":"string.unquoted.heredoc.shell.perl","end":"^((?!\\\\5)\\\\s+)?((\\\\6))$","endCaptures":{"2":{"name":"string.unquoted.heredoc.interpolated.perl"},"3":{"name":"punctuation.definition.string.end.perl"}},"patterns":[{"include":"#escaped_char"},{"include":"#variable"}]}]},"line_comment":{"patterns":[{"begin":"(^[\\\\t ]+)?(?=#)","beginCaptures":{"1":{"name":"punctuation.whitespace.comment.leading.perl"}},"end":"(?!\\\\G)","patterns":[{"begin":"#","beginCaptures":{"0":{"name":"punctuation.definition.comment.perl"}},"end":"\\\\n","name":"comment.line.number-sign.perl"}]}]},"nested_braces":{"begin":"\\\\{","captures":{"1":{"name":"punctuation.section.scope.perl"}},"end":"}","patterns":[{"include":"#escaped_char"},{"include":"#nested_braces"}]},"nested_braces_interpolated":{"begin":"\\\\{","captures":{"1":{"name":"punctuation.section.scope.perl"}},"end":"}","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_braces_interpolated"}]},"nested_brackets":{"begin":"\\\\[","captures":{"1":{"name":"punctuation.section.scope.perl"}},"end":"]","patterns":[{"include":"#escaped_char"},{"include":"#nested_brackets"}]},"nested_brackets_interpolated":{"begin":"\\\\[","captures":{"1":{"name":"punctuation.section.scope.perl"}},"end":"]","patterns":[{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_brackets_interpolated"}]},"nested_ltgt":{"begin":"<","captures":{"1":{"name":"punctuation.section.scope.perl"}},"end":">","patterns":[{"include":"#nested_ltgt"}]},"nested_ltgt_interpolated":{"begin":"<","captures":{"1":{"name":"punctuation.section.scope.perl"}},"end":">","patterns":[{"include":"#variable"},{"include":"#nested_ltgt_interpolated"}]},"nested_parens":{"begin":"\\\\(","captures":{"1":{"name":"punctuation.section.scope.perl"}},"end":"\\\\)","patterns":[{"include":"#escaped_char"},{"include":"#nested_parens"}]},"nested_parens_interpolated":{"begin":"\\\\(","captures":{"1":{"name":"punctuation.section.scope.perl"}},"end":"\\\\)","patterns":[{"match":"\\\\$(?=[^'(<\\\\[{\\\\s\\\\w])","name":"keyword.control.anchor.perl"},{"include":"#escaped_char"},{"include":"#variable"},{"include":"#nested_parens_interpolated"}]},"pod":{"patterns":[{"match":"^=(pod|back|cut)\\\\b","name":"storage.type.class.pod.perl"},{"begin":"^(=begin)\\\\s+(html)\\\\s*$","beginCaptures":{"1":{"name":"storage.type.class.pod.perl"},"2":{"name":"variable.other.pod.perl"}},"contentName":"text.embedded.html.basic","end":"^(?:(=end)\\\\s+(html)|(?==cut))","endCaptures":{"1":{"name":"storage.type.class.pod.perl"},"2":{"name":"variable.other.pod.perl"}},"name":"meta.embedded.pod.perl","patterns":[{"include":"text.html.basic"}]},{"captures":{"1":{"name":"storage.type.class.pod.perl"},"2":{"name":"variable.other.pod.perl","patterns":[{"include":"#pod-formatting"}]}},"match":"^(=(?:head[1-4]|item|over|encoding|begin|end|for))\\\\b\\\\s*(.*)"},{"include":"#pod-formatting"}]},"pod-formatting":{"patterns":[{"captures":{"1":{"name":"markup.italic.pod.perl"},"2":{"name":"markup.italic.pod.perl"}},"match":"I(?:<([^<>]+)>|<+(\\\\s+(?:(?<!\\\\s)>|[^>])+\\\\s+)>+)","name":"entity.name.type.instance.pod.perl"},{"captures":{"1":{"name":"markup.bold.pod.perl"},"2":{"name":"markup.bold.pod.perl"}},"match":"B(?:<([^<>]+)>|<+(\\\\s+(?:(?<!\\\\s)>|[^>])+\\\\s+)>+)","name":"entity.name.type.instance.pod.perl"},{"captures":{"1":{"name":"markup.raw.pod.perl"},"2":{"name":"markup.raw.pod.perl"}},"match":"C(?:<([^<>]+)>|<+(\\\\\\\\s+(?:(?<!\\\\\\\\s)>|[^>])+\\\\\\\\s+)>+)","name":"entity.name.type.instance.pod.perl"},{"captures":{"1":{"name":"markup.underline.link.hyperlink.pod.perl"}},"match":"L<([^>]+)>","name":"entity.name.type.instance.pod.perl"},{"match":"[EFSXZ]<[^>]*>","name":"entity.name.type.instance.pod.perl"}]},"variable":{"patterns":[{"captures":{"1":{"name":"punctuation.definition.variable.perl"}},"match":"(\\\\$)&(?![0-9A-Z_a-z])","name":"variable.other.regexp.match.perl"},{"captures":{"1":{"name":"punctuation.definition.variable.perl"}},"match":"(\\\\$)\`(?![0-9A-Z_a-z])","name":"variable.other.regexp.pre-match.perl"},{"captures":{"1":{"name":"punctuation.definition.variable.perl"}},"match":"(\\\\$)'(?![0-9A-Z_a-z])","name":"variable.other.regexp.post-match.perl"},{"captures":{"1":{"name":"punctuation.definition.variable.perl"}},"match":"(\\\\$)\\\\+(?![0-9A-Z_a-z])","name":"variable.other.regexp.last-paren-match.perl"},{"captures":{"1":{"name":"punctuation.definition.variable.perl"}},"match":"(\\\\$)\\"(?![0-9A-Z_a-z])","name":"variable.other.readwrite.list-separator.perl"},{"captures":{"1":{"name":"punctuation.definition.variable.perl"}},"match":"(\\\\$)0(?![0-9A-Z_a-z])","name":"variable.other.predefined.program-name.perl"},{"captures":{"1":{"name":"punctuation.definition.variable.perl"}},"match":"(\\\\$)[!#$%()*,-/:-@\\\\[-_ab|~](?![0-9A-Z_a-z])","name":"variable.other.predefined.perl"},{"captures":{"1":{"name":"punctuation.definition.variable.perl"}},"match":"(\\\\$)[0-9]+(?![0-9A-Z_a-z])","name":"variable.other.subpattern.perl"},{"captures":{"1":{"name":"punctuation.definition.variable.perl"}},"match":"([$%@](#)?)([$7A-Za-z]|::)([$0-9A-Z_a-z]|::)*\\\\b","name":"variable.other.readwrite.global.perl"},{"captures":{"1":{"name":"punctuation.definition.variable.perl"},"2":{"name":"punctuation.definition.variable.perl"}},"match":"(\\\\$\\\\{)(?:[$7A-Za-z]|::)(?:[$0-9A-Z_a-z]|::)*(})","name":"variable.other.readwrite.global.perl"},{"captures":{"1":{"name":"punctuation.definition.variable.perl"}},"match":"([$%@](#)?)[0-9_]\\\\b","name":"variable.other.readwrite.global.special.perl"}]}},"scopeName":"source.perl","embeddedLangs":["html","xml","css","javascript","sql"]}`)),o=[...r,...i,...t,...n,...e,a];export{o as default};
|
dist/assets/{php-Btwm84O4.js → php-B7QoxYrN.js}
RENAMED
|
The diff for this file is too large to render.
See raw diff
|
|
|
dist/assets/{ruby--A1ICNIQ.js → ruby-CJjou4ZR.js}
RENAMED
|
The diff for this file is too large to render.
See raw diff
|
|
|
dist/assets/{tsx-qUOhHegv.js → tsx-DD_ZyZUf.js}
RENAMED
|
The diff for this file is too large to render.
See raw diff
|
|
|
dist/assets/{typescript-T-I1Y_bC.js → typescript-D7sEy3Rx.js}
RENAMED
|
The diff for this file is too large to render.
See raw diff
|
|
|
dist/assets/{xml-CkTAj7zh.js → xml-DoonlvgL.js}
RENAMED
|
@@ -1 +1 @@
|
|
| 1 |
-
import{t as e}from"./java-
|
|
|
|
| 1 |
+
import{t as e}from"./java-DisdHHsr.js";var t=Object.freeze(JSON.parse(`{"displayName":"XML","name":"xml","patterns":[{"begin":"(<\\\\?)\\\\s*([-0-9A-Z_a-z]+)","captures":{"1":{"name":"punctuation.definition.tag.xml"},"2":{"name":"entity.name.tag.xml"}},"end":"(\\\\?>)","name":"meta.tag.preprocessor.xml","patterns":[{"match":" ([-A-Za-z]+)","name":"entity.other.attribute-name.xml"},{"include":"#doublequotedString"},{"include":"#singlequotedString"}]},{"begin":"(<!)(DOCTYPE)\\\\s+([:A-Z_a-z][-.0-:A-Z_a-z]*)","captures":{"1":{"name":"punctuation.definition.tag.xml"},"2":{"name":"keyword.other.doctype.xml"},"3":{"name":"variable.language.documentroot.xml"}},"end":"\\\\s*(>)","name":"meta.tag.sgml.doctype.xml","patterns":[{"include":"#internalSubset"}]},{"include":"#comments"},{"begin":"(<)((?:([-0-9A-Z_a-z]+)(:))?([-0-:A-Z_a-z]+))(?=(\\\\s[^>]*)?></\\\\2>)","beginCaptures":{"1":{"name":"punctuation.definition.tag.xml"},"2":{"name":"entity.name.tag.xml"},"3":{"name":"entity.name.tag.namespace.xml"},"4":{"name":"punctuation.separator.namespace.xml"},"5":{"name":"entity.name.tag.localname.xml"}},"end":"(>)(</)((?:([-0-9A-Z_a-z]+)(:))?([-0-:A-Z_a-z]+))(>)","endCaptures":{"1":{"name":"punctuation.definition.tag.xml"},"2":{"name":"punctuation.definition.tag.xml"},"3":{"name":"entity.name.tag.xml"},"4":{"name":"entity.name.tag.namespace.xml"},"5":{"name":"punctuation.separator.namespace.xml"},"6":{"name":"entity.name.tag.localname.xml"},"7":{"name":"punctuation.definition.tag.xml"}},"name":"meta.tag.no-content.xml","patterns":[{"include":"#tagStuff"}]},{"begin":"(</?)(?:([-.\\\\w]+)((:)))?([-.:\\\\w]+)","captures":{"1":{"name":"punctuation.definition.tag.xml"},"2":{"name":"entity.name.tag.namespace.xml"},"3":{"name":"entity.name.tag.xml"},"4":{"name":"punctuation.separator.namespace.xml"},"5":{"name":"entity.name.tag.localname.xml"}},"end":"(/?>)","name":"meta.tag.xml","patterns":[{"include":"#tagStuff"}]},{"include":"#entity"},{"include":"#bare-ampersand"},{"begin":"<%@","beginCaptures":{"0":{"name":"punctuation.section.embedded.begin.xml"}},"end":"%>","endCaptures":{"0":{"name":"punctuation.section.embedded.end.xml"}},"name":"source.java-props.embedded.xml","patterns":[{"match":"page|include|taglib","name":"keyword.other.page-props.xml"}]},{"begin":"<%[!=]?(?!--)","beginCaptures":{"0":{"name":"punctuation.section.embedded.begin.xml"}},"end":"(?!--)%>","endCaptures":{"0":{"name":"punctuation.section.embedded.end.xml"}},"name":"source.java.embedded.xml","patterns":[{"include":"source.java"}]},{"begin":"<!\\\\[CDATA\\\\[","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.xml"}},"end":"]]>","endCaptures":{"0":{"name":"punctuation.definition.string.end.xml"}},"name":"string.unquoted.cdata.xml"}],"repository":{"EntityDecl":{"begin":"(<!)(ENTITY)\\\\s+(%\\\\s+)?([:A-Z_a-z][-.0-:A-Z_a-z]*)(\\\\s+(?:SYSTEM|PUBLIC)\\\\s+)?","captures":{"1":{"name":"punctuation.definition.tag.xml"},"2":{"name":"keyword.other.entity.xml"},"3":{"name":"punctuation.definition.entity.xml"},"4":{"name":"variable.language.entity.xml"},"5":{"name":"keyword.other.entitytype.xml"}},"end":"(>)","patterns":[{"include":"#doublequotedString"},{"include":"#singlequotedString"}]},"bare-ampersand":{"match":"&","name":"invalid.illegal.bad-ampersand.xml"},"comments":{"patterns":[{"begin":"<%--","captures":{"0":{"name":"punctuation.definition.comment.xml"},"end":"--%>","name":"comment.block.xml"}},{"begin":"<!--","captures":{"0":{"name":"punctuation.definition.comment.xml"}},"end":"-->","name":"comment.block.xml","patterns":[{"begin":"--(?!>)","captures":{"0":{"name":"invalid.illegal.bad-comments-or-CDATA.xml"}}}]}]},"doublequotedString":{"begin":"\\"","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.xml"}},"end":"\\"","endCaptures":{"0":{"name":"punctuation.definition.string.end.xml"}},"name":"string.quoted.double.xml","patterns":[{"include":"#entity"},{"include":"#bare-ampersand"}]},"entity":{"captures":{"1":{"name":"punctuation.definition.constant.xml"},"3":{"name":"punctuation.definition.constant.xml"}},"match":"(&)([:A-Z_a-z][-.0-:A-Z_a-z]*|#[0-9]+|#x\\\\h+)(;)","name":"constant.character.entity.xml"},"internalSubset":{"begin":"(\\\\[)","captures":{"1":{"name":"punctuation.definition.constant.xml"}},"end":"(])","name":"meta.internalsubset.xml","patterns":[{"include":"#EntityDecl"},{"include":"#parameterEntity"},{"include":"#comments"}]},"parameterEntity":{"captures":{"1":{"name":"punctuation.definition.constant.xml"},"3":{"name":"punctuation.definition.constant.xml"}},"match":"(%)([:A-Z_a-z][-.0-:A-Z_a-z]*)(;)","name":"constant.character.parameter-entity.xml"},"singlequotedString":{"begin":"'","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.xml"}},"end":"'","endCaptures":{"0":{"name":"punctuation.definition.string.end.xml"}},"name":"string.quoted.single.xml","patterns":[{"include":"#entity"},{"include":"#bare-ampersand"}]},"tagStuff":{"patterns":[{"captures":{"1":{"name":"entity.other.attribute-name.namespace.xml"},"2":{"name":"entity.other.attribute-name.xml"},"3":{"name":"punctuation.separator.namespace.xml"},"4":{"name":"entity.other.attribute-name.localname.xml"}},"match":"(?:^|\\\\s+)(?:([-.\\\\w]+)((:)))?([-.:\\\\w]+)\\\\s*="},{"include":"#doublequotedString"},{"include":"#singlequotedString"}]}},"scopeName":"text.xml","embeddedLangs":["java"]}`)),n=[...e,t];export{n as default};
|
dist/index.html
CHANGED
|
@@ -10,8 +10,8 @@
|
|
| 10 |
content="Bonsai Chat runs private WebGPU language models locally in your browser."
|
| 11 |
/>
|
| 12 |
<title>Bonsai Chat · WebGPU</title>
|
| 13 |
-
<script type="module" crossorigin src="/assets/index-
|
| 14 |
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
| 15 |
</head>
|
| 16 |
<body>
|
| 17 |
<div id="root"></div>
|
|
|
|
| 10 |
content="Bonsai Chat runs private WebGPU language models locally in your browser."
|
| 11 |
/>
|
| 12 |
<title>Bonsai Chat · WebGPU</title>
|
| 13 |
+
<script type="module" crossorigin src="/assets/index-Qym19Dm5.js"></script>
|
| 14 |
+
<link rel="stylesheet" crossorigin href="/assets/index-B4DG8rDO.css">
|
| 15 |
</head>
|
| 16 |
<body>
|
| 17 |
<div id="root"></div>
|
nginx.conf
CHANGED
|
@@ -34,6 +34,15 @@ http {
|
|
| 34 |
return 200 "ok\n";
|
| 35 |
}
|
| 36 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
location / {
|
| 38 |
try_files $uri $uri/ /index.html;
|
| 39 |
}
|
|
|
|
| 34 |
return 200 "ok\n";
|
| 35 |
}
|
| 36 |
|
| 37 |
+
location = /artifact-sw.js {
|
| 38 |
+
try_files /artifact-sw.js =404;
|
| 39 |
+
add_header Cache-Control "no-cache, no-store, must-revalidate" always;
|
| 40 |
+
add_header Service-Worker-Allowed "/" always;
|
| 41 |
+
add_header Cross-Origin-Embedder-Policy "require-corp" always;
|
| 42 |
+
add_header Cross-Origin-Opener-Policy "same-origin" always;
|
| 43 |
+
add_header Cross-Origin-Resource-Policy "cross-origin" always;
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
location / {
|
| 47 |
try_files $uri $uri/ /index.html;
|
| 48 |
}
|
public/artifact-sw.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const ARTIFACT_CACHE = 'bonsai-artifact-deployments-v2';
|
| 2 |
+
const ROUTE_MARKER = '/__bonsai_artifact__/';
|
| 3 |
+
|
| 4 |
+
self.addEventListener('install', (event) => {
|
| 5 |
+
event.waitUntil(self.skipWaiting());
|
| 6 |
+
});
|
| 7 |
+
|
| 8 |
+
self.addEventListener('activate', (event) => {
|
| 9 |
+
event.waitUntil(self.clients.claim());
|
| 10 |
+
});
|
| 11 |
+
|
| 12 |
+
self.addEventListener('fetch', (event) => {
|
| 13 |
+
const url = new URL(event.request.url);
|
| 14 |
+
const marker = url.pathname.indexOf(ROUTE_MARKER);
|
| 15 |
+
if (marker < 0 || event.request.method !== 'GET') return;
|
| 16 |
+
event.respondWith((async () => {
|
| 17 |
+
const cache = await caches.open(ARTIFACT_CACHE);
|
| 18 |
+
const exact = await cache.match(event.request, { ignoreSearch: true });
|
| 19 |
+
if (exact) return exact;
|
| 20 |
+
if (event.request.mode === 'navigate') {
|
| 21 |
+
const route = url.pathname.slice(0, marker + ROUTE_MARKER.length);
|
| 22 |
+
const tail = url.pathname.slice(marker + ROUTE_MARKER.length).split('/').filter(Boolean);
|
| 23 |
+
if (tail.length >= 2) {
|
| 24 |
+
const root = `${url.origin}${route}${tail[0]}/${tail[1]}/`;
|
| 25 |
+
const fallback = await cache.match(root, { ignoreSearch: true });
|
| 26 |
+
if (fallback) return fallback;
|
| 27 |
+
}
|
| 28 |
+
}
|
| 29 |
+
return new Response('Artifact file not found', {
|
| 30 |
+
status: 404,
|
| 31 |
+
headers: {
|
| 32 |
+
'Access-Control-Allow-Origin': '*',
|
| 33 |
+
'Cache-Control': 'no-store',
|
| 34 |
+
'Content-Type': 'text/plain; charset=utf-8',
|
| 35 |
+
'Cross-Origin-Resource-Policy': 'cross-origin',
|
| 36 |
+
'X-Content-Type-Options': 'nosniff',
|
| 37 |
+
},
|
| 38 |
+
});
|
| 39 |
+
})());
|
| 40 |
+
});
|
scripts/test-artifact-csp.mjs
CHANGED
|
@@ -64,6 +64,12 @@ try {
|
|
| 64 |
|
| 65 |
browser = await chromium.launch({ headless: true });
|
| 66 |
const page = await browser.newPage();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
await page.goto(`http://127.0.0.1:${viteAddress.port}/artifact-csp-probe.html`);
|
| 68 |
|
| 69 |
const payloads = [
|
|
@@ -94,8 +100,12 @@ try {
|
|
| 94 |
}, { artifactId: payload.id, sourceHtml: payload.html, shouldReject: payload.rejected });
|
| 95 |
}
|
| 96 |
|
| 97 |
-
const
|
| 98 |
-
const {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
const artifact = prepareHtmlArtifact(
|
| 100 |
`<!doctype html><html><head><title>Live artifact</title><style>#output{color:rgb(17, 34, 51);background:rgb(238, 244, 240)}</style></head><body><section id="output">Waiting</section><script>
|
| 101 |
document.querySelector('#output').textContent = 'JavaScript artifact rendered';
|
|
@@ -106,16 +116,45 @@ try {
|
|
| 106 |
'Live artifact probe',
|
| 107 |
'live-evaluation',
|
| 108 |
);
|
| 109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
}, { blockedUrl: `${probeBaseUrl}/probe/fetch` });
|
|
|
|
| 111 |
if (passingEvaluation.status !== 'passed') {
|
| 112 |
-
throw new Error(`Passing artifact reported failure: ${JSON.stringify(
|
| 113 |
}
|
| 114 |
if (!passingEvaluation.entries.some((entry) => entry.message.includes('artifact booted'))
|
| 115 |
|| !passingEvaluation.entries.some((entry) => entry.message.includes('storage blocked'))
|
| 116 |
|| passingEvaluation.dom?.textPreview !== 'JavaScript artifact rendered') {
|
| 117 |
throw new Error(`Passing artifact diagnostics were incomplete: ${JSON.stringify(passingEvaluation)}`);
|
| 118 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
|
| 120 |
const failingEvaluation = await page.evaluate(async () => {
|
| 121 |
const { evaluateHtmlArtifact, prepareHtmlArtifact } = await import('/src/lib/artifact-runtime.ts');
|
|
@@ -134,26 +173,60 @@ try {
|
|
| 134 |
|
| 135 |
const lifecycle = await page.evaluate(async () => {
|
| 136 |
const { executeAgentTool } = await import('/src/lib/agent-tools.ts');
|
|
|
|
|
|
|
| 137 |
const context = { artifacts: new Map() };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
const create = await executeAgentTool({
|
| 139 |
-
id: '
|
| 140 |
type: 'function',
|
| 141 |
function: {
|
| 142 |
-
name: '
|
| 143 |
arguments: JSON.stringify({
|
| 144 |
-
title: '
|
| 145 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 146 |
}),
|
| 147 |
},
|
| 148 |
}, undefined, context);
|
|
|
|
|
|
|
| 149 |
const update = await executeAgentTool({
|
| 150 |
id: 'repair-call',
|
| 151 |
type: 'function',
|
| 152 |
function: {
|
| 153 |
-
name: '
|
| 154 |
arguments: JSON.stringify({
|
| 155 |
-
artifact_id:
|
| 156 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 157 |
}),
|
| 158 |
},
|
| 159 |
}, undefined, context);
|
|
@@ -162,7 +235,7 @@ try {
|
|
| 162 |
type: 'function',
|
| 163 |
function: {
|
| 164 |
name: 'artifact_test',
|
| 165 |
-
arguments: JSON.stringify({ artifact_id:
|
| 166 |
},
|
| 167 |
}, undefined, context);
|
| 168 |
const inspect = await executeAgentTool({
|
|
@@ -170,26 +243,81 @@ try {
|
|
| 170 |
type: 'function',
|
| 171 |
function: {
|
| 172 |
name: 'artifact_inspect',
|
| 173 |
-
arguments: JSON.stringify({
|
|
|
|
|
|
|
|
|
|
| 174 |
},
|
| 175 |
}, undefined, context);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 176 |
return {
|
| 177 |
-
create:
|
|
|
|
| 178 |
update: JSON.parse(update.output),
|
|
|
|
| 179 |
retest: JSON.parse(retest.output),
|
| 180 |
inspect: JSON.parse(inspect.output),
|
|
|
|
| 181 |
stableId: update.artifact?.id,
|
|
|
|
|
|
|
| 182 |
artifactCount: context.artifacts.size,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 183 |
};
|
| 184 |
});
|
| 185 |
if (lifecycle.create.evaluation.status !== 'failed'
|
|
|
|
| 186 |
|| lifecycle.update.evaluation.status !== 'passed'
|
|
|
|
| 187 |
|| lifecycle.retest.evaluation.status !== 'passed'
|
| 188 |
|| lifecycle.inspect.artifact.evaluation.status !== 'passed'
|
| 189 |
-
||
|
| 190 |
-
|| lifecycle.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 191 |
|| lifecycle.artifactCount !== 1) {
|
| 192 |
-
throw new Error(`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 193 |
}
|
| 194 |
|
| 195 |
await page.evaluate(async () => {
|
|
@@ -225,7 +353,7 @@ try {
|
|
| 225 |
|| staticRender.background !== 'rgb(238, 244, 240)') {
|
| 226 |
throw new Error(`Static HTML/CSS render failed: ${JSON.stringify(staticRender)}`);
|
| 227 |
}
|
| 228 |
-
console.log(`artifact runtime probe passed: ${payloads.length} network bypasses emitted 0 requests;
|
| 229 |
} finally {
|
| 230 |
await browser?.close();
|
| 231 |
await vite?.close();
|
|
|
|
| 64 |
|
| 65 |
browser = await chromium.launch({ headless: true });
|
| 66 |
const page = await browser.newPage();
|
| 67 |
+
const browserDiagnostics = [];
|
| 68 |
+
page.on('console', (message) => browserDiagnostics.push(`console:${message.type()}:${message.text()}`));
|
| 69 |
+
page.on('pageerror', (error) => browserDiagnostics.push(`pageerror:${error.message}`));
|
| 70 |
+
page.on('requestfailed', (request) => {
|
| 71 |
+
browserDiagnostics.push(`requestfailed:${request.url()}:${request.failure()?.errorText ?? 'unknown'}`);
|
| 72 |
+
});
|
| 73 |
await page.goto(`http://127.0.0.1:${viteAddress.port}/artifact-csp-probe.html`);
|
| 74 |
|
| 75 |
const payloads = [
|
|
|
|
| 100 |
}, { artifactId: payload.id, sourceHtml: payload.html, shouldReject: payload.rejected });
|
| 101 |
}
|
| 102 |
|
| 103 |
+
const passingProbe = await page.evaluate(async ({ blockedUrl }) => {
|
| 104 |
+
const {
|
| 105 |
+
deployArtifactDocument,
|
| 106 |
+
evaluateHtmlArtifact,
|
| 107 |
+
prepareHtmlArtifact,
|
| 108 |
+
} = await import('/src/lib/artifact-runtime.ts');
|
| 109 |
const artifact = prepareHtmlArtifact(
|
| 110 |
`<!doctype html><html><head><title>Live artifact</title><style>#output{color:rgb(17, 34, 51);background:rgb(238, 244, 240)}</style></head><body><section id="output">Waiting</section><script>
|
| 111 |
document.querySelector('#output').textContent = 'JavaScript artifact rendered';
|
|
|
|
| 116 |
'Live artifact probe',
|
| 117 |
'live-evaluation',
|
| 118 |
);
|
| 119 |
+
const runtimeMessages = [];
|
| 120 |
+
const observe = (event) => {
|
| 121 |
+
if (event.data?.channel === 'bonsai-artifact-runtime') {
|
| 122 |
+
runtimeMessages.push({
|
| 123 |
+
artifactId: event.data.artifactId,
|
| 124 |
+
phase: event.data.phase,
|
| 125 |
+
origin: event.origin,
|
| 126 |
+
});
|
| 127 |
+
}
|
| 128 |
+
};
|
| 129 |
+
window.addEventListener('message', observe);
|
| 130 |
+
const deployment = await deployArtifactDocument(artifact);
|
| 131 |
+
const deployedResponse = await fetch(deployment.publishedUrl);
|
| 132 |
+
const deployedSource = await deployedResponse.text();
|
| 133 |
+
const evaluation = await evaluateHtmlArtifact(artifact);
|
| 134 |
+
window.removeEventListener('message', observe);
|
| 135 |
+
return {
|
| 136 |
+
evaluation,
|
| 137 |
+
runtimeMessages,
|
| 138 |
+
deploymentUrl: deployment.publishedUrl,
|
| 139 |
+
deployedStatus: deployedResponse.status,
|
| 140 |
+
deployedContentType: deployedResponse.headers.get('content-type'),
|
| 141 |
+
deployedCsp: deployedResponse.headers.get('content-security-policy'),
|
| 142 |
+
deployedSourcePreview: deployedSource.slice(0, 500),
|
| 143 |
+
};
|
| 144 |
}, { blockedUrl: `${probeBaseUrl}/probe/fetch` });
|
| 145 |
+
const passingEvaluation = passingProbe.evaluation;
|
| 146 |
if (passingEvaluation.status !== 'passed') {
|
| 147 |
+
throw new Error(`Passing artifact reported failure: ${JSON.stringify({ ...passingProbe, browserDiagnostics })}`);
|
| 148 |
}
|
| 149 |
if (!passingEvaluation.entries.some((entry) => entry.message.includes('artifact booted'))
|
| 150 |
|| !passingEvaluation.entries.some((entry) => entry.message.includes('storage blocked'))
|
| 151 |
|| passingEvaluation.dom?.textPreview !== 'JavaScript artifact rendered') {
|
| 152 |
throw new Error(`Passing artifact diagnostics were incomplete: ${JSON.stringify(passingEvaluation)}`);
|
| 153 |
}
|
| 154 |
+
if (!passingProbe.deployedCsp?.includes("script-src 'none'")
|
| 155 |
+
|| passingProbe.deployedSourcePreview.includes('data-bonsai-artifact-runtime')) {
|
| 156 |
+
throw new Error(`Published same-host HTML was not inert: ${JSON.stringify(passingProbe)}`);
|
| 157 |
+
}
|
| 158 |
|
| 159 |
const failingEvaluation = await page.evaluate(async () => {
|
| 160 |
const { evaluateHtmlArtifact, prepareHtmlArtifact } = await import('/src/lib/artifact-runtime.ts');
|
|
|
|
| 173 |
|
| 174 |
const lifecycle = await page.evaluate(async () => {
|
| 175 |
const { executeAgentTool } = await import('/src/lib/agent-tools.ts');
|
| 176 |
+
const { artifactPreviewUrl } = await import('/src/lib/artifact-workspace.ts');
|
| 177 |
+
const { configureArtifactIframe } = await import('/src/lib/artifact-runtime.ts');
|
| 178 |
const context = { artifacts: new Map() };
|
| 179 |
+
const runtimeOrigins = [];
|
| 180 |
+
const recordRuntimeOrigin = (event) => {
|
| 181 |
+
if (event.data?.channel === 'bonsai-artifact-runtime') runtimeOrigins.push(event.origin);
|
| 182 |
+
};
|
| 183 |
+
window.addEventListener('message', recordRuntimeOrigin);
|
| 184 |
const create = await executeAgentTool({
|
| 185 |
+
id: 'deploy-call',
|
| 186 |
type: 'function',
|
| 187 |
function: {
|
| 188 |
+
name: 'artifact_deploy',
|
| 189 |
arguments: JSON.stringify({
|
| 190 |
+
title: 'Multi-file lifecycle',
|
| 191 |
+
files: [
|
| 192 |
+
{
|
| 193 |
+
path: 'index.html',
|
| 194 |
+
content: '<!doctype html><html><head><link rel="stylesheet" href="./styles/app.css"></head><body><main id="app">Starting</main><script type="module" src="./src/main.js"></script></body></html>',
|
| 195 |
+
},
|
| 196 |
+
{
|
| 197 |
+
path: 'styles/app.css',
|
| 198 |
+
content: '#app{color:rgb(17, 34, 51);background:rgb(238, 244, 240) url("../assets/logo.svg") no-repeat right center}',
|
| 199 |
+
},
|
| 200 |
+
{
|
| 201 |
+
path: 'src/main.js',
|
| 202 |
+
content: 'import { message } from "./message.js"; const config = await fetch("../data/config.json").then((response) => response.json()); const { suffix } = await import("./dynamic.js"); document.querySelector("#app").textContent = `${message}:${config.value}:${suffix}`; console.error("repair me");',
|
| 203 |
+
},
|
| 204 |
+
{ path: 'src/message.js', content: 'export const message = "Bonsai";' },
|
| 205 |
+
{ path: 'src/dynamic.js', content: 'export const suffix = "dynamic";' },
|
| 206 |
+
{ path: 'data/config.json', content: '{"value":"v1"}' },
|
| 207 |
+
{ path: 'assets/logo.svg', content: '<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8"><circle cx="4" cy="4" r="4" fill="#e34e37"/></svg>' },
|
| 208 |
+
{ path: 'obsolete.txt', content: 'remove me' },
|
| 209 |
+
],
|
| 210 |
}),
|
| 211 |
},
|
| 212 |
}, undefined, context);
|
| 213 |
+
const created = JSON.parse(create.output);
|
| 214 |
+
const artifactId = created.artifactId;
|
| 215 |
const update = await executeAgentTool({
|
| 216 |
id: 'repair-call',
|
| 217 |
type: 'function',
|
| 218 |
function: {
|
| 219 |
+
name: 'artifact_write',
|
| 220 |
arguments: JSON.stringify({
|
| 221 |
+
artifact_id: artifactId,
|
| 222 |
+
files: [
|
| 223 |
+
{
|
| 224 |
+
path: 'src/main.js',
|
| 225 |
+
content: 'import { message } from "./message.js"; const config = await fetch("../data/config.json").then((response) => response.json()); const { suffix } = await import("./dynamic.js"); document.querySelector("#app").textContent = `${message}:${config.value}:${suffix}`; console.log("multi-file ready");',
|
| 226 |
+
},
|
| 227 |
+
{ path: 'data/config.json', content: '{"value":"v2"}' },
|
| 228 |
+
],
|
| 229 |
+
delete_paths: ['obsolete.txt'],
|
| 230 |
}),
|
| 231 |
},
|
| 232 |
}, undefined, context);
|
|
|
|
| 235 |
type: 'function',
|
| 236 |
function: {
|
| 237 |
name: 'artifact_test',
|
| 238 |
+
arguments: JSON.stringify({ artifact_id: artifactId }),
|
| 239 |
},
|
| 240 |
}, undefined, context);
|
| 241 |
const inspect = await executeAgentTool({
|
|
|
|
| 243 |
type: 'function',
|
| 244 |
function: {
|
| 245 |
name: 'artifact_inspect',
|
| 246 |
+
arguments: JSON.stringify({
|
| 247 |
+
artifact_id: artifactId,
|
| 248 |
+
paths: ['src/main.js', 'data/config.json'],
|
| 249 |
+
}),
|
| 250 |
},
|
| 251 |
}, undefined, context);
|
| 252 |
+
window.removeEventListener('message', recordRuntimeOrigin);
|
| 253 |
+
const current = context.artifacts.get(artifactId);
|
| 254 |
+
const previewUrl = artifactPreviewUrl(current);
|
| 255 |
+
const iframe = document.createElement('iframe');
|
| 256 |
+
iframe.dataset.artifactId = artifactId;
|
| 257 |
+
configureArtifactIframe(iframe);
|
| 258 |
+
await new Promise((resolveLoad) => {
|
| 259 |
+
iframe.addEventListener('load', resolveLoad, { once: true });
|
| 260 |
+
iframe.srcdoc = current.sandboxedSource;
|
| 261 |
+
document.body.append(iframe);
|
| 262 |
+
});
|
| 263 |
+
const cacheRequests = (await Promise.all((await caches.keys()).map(async (cacheName) => {
|
| 264 |
+
const cache = await caches.open(cacheName);
|
| 265 |
+
return Promise.all((await cache.keys()).map((request) => request.url));
|
| 266 |
+
}))).flat();
|
| 267 |
return {
|
| 268 |
+
create: created,
|
| 269 |
+
createToolFailed: create.failed,
|
| 270 |
update: JSON.parse(update.output),
|
| 271 |
+
updateToolFailed: update.failed,
|
| 272 |
retest: JSON.parse(retest.output),
|
| 273 |
inspect: JSON.parse(inspect.output),
|
| 274 |
+
artifactId,
|
| 275 |
stableId: update.artifact?.id,
|
| 276 |
+
createToken: create.artifact?.runtimeToken,
|
| 277 |
+
updateToken: update.artifact?.runtimeToken,
|
| 278 |
artifactCount: context.artifacts.size,
|
| 279 |
+
previewUrl,
|
| 280 |
+
cacheRequests,
|
| 281 |
+
runtimeOrigins: [...new Set(runtimeOrigins)],
|
| 282 |
+
serviceWorkerControlled: Boolean(navigator.serviceWorker.controller),
|
| 283 |
};
|
| 284 |
});
|
| 285 |
if (lifecycle.create.evaluation.status !== 'failed'
|
| 286 |
+
|| lifecycle.createToolFailed
|
| 287 |
|| lifecycle.update.evaluation.status !== 'passed'
|
| 288 |
+
|| lifecycle.updateToolFailed
|
| 289 |
|| lifecycle.retest.evaluation.status !== 'passed'
|
| 290 |
|| lifecycle.inspect.artifact.evaluation.status !== 'passed'
|
| 291 |
+
|| lifecycle.create.fileCount !== 8
|
| 292 |
+
|| lifecycle.update.fileCount !== 7
|
| 293 |
+
|| lifecycle.update.workspace.storage !== 'opfs'
|
| 294 |
+
|| lifecycle.inspect.artifact.contents.length !== 2
|
| 295 |
+
|| !lifecycle.inspect.artifact.contents.some((file) => file.path === 'data/config.json' && file.content.includes('"v2"'))
|
| 296 |
+
|| lifecycle.stableId !== lifecycle.artifactId
|
| 297 |
+
|| lifecycle.createToken === lifecycle.updateToken
|
| 298 |
|| lifecycle.artifactCount !== 1) {
|
| 299 |
+
throw new Error(`Multi-file artifact lifecycle failed: ${JSON.stringify(lifecycle)}`);
|
| 300 |
+
}
|
| 301 |
+
if (!lifecycle.serviceWorkerControlled
|
| 302 |
+
|| lifecycle.runtimeOrigins.length !== 1
|
| 303 |
+
|| lifecycle.runtimeOrigins[0] !== 'null'
|
| 304 |
+
|| !lifecycle.previewUrl.includes('/__bonsai_artifact__/')
|
| 305 |
+
|| !lifecycle.cacheRequests.some((url) => url === lifecycle.previewUrl)
|
| 306 |
+
|| !lifecycle.cacheRequests.some((url) => url.endsWith('/src/main.js'))
|
| 307 |
+
|| !lifecycle.cacheRequests.some((url) => url.endsWith('/data/config.json'))) {
|
| 308 |
+
throw new Error(`Multi-file serving or opaque-origin guard failed: ${JSON.stringify(lifecycle)}`);
|
| 309 |
+
}
|
| 310 |
+
const multiFileApp = page.frameLocator(`iframe[data-artifact-id="${lifecycle.artifactId}"]`).locator('#app');
|
| 311 |
+
await multiFileApp.waitFor();
|
| 312 |
+
const multiFileRender = await multiFileApp.evaluate((element) => ({
|
| 313 |
+
text: element.textContent,
|
| 314 |
+
color: getComputedStyle(element).color,
|
| 315 |
+
background: getComputedStyle(element).backgroundColor,
|
| 316 |
+
}));
|
| 317 |
+
if (multiFileRender.text !== 'Bonsai:v2:dynamic'
|
| 318 |
+
|| multiFileRender.color !== 'rgb(17, 34, 51)'
|
| 319 |
+
|| multiFileRender.background !== 'rgb(238, 244, 240)') {
|
| 320 |
+
throw new Error(`Multi-file render failed: ${JSON.stringify(multiFileRender)}`);
|
| 321 |
}
|
| 322 |
|
| 323 |
await page.evaluate(async () => {
|
|
|
|
| 353 |
|| staticRender.background !== 'rgb(238, 244, 240)') {
|
| 354 |
throw new Error(`Static HTML/CSS render failed: ${JSON.stringify(staticRender)}`);
|
| 355 |
}
|
| 356 |
+
console.log(`artifact runtime probe passed: ${payloads.length} network bypasses emitted 0 requests; opaque-origin multi-file CSS, modules, dynamic import, fetch, OPFS persistence, stable-ID repair, inspect, and retest passed`);
|
| 357 |
} finally {
|
| 358 |
await browser?.close();
|
| 359 |
await vite?.close();
|
scripts/test-persistence.mjs
CHANGED
|
@@ -6,6 +6,7 @@ import { createServer as createViteServer } from 'vite';
|
|
| 6 |
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
| 7 |
const memoryKey = '__bonsai_persistence_probe__';
|
| 8 |
const conversationId = '__bonsai_conversation_probe__';
|
|
|
|
| 9 |
let browser;
|
| 10 |
let page;
|
| 11 |
let vite;
|
|
@@ -32,25 +33,76 @@ try {
|
|
| 32 |
browser = await chromium.launch({ headless: true });
|
| 33 |
page = await browser.newPage();
|
| 34 |
await page.goto(`http://127.0.0.1:${address.port}/persistence-probe.html`);
|
| 35 |
-
await page.evaluate(async ({ memoryKey, conversationId }) => {
|
| 36 |
const idb = await import('/src/lib/idb.ts');
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
await idb.deleteMemory(memoryKey);
|
| 38 |
await idb.putMemory(memoryKey, 'survives reload');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
await idb.saveConversation({
|
| 40 |
id: conversationId,
|
| 41 |
title: 'Persistence probe',
|
| 42 |
modelId: 'bonsai-1.7b',
|
| 43 |
updatedAt: 0,
|
| 44 |
-
messages: [
|
|
|
|
|
|
|
|
|
|
| 45 |
});
|
| 46 |
-
}, { memoryKey, conversationId });
|
| 47 |
|
| 48 |
await page.reload({ waitUntil: 'domcontentloaded' });
|
| 49 |
const persisted = await page.evaluate(async ({ memoryKey, conversationId }) => {
|
| 50 |
const idb = await import('/src/lib/idb.ts');
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
const memory = await idb.getMemory(memoryKey);
|
| 52 |
const conversation = await idb.loadConversation(conversationId);
|
| 53 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
}, { memoryKey, conversationId });
|
| 55 |
|
| 56 |
if (persisted.memory?.value !== 'survives reload') {
|
|
@@ -59,12 +111,24 @@ try {
|
|
| 59 |
if (persisted.conversation?.messages?.[0]?.content !== 'keep locally') {
|
| 60 |
throw new Error(`Conversation did not survive reload: ${JSON.stringify(persisted.conversation)}`);
|
| 61 |
}
|
| 62 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
} finally {
|
| 64 |
if (page) {
|
| 65 |
-
await page.evaluate(async ({ memoryKey, conversationId }) => {
|
| 66 |
const idb = await import('/src/lib/idb.ts');
|
|
|
|
| 67 |
await idb.deleteMemory(memoryKey).catch(() => undefined);
|
|
|
|
| 68 |
const request = indexedDB.open('bonsai-webgpu-chat', 1);
|
| 69 |
await new Promise((resolve) => {
|
| 70 |
request.onsuccess = () => {
|
|
@@ -76,7 +140,7 @@ try {
|
|
| 76 |
};
|
| 77 |
request.onerror = () => resolve();
|
| 78 |
});
|
| 79 |
-
}, { memoryKey, conversationId }).catch(() => undefined);
|
| 80 |
}
|
| 81 |
await browser?.close();
|
| 82 |
await vite?.close();
|
|
|
|
| 6 |
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
| 7 |
const memoryKey = '__bonsai_persistence_probe__';
|
| 8 |
const conversationId = '__bonsai_conversation_probe__';
|
| 9 |
+
const artifactId = '__bonsai_artifact_persistence_probe__';
|
| 10 |
let browser;
|
| 11 |
let page;
|
| 12 |
let vite;
|
|
|
|
| 33 |
browser = await chromium.launch({ headless: true });
|
| 34 |
page = await browser.newPage();
|
| 35 |
await page.goto(`http://127.0.0.1:${address.port}/persistence-probe.html`);
|
| 36 |
+
await page.evaluate(async ({ memoryKey, conversationId, artifactId }) => {
|
| 37 |
const idb = await import('/src/lib/idb.ts');
|
| 38 |
+
const {
|
| 39 |
+
evaluateHtmlArtifact,
|
| 40 |
+
prepareArtifactDeployment,
|
| 41 |
+
} = await import('/src/lib/artifact-runtime.ts');
|
| 42 |
await idb.deleteMemory(memoryKey);
|
| 43 |
await idb.putMemory(memoryKey, 'survives reload');
|
| 44 |
+
const artifact = prepareArtifactDeployment([
|
| 45 |
+
{
|
| 46 |
+
path: 'index.html',
|
| 47 |
+
content: '<main id="app">Loading</main><script type="module" src="./src/main.js"></script>',
|
| 48 |
+
},
|
| 49 |
+
{
|
| 50 |
+
path: 'src/main.js',
|
| 51 |
+
content: 'const data = await fetch("../data/state.json").then((response) => response.json()); document.querySelector("#app").textContent = data.message;',
|
| 52 |
+
},
|
| 53 |
+
{ path: 'data/state.json', content: '{"message":"workspace survives reload"}' },
|
| 54 |
+
], 'Persistent workspace', 'index.html', artifactId);
|
| 55 |
+
artifact.evaluation = await evaluateHtmlArtifact(artifact);
|
| 56 |
+
if (artifact.evaluation.status !== 'passed') {
|
| 57 |
+
throw new Error(`Artifact setup failed: ${JSON.stringify(artifact.evaluation)}`);
|
| 58 |
+
}
|
| 59 |
+
const staleRecoverySnapshot = {
|
| 60 |
+
...artifact,
|
| 61 |
+
files: artifact.files.map((file) => file.path === 'data/state.json'
|
| 62 |
+
? {
|
| 63 |
+
...file,
|
| 64 |
+
content: '{"message":"stale conversation snapshot"}',
|
| 65 |
+
bytes: new TextEncoder().encode('{"message":"stale conversation snapshot"}').byteLength,
|
| 66 |
+
}
|
| 67 |
+
: file),
|
| 68 |
+
};
|
| 69 |
await idb.saveConversation({
|
| 70 |
id: conversationId,
|
| 71 |
title: 'Persistence probe',
|
| 72 |
modelId: 'bonsai-1.7b',
|
| 73 |
updatedAt: 0,
|
| 74 |
+
messages: [
|
| 75 |
+
{ role: 'user', content: 'keep locally' },
|
| 76 |
+
{ role: 'assistant', content: '', artifacts: [staleRecoverySnapshot] },
|
| 77 |
+
],
|
| 78 |
});
|
| 79 |
+
}, { memoryKey, conversationId, artifactId });
|
| 80 |
|
| 81 |
await page.reload({ waitUntil: 'domcontentloaded' });
|
| 82 |
const persisted = await page.evaluate(async ({ memoryKey, conversationId }) => {
|
| 83 |
const idb = await import('/src/lib/idb.ts');
|
| 84 |
+
const {
|
| 85 |
+
evaluateHtmlArtifact,
|
| 86 |
+
hydrateArtifactDocument,
|
| 87 |
+
} = await import('/src/lib/artifact-runtime.ts');
|
| 88 |
const memory = await idb.getMemory(memoryKey);
|
| 89 |
const conversation = await idb.loadConversation(conversationId);
|
| 90 |
+
const snapshot = conversation?.messages?.[1]?.artifacts?.[0];
|
| 91 |
+
if (!snapshot) throw new Error('Saved conversation lost its artifact snapshot');
|
| 92 |
+
const artifact = await hydrateArtifactDocument(snapshot);
|
| 93 |
+
const evaluation = await evaluateHtmlArtifact(artifact);
|
| 94 |
+
return {
|
| 95 |
+
memory,
|
| 96 |
+
conversation,
|
| 97 |
+
artifact: {
|
| 98 |
+
id: artifact.id,
|
| 99 |
+
storage: artifact.workspaceStorage,
|
| 100 |
+
files: artifact.files?.map(({ path, content }) => ({ path, content })),
|
| 101 |
+
sandboxContainsCurrent: artifact.sandboxedSource.includes('workspace survives reload'),
|
| 102 |
+
sandboxContainsStale: artifact.sandboxedSource.includes('stale conversation snapshot'),
|
| 103 |
+
evaluation,
|
| 104 |
+
},
|
| 105 |
+
};
|
| 106 |
}, { memoryKey, conversationId });
|
| 107 |
|
| 108 |
if (persisted.memory?.value !== 'survives reload') {
|
|
|
|
| 111 |
if (persisted.conversation?.messages?.[0]?.content !== 'keep locally') {
|
| 112 |
throw new Error(`Conversation did not survive reload: ${JSON.stringify(persisted.conversation)}`);
|
| 113 |
}
|
| 114 |
+
if (persisted.artifact?.id !== artifactId
|
| 115 |
+
|| persisted.artifact.storage !== 'opfs'
|
| 116 |
+
|| persisted.artifact.files?.length !== 3
|
| 117 |
+
|| !persisted.artifact.files.some((file) => file.path === 'data/state.json' && file.content.includes('survives reload'))
|
| 118 |
+
|| persisted.artifact.sandboxContainsCurrent !== true
|
| 119 |
+
|| persisted.artifact.sandboxContainsStale !== false
|
| 120 |
+
|| persisted.artifact.evaluation?.status !== 'passed'
|
| 121 |
+
|| persisted.artifact.evaluation?.dom?.textPreview !== 'workspace survives reload') {
|
| 122 |
+
throw new Error(`Artifact workspace did not survive reload: ${JSON.stringify(persisted.artifact)}`);
|
| 123 |
+
}
|
| 124 |
+
console.log('Persistence passed: memory, conversation, and its three-file OPFS artifact survived reload and re-evaluated');
|
| 125 |
} finally {
|
| 126 |
if (page) {
|
| 127 |
+
await page.evaluate(async ({ memoryKey, conversationId, artifactId }) => {
|
| 128 |
const idb = await import('/src/lib/idb.ts');
|
| 129 |
+
const { deleteArtifactDocumentStorage } = await import('/src/lib/artifact-runtime.ts');
|
| 130 |
await idb.deleteMemory(memoryKey).catch(() => undefined);
|
| 131 |
+
await deleteArtifactDocumentStorage(artifactId).catch(() => undefined);
|
| 132 |
const request = indexedDB.open('bonsai-webgpu-chat', 1);
|
| 133 |
await new Promise((resolve) => {
|
| 134 |
request.onsuccess = () => {
|
|
|
|
| 140 |
};
|
| 141 |
request.onerror = () => resolve();
|
| 142 |
});
|
| 143 |
+
}, { memoryKey, conversationId, artifactId }).catch(() => undefined);
|
| 144 |
}
|
| 145 |
await browser?.close();
|
| 146 |
await vite?.close();
|
src/app/App.test.ts
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
| 14 |
reportsModelWeightProgress,
|
| 15 |
requiresModelReload,
|
| 16 |
} from './App';
|
| 17 |
-
import { prepareHtmlArtifact, type ToolExecution } from '../lib/agent-tools';
|
| 18 |
|
| 19 |
function engineError(code: string): EngineClientError {
|
| 20 |
return new EngineClientError({ code, message: code });
|
|
@@ -102,16 +102,23 @@ describe('App backend diagnostics', () => {
|
|
| 102 |
});
|
| 103 |
|
| 104 |
describe('App artifact identity', () => {
|
| 105 |
-
it('
|
| 106 |
-
const original =
|
| 107 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
const execution: ToolExecution = {
|
| 109 |
call: {
|
| 110 |
id: 'update-call',
|
| 111 |
type: 'function',
|
| 112 |
-
function: { name: '
|
| 113 |
},
|
| 114 |
artifact: replacement,
|
|
|
|
| 115 |
output: '{"ok":true}',
|
| 116 |
failed: false,
|
| 117 |
};
|
|
@@ -122,12 +129,12 @@ describe('App artifact identity', () => {
|
|
| 122 |
role: 'assistant',
|
| 123 |
content: '',
|
| 124 |
timestamp: '10:01',
|
| 125 |
-
tools: [{ id: 'update-call', name: '
|
| 126 |
},
|
| 127 |
], 'current', 'update-call', execution);
|
| 128 |
|
| 129 |
-
expect(next[0]?.artifacts).toEqual([
|
| 130 |
-
expect(next[1]?.artifacts).
|
| 131 |
expect(next[1]?.tools?.[0]).toMatchObject({
|
| 132 |
state: 'complete',
|
| 133 |
output: '{"ok":true}',
|
|
@@ -135,11 +142,39 @@ describe('App artifact identity', () => {
|
|
| 135 |
});
|
| 136 |
});
|
| 137 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
it('attaches a newly created artifact to the current assistant message', () => {
|
| 139 |
-
const artifact =
|
|
|
|
|
|
|
|
|
|
| 140 |
const execution: ToolExecution = {
|
| 141 |
-
call: { id: 'create-call', type: 'function', function: { name: '
|
| 142 |
artifact,
|
|
|
|
| 143 |
output: '{"ok":true}',
|
| 144 |
failed: false,
|
| 145 |
};
|
|
@@ -148,7 +183,7 @@ describe('App artifact identity', () => {
|
|
| 148 |
role: 'assistant',
|
| 149 |
content: '',
|
| 150 |
timestamp: '10:01',
|
| 151 |
-
tools: [{ id: 'create-call', name: '
|
| 152 |
}], 'current', 'create-call', execution);
|
| 153 |
|
| 154 |
expect(next[0]?.artifacts).toEqual([artifact]);
|
|
|
|
| 14 |
reportsModelWeightProgress,
|
| 15 |
requiresModelReload,
|
| 16 |
} from './App';
|
| 17 |
+
import { prepareArtifactDeployment, prepareHtmlArtifact, type ToolExecution } from '../lib/agent-tools';
|
| 18 |
|
| 19 |
function engineError(code: string): EngineClientError {
|
| 20 |
return new EngineClientError({ code, message: code });
|
|
|
|
| 102 |
});
|
| 103 |
|
| 104 |
describe('App artifact identity', () => {
|
| 105 |
+
it('moves an edited artifact to the current tool position while completing the tool run', () => {
|
| 106 |
+
const original = prepareArtifactDeployment([
|
| 107 |
+
{ path: 'index.html', content: '<script type="module" src="./src/main.js"></script>' },
|
| 108 |
+
{ path: 'src/main.js', content: 'document.body.textContent = "old";' },
|
| 109 |
+
], 'Demo', 'index.html', 'stable-artifact', 'old-runtime');
|
| 110 |
+
const replacement = prepareArtifactDeployment([
|
| 111 |
+
{ path: 'index.html', content: '<script type="module" src="./src/main.js"></script>' },
|
| 112 |
+
{ path: 'src/main.js', content: 'document.body.textContent = "new";' },
|
| 113 |
+
], 'Demo', 'index.html', 'stable-artifact', 'new-runtime');
|
| 114 |
const execution: ToolExecution = {
|
| 115 |
call: {
|
| 116 |
id: 'update-call',
|
| 117 |
type: 'function',
|
| 118 |
+
function: { name: 'artifact_write', arguments: '{}' },
|
| 119 |
},
|
| 120 |
artifact: replacement,
|
| 121 |
+
relocateArtifact: true,
|
| 122 |
output: '{"ok":true}',
|
| 123 |
failed: false,
|
| 124 |
};
|
|
|
|
| 129 |
role: 'assistant',
|
| 130 |
content: '',
|
| 131 |
timestamp: '10:01',
|
| 132 |
+
tools: [{ id: 'update-call', name: 'artifact_write', input: '{}', state: 'running' }],
|
| 133 |
},
|
| 134 |
], 'current', 'update-call', execution);
|
| 135 |
|
| 136 |
+
expect(next[0]?.artifacts).toEqual([]);
|
| 137 |
+
expect(next[1]?.artifacts).toEqual([replacement]);
|
| 138 |
expect(next[1]?.tools?.[0]).toMatchObject({
|
| 139 |
state: 'complete',
|
| 140 |
output: '{"ok":true}',
|
|
|
|
| 142 |
});
|
| 143 |
});
|
| 144 |
|
| 145 |
+
it('keeps a test-only artifact in place while returning diagnostics to the current turn', () => {
|
| 146 |
+
const artifact = prepareHtmlArtifact('<p>tested</p>', 'Demo', 'stable-artifact', 'runtime');
|
| 147 |
+
const execution: ToolExecution = {
|
| 148 |
+
call: { id: 'test-call', type: 'function', function: { name: 'artifact_test', arguments: '{}' } },
|
| 149 |
+
artifact,
|
| 150 |
+
relocateArtifact: false,
|
| 151 |
+
output: '{"ok":true}',
|
| 152 |
+
failed: false,
|
| 153 |
+
};
|
| 154 |
+
const next = applyToolExecutionToMessages([
|
| 155 |
+
{ id: 'older', role: 'assistant', content: '', timestamp: '10:00', artifacts: [artifact] },
|
| 156 |
+
{
|
| 157 |
+
id: 'current',
|
| 158 |
+
role: 'assistant',
|
| 159 |
+
content: '',
|
| 160 |
+
timestamp: '10:01',
|
| 161 |
+
tools: [{ id: 'test-call', name: 'artifact_test', input: '{}', state: 'running' }],
|
| 162 |
+
},
|
| 163 |
+
], 'current', 'test-call', execution);
|
| 164 |
+
expect(next[0]?.artifacts).toEqual([artifact]);
|
| 165 |
+
expect(next[1]?.artifacts).toBeUndefined();
|
| 166 |
+
expect(next[1]?.tools?.[0]).toMatchObject({ state: 'complete', artifactId: 'stable-artifact' });
|
| 167 |
+
});
|
| 168 |
+
|
| 169 |
it('attaches a newly created artifact to the current assistant message', () => {
|
| 170 |
+
const artifact = prepareArtifactDeployment([
|
| 171 |
+
{ path: 'index.html', content: '<link rel="stylesheet" href="./styles/app.css"><p>new</p>' },
|
| 172 |
+
{ path: 'styles/app.css', content: 'p { color: green; }' },
|
| 173 |
+
], 'Demo', 'index.html', 'new-artifact', 'runtime');
|
| 174 |
const execution: ToolExecution = {
|
| 175 |
+
call: { id: 'create-call', type: 'function', function: { name: 'artifact_deploy', arguments: '{}' } },
|
| 176 |
artifact,
|
| 177 |
+
relocateArtifact: true,
|
| 178 |
output: '{"ok":true}',
|
| 179 |
failed: false,
|
| 180 |
};
|
|
|
|
| 183 |
role: 'assistant',
|
| 184 |
content: '',
|
| 185 |
timestamp: '10:01',
|
| 186 |
+
tools: [{ id: 'create-call', name: 'artifact_deploy', input: '{}', state: 'running' }],
|
| 187 |
}], 'current', 'create-call', execution);
|
| 188 |
|
| 189 |
expect(next[0]?.artifacts).toEqual([artifact]);
|
src/app/App.tsx
CHANGED
|
@@ -16,7 +16,11 @@ import {
|
|
| 16 |
type RequestedBackend,
|
| 17 |
} from '../engine';
|
| 18 |
import { executeAgentTool, type ToolExecution } from '../lib/agent-tools';
|
| 19 |
-
import {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
import type {
|
| 21 |
ChatMessage,
|
| 22 |
ChatSession,
|
|
@@ -249,20 +253,31 @@ export function applyToolExecutionToMessages(
|
|
| 249 |
? messages.find((message) => message.artifacts?.some((artifact) => artifact.id === execution.artifact?.id))?.id
|
| 250 |
: undefined;
|
| 251 |
return messages.map((message) => {
|
| 252 |
-
|
| 253 |
-
|
| 254 |
-
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
|
| 258 |
-
|
| 259 |
-
|
| 260 |
-
|
| 261 |
-
|
| 262 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 263 |
return {
|
| 264 |
...message,
|
| 265 |
-
...(
|
| 266 |
...(message.id === assistantId ? {
|
| 267 |
tools: (message.tools ?? []).map((item) => item.id === callId ? {
|
| 268 |
...item,
|
|
@@ -281,6 +296,12 @@ export function normalizeStoredMessages(messages: ChatMessage[]): ChatMessage[]
|
|
| 281 |
: message));
|
| 282 |
}
|
| 283 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 284 |
export function buildEngineHistory(messages: ChatMessage[], systemPrompt: string): EngineChatMessage[] {
|
| 285 |
const history: EngineChatMessage[] = systemPrompt.trim()
|
| 286 |
? [{ role: 'system', content: systemPrompt.trim() }]
|
|
@@ -501,14 +522,15 @@ export function App() {
|
|
| 501 |
if (!cancelled) setError(`Capability inspection failed: ${errorMessage(capabilityError)}`);
|
| 502 |
}
|
| 503 |
try {
|
| 504 |
-
const storedConversations = (await listConversations<ChatMessage>())
|
| 505 |
-
.
|
| 506 |
-
|
| 507 |
-
|
| 508 |
-
|
| 509 |
-
|
| 510 |
-
|
| 511 |
-
|
|
|
|
| 512 |
const latest = storedConversations[0];
|
| 513 |
if (!cancelled) {
|
| 514 |
setConversations(storedConversations);
|
|
@@ -1261,12 +1283,16 @@ export function App() {
|
|
| 1261 |
const handleClearConversation = () => {
|
| 1262 |
if (operationRef.current) return;
|
| 1263 |
const clearedId = activeConversationId;
|
|
|
|
| 1264 |
setConversations((current) => current.filter((conversation) => conversation.id !== clearedId));
|
| 1265 |
setActiveConversationId(createConversationId());
|
| 1266 |
setMessages([]);
|
| 1267 |
setToolEvents([]);
|
| 1268 |
setBootStatus('Conversation cleared · model remains local');
|
| 1269 |
-
void
|
|
|
|
|
|
|
|
|
|
| 1270 |
};
|
| 1271 |
|
| 1272 |
const handleOpenConversationList = () => {
|
|
@@ -1324,6 +1350,8 @@ export function App() {
|
|
| 1324 |
if (operationRef.current) return;
|
| 1325 |
const conversation = conversations.find((candidate) => candidate.id === conversationId);
|
| 1326 |
if (!conversation || !window.confirm(`Delete “${conversation.title}” from this browser?`)) return;
|
|
|
|
|
|
|
| 1327 |
setConversations((current) => current.filter((candidate) => candidate.id !== conversationId));
|
| 1328 |
if (conversationId === activeConversationId) {
|
| 1329 |
setActiveConversationId(createConversationId());
|
|
@@ -1331,9 +1359,12 @@ export function App() {
|
|
| 1331 |
setToolEvents([]);
|
| 1332 |
setSettings((current) => ({ ...current, systemPrompt: INITIAL_SETTINGS.systemPrompt }));
|
| 1333 |
}
|
| 1334 |
-
void
|
|
|
|
|
|
|
|
|
|
| 1335 |
.then(() => setBootStatus('Local chat deleted'))
|
| 1336 |
-
.catch(() => setBootStatus('Chat removed for this tab · local
|
| 1337 |
};
|
| 1338 |
|
| 1339 |
const effectiveLoadedModelId = (() => {
|
|
|
|
| 16 |
type RequestedBackend,
|
| 17 |
} from '../engine';
|
| 18 |
import { executeAgentTool, type ToolExecution } from '../lib/agent-tools';
|
| 19 |
+
import {
|
| 20 |
+
deleteArtifactDocumentStorage,
|
| 21 |
+
hydrateArtifactDocument,
|
| 22 |
+
normalizeArtifactDocument,
|
| 23 |
+
} from '../lib/artifact-runtime';
|
| 24 |
import type {
|
| 25 |
ChatMessage,
|
| 26 |
ChatSession,
|
|
|
|
| 253 |
? messages.find((message) => message.artifacts?.some((artifact) => artifact.id === execution.artifact?.id))?.id
|
| 254 |
: undefined;
|
| 255 |
return messages.map((message) => {
|
| 256 |
+
let artifacts = message.artifacts;
|
| 257 |
+
let artifactsChanged = false;
|
| 258 |
+
if (execution.artifact) {
|
| 259 |
+
const relocate = execution.relocateArtifact !== false;
|
| 260 |
+
if (message.id === artifactOwnerId) {
|
| 261 |
+
artifactsChanged = true;
|
| 262 |
+
artifacts = relocate && artifactOwnerId !== assistantId
|
| 263 |
+
? (message.artifacts ?? []).filter((artifact) => artifact.id !== execution.artifact?.id)
|
| 264 |
+
: (message.artifacts ?? []).map((artifact) => artifact.id === execution.artifact?.id
|
| 265 |
+
? execution.artifact as NonNullable<ToolExecution['artifact']>
|
| 266 |
+
: artifact);
|
| 267 |
+
}
|
| 268 |
+
if (message.id === assistantId && artifactOwnerId !== assistantId
|
| 269 |
+
&& (relocate || !artifactOwnerId)) {
|
| 270 |
+
artifactsChanged = true;
|
| 271 |
+
artifacts = [
|
| 272 |
+
...(message.artifacts ?? []).filter((artifact) => artifact.id !== execution.artifact?.id),
|
| 273 |
+
execution.artifact,
|
| 274 |
+
];
|
| 275 |
+
}
|
| 276 |
+
}
|
| 277 |
+
if (message.id !== assistantId && !artifactsChanged) return message;
|
| 278 |
return {
|
| 279 |
...message,
|
| 280 |
+
...(artifactsChanged ? { artifacts } : {}),
|
| 281 |
...(message.id === assistantId ? {
|
| 282 |
tools: (message.tools ?? []).map((item) => item.id === callId ? {
|
| 283 |
...item,
|
|
|
|
| 296 |
: message));
|
| 297 |
}
|
| 298 |
|
| 299 |
+
export async function hydrateStoredMessages(messages: ChatMessage[]): Promise<ChatMessage[]> {
|
| 300 |
+
return Promise.all(normalizeStoredMessages(messages).map(async (message) => message.artifacts
|
| 301 |
+
? { ...message, artifacts: await Promise.all(message.artifacts.map(hydrateArtifactDocument)) }
|
| 302 |
+
: message));
|
| 303 |
+
}
|
| 304 |
+
|
| 305 |
export function buildEngineHistory(messages: ChatMessage[], systemPrompt: string): EngineChatMessage[] {
|
| 306 |
const history: EngineChatMessage[] = systemPrompt.trim()
|
| 307 |
? [{ role: 'system', content: systemPrompt.trim() }]
|
|
|
|
| 522 |
if (!cancelled) setError(`Capability inspection failed: ${errorMessage(capabilityError)}`);
|
| 523 |
}
|
| 524 |
try {
|
| 525 |
+
const storedConversations = await Promise.all((await listConversations<ChatMessage>())
|
| 526 |
+
.map(async (conversation) => ({
|
| 527 |
+
...conversation,
|
| 528 |
+
messages: await hydrateStoredMessages(conversation.messages),
|
| 529 |
+
modelId: normalizeConversationModelId(conversation.modelId),
|
| 530 |
+
systemPrompt: typeof conversation.systemPrompt === 'string'
|
| 531 |
+
? conversation.systemPrompt
|
| 532 |
+
: INITIAL_SETTINGS.systemPrompt,
|
| 533 |
+
})));
|
| 534 |
const latest = storedConversations[0];
|
| 535 |
if (!cancelled) {
|
| 536 |
setConversations(storedConversations);
|
|
|
|
| 1283 |
const handleClearConversation = () => {
|
| 1284 |
if (operationRef.current) return;
|
| 1285 |
const clearedId = activeConversationId;
|
| 1286 |
+
const artifactIds = messages.flatMap((message) => message.artifacts?.map((artifact) => artifact.id) ?? []);
|
| 1287 |
setConversations((current) => current.filter((conversation) => conversation.id !== clearedId));
|
| 1288 |
setActiveConversationId(createConversationId());
|
| 1289 |
setMessages([]);
|
| 1290 |
setToolEvents([]);
|
| 1291 |
setBootStatus('Conversation cleared · model remains local');
|
| 1292 |
+
void Promise.all([
|
| 1293 |
+
deleteConversation(clearedId),
|
| 1294 |
+
...artifactIds.map(deleteArtifactDocumentStorage),
|
| 1295 |
+
]).catch(() => setBootStatus('Conversation cleared for this tab · some local workspace data may remain'));
|
| 1296 |
};
|
| 1297 |
|
| 1298 |
const handleOpenConversationList = () => {
|
|
|
|
| 1350 |
if (operationRef.current) return;
|
| 1351 |
const conversation = conversations.find((candidate) => candidate.id === conversationId);
|
| 1352 |
if (!conversation || !window.confirm(`Delete “${conversation.title}” from this browser?`)) return;
|
| 1353 |
+
const artifactIds = (conversationId === activeConversationId ? messages : conversation.messages)
|
| 1354 |
+
.flatMap((message) => message.artifacts?.map((artifact) => artifact.id) ?? []);
|
| 1355 |
setConversations((current) => current.filter((candidate) => candidate.id !== conversationId));
|
| 1356 |
if (conversationId === activeConversationId) {
|
| 1357 |
setActiveConversationId(createConversationId());
|
|
|
|
| 1359 |
setToolEvents([]);
|
| 1360 |
setSettings((current) => ({ ...current, systemPrompt: INITIAL_SETTINGS.systemPrompt }));
|
| 1361 |
}
|
| 1362 |
+
void Promise.all([
|
| 1363 |
+
deleteConversation(conversationId),
|
| 1364 |
+
...artifactIds.map(deleteArtifactDocumentStorage),
|
| 1365 |
+
])
|
| 1366 |
.then(() => setBootStatus('Local chat deleted'))
|
| 1367 |
+
.catch(() => setBootStatus('Chat removed for this tab · some local workspace data may remain'));
|
| 1368 |
};
|
| 1369 |
|
| 1370 |
const effectiveLoadedModelId = (() => {
|
src/app/components/ArtifactCard.tsx
CHANGED
|
@@ -2,10 +2,13 @@ import { useEffect, useRef, useState } from 'react';
|
|
| 2 |
import type { ArtifactDocument } from '../../lib/agent-tools';
|
| 3 |
import {
|
| 4 |
configureArtifactIframe,
|
|
|
|
| 5 |
evaluationFromRuntimeMessage,
|
|
|
|
| 6 |
recordArtifactDiagnostics,
|
| 7 |
type ArtifactEvaluation,
|
| 8 |
} from '../../lib/artifact-runtime';
|
|
|
|
| 9 |
|
| 10 |
interface ArtifactCardProps {
|
| 11 |
artifact: ArtifactDocument;
|
|
@@ -21,26 +24,65 @@ interface WebkitFullscreenDocument extends Document {
|
|
| 21 |
}
|
| 22 |
|
| 23 |
export function ArtifactCard({ artifact }: ArtifactCardProps) {
|
| 24 |
-
const
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
const [fallbackFullscreen, setFallbackFullscreen] = useState(false);
|
| 26 |
const [nativeFullscreen, setNativeFullscreen] = useState(false);
|
| 27 |
const [evaluation, setEvaluation] = useState<ArtifactEvaluation | undefined>(artifact.evaluation);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
const renderedRef = useRef<HTMLDivElement>(null);
|
| 29 |
const iframeRef = useRef<HTMLIFrameElement>(null);
|
| 30 |
|
| 31 |
useEffect(() => {
|
| 32 |
-
setTab('
|
|
|
|
| 33 |
setFallbackFullscreen(false);
|
| 34 |
-
}, [artifact.id]);
|
| 35 |
|
| 36 |
useEffect(() => {
|
| 37 |
setEvaluation(artifact.evaluation);
|
|
|
|
|
|
|
| 38 |
}, [artifact.evaluation, artifact.runtimeToken]);
|
| 39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
useEffect(() => {
|
| 41 |
if (tab !== 'rendered') return;
|
| 42 |
const handleMessage = (event: MessageEvent) => {
|
| 43 |
-
if (event
|
| 44 |
const next = evaluationFromRuntimeMessage(event.data, artifact.id, artifact.runtimeToken);
|
| 45 |
if (!next) return;
|
| 46 |
recordArtifactDiagnostics(artifact.id, artifact.runtimeToken, next);
|
|
@@ -97,6 +139,7 @@ export function ArtifactCard({ artifact }: ArtifactCardProps) {
|
|
| 97 |
};
|
| 98 |
|
| 99 |
const fullscreen = nativeFullscreen || fallbackFullscreen;
|
|
|
|
| 100 |
|
| 101 |
return (
|
| 102 |
<section
|
|
@@ -110,11 +153,11 @@ export function ArtifactCard({ artifact }: ArtifactCardProps) {
|
|
| 110 |
<button
|
| 111 |
type="button"
|
| 112 |
role="tab"
|
| 113 |
-
aria-selected={tab === '
|
| 114 |
-
aria-controls={`artifact-
|
| 115 |
-
onClick={() => setTab('
|
| 116 |
>
|
| 117 |
-
|
| 118 |
</button>
|
| 119 |
<button
|
| 120 |
type="button"
|
|
@@ -128,6 +171,9 @@ export function ArtifactCard({ artifact }: ArtifactCardProps) {
|
|
| 128 |
</div>
|
| 129 |
<div className="artifact-title-block">
|
| 130 |
<strong id={`artifact-title-${artifact.id}`}>{artifact.title}</strong>
|
|
|
|
|
|
|
|
|
|
| 131 |
<span className={`artifact-test-status is-${evaluation?.status ?? 'pending'}`}>
|
| 132 |
{artifactStatus(evaluation)}
|
| 133 |
</span>
|
|
@@ -145,12 +191,34 @@ export function ArtifactCard({ artifact }: ArtifactCardProps) {
|
|
| 145 |
)}
|
| 146 |
</div>
|
| 147 |
|
| 148 |
-
{tab === '
|
| 149 |
-
<
|
| 150 |
-
className="artifact-
|
| 151 |
-
id={`artifact-
|
| 152 |
role="tabpanel"
|
| 153 |
-
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
) : (
|
| 155 |
<div
|
| 156 |
className={`artifact-rendered${fallbackFullscreen ? ' is-fallback-fullscreen' : ''}`}
|
|
@@ -167,18 +235,33 @@ export function ArtifactCard({ artifact }: ArtifactCardProps) {
|
|
| 167 |
Exit fullscreen
|
| 168 |
</button>
|
| 169 |
)}
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 180 |
</div>
|
| 181 |
)}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 182 |
{evaluation && evaluation.entries.length > 0 && (
|
| 183 |
<details className="artifact-console" open={evaluation.status !== 'passed'}>
|
| 184 |
<summary>
|
|
|
|
| 2 |
import type { ArtifactDocument } from '../../lib/agent-tools';
|
| 3 |
import {
|
| 4 |
configureArtifactIframe,
|
| 5 |
+
deployArtifactDocument,
|
| 6 |
evaluationFromRuntimeMessage,
|
| 7 |
+
isArtifactRuntimeMessageEvent,
|
| 8 |
recordArtifactDiagnostics,
|
| 9 |
type ArtifactEvaluation,
|
| 10 |
} from '../../lib/artifact-runtime';
|
| 11 |
+
import { formatBytes } from '../../lib/format';
|
| 12 |
|
| 13 |
interface ArtifactCardProps {
|
| 14 |
artifact: ArtifactDocument;
|
|
|
|
| 24 |
}
|
| 25 |
|
| 26 |
export function ArtifactCard({ artifact }: ArtifactCardProps) {
|
| 27 |
+
const files = artifact.files?.length ? artifact.files : [{
|
| 28 |
+
path: artifact.entryPath ?? 'index.html',
|
| 29 |
+
content: artifact.source,
|
| 30 |
+
mime: 'text/html; charset=utf-8',
|
| 31 |
+
bytes: new TextEncoder().encode(artifact.source).byteLength,
|
| 32 |
+
}];
|
| 33 |
+
const [tab, setTab] = useState<'files' | 'rendered'>(
|
| 34 |
+
artifact.evaluation?.status === 'passed' ? 'rendered' : 'files',
|
| 35 |
+
);
|
| 36 |
+
const [selectedPath, setSelectedPath] = useState(artifact.entryPath ?? files[0]?.path ?? 'index.html');
|
| 37 |
const [fallbackFullscreen, setFallbackFullscreen] = useState(false);
|
| 38 |
const [nativeFullscreen, setNativeFullscreen] = useState(false);
|
| 39 |
const [evaluation, setEvaluation] = useState<ArtifactEvaluation | undefined>(artifact.evaluation);
|
| 40 |
+
const [deploymentUrl, setDeploymentUrl] = useState<string | null>(null);
|
| 41 |
+
const [deploymentReady, setDeploymentReady] = useState(false);
|
| 42 |
+
const [deploymentError, setDeploymentError] = useState<string | null>(null);
|
| 43 |
+
const [workspaceStorage, setWorkspaceStorage] = useState(artifact.workspaceStorage ?? 'snapshot');
|
| 44 |
+
const [workspaceWarning, setWorkspaceWarning] = useState(artifact.workspaceWarning);
|
| 45 |
const renderedRef = useRef<HTMLDivElement>(null);
|
| 46 |
const iframeRef = useRef<HTMLIFrameElement>(null);
|
| 47 |
|
| 48 |
useEffect(() => {
|
| 49 |
+
setTab(artifact.evaluation?.status === 'passed' ? 'rendered' : 'files');
|
| 50 |
+
setSelectedPath(artifact.entryPath ?? artifact.files?.[0]?.path ?? 'index.html');
|
| 51 |
setFallbackFullscreen(false);
|
| 52 |
+
}, [artifact.id, artifact.runtimeToken, artifact.evaluation?.status, artifact.entryPath, artifact.files]);
|
| 53 |
|
| 54 |
useEffect(() => {
|
| 55 |
setEvaluation(artifact.evaluation);
|
| 56 |
+
if (artifact.evaluation?.status === 'passed') setTab('rendered');
|
| 57 |
+
if (artifact.evaluation && artifact.evaluation.status !== 'passed') setTab('files');
|
| 58 |
}, [artifact.evaluation, artifact.runtimeToken]);
|
| 59 |
|
| 60 |
+
useEffect(() => {
|
| 61 |
+
let cancelled = false;
|
| 62 |
+
setDeploymentUrl(null);
|
| 63 |
+
setDeploymentReady(false);
|
| 64 |
+
setDeploymentError(null);
|
| 65 |
+
setWorkspaceWarning(artifact.workspaceWarning);
|
| 66 |
+
void deployArtifactDocument(artifact)
|
| 67 |
+
.then((deployment) => {
|
| 68 |
+
if (cancelled) return;
|
| 69 |
+
setDeploymentUrl(deployment.previewUrl);
|
| 70 |
+
setDeploymentReady(true);
|
| 71 |
+
setWorkspaceStorage(deployment.artifact.workspaceStorage ?? 'snapshot');
|
| 72 |
+
setWorkspaceWarning(deployment.artifact.workspaceWarning);
|
| 73 |
+
})
|
| 74 |
+
.catch((error) => {
|
| 75 |
+
if (cancelled) return;
|
| 76 |
+
setDeploymentError(error instanceof Error ? error.message : String(error));
|
| 77 |
+
setTab('files');
|
| 78 |
+
});
|
| 79 |
+
return () => { cancelled = true; };
|
| 80 |
+
}, [artifact.id, artifact.runtimeToken]);
|
| 81 |
+
|
| 82 |
useEffect(() => {
|
| 83 |
if (tab !== 'rendered') return;
|
| 84 |
const handleMessage = (event: MessageEvent) => {
|
| 85 |
+
if (!isArtifactRuntimeMessageEvent(event, iframeRef.current?.contentWindow)) return;
|
| 86 |
const next = evaluationFromRuntimeMessage(event.data, artifact.id, artifact.runtimeToken);
|
| 87 |
if (!next) return;
|
| 88 |
recordArtifactDiagnostics(artifact.id, artifact.runtimeToken, next);
|
|
|
|
| 139 |
};
|
| 140 |
|
| 141 |
const fullscreen = nativeFullscreen || fallbackFullscreen;
|
| 142 |
+
const selectedFile = files.find((file) => file.path === selectedPath) ?? files[0];
|
| 143 |
|
| 144 |
return (
|
| 145 |
<section
|
|
|
|
| 153 |
<button
|
| 154 |
type="button"
|
| 155 |
role="tab"
|
| 156 |
+
aria-selected={tab === 'files'}
|
| 157 |
+
aria-controls={`artifact-files-${artifact.id}`}
|
| 158 |
+
onClick={() => setTab('files')}
|
| 159 |
>
|
| 160 |
+
Files
|
| 161 |
</button>
|
| 162 |
<button
|
| 163 |
type="button"
|
|
|
|
| 171 |
</div>
|
| 172 |
<div className="artifact-title-block">
|
| 173 |
<strong id={`artifact-title-${artifact.id}`}>{artifact.title}</strong>
|
| 174 |
+
<span className="artifact-workspace-status">
|
| 175 |
+
{workspaceStorage === 'opfs' ? 'OPFS' : 'snapshot'} · {files.length} {files.length === 1 ? 'file' : 'files'}
|
| 176 |
+
</span>
|
| 177 |
<span className={`artifact-test-status is-${evaluation?.status ?? 'pending'}`}>
|
| 178 |
{artifactStatus(evaluation)}
|
| 179 |
</span>
|
|
|
|
| 191 |
)}
|
| 192 |
</div>
|
| 193 |
|
| 194 |
+
{tab === 'files' ? (
|
| 195 |
+
<div
|
| 196 |
+
className="artifact-files"
|
| 197 |
+
id={`artifact-files-${artifact.id}`}
|
| 198 |
role="tabpanel"
|
| 199 |
+
>
|
| 200 |
+
<nav aria-label={`${artifact.title} files`}>
|
| 201 |
+
{files.map((file) => (
|
| 202 |
+
<button
|
| 203 |
+
type="button"
|
| 204 |
+
className={file.path === selectedFile?.path ? 'is-selected' : ''}
|
| 205 |
+
aria-current={file.path === selectedFile?.path ? 'true' : undefined}
|
| 206 |
+
onClick={() => setSelectedPath(file.path)}
|
| 207 |
+
key={file.path}
|
| 208 |
+
>
|
| 209 |
+
<span>{file.path}</span>
|
| 210 |
+
<small>{formatBytes(file.bytes)}</small>
|
| 211 |
+
</button>
|
| 212 |
+
))}
|
| 213 |
+
</nav>
|
| 214 |
+
<div className="artifact-file-source">
|
| 215 |
+
<header>
|
| 216 |
+
<code>/{selectedFile?.path}</code>
|
| 217 |
+
<span>{selectedFile?.mime}</span>
|
| 218 |
+
</header>
|
| 219 |
+
<pre className="artifact-code"><code>{selectedFile?.content}</code></pre>
|
| 220 |
+
</div>
|
| 221 |
+
</div>
|
| 222 |
) : (
|
| 223 |
<div
|
| 224 |
className={`artifact-rendered${fallbackFullscreen ? ' is-fallback-fullscreen' : ''}`}
|
|
|
|
| 235 |
Exit fullscreen
|
| 236 |
</button>
|
| 237 |
)}
|
| 238 |
+
{deploymentError ? (
|
| 239 |
+
<div className="artifact-deployment-error" role="alert">
|
| 240 |
+
<strong>Deployment unavailable</strong>
|
| 241 |
+
<span>{deploymentError}</span>
|
| 242 |
+
</div>
|
| 243 |
+
) : deploymentReady ? (
|
| 244 |
+
<iframe
|
| 245 |
+
key={`${artifact.id}-${artifact.runtimeToken}-${deploymentUrl ?? 'srcdoc'}`}
|
| 246 |
+
ref={(node) => {
|
| 247 |
+
iframeRef.current = node;
|
| 248 |
+
if (node) configureArtifactIframe(node, deploymentUrl ? 'deployment' : 'srcdoc');
|
| 249 |
+
}}
|
| 250 |
+
title={artifact.title}
|
| 251 |
+
sandbox="allow-scripts"
|
| 252 |
+
referrerPolicy="no-referrer"
|
| 253 |
+
{...(deploymentUrl ? { src: deploymentUrl } : { srcDoc: artifact.sandboxedSource })}
|
| 254 |
+
/>
|
| 255 |
+
) : (
|
| 256 |
+
<div className="artifact-deployment-loading" role="status">Publishing local deployment…</div>
|
| 257 |
+
)}
|
| 258 |
</div>
|
| 259 |
)}
|
| 260 |
+
{workspaceWarning && (
|
| 261 |
+
<p className="artifact-workspace-warning">
|
| 262 |
+
OPFS unavailable · the file snapshot remains saved with this chat.
|
| 263 |
+
</p>
|
| 264 |
+
)}
|
| 265 |
{evaluation && evaluation.entries.length > 0 && (
|
| 266 |
<details className="artifact-console" open={evaluation.status !== 'passed'}>
|
| 267 |
<summary>
|
src/app/components/ChatSurface.test.tsx
CHANGED
|
@@ -64,8 +64,8 @@ describe('ChatSurface message actions', () => {
|
|
| 64 |
expect(html).toContain('aria-label="Edit message and regenerate response"');
|
| 65 |
expect(html).not.toContain('Regenerate last');
|
| 66 |
expect(html).toContain('aria-label="Show available tools"');
|
| 67 |
-
expect(html).toContain('<code>
|
| 68 |
-
expect(html).toContain('<code>
|
| 69 |
expect(html).toContain('<code>bar_chart</code>');
|
| 70 |
expect(html).toContain('<code>pie_chart</code>');
|
| 71 |
expect(html).toContain('<code>web_search</code>');
|
|
@@ -91,7 +91,7 @@ describe('ChatSurface message actions', () => {
|
|
| 91 |
content: '',
|
| 92 |
timestamp: '10:01',
|
| 93 |
state: 'streaming',
|
| 94 |
-
toolActivity: { name: '
|
| 95 |
},
|
| 96 |
]}
|
| 97 |
streamState="streaming"
|
|
@@ -115,13 +115,13 @@ describe('ChatSurface message actions', () => {
|
|
| 115 |
);
|
| 116 |
|
| 117 |
expect(html).toContain('Visible streamed text');
|
| 118 |
-
expect(html).toContain('Generating
|
| 119 |
-
expect(html).toContain('<code>
|
| 120 |
expect(html).toContain('12,345 chars');
|
| 121 |
expect(html.match(/stream-cursor/g)).toHaveLength(2);
|
| 122 |
});
|
| 123 |
|
| 124 |
-
it('renders generated artifacts inline with
|
| 125 |
const html = renderToStaticMarkup(
|
| 126 |
<ChatSurface
|
| 127 |
activeModel={model}
|
|
@@ -162,8 +162,9 @@ describe('ChatSurface message actions', () => {
|
|
| 162 |
|
| 163 |
expect(html).toContain('id="artifact-artifact-one"');
|
| 164 |
expect(html).toContain('role="tab" aria-selected="true"');
|
| 165 |
-
expect(html).toContain('>
|
| 166 |
expect(html).toContain('>Rendered</button>');
|
|
|
|
| 167 |
expect(html).toContain('<main>Counter</main>');
|
| 168 |
expect(html).not.toContain('<iframe');
|
| 169 |
});
|
|
|
|
| 64 |
expect(html).toContain('aria-label="Edit message and regenerate response"');
|
| 65 |
expect(html).not.toContain('Regenerate last');
|
| 66 |
expect(html).toContain('aria-label="Show available tools"');
|
| 67 |
+
expect(html).toContain('<code>artifact_deploy</code>');
|
| 68 |
+
expect(html).toContain('<code>artifact_write</code>');
|
| 69 |
expect(html).toContain('<code>bar_chart</code>');
|
| 70 |
expect(html).toContain('<code>pie_chart</code>');
|
| 71 |
expect(html).toContain('<code>web_search</code>');
|
|
|
|
| 91 |
content: '',
|
| 92 |
timestamp: '10:01',
|
| 93 |
state: 'streaming',
|
| 94 |
+
toolActivity: { name: 'artifact_deploy', argumentCharacters: 12_345 },
|
| 95 |
},
|
| 96 |
]}
|
| 97 |
streamState="streaming"
|
|
|
|
| 115 |
);
|
| 116 |
|
| 117 |
expect(html).toContain('Visible streamed text');
|
| 118 |
+
expect(html).toContain('Generating artifact_deploy tool call');
|
| 119 |
+
expect(html).toContain('<code>artifact_deploy</code>');
|
| 120 |
expect(html).toContain('12,345 chars');
|
| 121 |
expect(html.match(/stream-cursor/g)).toHaveLength(2);
|
| 122 |
});
|
| 123 |
|
| 124 |
+
it('renders generated artifacts inline with Files and Rendered tabs', () => {
|
| 125 |
const html = renderToStaticMarkup(
|
| 126 |
<ChatSurface
|
| 127 |
activeModel={model}
|
|
|
|
| 162 |
|
| 163 |
expect(html).toContain('id="artifact-artifact-one"');
|
| 164 |
expect(html).toContain('role="tab" aria-selected="true"');
|
| 165 |
+
expect(html).toContain('>Files</button>');
|
| 166 |
expect(html).toContain('>Rendered</button>');
|
| 167 |
+
expect(html).toContain('/index.html');
|
| 168 |
expect(html).toContain('<main>Counter</main>');
|
| 169 |
expect(html).not.toContain('<iframe');
|
| 170 |
});
|
src/app/components/InspectorPanel.tsx
CHANGED
|
@@ -107,7 +107,7 @@ export function InspectorPanel({ hidden = false, telemetry, toolEvents, artifact
|
|
| 107 |
<span className="artifact-count" aria-label={`${artifacts.length} artifacts`}>{artifacts.length}</span>
|
| 108 |
</div>
|
| 109 |
{artifacts.length === 0 ? (
|
| 110 |
-
<p className="artifact-empty">Generated
|
| 111 |
) : (
|
| 112 |
<ol className="artifact-index">
|
| 113 |
{artifacts.map((artifact, index) => (
|
|
|
|
| 107 |
<span className="artifact-count" aria-label={`${artifacts.length} artifacts`}>{artifacts.length}</span>
|
| 108 |
</div>
|
| 109 |
{artifacts.length === 0 ? (
|
| 110 |
+
<p className="artifact-empty">Generated web deployments will be indexed here and rendered in the conversation.</p>
|
| 111 |
) : (
|
| 112 |
<ol className="artifact-index">
|
| 113 |
{artifacts.map((artifact, index) => (
|
src/app/styles.css
CHANGED
|
@@ -2445,9 +2445,9 @@ button:disabled {
|
|
| 2445 |
|
| 2446 |
.artifact-title-block {
|
| 2447 |
min-width: 0;
|
| 2448 |
-
display:
|
|
|
|
| 2449 |
align-items: center;
|
| 2450 |
-
justify-content: space-between;
|
| 2451 |
gap: 10px;
|
| 2452 |
padding: 0 12px;
|
| 2453 |
}
|
|
@@ -2461,6 +2461,12 @@ button:disabled {
|
|
| 2461 |
white-space: nowrap;
|
| 2462 |
}
|
| 2463 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2464 |
.artifact-test-status {
|
| 2465 |
flex: 0 0 auto;
|
| 2466 |
color: var(--canvas-muted);
|
|
@@ -2564,6 +2570,121 @@ button:disabled {
|
|
| 2564 |
white-space: pre;
|
| 2565 |
}
|
| 2566 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2567 |
.artifact-console {
|
| 2568 |
color: var(--canvas-text);
|
| 2569 |
border-top: 1px solid var(--canvas-line);
|
|
@@ -3382,6 +3503,51 @@ button:disabled {
|
|
| 3382 |
max-width: 91%;
|
| 3383 |
}
|
| 3384 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3385 |
.composer-meta > span {
|
| 3386 |
display: none;
|
| 3387 |
}
|
|
|
|
| 2445 |
|
| 2446 |
.artifact-title-block {
|
| 2447 |
min-width: 0;
|
| 2448 |
+
display: grid;
|
| 2449 |
+
grid-template-columns: minmax(0, 1fr) auto auto;
|
| 2450 |
align-items: center;
|
|
|
|
| 2451 |
gap: 10px;
|
| 2452 |
padding: 0 12px;
|
| 2453 |
}
|
|
|
|
| 2461 |
white-space: nowrap;
|
| 2462 |
}
|
| 2463 |
|
| 2464 |
+
.artifact-workspace-status {
|
| 2465 |
+
color: var(--canvas-muted);
|
| 2466 |
+
font: var(--type-utility)/1 var(--mono);
|
| 2467 |
+
white-space: nowrap;
|
| 2468 |
+
}
|
| 2469 |
+
|
| 2470 |
.artifact-test-status {
|
| 2471 |
flex: 0 0 auto;
|
| 2472 |
color: var(--canvas-muted);
|
|
|
|
| 2570 |
white-space: pre;
|
| 2571 |
}
|
| 2572 |
|
| 2573 |
+
.artifact-files {
|
| 2574 |
+
min-height: 320px;
|
| 2575 |
+
display: grid;
|
| 2576 |
+
grid-template-columns: minmax(170px, 24%) minmax(0, 1fr);
|
| 2577 |
+
background: #0d100e;
|
| 2578 |
+
}
|
| 2579 |
+
|
| 2580 |
+
.artifact-files > nav {
|
| 2581 |
+
max-height: min(520px, 60vh);
|
| 2582 |
+
overflow: auto;
|
| 2583 |
+
padding: 7px 0;
|
| 2584 |
+
border-right: 1px solid rgba(241, 242, 237, 0.16);
|
| 2585 |
+
background: #151915;
|
| 2586 |
+
}
|
| 2587 |
+
|
| 2588 |
+
.artifact-files > nav button {
|
| 2589 |
+
width: 100%;
|
| 2590 |
+
min-height: 34px;
|
| 2591 |
+
display: grid;
|
| 2592 |
+
grid-template-columns: minmax(0, 1fr) auto;
|
| 2593 |
+
align-items: center;
|
| 2594 |
+
gap: 8px;
|
| 2595 |
+
padding: 6px 10px 6px 12px;
|
| 2596 |
+
color: rgba(241, 242, 237, 0.62);
|
| 2597 |
+
border: 0;
|
| 2598 |
+
border-left: 2px solid transparent;
|
| 2599 |
+
background: transparent;
|
| 2600 |
+
text-align: left;
|
| 2601 |
+
cursor: pointer;
|
| 2602 |
+
}
|
| 2603 |
+
|
| 2604 |
+
.artifact-files > nav button:hover,
|
| 2605 |
+
.artifact-files > nav button:focus-visible {
|
| 2606 |
+
color: var(--paper);
|
| 2607 |
+
background: rgba(241, 242, 237, 0.06);
|
| 2608 |
+
}
|
| 2609 |
+
|
| 2610 |
+
.artifact-files > nav button.is-selected {
|
| 2611 |
+
color: var(--paper);
|
| 2612 |
+
border-left-color: var(--phosphor);
|
| 2613 |
+
background: rgba(241, 242, 237, 0.09);
|
| 2614 |
+
}
|
| 2615 |
+
|
| 2616 |
+
.artifact-files > nav button span {
|
| 2617 |
+
overflow: hidden;
|
| 2618 |
+
font: var(--type-utility)/1.3 var(--mono);
|
| 2619 |
+
text-overflow: ellipsis;
|
| 2620 |
+
white-space: nowrap;
|
| 2621 |
+
}
|
| 2622 |
+
|
| 2623 |
+
.artifact-files > nav button small {
|
| 2624 |
+
color: rgba(241, 242, 237, 0.42);
|
| 2625 |
+
font: 9px/1 var(--mono);
|
| 2626 |
+
}
|
| 2627 |
+
|
| 2628 |
+
.artifact-file-source {
|
| 2629 |
+
min-width: 0;
|
| 2630 |
+
display: grid;
|
| 2631 |
+
grid-template-rows: auto minmax(0, 1fr);
|
| 2632 |
+
}
|
| 2633 |
+
|
| 2634 |
+
.artifact-file-source > header {
|
| 2635 |
+
min-height: 34px;
|
| 2636 |
+
display: flex;
|
| 2637 |
+
align-items: center;
|
| 2638 |
+
justify-content: space-between;
|
| 2639 |
+
gap: 12px;
|
| 2640 |
+
padding: 0 12px;
|
| 2641 |
+
color: rgba(241, 242, 237, 0.58);
|
| 2642 |
+
border-bottom: 1px solid rgba(241, 242, 237, 0.12);
|
| 2643 |
+
font: var(--type-utility)/1 var(--mono);
|
| 2644 |
+
}
|
| 2645 |
+
|
| 2646 |
+
.artifact-file-source > header code {
|
| 2647 |
+
overflow: hidden;
|
| 2648 |
+
color: var(--paper);
|
| 2649 |
+
text-overflow: ellipsis;
|
| 2650 |
+
white-space: nowrap;
|
| 2651 |
+
}
|
| 2652 |
+
|
| 2653 |
+
.artifact-file-source .artifact-code {
|
| 2654 |
+
min-height: 286px;
|
| 2655 |
+
padding-top: 13px;
|
| 2656 |
+
}
|
| 2657 |
+
|
| 2658 |
+
.artifact-deployment-loading,
|
| 2659 |
+
.artifact-deployment-error {
|
| 2660 |
+
min-height: 380px;
|
| 2661 |
+
display: grid;
|
| 2662 |
+
place-content: center;
|
| 2663 |
+
gap: 7px;
|
| 2664 |
+
padding: 28px;
|
| 2665 |
+
color: #4e5a51;
|
| 2666 |
+
background: #f6f7f3;
|
| 2667 |
+
text-align: center;
|
| 2668 |
+
font: var(--type-caption)/1.4 var(--body);
|
| 2669 |
+
}
|
| 2670 |
+
|
| 2671 |
+
.artifact-deployment-error strong {
|
| 2672 |
+
color: var(--rust);
|
| 2673 |
+
}
|
| 2674 |
+
|
| 2675 |
+
.artifact-deployment-error span {
|
| 2676 |
+
max-width: 560px;
|
| 2677 |
+
}
|
| 2678 |
+
|
| 2679 |
+
.artifact-workspace-warning {
|
| 2680 |
+
margin: 0;
|
| 2681 |
+
padding: 8px 12px;
|
| 2682 |
+
color: #87571e;
|
| 2683 |
+
border-top: 1px solid var(--canvas-line);
|
| 2684 |
+
background: var(--canvas-raised);
|
| 2685 |
+
font: var(--type-utility)/1.4 var(--body);
|
| 2686 |
+
}
|
| 2687 |
+
|
| 2688 |
.artifact-console {
|
| 2689 |
color: var(--canvas-text);
|
| 2690 |
border-top: 1px solid var(--canvas-line);
|
|
|
|
| 3503 |
max-width: 91%;
|
| 3504 |
}
|
| 3505 |
|
| 3506 |
+
.artifact-toolbar {
|
| 3507 |
+
grid-template-columns: auto minmax(0, 1fr) auto;
|
| 3508 |
+
}
|
| 3509 |
+
|
| 3510 |
+
.artifact-title-block {
|
| 3511 |
+
grid-template-columns: minmax(0, 1fr) auto;
|
| 3512 |
+
gap: 6px;
|
| 3513 |
+
padding-inline: 8px;
|
| 3514 |
+
}
|
| 3515 |
+
|
| 3516 |
+
.artifact-workspace-status {
|
| 3517 |
+
display: none;
|
| 3518 |
+
}
|
| 3519 |
+
|
| 3520 |
+
.artifact-files {
|
| 3521 |
+
grid-template-columns: minmax(0, 1fr);
|
| 3522 |
+
grid-template-rows: auto minmax(0, 1fr);
|
| 3523 |
+
}
|
| 3524 |
+
|
| 3525 |
+
.artifact-files > nav {
|
| 3526 |
+
display: flex;
|
| 3527 |
+
max-height: none;
|
| 3528 |
+
overflow-x: auto;
|
| 3529 |
+
padding: 0;
|
| 3530 |
+
border-right: 0;
|
| 3531 |
+
border-bottom: 1px solid rgba(241, 242, 237, 0.16);
|
| 3532 |
+
}
|
| 3533 |
+
|
| 3534 |
+
.artifact-files > nav button {
|
| 3535 |
+
width: auto;
|
| 3536 |
+
min-width: 132px;
|
| 3537 |
+
flex: 0 0 auto;
|
| 3538 |
+
border-left: 0;
|
| 3539 |
+
border-bottom: 2px solid transparent;
|
| 3540 |
+
}
|
| 3541 |
+
|
| 3542 |
+
.artifact-files > nav button.is-selected {
|
| 3543 |
+
border-left-color: transparent;
|
| 3544 |
+
border-bottom-color: var(--phosphor);
|
| 3545 |
+
}
|
| 3546 |
+
|
| 3547 |
+
.artifact-file-source > header > span {
|
| 3548 |
+
display: none;
|
| 3549 |
+
}
|
| 3550 |
+
|
| 3551 |
.composer-meta > span {
|
| 3552 |
display: none;
|
| 3553 |
}
|
src/lib/agent-tools.test.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
import { describe, expect, it } from 'vitest';
|
| 2 |
-
import { prepareHtmlArtifact } from './agent-tools';
|
| 3 |
|
| 4 |
describe('prepareHtmlArtifact', () => {
|
| 5 |
it('injects a deny-by-default CSP while preserving source for the code view', () => {
|
|
@@ -26,8 +26,31 @@ describe('prepareHtmlArtifact', () => {
|
|
| 26 |
expect(() => prepareHtmlArtifact('<script>location.href="https://example.com"</script>'))
|
| 27 |
.toThrow('cannot navigate');
|
| 28 |
expect(() => prepareHtmlArtifact('<meta http-equiv="refresh" content="0;url=https://example.com">'))
|
| 29 |
-
.toThrow('navigation or refresh');
|
| 30 |
expect(() => prepareHtmlArtifact('<script>document.body.textContent = "ok"</script>'))
|
| 31 |
.not.toThrow();
|
| 32 |
});
|
| 33 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import { describe, expect, it } from 'vitest';
|
| 2 |
+
import { prepareArtifactDeployment, prepareHtmlArtifact } from './agent-tools';
|
| 3 |
|
| 4 |
describe('prepareHtmlArtifact', () => {
|
| 5 |
it('injects a deny-by-default CSP while preserving source for the code view', () => {
|
|
|
|
| 26 |
expect(() => prepareHtmlArtifact('<script>location.href="https://example.com"</script>'))
|
| 27 |
.toThrow('cannot navigate');
|
| 28 |
expect(() => prepareHtmlArtifact('<meta http-equiv="refresh" content="0;url=https://example.com">'))
|
| 29 |
+
.toThrow('navigation, or refresh');
|
| 30 |
expect(() => prepareHtmlArtifact('<script>document.body.textContent = "ok"</script>'))
|
| 31 |
.not.toThrow();
|
| 32 |
});
|
| 33 |
});
|
| 34 |
+
|
| 35 |
+
describe('prepareArtifactDeployment', () => {
|
| 36 |
+
it('preserves a multi-file tree and rejects root-absolute resources', () => {
|
| 37 |
+
const artifact = prepareArtifactDeployment([
|
| 38 |
+
{ path: 'index.html', content: '<link rel="stylesheet" href="./styles/app.css"><script type="module" src="./src/main.js"></script>' },
|
| 39 |
+
{ path: 'styles/app.css', content: 'body { color: green; }' },
|
| 40 |
+
{ path: 'src/main.js', content: 'import "./view.js";' },
|
| 41 |
+
{ path: 'src/view.js', content: 'document.body.dataset.ready = "1";' },
|
| 42 |
+
], 'Multi-file', 'index.html', 'deployment-1', 'runtime-1');
|
| 43 |
+
expect(artifact.files?.map((file) => file.path)).toEqual([
|
| 44 |
+
'index.html',
|
| 45 |
+
'styles/app.css',
|
| 46 |
+
'src/main.js',
|
| 47 |
+
'src/view.js',
|
| 48 |
+
]);
|
| 49 |
+
expect(artifact.entryPath).toBe('index.html');
|
| 50 |
+
expect(artifact.schemaVersion).toBe(2);
|
| 51 |
+
expect(() => prepareArtifactDeployment([
|
| 52 |
+
{ path: 'index.html', content: '<script src="/src/main.js"></script>' },
|
| 53 |
+
{ path: 'src/main.js', content: '' },
|
| 54 |
+
])).toThrow('root-absolute');
|
| 55 |
+
});
|
| 56 |
+
});
|
src/lib/agent-tools.ts
CHANGED
|
@@ -2,22 +2,26 @@ import type { EngineChatTool, EngineChatToolCall } from '../engine';
|
|
| 2 |
import {
|
| 3 |
evaluateHtmlArtifact,
|
| 4 |
getArtifactDiagnostics,
|
|
|
|
| 5 |
prepareHtmlArtifact,
|
| 6 |
type ArtifactDocument,
|
| 7 |
type ArtifactEvaluation,
|
|
|
|
| 8 |
} from './artifact-runtime';
|
|
|
|
| 9 |
import { generateBarChartHtml, generatePieChartHtml } from './chart-tools';
|
| 10 |
import { deleteMemory, getMemory, listMemory, putMemory } from './idb';
|
| 11 |
import { runJavaScript } from './js-sandbox';
|
| 12 |
import { searchWikipedia } from './web-search';
|
| 13 |
|
| 14 |
export type { ArtifactDocument, ArtifactEvaluation } from './artifact-runtime';
|
| 15 |
-
export { prepareHtmlArtifact } from './artifact-runtime';
|
| 16 |
|
| 17 |
export interface ToolExecution {
|
| 18 |
call: EngineChatToolCall;
|
| 19 |
output: string;
|
| 20 |
artifact?: ArtifactDocument;
|
|
|
|
| 21 |
failed: boolean;
|
| 22 |
}
|
| 23 |
|
|
@@ -35,10 +39,10 @@ export interface ToolCatalogEntry {
|
|
| 35 |
const MAX_TOOL_RESULT_CHARACTERS = 64 * 1024;
|
| 36 |
|
| 37 |
export const TOOL_CATALOG: ToolCatalogEntry[] = [
|
| 38 |
-
{ name: '
|
| 39 |
-
{ name: '
|
| 40 |
{ name: 'artifact_test', label: 'Test artifact', description: 'Rerun an artifact and collect console and DOM diagnostics.', scope: 'local' },
|
| 41 |
-
{ name: 'artifact_inspect', label: 'Inspect
|
| 42 |
{ name: 'bar_chart', label: 'Bar chart', description: 'Turn labelled numeric data into an accessible bar-chart artifact.', scope: 'local' },
|
| 43 |
{ name: 'pie_chart', label: 'Pie chart', description: 'Turn parts of a whole into an accessible pie-chart artifact.', scope: 'local' },
|
| 44 |
{ name: 'js_eval', label: 'JavaScript eval', description: 'Run deterministic calculations in a disposable worker.', scope: 'local' },
|
|
@@ -63,25 +67,73 @@ export const HTML_ARTIFACT_TOOL: EngineChatTool = {
|
|
| 63 |
},
|
| 64 |
};
|
| 65 |
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
{
|
| 69 |
-
type: '
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
},
|
| 80 |
-
required: ['artifact_id', 'html'],
|
| 81 |
-
additionalProperties: false,
|
| 82 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
},
|
| 84 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 85 |
{
|
| 86 |
type: 'function',
|
| 87 |
function: {
|
|
@@ -101,12 +153,17 @@ export const AGENT_TOOLS: EngineChatTool[] = [
|
|
| 101 |
type: 'function',
|
| 102 |
function: {
|
| 103 |
name: 'artifact_inspect',
|
| 104 |
-
description: 'List identifiable
|
| 105 |
parameters: {
|
| 106 |
type: 'object',
|
| 107 |
properties: {
|
| 108 |
artifact_id: { type: 'string', description: 'Artifact ID. Omit to list all artifacts.' },
|
| 109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
},
|
| 111 |
additionalProperties: false,
|
| 112 |
},
|
|
@@ -116,7 +173,7 @@ export const AGENT_TOOLS: EngineChatTool[] = [
|
|
| 116 |
type: 'function',
|
| 117 |
function: {
|
| 118 |
name: 'bar_chart',
|
| 119 |
-
description: 'Create and test an accessible bar-chart
|
| 120 |
parameters: {
|
| 121 |
type: 'object',
|
| 122 |
properties: {
|
|
@@ -247,6 +304,48 @@ function evaluationResult(evaluation: ArtifactEvaluation | undefined) {
|
|
| 247 |
};
|
| 248 |
}
|
| 249 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 250 |
async function testedArtifact(
|
| 251 |
source: string,
|
| 252 |
title: string,
|
|
@@ -254,9 +353,14 @@ async function testedArtifact(
|
|
| 254 |
signal: AbortSignal | undefined,
|
| 255 |
createdAt?: number,
|
| 256 |
): Promise<ArtifactDocument> {
|
| 257 |
-
|
| 258 |
-
|
| 259 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 260 |
}
|
| 261 |
|
| 262 |
async function executeMemory(args: Record<string, unknown>): Promise<unknown> {
|
|
@@ -298,6 +402,64 @@ export async function executeAgentTool(
|
|
| 298 |
try {
|
| 299 |
if (signal?.aborted) throw new DOMException('The tool operation was aborted.', 'AbortError');
|
| 300 |
const args = parseArguments(call);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 301 |
if (call.function.name === 'html_artifact') {
|
| 302 |
const artifact = await testedArtifact(
|
| 303 |
requiredString(args.html, 'html_artifact.html'),
|
|
@@ -309,6 +471,7 @@ export async function executeAgentTool(
|
|
| 309 |
return {
|
| 310 |
call,
|
| 311 |
artifact,
|
|
|
|
| 312 |
output: boundedJson({ ok: true, artifactId: artifact.id, title: artifact.title, bytes: artifact.source.length, evaluation: evaluationResult(artifact.evaluation) }),
|
| 313 |
failed: false,
|
| 314 |
};
|
|
@@ -328,6 +491,7 @@ export async function executeAgentTool(
|
|
| 328 |
return {
|
| 329 |
call,
|
| 330 |
artifact,
|
|
|
|
| 331 |
output: boundedJson({ ok: true, artifactId: artifact.id, title: artifact.title, updated: true, bytes: artifact.source.length, evaluation: evaluationResult(artifact.evaluation) }),
|
| 332 |
failed: false,
|
| 333 |
};
|
|
@@ -342,6 +506,7 @@ export async function executeAgentTool(
|
|
| 342 |
return {
|
| 343 |
call,
|
| 344 |
artifact,
|
|
|
|
| 345 |
output: boundedJson({ ok: true, artifactId, evaluation: evaluationResult(evaluation) }),
|
| 346 |
failed: false,
|
| 347 |
};
|
|
@@ -356,7 +521,10 @@ export async function executeAgentTool(
|
|
| 356 |
artifacts: [...context.artifacts.values()].map((artifact) => ({
|
| 357 |
id: artifact.id,
|
| 358 |
title: artifact.title,
|
| 359 |
-
|
|
|
|
|
|
|
|
|
|
| 360 |
evaluation: evaluationResult(getArtifactDiagnostics(artifact)),
|
| 361 |
})),
|
| 362 |
}),
|
|
@@ -365,16 +533,29 @@ export async function executeAgentTool(
|
|
| 365 |
}
|
| 366 |
const artifact = context.artifacts.get(artifactId);
|
| 367 |
if (!artifact) throw new Error(`artifact ${artifactId} is not available in this chat`);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 368 |
return {
|
| 369 |
call,
|
| 370 |
output: boundedJson({
|
| 371 |
ok: true,
|
| 372 |
artifact: {
|
| 373 |
-
|
| 374 |
-
title: artifact.title,
|
| 375 |
-
bytes: artifact.source.length,
|
| 376 |
evaluation: evaluationResult(getArtifactDiagnostics(artifact)),
|
| 377 |
-
...(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 378 |
},
|
| 379 |
}),
|
| 380 |
failed: false,
|
|
@@ -396,6 +577,7 @@ export async function executeAgentTool(
|
|
| 396 |
return {
|
| 397 |
call,
|
| 398 |
artifact,
|
|
|
|
| 399 |
output: boundedJson({ ok: true, artifactId: artifact.id, title, chart: call.function.name, evaluation: evaluationResult(artifact.evaluation) }),
|
| 400 |
failed: false,
|
| 401 |
};
|
|
|
|
| 2 |
import {
|
| 3 |
evaluateHtmlArtifact,
|
| 4 |
getArtifactDiagnostics,
|
| 5 |
+
prepareArtifactDeployment,
|
| 6 |
prepareHtmlArtifact,
|
| 7 |
type ArtifactDocument,
|
| 8 |
type ArtifactEvaluation,
|
| 9 |
+
type ArtifactFileInput,
|
| 10 |
} from './artifact-runtime';
|
| 11 |
+
import { normalizeArtifactPath } from './artifact-workspace';
|
| 12 |
import { generateBarChartHtml, generatePieChartHtml } from './chart-tools';
|
| 13 |
import { deleteMemory, getMemory, listMemory, putMemory } from './idb';
|
| 14 |
import { runJavaScript } from './js-sandbox';
|
| 15 |
import { searchWikipedia } from './web-search';
|
| 16 |
|
| 17 |
export type { ArtifactDocument, ArtifactEvaluation } from './artifact-runtime';
|
| 18 |
+
export { prepareArtifactDeployment, prepareHtmlArtifact } from './artifact-runtime';
|
| 19 |
|
| 20 |
export interface ToolExecution {
|
| 21 |
call: EngineChatToolCall;
|
| 22 |
output: string;
|
| 23 |
artifact?: ArtifactDocument;
|
| 24 |
+
relocateArtifact?: boolean;
|
| 25 |
failed: boolean;
|
| 26 |
}
|
| 27 |
|
|
|
|
| 39 |
const MAX_TOOL_RESULT_CHARACTERS = 64 * 1024;
|
| 40 |
|
| 41 |
export const TOOL_CATALOG: ToolCatalogEntry[] = [
|
| 42 |
+
{ name: 'artifact_deploy', label: 'Deploy artifact', description: 'Create and test a persistent multi-file web deployment.', scope: 'local' },
|
| 43 |
+
{ name: 'artifact_write', label: 'Write artifact files', description: 'Add, replace, or delete files and test the new deployment.', scope: 'local' },
|
| 44 |
{ name: 'artifact_test', label: 'Test artifact', description: 'Rerun an artifact and collect console and DOM diagnostics.', scope: 'local' },
|
| 45 |
+
{ name: 'artifact_inspect', label: 'Inspect artifact files', description: 'List deployments or read selected files and live diagnostics.', scope: 'local' },
|
| 46 |
{ name: 'bar_chart', label: 'Bar chart', description: 'Turn labelled numeric data into an accessible bar-chart artifact.', scope: 'local' },
|
| 47 |
{ name: 'pie_chart', label: 'Pie chart', description: 'Turn parts of a whole into an accessible pie-chart artifact.', scope: 'local' },
|
| 48 |
{ name: 'js_eval', label: 'JavaScript eval', description: 'Run deterministic calculations in a disposable worker.', scope: 'local' },
|
|
|
|
| 67 |
},
|
| 68 |
};
|
| 69 |
|
| 70 |
+
const ARTIFACT_FILE_SCHEMA = {
|
| 71 |
+
type: 'object',
|
| 72 |
+
properties: {
|
| 73 |
+
path: { type: 'string', description: 'Relative POSIX path such as index.html, styles/app.css, or src/main.js. Never start with /.' },
|
| 74 |
+
content: { type: 'string', description: 'Complete UTF-8 text file content.' },
|
| 75 |
+
},
|
| 76 |
+
required: ['path', 'content'],
|
| 77 |
+
additionalProperties: false,
|
| 78 |
+
} as const;
|
| 79 |
+
|
| 80 |
+
export const ARTIFACT_DEPLOY_TOOL: EngineChatTool = {
|
| 81 |
+
type: 'function',
|
| 82 |
+
function: {
|
| 83 |
+
name: 'artifact_deploy',
|
| 84 |
+
description: 'Create and immediately test one persistent multi-file web deployment. Use for every webpage, mini-app, diagram, custom visualization, or programmatic interface. Provide browser-ready HTML/CSS/JavaScript with no build step or packages. Every local URL and module import must be relative (./ or ../), never root-absolute. The opaque-origin sandbox blocks external network, storage, navigation, popups, workers, and parent access; console, resource, promise, and DOM diagnostics are returned.',
|
| 85 |
+
parameters: {
|
| 86 |
+
type: 'object',
|
| 87 |
+
properties: {
|
| 88 |
+
title: { type: 'string', description: 'Short deployment title.' },
|
| 89 |
+
entry_path: { type: 'string', description: 'HTML entry path. Defaults to index.html.' },
|
| 90 |
+
files: {
|
| 91 |
+
type: 'array',
|
| 92 |
+
description: 'Complete initial file tree. Keep it compact and browser-ready.',
|
| 93 |
+
items: ARTIFACT_FILE_SCHEMA,
|
| 94 |
+
minItems: 1,
|
| 95 |
+
maxItems: 48,
|
| 96 |
},
|
|
|
|
|
|
|
| 97 |
},
|
| 98 |
+
required: ['files'],
|
| 99 |
+
additionalProperties: false,
|
| 100 |
+
},
|
| 101 |
+
},
|
| 102 |
+
};
|
| 103 |
+
|
| 104 |
+
export const ARTIFACT_WRITE_TOOL: EngineChatTool = {
|
| 105 |
+
type: 'function',
|
| 106 |
+
function: {
|
| 107 |
+
name: 'artifact_write',
|
| 108 |
+
description: 'Edit an existing deployment by stable artifact_id, then publish and test a new immutable snapshot. Use to repair diagnostics or revise a site. Upsert only changed files, optionally delete obsolete paths, and keep all resource URLs relative. The updated deployment stays the same artifact but moves to this point in the agent transcript.',
|
| 109 |
+
parameters: {
|
| 110 |
+
type: 'object',
|
| 111 |
+
properties: {
|
| 112 |
+
artifact_id: { type: 'string', description: 'Stable deployment ID returned by artifact_deploy or a chart tool.' },
|
| 113 |
+
files: {
|
| 114 |
+
type: 'array',
|
| 115 |
+
description: 'Files to create or completely replace.',
|
| 116 |
+
items: ARTIFACT_FILE_SCHEMA,
|
| 117 |
+
maxItems: 24,
|
| 118 |
+
},
|
| 119 |
+
delete_paths: {
|
| 120 |
+
type: 'array',
|
| 121 |
+
description: 'Relative file paths to remove.',
|
| 122 |
+
items: { type: 'string' },
|
| 123 |
+
maxItems: 24,
|
| 124 |
+
},
|
| 125 |
+
entry_path: { type: 'string', description: 'Optional replacement HTML entry path.' },
|
| 126 |
+
title: { type: 'string', description: 'Optional replacement title.' },
|
| 127 |
+
},
|
| 128 |
+
required: ['artifact_id'],
|
| 129 |
+
additionalProperties: false,
|
| 130 |
},
|
| 131 |
},
|
| 132 |
+
};
|
| 133 |
+
|
| 134 |
+
export const AGENT_TOOLS: EngineChatTool[] = [
|
| 135 |
+
ARTIFACT_DEPLOY_TOOL,
|
| 136 |
+
ARTIFACT_WRITE_TOOL,
|
| 137 |
{
|
| 138 |
type: 'function',
|
| 139 |
function: {
|
|
|
|
| 153 |
type: 'function',
|
| 154 |
function: {
|
| 155 |
name: 'artifact_inspect',
|
| 156 |
+
description: 'List identifiable deployments, or inspect one deployment file tree, selected text files, and its latest live diagnostics. Use before artifact_write or when investigating a failure.',
|
| 157 |
parameters: {
|
| 158 |
type: 'object',
|
| 159 |
properties: {
|
| 160 |
artifact_id: { type: 'string', description: 'Artifact ID. Omit to list all artifacts.' },
|
| 161 |
+
paths: {
|
| 162 |
+
type: 'array',
|
| 163 |
+
description: 'Exact relative paths to read. Omit to return only the file manifest.',
|
| 164 |
+
items: { type: 'string' },
|
| 165 |
+
maxItems: 12,
|
| 166 |
+
},
|
| 167 |
},
|
| 168 |
additionalProperties: false,
|
| 169 |
},
|
|
|
|
| 173 |
type: 'function',
|
| 174 |
function: {
|
| 175 |
name: 'bar_chart',
|
| 176 |
+
description: 'Create and test an accessible bar-chart deployment from labelled non-negative values. Use for comparing magnitudes across categories; use artifact_deploy for bespoke or interactive visualizations.',
|
| 177 |
parameters: {
|
| 178 |
type: 'object',
|
| 179 |
properties: {
|
|
|
|
| 304 |
};
|
| 305 |
}
|
| 306 |
|
| 307 |
+
function artifactFileInputs(value: unknown, field: string): ArtifactFileInput[] {
|
| 308 |
+
if (!Array.isArray(value)) throw new Error(`${field} must be an array`);
|
| 309 |
+
return value.map((item, index) => {
|
| 310 |
+
if (!isRecord(item)) throw new Error(`${field}[${index}] must be an object`);
|
| 311 |
+
if (typeof item.content !== 'string') throw new Error(`${field}[${index}].content must be text`);
|
| 312 |
+
return {
|
| 313 |
+
path: requiredString(item.path, `${field}[${index}].path`),
|
| 314 |
+
content: item.content,
|
| 315 |
+
};
|
| 316 |
+
});
|
| 317 |
+
}
|
| 318 |
+
|
| 319 |
+
function artifactResult(artifact: ArtifactDocument) {
|
| 320 |
+
const files = artifact.files ?? [];
|
| 321 |
+
return {
|
| 322 |
+
artifactId: artifact.id,
|
| 323 |
+
title: artifact.title,
|
| 324 |
+
entryPath: artifact.entryPath ?? 'index.html',
|
| 325 |
+
fileCount: files.length,
|
| 326 |
+
bytes: files.reduce((total, file) => total + file.bytes, 0),
|
| 327 |
+
files: files.map(({ path, mime, bytes }) => ({ path, mime, bytes })),
|
| 328 |
+
workspace: {
|
| 329 |
+
storage: artifact.workspaceStorage ?? 'snapshot',
|
| 330 |
+
...(artifact.workspaceWarning ? { warning: artifact.workspaceWarning } : {}),
|
| 331 |
+
},
|
| 332 |
+
evaluation: evaluationResult(artifact.evaluation),
|
| 333 |
+
};
|
| 334 |
+
}
|
| 335 |
+
|
| 336 |
+
async function testedDeployment(
|
| 337 |
+
files: ArtifactFileInput[],
|
| 338 |
+
title: string,
|
| 339 |
+
entryPath: string,
|
| 340 |
+
id: string,
|
| 341 |
+
signal: AbortSignal | undefined,
|
| 342 |
+
createdAt?: number,
|
| 343 |
+
): Promise<ArtifactDocument> {
|
| 344 |
+
const prepared = prepareArtifactDeployment(files, title, entryPath, id);
|
| 345 |
+
const evaluation = await evaluateHtmlArtifact(prepared, 3000, signal);
|
| 346 |
+
return { ...prepared, ...(createdAt ? { createdAt } : {}), evaluation };
|
| 347 |
+
}
|
| 348 |
+
|
| 349 |
async function testedArtifact(
|
| 350 |
source: string,
|
| 351 |
title: string,
|
|
|
|
| 353 |
signal: AbortSignal | undefined,
|
| 354 |
createdAt?: number,
|
| 355 |
): Promise<ArtifactDocument> {
|
| 356 |
+
return testedDeployment(
|
| 357 |
+
[{ path: 'index.html', content: source }],
|
| 358 |
+
title,
|
| 359 |
+
'index.html',
|
| 360 |
+
id,
|
| 361 |
+
signal,
|
| 362 |
+
createdAt,
|
| 363 |
+
);
|
| 364 |
}
|
| 365 |
|
| 366 |
async function executeMemory(args: Record<string, unknown>): Promise<unknown> {
|
|
|
|
| 402 |
try {
|
| 403 |
if (signal?.aborted) throw new DOMException('The tool operation was aborted.', 'AbortError');
|
| 404 |
const args = parseArguments(call);
|
| 405 |
+
if (call.function.name === 'artifact_deploy') {
|
| 406 |
+
const artifact = await testedDeployment(
|
| 407 |
+
artifactFileInputs(args.files, 'artifact_deploy.files'),
|
| 408 |
+
typeof args.title === 'string' ? args.title : 'Untitled artifact',
|
| 409 |
+
typeof args.entry_path === 'string' ? args.entry_path : 'index.html',
|
| 410 |
+
crypto.randomUUID(),
|
| 411 |
+
signal,
|
| 412 |
+
);
|
| 413 |
+
context.artifacts.set(artifact.id, artifact);
|
| 414 |
+
return {
|
| 415 |
+
call,
|
| 416 |
+
artifact,
|
| 417 |
+
relocateArtifact: true,
|
| 418 |
+
output: boundedJson({ ok: true, ...artifactResult(artifact) }),
|
| 419 |
+
failed: false,
|
| 420 |
+
};
|
| 421 |
+
}
|
| 422 |
+
if (call.function.name === 'artifact_write') {
|
| 423 |
+
const artifactId = requiredString(args.artifact_id, 'artifact_write.artifact_id');
|
| 424 |
+
const current = context.artifacts.get(artifactId);
|
| 425 |
+
if (!current) throw new Error(`artifact ${artifactId} is not available in this chat`);
|
| 426 |
+
const replacements = args.files === undefined
|
| 427 |
+
? []
|
| 428 |
+
: artifactFileInputs(args.files, 'artifact_write.files');
|
| 429 |
+
const deletePaths = args.delete_paths === undefined
|
| 430 |
+
? []
|
| 431 |
+
: stringArray(args.delete_paths, 'artifact_write.delete_paths').map(normalizeArtifactPath);
|
| 432 |
+
if (replacements.length === 0 && deletePaths.length === 0
|
| 433 |
+
&& args.title === undefined && args.entry_path === undefined) {
|
| 434 |
+
throw new Error('artifact_write must change files, title, or entry_path');
|
| 435 |
+
}
|
| 436 |
+
const files = new Map((current.files ?? [{
|
| 437 |
+
path: current.entryPath ?? 'index.html',
|
| 438 |
+
content: current.source,
|
| 439 |
+
}]).map((file) => [file.path, { path: file.path, content: file.content }]));
|
| 440 |
+
for (const path of deletePaths) files.delete(path);
|
| 441 |
+
for (const replacement of replacements) {
|
| 442 |
+
const path = normalizeArtifactPath(replacement.path);
|
| 443 |
+
if (deletePaths.includes(path)) throw new Error(`${path} cannot be written and deleted in one artifact_write`);
|
| 444 |
+
files.set(path, { path, content: replacement.content });
|
| 445 |
+
}
|
| 446 |
+
const artifact = await testedDeployment(
|
| 447 |
+
[...files.values()],
|
| 448 |
+
typeof args.title === 'string' ? args.title : current.title,
|
| 449 |
+
typeof args.entry_path === 'string' ? args.entry_path : current.entryPath ?? 'index.html',
|
| 450 |
+
current.id,
|
| 451 |
+
signal,
|
| 452 |
+
current.createdAt,
|
| 453 |
+
);
|
| 454 |
+
context.artifacts.set(artifact.id, artifact);
|
| 455 |
+
return {
|
| 456 |
+
call,
|
| 457 |
+
artifact,
|
| 458 |
+
relocateArtifact: true,
|
| 459 |
+
output: boundedJson({ ok: true, updated: true, ...artifactResult(artifact) }),
|
| 460 |
+
failed: false,
|
| 461 |
+
};
|
| 462 |
+
}
|
| 463 |
if (call.function.name === 'html_artifact') {
|
| 464 |
const artifact = await testedArtifact(
|
| 465 |
requiredString(args.html, 'html_artifact.html'),
|
|
|
|
| 471 |
return {
|
| 472 |
call,
|
| 473 |
artifact,
|
| 474 |
+
relocateArtifact: true,
|
| 475 |
output: boundedJson({ ok: true, artifactId: artifact.id, title: artifact.title, bytes: artifact.source.length, evaluation: evaluationResult(artifact.evaluation) }),
|
| 476 |
failed: false,
|
| 477 |
};
|
|
|
|
| 491 |
return {
|
| 492 |
call,
|
| 493 |
artifact,
|
| 494 |
+
relocateArtifact: true,
|
| 495 |
output: boundedJson({ ok: true, artifactId: artifact.id, title: artifact.title, updated: true, bytes: artifact.source.length, evaluation: evaluationResult(artifact.evaluation) }),
|
| 496 |
failed: false,
|
| 497 |
};
|
|
|
|
| 506 |
return {
|
| 507 |
call,
|
| 508 |
artifact,
|
| 509 |
+
relocateArtifact: false,
|
| 510 |
output: boundedJson({ ok: true, artifactId, evaluation: evaluationResult(evaluation) }),
|
| 511 |
failed: false,
|
| 512 |
};
|
|
|
|
| 521 |
artifacts: [...context.artifacts.values()].map((artifact) => ({
|
| 522 |
id: artifact.id,
|
| 523 |
title: artifact.title,
|
| 524 |
+
entryPath: artifact.entryPath ?? 'index.html',
|
| 525 |
+
fileCount: artifact.files?.length ?? 1,
|
| 526 |
+
bytes: (artifact.files ?? []).reduce((total, file) => total + file.bytes, artifact.files ? 0 : artifact.source.length),
|
| 527 |
+
workspaceStorage: artifact.workspaceStorage ?? 'snapshot',
|
| 528 |
evaluation: evaluationResult(getArtifactDiagnostics(artifact)),
|
| 529 |
})),
|
| 530 |
}),
|
|
|
|
| 533 |
}
|
| 534 |
const artifact = context.artifacts.get(artifactId);
|
| 535 |
if (!artifact) throw new Error(`artifact ${artifactId} is not available in this chat`);
|
| 536 |
+
const requestedPaths = Array.isArray(args.paths)
|
| 537 |
+
? stringArray(args.paths, 'artifact_inspect.paths').map(normalizeArtifactPath)
|
| 538 |
+
: args.include_source === true ? [artifact.entryPath ?? 'index.html'] : [];
|
| 539 |
+
const files = artifact.files ?? [{
|
| 540 |
+
path: artifact.entryPath ?? 'index.html',
|
| 541 |
+
content: artifact.source,
|
| 542 |
+
mime: 'text/html; charset=utf-8',
|
| 543 |
+
bytes: new TextEncoder().encode(artifact.source).byteLength,
|
| 544 |
+
}];
|
| 545 |
return {
|
| 546 |
call,
|
| 547 |
output: boundedJson({
|
| 548 |
ok: true,
|
| 549 |
artifact: {
|
| 550 |
+
...artifactResult(artifact),
|
|
|
|
|
|
|
| 551 |
evaluation: evaluationResult(getArtifactDiagnostics(artifact)),
|
| 552 |
+
...(requestedPaths.length > 0 ? {
|
| 553 |
+
contents: requestedPaths.map((path) => {
|
| 554 |
+
const file = files.find((candidate) => candidate.path === path);
|
| 555 |
+
if (!file) throw new Error(`artifact file does not exist: ${path}`);
|
| 556 |
+
return { path: file.path, content: file.content };
|
| 557 |
+
}),
|
| 558 |
+
} : {}),
|
| 559 |
},
|
| 560 |
}),
|
| 561 |
failed: false,
|
|
|
|
| 577 |
return {
|
| 578 |
call,
|
| 579 |
artifact,
|
| 580 |
+
relocateArtifact: true,
|
| 581 |
output: boundedJson({ ok: true, artifactId: artifact.id, title, chart: call.function.name, evaluation: evaluationResult(artifact.evaluation) }),
|
| 582 |
failed: false,
|
| 583 |
};
|
src/lib/artifact-runtime.ts
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
export type ArtifactConsoleLevel = 'log' | 'info' | 'warn' | 'error';
|
| 2 |
|
| 3 |
export interface ArtifactConsoleEntry {
|
|
@@ -27,6 +41,11 @@ export interface ArtifactDocument {
|
|
| 27 |
sandboxedSource: string;
|
| 28 |
runtimeToken: string;
|
| 29 |
createdAt: number;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
evaluation?: ArtifactEvaluation;
|
| 31 |
}
|
| 32 |
|
|
@@ -43,6 +62,10 @@ const META_REFRESH = /<meta\b(?=[^>]*\bhttp-equiv\s*=\s*["']?refresh\b)[^>]*>/iu
|
|
| 43 |
const JAVASCRIPT_URL = /\b(?:href|src)\s*=\s*["']\s*javascript:/iu;
|
| 44 |
const SCRIPT_BLOCK = /<script\b[^>]*>([\s\S]*?)<\/script\s*>/giu;
|
| 45 |
const SCRIPT_NAVIGATION = /(?:\b(?:window\s*\.\s*)?location\s*(?:=|\.\s*href\s*=|\.\s*(?:assign|replace|reload)\s*\()|\bwindow\s*\.\s*open\s*\()/iu;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
|
| 47 |
export const ARTIFACT_CONTENT_SECURITY_POLICY = [
|
| 48 |
"default-src 'none'",
|
|
@@ -55,23 +78,236 @@ export const ARTIFACT_CONTENT_SECURITY_POLICY = [
|
|
| 55 |
"media-src data: blob:",
|
| 56 |
"object-src 'none'",
|
| 57 |
"style-src 'unsafe-inline'",
|
| 58 |
-
"script-src 'unsafe-inline'",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 59 |
"worker-src 'none'",
|
| 60 |
].join('; ');
|
| 61 |
|
| 62 |
-
export function configureArtifactIframe(
|
|
|
|
|
|
|
|
|
|
| 63 |
iframe.setAttribute('sandbox', 'allow-scripts');
|
| 64 |
-
iframe.setAttribute('
|
| 65 |
-
iframe.setAttribute('
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
}
|
| 67 |
|
| 68 |
-
function
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
return `<script data-bonsai-artifact-runtime>
|
| 70 |
(() => {
|
| 71 |
const artifactId = ${JSON.stringify(artifactId)};
|
| 72 |
const runtimeToken = ${JSON.stringify(runtimeToken)};
|
|
|
|
|
|
|
| 73 |
const startedAt = performance.now();
|
| 74 |
const entries = [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
const render = (value) => {
|
| 76 |
if (value instanceof Error) return value.stack || value.message;
|
| 77 |
if (typeof value === 'string') return value;
|
|
@@ -142,49 +378,103 @@ function runtimeBridge(artifactId: string, runtimeToken: string): string {
|
|
| 142 |
addEventListener('unhandledrejection', (event) => {
|
| 143 |
record('error', ['Unhandled promise rejection:', event.reason]);
|
| 144 |
});
|
| 145 |
-
addEventListener('DOMContentLoaded', () => setTimeout(() => send('settled'),
|
| 146 |
-
setTimeout(() => send('settled'),
|
| 147 |
})();
|
| 148 |
<\/script>`;
|
| 149 |
}
|
| 150 |
|
| 151 |
-
function
|
| 152 |
-
const
|
| 153 |
-
const
|
| 154 |
-
|
| 155 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 156 |
}
|
| 157 |
|
| 158 |
-
|
| 159 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 160 |
title = 'Untitled artifact',
|
|
|
|
| 161 |
id: string = crypto.randomUUID(),
|
| 162 |
runtimeToken: string = crypto.randomUUID(),
|
| 163 |
): ArtifactDocument {
|
| 164 |
-
const
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
}
|
| 169 |
-
for (const match of source.matchAll(SCRIPT_BLOCK)) {
|
| 170 |
-
if (SCRIPT_NAVIGATION.test(match[1] ?? '')) {
|
| 171 |
-
throw new Error('html_artifact scripts cannot navigate or open another document');
|
| 172 |
-
}
|
| 173 |
-
}
|
| 174 |
return {
|
| 175 |
id,
|
| 176 |
title: title.trim().slice(0, 120) || 'Untitled artifact',
|
| 177 |
-
source,
|
| 178 |
-
sandboxedSource:
|
| 179 |
runtimeToken,
|
| 180 |
createdAt: Date.now(),
|
|
|
|
|
|
|
|
|
|
| 181 |
};
|
| 182 |
}
|
| 183 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
export function normalizeArtifactDocument(artifact: ArtifactDocument): ArtifactDocument {
|
| 185 |
-
const normalized =
|
| 186 |
-
artifact.source,
|
| 187 |
artifact.title,
|
|
|
|
| 188 |
artifact.id,
|
| 189 |
typeof artifact.runtimeToken === 'string' && artifact.runtimeToken
|
| 190 |
? artifact.runtimeToken
|
|
@@ -193,10 +483,74 @@ export function normalizeArtifactDocument(artifact: ArtifactDocument): ArtifactD
|
|
| 193 |
return {
|
| 194 |
...normalized,
|
| 195 |
createdAt: typeof artifact.createdAt === 'number' ? artifact.createdAt : normalized.createdAt,
|
|
|
|
|
|
|
| 196 |
...(artifact.evaluation ? { evaluation: artifact.evaluation } : {}),
|
| 197 |
};
|
| 198 |
}
|
| 199 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 200 |
export function evaluationFromRuntimeMessage(
|
| 201 |
data: unknown,
|
| 202 |
artifactId: string,
|
|
@@ -279,6 +633,15 @@ export function artifactDiagnosticsEventName(): string {
|
|
| 279 |
return ARTIFACT_DIAGNOSTICS_EVENT;
|
| 280 |
}
|
| 281 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 282 |
export async function evaluateHtmlArtifact(
|
| 283 |
artifact: ArtifactDocument,
|
| 284 |
timeoutMs = 2500,
|
|
@@ -287,8 +650,16 @@ export async function evaluateHtmlArtifact(
|
|
| 287 |
if (typeof document === 'undefined' || !document.documentElement) {
|
| 288 |
throw new Error('artifact evaluation requires a browser document');
|
| 289 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 290 |
const iframe = document.createElement('iframe');
|
| 291 |
-
configureArtifactIframe(iframe);
|
| 292 |
iframe.setAttribute('aria-hidden', 'true');
|
| 293 |
iframe.style.position = 'fixed';
|
| 294 |
iframe.style.left = '-10000px';
|
|
@@ -297,7 +668,8 @@ export async function evaluateHtmlArtifact(
|
|
| 297 |
iframe.style.height = '768px';
|
| 298 |
iframe.style.visibility = 'hidden';
|
| 299 |
iframe.style.pointerEvents = 'none';
|
| 300 |
-
iframe.
|
|
|
|
| 301 |
const startedAt = performance.now();
|
| 302 |
|
| 303 |
return new Promise((resolve, reject) => {
|
|
@@ -319,7 +691,7 @@ export async function evaluateHtmlArtifact(
|
|
| 319 |
testedAt: Date.now(),
|
| 320 |
}), timeoutMs);
|
| 321 |
const onMessage = (event: MessageEvent) => {
|
| 322 |
-
if (event
|
| 323 |
const evaluation = evaluationFromRuntimeMessage(event.data, artifact.id, artifact.runtimeToken);
|
| 324 |
if (!evaluation || event.data?.phase !== 'settled') return;
|
| 325 |
finish(evaluation);
|
|
|
|
| 1 |
+
import {
|
| 2 |
+
deleteArtifactWorkspace,
|
| 3 |
+
normalizeArtifactFiles,
|
| 4 |
+
persistArtifactWorkspace,
|
| 5 |
+
publishArtifactWorkspace,
|
| 6 |
+
readArtifactWorkspace,
|
| 7 |
+
type ArtifactFile,
|
| 8 |
+
type ArtifactFileInput,
|
| 9 |
+
type ArtifactWorkspacePersistence,
|
| 10 |
+
type ArtifactWorkspaceSnapshot,
|
| 11 |
+
} from './artifact-workspace';
|
| 12 |
+
|
| 13 |
+
export type { ArtifactFile, ArtifactFileInput } from './artifact-workspace';
|
| 14 |
+
|
| 15 |
export type ArtifactConsoleLevel = 'log' | 'info' | 'warn' | 'error';
|
| 16 |
|
| 17 |
export interface ArtifactConsoleEntry {
|
|
|
|
| 41 |
sandboxedSource: string;
|
| 42 |
runtimeToken: string;
|
| 43 |
createdAt: number;
|
| 44 |
+
entryPath?: string;
|
| 45 |
+
files?: ArtifactFile[];
|
| 46 |
+
schemaVersion?: 2;
|
| 47 |
+
workspaceStorage?: ArtifactWorkspacePersistence['backend'];
|
| 48 |
+
workspaceWarning?: string;
|
| 49 |
evaluation?: ArtifactEvaluation;
|
| 50 |
}
|
| 51 |
|
|
|
|
| 62 |
const JAVASCRIPT_URL = /\b(?:href|src)\s*=\s*["']\s*javascript:/iu;
|
| 63 |
const SCRIPT_BLOCK = /<script\b[^>]*>([\s\S]*?)<\/script\s*>/giu;
|
| 64 |
const SCRIPT_NAVIGATION = /(?:\b(?:window\s*\.\s*)?location\s*(?:=|\.\s*href\s*=|\.\s*(?:assign|replace|reload)\s*\()|\bwindow\s*\.\s*open\s*\()/iu;
|
| 65 |
+
const ROOT_ABSOLUTE_HTML_RESOURCE = /\b(?:src|href|action)\s*=\s*["']\/(?!\/)/iu;
|
| 66 |
+
const ROOT_ABSOLUTE_CSS_RESOURCE = /\burl\s*\(\s*["']?\/(?!\/)/iu;
|
| 67 |
+
const ROOT_ABSOLUTE_MODULE_RESOURCE = /\b(?:from\s*|import\s*(?:\(\s*)?)["']\/(?!\/)/iu;
|
| 68 |
+
const BASE_ELEMENT = /<base\b/iu;
|
| 69 |
|
| 70 |
export const ARTIFACT_CONTENT_SECURITY_POLICY = [
|
| 71 |
"default-src 'none'",
|
|
|
|
| 78 |
"media-src data: blob:",
|
| 79 |
"object-src 'none'",
|
| 80 |
"style-src 'unsafe-inline'",
|
| 81 |
+
"script-src 'unsafe-inline' data:",
|
| 82 |
+
"worker-src 'none'",
|
| 83 |
+
].join('; ');
|
| 84 |
+
|
| 85 |
+
const PUBLISHED_ARTIFACT_CONTENT_SECURITY_POLICY = [
|
| 86 |
+
"default-src 'none'",
|
| 87 |
+
"base-uri 'none'",
|
| 88 |
+
"connect-src 'none'",
|
| 89 |
+
"form-action 'none'",
|
| 90 |
+
"frame-src 'none'",
|
| 91 |
+
"img-src data:",
|
| 92 |
+
"object-src 'none'",
|
| 93 |
+
"style-src 'unsafe-inline'",
|
| 94 |
+
"script-src 'none'",
|
| 95 |
"worker-src 'none'",
|
| 96 |
].join('; ');
|
| 97 |
|
| 98 |
+
export function configureArtifactIframe(
|
| 99 |
+
iframe: HTMLIFrameElement,
|
| 100 |
+
source: 'srcdoc' | 'deployment' = 'srcdoc',
|
| 101 |
+
): void {
|
| 102 |
iframe.setAttribute('sandbox', 'allow-scripts');
|
| 103 |
+
iframe.setAttribute('referrerpolicy', 'no-referrer');
|
| 104 |
+
iframe.setAttribute('allow', '');
|
| 105 |
+
if (source === 'srcdoc') {
|
| 106 |
+
iframe.setAttribute('credentialless', '');
|
| 107 |
+
iframe.setAttribute('csp', ARTIFACT_CONTENT_SECURITY_POLICY);
|
| 108 |
+
} else {
|
| 109 |
+
// Credentialless frames use a separate network context and cannot reach this page's Service Worker.
|
| 110 |
+
iframe.removeAttribute('credentialless');
|
| 111 |
+
iframe.removeAttribute('csp');
|
| 112 |
+
}
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
function scriptSafeJson(value: unknown): string {
|
| 116 |
+
return JSON.stringify(value).replaceAll('<', '\\u003c');
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
function resolveWorkspaceSpecifier(fromPath: string, specifier: string): string | null {
|
| 120 |
+
const clean = specifier.split(/[?#]/u, 1)[0];
|
| 121 |
+
if (!clean
|
| 122 |
+
|| clean.startsWith('#')
|
| 123 |
+
|| clean.startsWith('data:')
|
| 124 |
+
|| clean.startsWith('blob:')
|
| 125 |
+
|| clean.startsWith('//')
|
| 126 |
+
|| /^[a-z][a-z\d+.-]*:/iu.test(clean)
|
| 127 |
+
|| clean.startsWith('/')) return null;
|
| 128 |
+
const segments = fromPath.split('/');
|
| 129 |
+
segments.pop();
|
| 130 |
+
for (const segment of clean.split('/')) {
|
| 131 |
+
if (!segment || segment === '.') continue;
|
| 132 |
+
if (segment === '..') {
|
| 133 |
+
if (segments.length === 0) return null;
|
| 134 |
+
segments.pop();
|
| 135 |
+
} else {
|
| 136 |
+
segments.push(segment);
|
| 137 |
+
}
|
| 138 |
+
}
|
| 139 |
+
return segments.length > 0 ? segments.join('/') : null;
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
function rewriteVfsFetches(source: string, fromPath: string): string {
|
| 143 |
+
return source.replace(
|
| 144 |
+
/\bfetch\s*\(\s*(["'])(\.{1,2}\/[^"']+)\1/gu,
|
| 145 |
+
(match, _quote: string, specifier: string) => {
|
| 146 |
+
const path = resolveWorkspaceSpecifier(fromPath, specifier);
|
| 147 |
+
return path ? `__bonsaiVfsFetch(${JSON.stringify(path)}` : match;
|
| 148 |
+
},
|
| 149 |
+
);
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
function rewriteModuleSource(source: string, fromPath: string): string {
|
| 153 |
+
const rewrite = (match: string, prefix: string, quote: string, specifier: string) => {
|
| 154 |
+
const path = resolveWorkspaceSpecifier(fromPath, specifier);
|
| 155 |
+
return path ? `${prefix}${quote}artifact:${path}${quote}` : match;
|
| 156 |
+
};
|
| 157 |
+
return rewriteVfsFetches(source, fromPath)
|
| 158 |
+
.replace(
|
| 159 |
+
/(\b(?:import|export)\s+(?:[^"'`]*?\s+from\s*)?)(["'])(\.{1,2}\/[^"']+)\2/gu,
|
| 160 |
+
rewrite,
|
| 161 |
+
)
|
| 162 |
+
.replace(
|
| 163 |
+
/(\bimport\s*\(\s*)(["'])(\.{1,2}\/[^"']+)\2/gu,
|
| 164 |
+
rewrite,
|
| 165 |
+
);
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
function textDataUrl(file: Pick<ArtifactFile, 'mime' | 'content'>, content = file.content): string {
|
| 169 |
+
return `data:${file.mime},${encodeURIComponent(content)}`;
|
| 170 |
}
|
| 171 |
|
| 172 |
+
function buildArtifactSrcdoc(
|
| 173 |
+
files: ArtifactFile[],
|
| 174 |
+
entryPath: string,
|
| 175 |
+
artifactId: string,
|
| 176 |
+
runtimeToken: string,
|
| 177 |
+
): string {
|
| 178 |
+
const fileMap = new Map(files.map((file) => [file.path, file]));
|
| 179 |
+
const entry = fileMap.get(entryPath);
|
| 180 |
+
if (!entry) throw new Error(`artifact entry file is missing: ${entryPath}`);
|
| 181 |
+
const rewriteCss = (source: string, fromPath: string, stack = new Set<string>()): string => {
|
| 182 |
+
const withImports = source.replace(
|
| 183 |
+
/@import\s+(?:url\(\s*)?(["'])([^"']+)\1\s*\)?\s*;/giu,
|
| 184 |
+
(match, _quote: string, specifier: string) => {
|
| 185 |
+
const path = resolveWorkspaceSpecifier(fromPath, specifier);
|
| 186 |
+
const imported = path ? fileMap.get(path) : undefined;
|
| 187 |
+
if (!path || !imported?.mime.startsWith('text/css') || stack.has(path)) return match;
|
| 188 |
+
return rewriteCss(imported.content, path, new Set([...stack, path]));
|
| 189 |
+
},
|
| 190 |
+
);
|
| 191 |
+
return withImports.replace(
|
| 192 |
+
/url\(\s*(["']?)([^"')]+)\1\s*\)/giu,
|
| 193 |
+
(match, _quote: string, specifier: string) => {
|
| 194 |
+
const path = resolveWorkspaceSpecifier(fromPath, specifier.trim());
|
| 195 |
+
const asset = path ? fileMap.get(path) : undefined;
|
| 196 |
+
return asset ? `url("${textDataUrl(asset)}")` : match;
|
| 197 |
+
},
|
| 198 |
+
);
|
| 199 |
+
};
|
| 200 |
+
const moduleImports = Object.fromEntries(
|
| 201 |
+
files
|
| 202 |
+
.filter((file) => file.mime.startsWith('text/javascript'))
|
| 203 |
+
.map((file) => [
|
| 204 |
+
`artifact:${file.path}`,
|
| 205 |
+
textDataUrl(file, `${rewriteModuleSource(file.content, file.path)}\n//# sourceURL=artifact:${file.path}`),
|
| 206 |
+
]),
|
| 207 |
+
);
|
| 208 |
+
let source = entry.content;
|
| 209 |
+
source = source.replace(/<style\b([^>]*)>([\s\S]*?)<\/style\s*>/giu, (_match, attributes: string, css: string) => (
|
| 210 |
+
`<style${attributes}>${rewriteCss(css, entryPath, new Set([entryPath]))}</style>`
|
| 211 |
+
));
|
| 212 |
+
source = source.replace(/<link\b([^>]*)>/giu, (match, attributes: string) => {
|
| 213 |
+
const rel = /\brel\s*=\s*(["'])([^"']+)\1/iu.exec(attributes)?.[2]?.toLowerCase() ?? '';
|
| 214 |
+
const hrefMatch = /\bhref\s*=\s*(["'])([^"']+)\1/iu.exec(attributes);
|
| 215 |
+
if (!hrefMatch) return match;
|
| 216 |
+
const path = resolveWorkspaceSpecifier(entryPath, hrefMatch[2]!);
|
| 217 |
+
const file = path ? fileMap.get(path) : undefined;
|
| 218 |
+
if (path && rel.split(/\s+/u).includes('stylesheet') && file?.mime.startsWith('text/css')) {
|
| 219 |
+
return `<style data-bonsai-file="${path}">${rewriteCss(file.content, path, new Set([path]))}</style>`;
|
| 220 |
+
}
|
| 221 |
+
if (rel.split(/\s+/u).includes('icon') && file) {
|
| 222 |
+
return match.replace(hrefMatch[0], `href="${textDataUrl(file)}"`);
|
| 223 |
+
}
|
| 224 |
+
return match;
|
| 225 |
+
});
|
| 226 |
+
source = source.replace(/<(img|source|video|audio|track|input)\b([^>]*)>/giu, (match, tag: string, attributes: string) => {
|
| 227 |
+
const rewritten = attributes.replace(
|
| 228 |
+
/\b(src|poster)\s*=\s*(["'])([^"']+)\2/giu,
|
| 229 |
+
(attribute, name: string, _quote: string, specifier: string) => {
|
| 230 |
+
const path = resolveWorkspaceSpecifier(entryPath, specifier);
|
| 231 |
+
const file = path ? fileMap.get(path) : undefined;
|
| 232 |
+
return file ? `${name}="${textDataUrl(file)}"` : attribute;
|
| 233 |
+
},
|
| 234 |
+
);
|
| 235 |
+
return `<${tag}${rewritten}>`;
|
| 236 |
+
});
|
| 237 |
+
source = source.replace(/<script\b([^>]*)>([\s\S]*?)<\/script\s*>/giu, (match, attributes: string, inline: string) => {
|
| 238 |
+
const srcMatch = /\bsrc\s*=\s*(["'])([^"']+)\1/iu.exec(attributes);
|
| 239 |
+
const moduleScript = /\btype\s*=\s*(["'])module\1/iu.test(attributes);
|
| 240 |
+
const fromPath = srcMatch
|
| 241 |
+
? resolveWorkspaceSpecifier(entryPath, srcMatch[2]!) ?? entryPath
|
| 242 |
+
: entryPath;
|
| 243 |
+
const external = srcMatch ? fileMap.get(fromPath) : undefined;
|
| 244 |
+
if (srcMatch && !external) return match;
|
| 245 |
+
const code = external?.content ?? inline;
|
| 246 |
+
const rewritten = moduleScript
|
| 247 |
+
? rewriteModuleSource(code, fromPath)
|
| 248 |
+
: rewriteVfsFetches(code, fromPath);
|
| 249 |
+
const cleanAttributes = srcMatch
|
| 250 |
+
? attributes
|
| 251 |
+
.replace(srcMatch[0], '')
|
| 252 |
+
.replace(/\b(?:integrity|crossorigin|referrerpolicy)\s*=\s*(["'])[^"']*\1/giu, '')
|
| 253 |
+
: attributes;
|
| 254 |
+
return `<script${cleanAttributes}>${rewritten}<\/script>`;
|
| 255 |
+
});
|
| 256 |
+
const importMap = `<script type="importmap">${scriptSafeJson({ imports: moduleImports })}<\/script>`;
|
| 257 |
+
const injection = `<meta http-equiv="Content-Security-Policy" content="${ARTIFACT_CONTENT_SECURITY_POLICY}">${runtimeBridge(artifactId, runtimeToken, files, entryPath)}${importMap}`;
|
| 258 |
+
const doctype = /^\s*<!doctype\s+html[^>]*>/iu.exec(source);
|
| 259 |
+
if (!doctype) return `${injection}${source}`;
|
| 260 |
+
return `${doctype[0]}${injection}${source.slice(doctype[0].length)}`;
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
function runtimeBridge(
|
| 264 |
+
artifactId: string,
|
| 265 |
+
runtimeToken: string,
|
| 266 |
+
files: ArtifactFile[] = [],
|
| 267 |
+
entryPath = 'index.html',
|
| 268 |
+
): string {
|
| 269 |
+
const serializedFiles = scriptSafeJson(Object.fromEntries(files.map((file) => [
|
| 270 |
+
file.path,
|
| 271 |
+
{ content: file.content, mime: file.mime },
|
| 272 |
+
])));
|
| 273 |
return `<script data-bonsai-artifact-runtime>
|
| 274 |
(() => {
|
| 275 |
const artifactId = ${JSON.stringify(artifactId)};
|
| 276 |
const runtimeToken = ${JSON.stringify(runtimeToken)};
|
| 277 |
+
const vfsFiles = ${serializedFiles};
|
| 278 |
+
const entryPath = ${JSON.stringify(entryPath)};
|
| 279 |
const startedAt = performance.now();
|
| 280 |
const entries = [];
|
| 281 |
+
const resolvePath = (fromPath, specifier) => {
|
| 282 |
+
const value = String(specifier || '').split(/[?#]/, 1)[0];
|
| 283 |
+
if (!value || value.startsWith('/') || value.startsWith('//') || /^[a-z][a-z\\d+.-]*:/i.test(value)) return null;
|
| 284 |
+
const segments = fromPath.split('/');
|
| 285 |
+
segments.pop();
|
| 286 |
+
for (const segment of value.split('/')) {
|
| 287 |
+
if (!segment || segment === '.') continue;
|
| 288 |
+
if (segment === '..') {
|
| 289 |
+
if (segments.length === 0) return null;
|
| 290 |
+
segments.pop();
|
| 291 |
+
} else segments.push(segment);
|
| 292 |
+
}
|
| 293 |
+
return segments.join('/');
|
| 294 |
+
};
|
| 295 |
+
const vfsFetch = (path, init = {}) => {
|
| 296 |
+
const method = String(init?.method || 'GET').toUpperCase();
|
| 297 |
+
if (method !== 'GET' && method !== 'HEAD') return Promise.reject(new TypeError('Artifact VFS is read-only'));
|
| 298 |
+
const file = vfsFiles[path];
|
| 299 |
+
if (!file) return Promise.resolve(new Response('Artifact file not found', { status: 404 }));
|
| 300 |
+
return Promise.resolve(new Response(method === 'HEAD' ? null : file.content, {
|
| 301 |
+
status: 200,
|
| 302 |
+
headers: { 'Content-Type': file.mime, 'Cache-Control': 'no-store' },
|
| 303 |
+
}));
|
| 304 |
+
};
|
| 305 |
+
globalThis.__bonsaiVfsFetch = vfsFetch;
|
| 306 |
+
globalThis.fetch = (input, init) => {
|
| 307 |
+
if (typeof input !== 'string') return Promise.reject(new TypeError('Artifact network access is disabled'));
|
| 308 |
+
const path = resolvePath(entryPath, input);
|
| 309 |
+
return path ? vfsFetch(path, init) : Promise.reject(new TypeError('Artifact network access is disabled'));
|
| 310 |
+
};
|
| 311 |
const render = (value) => {
|
| 312 |
if (value instanceof Error) return value.stack || value.message;
|
| 313 |
if (typeof value === 'string') return value;
|
|
|
|
| 378 |
addEventListener('unhandledrejection', (event) => {
|
| 379 |
record('error', ['Unhandled promise rejection:', event.reason]);
|
| 380 |
});
|
| 381 |
+
addEventListener('DOMContentLoaded', () => setTimeout(() => send('settled'), 500), { once: true });
|
| 382 |
+
setTimeout(() => send('settled'), 1500);
|
| 383 |
})();
|
| 384 |
<\/script>`;
|
| 385 |
}
|
| 386 |
|
| 387 |
+
function validateArtifactSource(file: ArtifactFile): void {
|
| 388 |
+
const lowerPath = file.path.toLowerCase();
|
| 389 |
+
const isHtml = file.mime.startsWith('text/html');
|
| 390 |
+
const isCss = file.mime.startsWith('text/css');
|
| 391 |
+
const isJavaScript = file.mime.startsWith('text/javascript')
|
| 392 |
+
|| lowerPath.endsWith('.js')
|
| 393 |
+
|| lowerPath.endsWith('.mjs');
|
| 394 |
+
if (isHtml && (META_REFRESH.test(file.content) || JAVASCRIPT_URL.test(file.content) || BASE_ELEMENT.test(file.content))) {
|
| 395 |
+
throw new Error(`${file.path} cannot contain base, document navigation, or refresh directives`);
|
| 396 |
+
}
|
| 397 |
+
if (isHtml && ROOT_ABSOLUTE_HTML_RESOURCE.test(file.content)) {
|
| 398 |
+
throw new Error(`${file.path} uses a root-absolute resource; use ./ or another relative path`);
|
| 399 |
+
}
|
| 400 |
+
if (isCss && ROOT_ABSOLUTE_CSS_RESOURCE.test(file.content)) {
|
| 401 |
+
throw new Error(`${file.path} uses a root-absolute CSS resource; use a relative path`);
|
| 402 |
+
}
|
| 403 |
+
if (isJavaScript && ROOT_ABSOLUTE_MODULE_RESOURCE.test(file.content)) {
|
| 404 |
+
throw new Error(`${file.path} uses a root-absolute module; use a relative path`);
|
| 405 |
+
}
|
| 406 |
+
if (isJavaScript && SCRIPT_NAVIGATION.test(file.content)) {
|
| 407 |
+
throw new Error(`${file.path} cannot navigate or open another document`);
|
| 408 |
+
}
|
| 409 |
+
if (isHtml) {
|
| 410 |
+
for (const match of file.content.matchAll(SCRIPT_BLOCK)) {
|
| 411 |
+
if (SCRIPT_NAVIGATION.test(match[1] ?? '')) {
|
| 412 |
+
throw new Error(`${file.path} scripts cannot navigate or open another document`);
|
| 413 |
+
}
|
| 414 |
+
}
|
| 415 |
+
}
|
| 416 |
}
|
| 417 |
|
| 418 |
+
function workspaceSnapshot(artifact: ArtifactDocument): ArtifactWorkspaceSnapshot {
|
| 419 |
+
const normalized = normalizeArtifactFiles(
|
| 420 |
+
artifact.files?.length ? artifact.files : [{ path: 'index.html', content: artifact.source }],
|
| 421 |
+
artifact.entryPath ?? 'index.html',
|
| 422 |
+
);
|
| 423 |
+
for (const file of normalized.files) validateArtifactSource(file);
|
| 424 |
+
return {
|
| 425 |
+
id: artifact.id,
|
| 426 |
+
runtimeToken: artifact.runtimeToken,
|
| 427 |
+
entryPath: normalized.entryPath,
|
| 428 |
+
files: normalized.files,
|
| 429 |
+
};
|
| 430 |
+
}
|
| 431 |
+
|
| 432 |
+
export function prepareArtifactDeployment(
|
| 433 |
+
files: ArtifactFileInput[],
|
| 434 |
title = 'Untitled artifact',
|
| 435 |
+
entryPath = 'index.html',
|
| 436 |
id: string = crypto.randomUUID(),
|
| 437 |
runtimeToken: string = crypto.randomUUID(),
|
| 438 |
): ArtifactDocument {
|
| 439 |
+
const normalized = normalizeArtifactFiles(files, entryPath);
|
| 440 |
+
for (const file of normalized.files) validateArtifactSource(file);
|
| 441 |
+
const entry = normalized.files.find((file) => file.path === normalized.entryPath);
|
| 442 |
+
if (!entry) throw new Error(`artifact entry file is missing: ${normalized.entryPath}`);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 443 |
return {
|
| 444 |
id,
|
| 445 |
title: title.trim().slice(0, 120) || 'Untitled artifact',
|
| 446 |
+
source: entry.content,
|
| 447 |
+
sandboxedSource: buildArtifactSrcdoc(normalized.files, normalized.entryPath, id, runtimeToken),
|
| 448 |
runtimeToken,
|
| 449 |
createdAt: Date.now(),
|
| 450 |
+
entryPath: normalized.entryPath,
|
| 451 |
+
files: normalized.files,
|
| 452 |
+
schemaVersion: 2,
|
| 453 |
};
|
| 454 |
}
|
| 455 |
|
| 456 |
+
export function prepareHtmlArtifact(
|
| 457 |
+
source: string,
|
| 458 |
+
title = 'Untitled artifact',
|
| 459 |
+
id: string = crypto.randomUUID(),
|
| 460 |
+
runtimeToken: string = crypto.randomUUID(),
|
| 461 |
+
): ArtifactDocument {
|
| 462 |
+
const bytes = new TextEncoder().encode(source).byteLength;
|
| 463 |
+
if (bytes > MAX_ARTIFACT_BYTES) throw new Error('html_artifact source exceeds 256 KiB');
|
| 464 |
+
return prepareArtifactDeployment(
|
| 465 |
+
[{ path: 'index.html', content: source }],
|
| 466 |
+
title,
|
| 467 |
+
'index.html',
|
| 468 |
+
id,
|
| 469 |
+
runtimeToken,
|
| 470 |
+
);
|
| 471 |
+
}
|
| 472 |
+
|
| 473 |
export function normalizeArtifactDocument(artifact: ArtifactDocument): ArtifactDocument {
|
| 474 |
+
const normalized = prepareArtifactDeployment(
|
| 475 |
+
artifact.files?.length ? artifact.files : [{ path: 'index.html', content: artifact.source }],
|
| 476 |
artifact.title,
|
| 477 |
+
artifact.entryPath ?? 'index.html',
|
| 478 |
artifact.id,
|
| 479 |
typeof artifact.runtimeToken === 'string' && artifact.runtimeToken
|
| 480 |
? artifact.runtimeToken
|
|
|
|
| 483 |
return {
|
| 484 |
...normalized,
|
| 485 |
createdAt: typeof artifact.createdAt === 'number' ? artifact.createdAt : normalized.createdAt,
|
| 486 |
+
...(artifact.workspaceStorage ? { workspaceStorage: artifact.workspaceStorage } : {}),
|
| 487 |
+
...(artifact.workspaceWarning ? { workspaceWarning: artifact.workspaceWarning } : {}),
|
| 488 |
...(artifact.evaluation ? { evaluation: artifact.evaluation } : {}),
|
| 489 |
};
|
| 490 |
}
|
| 491 |
|
| 492 |
+
export async function hydrateArtifactDocument(artifact: ArtifactDocument): Promise<ArtifactDocument> {
|
| 493 |
+
const normalized = normalizeArtifactDocument(artifact);
|
| 494 |
+
const snapshot = workspaceSnapshot(normalized);
|
| 495 |
+
const stored = await readArtifactWorkspace(snapshot);
|
| 496 |
+
if (!stored) {
|
| 497 |
+
const persistence = await persistArtifactWorkspace(snapshot);
|
| 498 |
+
return {
|
| 499 |
+
...normalized,
|
| 500 |
+
workspaceStorage: persistence.backend,
|
| 501 |
+
...(persistence.warning ? { workspaceWarning: persistence.warning } : {}),
|
| 502 |
+
};
|
| 503 |
+
}
|
| 504 |
+
const files = normalizeArtifactFiles(stored, snapshot.entryPath).files;
|
| 505 |
+
const entry = files.find((file) => file.path === snapshot.entryPath);
|
| 506 |
+
const restored = normalizeArtifactDocument({
|
| 507 |
+
...normalized,
|
| 508 |
+
files,
|
| 509 |
+
source: entry?.content ?? normalized.source,
|
| 510 |
+
});
|
| 511 |
+
return {
|
| 512 |
+
...restored,
|
| 513 |
+
workspaceStorage: 'opfs',
|
| 514 |
+
workspaceWarning: undefined,
|
| 515 |
+
};
|
| 516 |
+
}
|
| 517 |
+
|
| 518 |
+
export interface ArtifactDeployment {
|
| 519 |
+
artifact: ArtifactDocument;
|
| 520 |
+
previewUrl: string | null;
|
| 521 |
+
publishedUrl: string | null;
|
| 522 |
+
}
|
| 523 |
+
|
| 524 |
+
export async function deployArtifactDocument(artifact: ArtifactDocument): Promise<ArtifactDeployment> {
|
| 525 |
+
const normalized = normalizeArtifactDocument(artifact);
|
| 526 |
+
const snapshot = workspaceSnapshot(normalized);
|
| 527 |
+
const persistence = await persistArtifactWorkspace(snapshot);
|
| 528 |
+
const withStorage: ArtifactDocument = {
|
| 529 |
+
...normalized,
|
| 530 |
+
workspaceStorage: persistence.backend,
|
| 531 |
+
...(persistence.warning ? { workspaceWarning: persistence.warning } : {}),
|
| 532 |
+
};
|
| 533 |
+
const entry = snapshot.files.find((file) => file.path === snapshot.entryPath);
|
| 534 |
+
if (!entry) throw new Error(`artifact entry file is missing: ${snapshot.entryPath}`);
|
| 535 |
+
try {
|
| 536 |
+
return {
|
| 537 |
+
artifact: withStorage,
|
| 538 |
+
previewUrl: null,
|
| 539 |
+
publishedUrl: await publishArtifactWorkspace(
|
| 540 |
+
snapshot,
|
| 541 |
+
entry.content,
|
| 542 |
+
PUBLISHED_ARTIFACT_CONTENT_SECURITY_POLICY,
|
| 543 |
+
),
|
| 544 |
+
};
|
| 545 |
+
} catch {
|
| 546 |
+
return { artifact: withStorage, previewUrl: null, publishedUrl: null };
|
| 547 |
+
}
|
| 548 |
+
}
|
| 549 |
+
|
| 550 |
+
export async function deleteArtifactDocumentStorage(artifactId: string): Promise<void> {
|
| 551 |
+
await deleteArtifactWorkspace(artifactId);
|
| 552 |
+
}
|
| 553 |
+
|
| 554 |
export function evaluationFromRuntimeMessage(
|
| 555 |
data: unknown,
|
| 556 |
artifactId: string,
|
|
|
|
| 633 |
return ARTIFACT_DIAGNOSTICS_EVENT;
|
| 634 |
}
|
| 635 |
|
| 636 |
+
export function isArtifactRuntimeMessageEvent(
|
| 637 |
+
event: MessageEvent,
|
| 638 |
+
contentWindow: Window | null | undefined,
|
| 639 |
+
): boolean {
|
| 640 |
+
return Boolean(contentWindow)
|
| 641 |
+
&& event.source === contentWindow
|
| 642 |
+
&& event.origin === 'null';
|
| 643 |
+
}
|
| 644 |
+
|
| 645 |
export async function evaluateHtmlArtifact(
|
| 646 |
artifact: ArtifactDocument,
|
| 647 |
timeoutMs = 2500,
|
|
|
|
| 650 |
if (typeof document === 'undefined' || !document.documentElement) {
|
| 651 |
throw new Error('artifact evaluation requires a browser document');
|
| 652 |
}
|
| 653 |
+
const deployment = await deployArtifactDocument(artifact);
|
| 654 |
+
Object.assign(artifact, {
|
| 655 |
+
files: deployment.artifact.files,
|
| 656 |
+
entryPath: deployment.artifact.entryPath,
|
| 657 |
+
schemaVersion: deployment.artifact.schemaVersion,
|
| 658 |
+
workspaceStorage: deployment.artifact.workspaceStorage,
|
| 659 |
+
workspaceWarning: deployment.artifact.workspaceWarning,
|
| 660 |
+
});
|
| 661 |
const iframe = document.createElement('iframe');
|
| 662 |
+
configureArtifactIframe(iframe, deployment.previewUrl ? 'deployment' : 'srcdoc');
|
| 663 |
iframe.setAttribute('aria-hidden', 'true');
|
| 664 |
iframe.style.position = 'fixed';
|
| 665 |
iframe.style.left = '-10000px';
|
|
|
|
| 668 |
iframe.style.height = '768px';
|
| 669 |
iframe.style.visibility = 'hidden';
|
| 670 |
iframe.style.pointerEvents = 'none';
|
| 671 |
+
if (deployment.previewUrl) iframe.src = deployment.previewUrl;
|
| 672 |
+
else iframe.srcdoc = deployment.artifact.sandboxedSource;
|
| 673 |
const startedAt = performance.now();
|
| 674 |
|
| 675 |
return new Promise((resolve, reject) => {
|
|
|
|
| 691 |
testedAt: Date.now(),
|
| 692 |
}), timeoutMs);
|
| 693 |
const onMessage = (event: MessageEvent) => {
|
| 694 |
+
if (!isArtifactRuntimeMessageEvent(event, iframe.contentWindow)) return;
|
| 695 |
const evaluation = evaluationFromRuntimeMessage(event.data, artifact.id, artifact.runtimeToken);
|
| 696 |
if (!evaluation || event.data?.phase !== 'settled') return;
|
| 697 |
finish(evaluation);
|
src/lib/artifact-workspace.test.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { describe, expect, it } from 'vitest';
|
| 2 |
+
import {
|
| 3 |
+
inferArtifactMime,
|
| 4 |
+
normalizeArtifactFiles,
|
| 5 |
+
normalizeArtifactPath,
|
| 6 |
+
} from './artifact-workspace';
|
| 7 |
+
|
| 8 |
+
describe('artifact workspace paths', () => {
|
| 9 |
+
it('normalizes relative paths and infers browser MIME types', () => {
|
| 10 |
+
expect(normalizeArtifactPath('./src/components/chart.js')).toBe('src/components/chart.js');
|
| 11 |
+
expect(inferArtifactMime('styles/app.css')).toBe('text/css; charset=utf-8');
|
| 12 |
+
expect(inferArtifactMime('assets/logo.svg')).toBe('image/svg+xml; charset=utf-8');
|
| 13 |
+
});
|
| 14 |
+
|
| 15 |
+
it.each([
|
| 16 |
+
'/index.html',
|
| 17 |
+
'../index.html',
|
| 18 |
+
'src/../../index.html',
|
| 19 |
+
'src\\main.js',
|
| 20 |
+
'src//main.js',
|
| 21 |
+
'.bonsai-workspace.json',
|
| 22 |
+
])('rejects paths that escape or collide with the workspace: %s', (path) => {
|
| 23 |
+
expect(() => normalizeArtifactPath(path)).toThrow();
|
| 24 |
+
});
|
| 25 |
+
});
|
| 26 |
+
|
| 27 |
+
describe('artifact workspace files', () => {
|
| 28 |
+
it('builds one bounded manifest with a real HTML entry file', () => {
|
| 29 |
+
const deployment = normalizeArtifactFiles([
|
| 30 |
+
{ path: 'index.html', content: '<link rel="stylesheet" href="./styles/app.css">' },
|
| 31 |
+
{ path: 'styles/app.css', content: 'body { color: green; }' },
|
| 32 |
+
{ path: 'src/main.js', content: 'console.log("ready")' },
|
| 33 |
+
]);
|
| 34 |
+
expect(deployment.entryPath).toBe('index.html');
|
| 35 |
+
expect(deployment.files.map((file) => file.path)).toEqual([
|
| 36 |
+
'index.html',
|
| 37 |
+
'styles/app.css',
|
| 38 |
+
'src/main.js',
|
| 39 |
+
]);
|
| 40 |
+
expect(deployment.totalBytes).toBeGreaterThan(0);
|
| 41 |
+
});
|
| 42 |
+
|
| 43 |
+
it('rejects duplicate, missing-entry, oversized, and non-HTML-entry deployments', () => {
|
| 44 |
+
expect(() => normalizeArtifactFiles([
|
| 45 |
+
{ path: 'index.html', content: 'a' },
|
| 46 |
+
{ path: './index.html', content: 'b' },
|
| 47 |
+
])).toThrow('duplicated');
|
| 48 |
+
expect(() => normalizeArtifactFiles([{ path: 'main.js', content: 'x' }])).toThrow('entry file is missing');
|
| 49 |
+
expect(() => normalizeArtifactFiles([
|
| 50 |
+
{ path: 'index.html', content: 'x'.repeat(512 * 1024 + 1) },
|
| 51 |
+
])).toThrow('512 KiB');
|
| 52 |
+
expect(() => normalizeArtifactFiles([{ path: 'main.js', content: 'x' }], 'main.js')).toThrow('must be HTML');
|
| 53 |
+
});
|
| 54 |
+
});
|
src/lib/artifact-workspace.ts
ADDED
|
@@ -0,0 +1,337 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
export interface ArtifactFileInput {
|
| 2 |
+
path: string;
|
| 3 |
+
content: string;
|
| 4 |
+
}
|
| 5 |
+
|
| 6 |
+
export interface ArtifactFile extends ArtifactFileInput {
|
| 7 |
+
mime: string;
|
| 8 |
+
bytes: number;
|
| 9 |
+
}
|
| 10 |
+
|
| 11 |
+
export interface ArtifactWorkspaceSnapshot {
|
| 12 |
+
id: string;
|
| 13 |
+
runtimeToken: string;
|
| 14 |
+
entryPath: string;
|
| 15 |
+
files: ArtifactFile[];
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
export interface ArtifactWorkspacePersistence {
|
| 19 |
+
backend: 'opfs' | 'snapshot';
|
| 20 |
+
warning?: string;
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
const WORKSPACE_DIRECTORY = 'bonsai-artifact-workspaces';
|
| 24 |
+
const ARTIFACT_CACHE = 'bonsai-artifact-deployments-v2';
|
| 25 |
+
const ARTIFACT_ROUTE = '__bonsai_artifact__';
|
| 26 |
+
const MAX_FILES = 48;
|
| 27 |
+
const MAX_FILE_BYTES = 512 * 1024;
|
| 28 |
+
const MAX_TOTAL_BYTES = 2 * 1024 * 1024;
|
| 29 |
+
const RESERVED_FILE = '.bonsai-workspace.json';
|
| 30 |
+
|
| 31 |
+
const MIME_TYPES: Record<string, string> = {
|
| 32 |
+
'.avif': 'image/avif',
|
| 33 |
+
'.css': 'text/css; charset=utf-8',
|
| 34 |
+
'.csv': 'text/csv; charset=utf-8',
|
| 35 |
+
'.gif': 'image/gif',
|
| 36 |
+
'.htm': 'text/html; charset=utf-8',
|
| 37 |
+
'.html': 'text/html; charset=utf-8',
|
| 38 |
+
'.ico': 'image/x-icon',
|
| 39 |
+
'.jpeg': 'image/jpeg',
|
| 40 |
+
'.jpg': 'image/jpeg',
|
| 41 |
+
'.js': 'text/javascript; charset=utf-8',
|
| 42 |
+
'.json': 'application/json; charset=utf-8',
|
| 43 |
+
'.mjs': 'text/javascript; charset=utf-8',
|
| 44 |
+
'.png': 'image/png',
|
| 45 |
+
'.svg': 'image/svg+xml; charset=utf-8',
|
| 46 |
+
'.txt': 'text/plain; charset=utf-8',
|
| 47 |
+
'.webp': 'image/webp',
|
| 48 |
+
'.woff': 'font/woff',
|
| 49 |
+
'.woff2': 'font/woff2',
|
| 50 |
+
'.xml': 'application/xml; charset=utf-8',
|
| 51 |
+
};
|
| 52 |
+
|
| 53 |
+
let serviceWorkerReady: Promise<void> | null = null;
|
| 54 |
+
|
| 55 |
+
function encodedSegment(value: string): string {
|
| 56 |
+
const bytes = new TextEncoder().encode(value);
|
| 57 |
+
let binary = '';
|
| 58 |
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
| 59 |
+
return btoa(binary).replaceAll('+', '-').replaceAll('/', '_').replace(/=+$/u, '');
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
export function normalizeArtifactPath(value: string): string {
|
| 63 |
+
let path = String(value ?? '').trim();
|
| 64 |
+
while (path.startsWith('./')) path = path.slice(2);
|
| 65 |
+
if (!path || path.length > 240 || path.startsWith('/') || path.includes('\\') || path.includes('\0')) {
|
| 66 |
+
throw new Error(`artifact path is invalid: ${JSON.stringify(value)}`);
|
| 67 |
+
}
|
| 68 |
+
const segments = path.split('/');
|
| 69 |
+
if (segments.some((segment) => !segment || segment === '.' || segment === '..')) {
|
| 70 |
+
throw new Error(`artifact path cannot traverse directories: ${JSON.stringify(value)}`);
|
| 71 |
+
}
|
| 72 |
+
if (segments.some((segment) => segment === RESERVED_FILE)) {
|
| 73 |
+
throw new Error(`${RESERVED_FILE} is reserved by the artifact workspace`);
|
| 74 |
+
}
|
| 75 |
+
return segments.join('/');
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
export function inferArtifactMime(path: string): string {
|
| 79 |
+
const normalized = normalizeArtifactPath(path);
|
| 80 |
+
const dot = normalized.lastIndexOf('.');
|
| 81 |
+
return dot >= 0
|
| 82 |
+
? MIME_TYPES[normalized.slice(dot).toLowerCase()] ?? 'text/plain; charset=utf-8'
|
| 83 |
+
: 'text/plain; charset=utf-8';
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
export function normalizeArtifactFiles(
|
| 87 |
+
values: ArtifactFileInput[],
|
| 88 |
+
requestedEntryPath = 'index.html',
|
| 89 |
+
): { files: ArtifactFile[]; entryPath: string; totalBytes: number } {
|
| 90 |
+
if (!Array.isArray(values) || values.length === 0) throw new Error('artifact deployment needs at least one file');
|
| 91 |
+
if (values.length > MAX_FILES) throw new Error(`artifact deployment exceeds ${MAX_FILES} files`);
|
| 92 |
+
const encoder = new TextEncoder();
|
| 93 |
+
const seen = new Set<string>();
|
| 94 |
+
let totalBytes = 0;
|
| 95 |
+
const files = values.map((value) => {
|
| 96 |
+
if (!value || typeof value.content !== 'string') throw new Error('artifact file content must be text');
|
| 97 |
+
const path = normalizeArtifactPath(value.path);
|
| 98 |
+
if (seen.has(path)) throw new Error(`artifact path is duplicated: ${path}`);
|
| 99 |
+
seen.add(path);
|
| 100 |
+
const bytes = encoder.encode(value.content).byteLength;
|
| 101 |
+
if (bytes > MAX_FILE_BYTES) throw new Error(`${path} exceeds the 512 KiB file limit`);
|
| 102 |
+
totalBytes += bytes;
|
| 103 |
+
return { path, content: value.content, mime: inferArtifactMime(path), bytes };
|
| 104 |
+
});
|
| 105 |
+
if (totalBytes > MAX_TOTAL_BYTES) throw new Error('artifact deployment exceeds the 2 MiB workspace limit');
|
| 106 |
+
const entryPath = normalizeArtifactPath(requestedEntryPath);
|
| 107 |
+
const entry = files.find((file) => file.path === entryPath);
|
| 108 |
+
if (!entry) throw new Error(`artifact entry file is missing: ${entryPath}`);
|
| 109 |
+
if (!entry.mime.startsWith('text/html')) throw new Error('artifact entry file must be HTML');
|
| 110 |
+
return { files, entryPath, totalBytes };
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
function workspaceRootUrl(): URL {
|
| 114 |
+
const base = new URL(import.meta.env.BASE_URL, document.baseURI);
|
| 115 |
+
return new URL(`${ARTIFACT_ROUTE}/`, base);
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
export function artifactPreviewUrl(snapshot: ArtifactWorkspaceSnapshot): string {
|
| 119 |
+
const root = workspaceRootUrl();
|
| 120 |
+
return new URL(`${encodeURIComponent(snapshot.id)}/${encodeURIComponent(snapshot.runtimeToken)}/`, root).href;
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
async function ensureArtifactServiceWorker(): Promise<void> {
|
| 124 |
+
if (serviceWorkerReady) return serviceWorkerReady;
|
| 125 |
+
serviceWorkerReady = (async () => {
|
| 126 |
+
if (!('serviceWorker' in navigator)) throw new Error('artifact virtual server requires Service Worker support');
|
| 127 |
+
const base = new URL(import.meta.env.BASE_URL, document.baseURI);
|
| 128 |
+
const registration = await navigator.serviceWorker.register(
|
| 129 |
+
new URL('artifact-sw.js', base).href,
|
| 130 |
+
{ scope: base.pathname },
|
| 131 |
+
);
|
| 132 |
+
await navigator.serviceWorker.ready;
|
| 133 |
+
if (navigator.serviceWorker.controller) return;
|
| 134 |
+
await new Promise<void>((resolve, reject) => {
|
| 135 |
+
const timer = window.setTimeout(() => {
|
| 136 |
+
navigator.serviceWorker.removeEventListener('controllerchange', handleController);
|
| 137 |
+
reject(new Error('artifact virtual server did not take control of this page'));
|
| 138 |
+
}, 4000);
|
| 139 |
+
const handleController = () => {
|
| 140 |
+
if (!navigator.serviceWorker.controller) return;
|
| 141 |
+
window.clearTimeout(timer);
|
| 142 |
+
navigator.serviceWorker.removeEventListener('controllerchange', handleController);
|
| 143 |
+
resolve();
|
| 144 |
+
};
|
| 145 |
+
navigator.serviceWorker.addEventListener('controllerchange', handleController);
|
| 146 |
+
void registration.update().catch(() => undefined);
|
| 147 |
+
});
|
| 148 |
+
})().catch((error) => {
|
| 149 |
+
serviceWorkerReady = null;
|
| 150 |
+
throw error;
|
| 151 |
+
});
|
| 152 |
+
return serviceWorkerReady;
|
| 153 |
+
}
|
| 154 |
+
|
| 155 |
+
function responseHeaders(file: ArtifactFile, csp?: string): Headers {
|
| 156 |
+
const headers = new Headers({
|
| 157 |
+
'Access-Control-Allow-Origin': '*',
|
| 158 |
+
'Cache-Control': 'no-store',
|
| 159 |
+
'Content-Type': file.mime,
|
| 160 |
+
'Cross-Origin-Resource-Policy': 'cross-origin',
|
| 161 |
+
'Referrer-Policy': 'no-referrer',
|
| 162 |
+
'X-Content-Type-Options': 'nosniff',
|
| 163 |
+
});
|
| 164 |
+
if (file.mime.startsWith('text/html')) {
|
| 165 |
+
headers.set('Content-Security-Policy', csp ?? "default-src 'none'");
|
| 166 |
+
headers.set(
|
| 167 |
+
'Permissions-Policy',
|
| 168 |
+
'camera=(), microphone=(), geolocation=(), payment=(), usb=(), serial=(), bluetooth=(), clipboard-read=(), clipboard-write=()',
|
| 169 |
+
);
|
| 170 |
+
}
|
| 171 |
+
return headers;
|
| 172 |
+
}
|
| 173 |
+
|
| 174 |
+
export async function publishArtifactWorkspace(
|
| 175 |
+
snapshot: ArtifactWorkspaceSnapshot,
|
| 176 |
+
instrumentedEntry: string,
|
| 177 |
+
contentSecurityPolicy: string,
|
| 178 |
+
): Promise<string> {
|
| 179 |
+
await ensureArtifactServiceWorker();
|
| 180 |
+
const cache = await caches.open(ARTIFACT_CACHE);
|
| 181 |
+
const previewUrl = artifactPreviewUrl(snapshot);
|
| 182 |
+
const artifactRoot = new URL(`../`, previewUrl).href;
|
| 183 |
+
const currentPrefix = previewUrl;
|
| 184 |
+
const requests = await cache.keys();
|
| 185 |
+
await Promise.all(requests
|
| 186 |
+
.filter((request) => request.url.startsWith(artifactRoot) && !request.url.startsWith(currentPrefix))
|
| 187 |
+
.map((request) => cache.delete(request)));
|
| 188 |
+
for (const file of snapshot.files) {
|
| 189 |
+
const body = file.path === snapshot.entryPath ? instrumentedEntry : file.content;
|
| 190 |
+
await cache.put(
|
| 191 |
+
new URL(file.path, previewUrl).href,
|
| 192 |
+
new Response(body, { headers: responseHeaders(file, contentSecurityPolicy) }),
|
| 193 |
+
);
|
| 194 |
+
}
|
| 195 |
+
const entry = snapshot.files.find((file) => file.path === snapshot.entryPath);
|
| 196 |
+
if (!entry) throw new Error(`artifact entry file disappeared: ${snapshot.entryPath}`);
|
| 197 |
+
await cache.put(
|
| 198 |
+
previewUrl,
|
| 199 |
+
new Response(instrumentedEntry, { headers: responseHeaders(entry, contentSecurityPolicy) }),
|
| 200 |
+
);
|
| 201 |
+
return previewUrl;
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
async function writeTextFile(directory: FileSystemDirectoryHandle, path: string, content: string): Promise<void> {
|
| 205 |
+
const segments = normalizeArtifactPath(path).split('/');
|
| 206 |
+
const filename = segments.pop();
|
| 207 |
+
if (!filename) throw new Error(`artifact file name is missing: ${path}`);
|
| 208 |
+
let parent = directory;
|
| 209 |
+
for (const segment of segments) {
|
| 210 |
+
parent = await parent.getDirectoryHandle(segment, { create: true });
|
| 211 |
+
}
|
| 212 |
+
const handle = await parent.getFileHandle(filename, { create: true });
|
| 213 |
+
const writable = await handle.createWritable();
|
| 214 |
+
await writable.write(content);
|
| 215 |
+
await writable.close();
|
| 216 |
+
}
|
| 217 |
+
|
| 218 |
+
async function writeWorkspaceManifest(directory: FileSystemDirectoryHandle, value: unknown): Promise<void> {
|
| 219 |
+
const handle = await directory.getFileHandle(RESERVED_FILE, { create: true });
|
| 220 |
+
const writable = await handle.createWritable();
|
| 221 |
+
await writable.write(JSON.stringify(value));
|
| 222 |
+
await writable.close();
|
| 223 |
+
}
|
| 224 |
+
|
| 225 |
+
async function artifactDirectory(
|
| 226 |
+
artifactId: string,
|
| 227 |
+
create: boolean,
|
| 228 |
+
): Promise<FileSystemDirectoryHandle> {
|
| 229 |
+
const storage = navigator.storage as StorageManager & {
|
| 230 |
+
getDirectory?: () => Promise<FileSystemDirectoryHandle>;
|
| 231 |
+
};
|
| 232 |
+
if (typeof storage.getDirectory !== 'function') throw new Error('OPFS is unavailable');
|
| 233 |
+
const root = await storage.getDirectory();
|
| 234 |
+
const workspaces = await root.getDirectoryHandle(WORKSPACE_DIRECTORY, { create });
|
| 235 |
+
return workspaces.getDirectoryHandle(encodedSegment(artifactId), { create });
|
| 236 |
+
}
|
| 237 |
+
|
| 238 |
+
export async function persistArtifactWorkspace(
|
| 239 |
+
snapshot: ArtifactWorkspaceSnapshot,
|
| 240 |
+
): Promise<ArtifactWorkspacePersistence> {
|
| 241 |
+
try {
|
| 242 |
+
const artifact = await artifactDirectory(snapshot.id, true);
|
| 243 |
+
const versionName = encodedSegment(snapshot.runtimeToken);
|
| 244 |
+
await artifact.removeEntry(versionName, { recursive: true }).catch(() => undefined);
|
| 245 |
+
const version = await artifact.getDirectoryHandle(versionName, { create: true });
|
| 246 |
+
for (const file of snapshot.files) await writeTextFile(version, file.path, file.content);
|
| 247 |
+
await writeWorkspaceManifest(version, {
|
| 248 |
+
schemaVersion: 1,
|
| 249 |
+
artifactId: snapshot.id,
|
| 250 |
+
runtimeToken: snapshot.runtimeToken,
|
| 251 |
+
entryPath: snapshot.entryPath,
|
| 252 |
+
files: snapshot.files.map(({ path, mime, bytes }) => ({ path, mime, bytes })),
|
| 253 |
+
});
|
| 254 |
+
await writeWorkspaceManifest(artifact, {
|
| 255 |
+
schemaVersion: 1,
|
| 256 |
+
runtimeToken: snapshot.runtimeToken,
|
| 257 |
+
entryPath: snapshot.entryPath,
|
| 258 |
+
});
|
| 259 |
+
const iterable = artifact as FileSystemDirectoryHandle & {
|
| 260 |
+
entries?: () => AsyncIterableIterator<[string, FileSystemHandle]>;
|
| 261 |
+
};
|
| 262 |
+
if (iterable.entries) {
|
| 263 |
+
for await (const [name, handle] of iterable.entries()) {
|
| 264 |
+
if (handle.kind === 'directory' && name !== versionName) {
|
| 265 |
+
await artifact.removeEntry(name, { recursive: true });
|
| 266 |
+
}
|
| 267 |
+
}
|
| 268 |
+
}
|
| 269 |
+
return { backend: 'opfs' };
|
| 270 |
+
} catch (error) {
|
| 271 |
+
return {
|
| 272 |
+
backend: 'snapshot',
|
| 273 |
+
warning: error instanceof Error ? error.message : String(error),
|
| 274 |
+
};
|
| 275 |
+
}
|
| 276 |
+
}
|
| 277 |
+
|
| 278 |
+
async function readTextFile(directory: FileSystemDirectoryHandle, path: string): Promise<string> {
|
| 279 |
+
const segments = normalizeArtifactPath(path).split('/');
|
| 280 |
+
const filename = segments.pop();
|
| 281 |
+
if (!filename) throw new Error(`artifact file name is missing: ${path}`);
|
| 282 |
+
let parent = directory;
|
| 283 |
+
for (const segment of segments) parent = await parent.getDirectoryHandle(segment);
|
| 284 |
+
return (await (await parent.getFileHandle(filename)).getFile()).text();
|
| 285 |
+
}
|
| 286 |
+
|
| 287 |
+
async function readWorkspaceManifest(directory: FileSystemDirectoryHandle): Promise<string> {
|
| 288 |
+
return (await (await directory.getFileHandle(RESERVED_FILE)).getFile()).text();
|
| 289 |
+
}
|
| 290 |
+
|
| 291 |
+
export async function readArtifactWorkspace(
|
| 292 |
+
snapshot: ArtifactWorkspaceSnapshot,
|
| 293 |
+
): Promise<ArtifactFile[] | null> {
|
| 294 |
+
try {
|
| 295 |
+
const artifact = await artifactDirectory(snapshot.id, false);
|
| 296 |
+
const version = await artifact.getDirectoryHandle(encodedSegment(snapshot.runtimeToken));
|
| 297 |
+
const manifest = JSON.parse(await readWorkspaceManifest(version)) as {
|
| 298 |
+
artifactId?: unknown;
|
| 299 |
+
runtimeToken?: unknown;
|
| 300 |
+
entryPath?: unknown;
|
| 301 |
+
files?: Array<{ path?: unknown }>;
|
| 302 |
+
};
|
| 303 |
+
if (manifest.artifactId !== snapshot.id
|
| 304 |
+
|| manifest.runtimeToken !== snapshot.runtimeToken
|
| 305 |
+
|| manifest.entryPath !== snapshot.entryPath
|
| 306 |
+
|| !Array.isArray(manifest.files)) return null;
|
| 307 |
+
const values = await Promise.all(manifest.files.map(async (file) => ({
|
| 308 |
+
path: String(file.path ?? ''),
|
| 309 |
+
content: await readTextFile(version, String(file.path ?? '')),
|
| 310 |
+
})));
|
| 311 |
+
return normalizeArtifactFiles(values, snapshot.entryPath).files;
|
| 312 |
+
} catch {
|
| 313 |
+
return null;
|
| 314 |
+
}
|
| 315 |
+
}
|
| 316 |
+
|
| 317 |
+
export async function deleteArtifactWorkspace(artifactId: string): Promise<void> {
|
| 318 |
+
const cache = 'caches' in globalThis
|
| 319 |
+
? await caches.open(ARTIFACT_CACHE).catch(() => null)
|
| 320 |
+
: null;
|
| 321 |
+
if (cache) {
|
| 322 |
+
const route = `${workspaceRootUrl().href}${encodeURIComponent(artifactId)}/`;
|
| 323 |
+
const requests = await cache.keys();
|
| 324 |
+
await Promise.all(requests.filter((request) => request.url.startsWith(route)).map((request) => cache.delete(request)));
|
| 325 |
+
}
|
| 326 |
+
try {
|
| 327 |
+
const storage = navigator.storage as StorageManager & {
|
| 328 |
+
getDirectory?: () => Promise<FileSystemDirectoryHandle>;
|
| 329 |
+
};
|
| 330 |
+
if (typeof storage.getDirectory !== 'function') return;
|
| 331 |
+
const root = await storage.getDirectory();
|
| 332 |
+
const workspaces = await root.getDirectoryHandle(WORKSPACE_DIRECTORY);
|
| 333 |
+
await workspaces.removeEntry(encodedSegment(artifactId), { recursive: true });
|
| 334 |
+
} catch {
|
| 335 |
+
// The workspace may already be absent or OPFS may be unavailable.
|
| 336 |
+
}
|
| 337 |
+
}
|
src/lib/tool-routing.test.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
import { describe, expect, it } from 'vitest';
|
| 2 |
-
import {
|
| 3 |
|
| 4 |
describe('HTML artifact intent routing', () => {
|
| 5 |
it.each([
|
|
@@ -23,17 +23,17 @@ describe('HTML artifact intent routing', () => {
|
|
| 23 |
expect(requestsHtmlArtifact(prompt)).toBe(false);
|
| 24 |
});
|
| 25 |
|
| 26 |
-
it('requires only
|
| 27 |
const plan = planClientTools('Напиши HTML-приложение для заметок', true, 0);
|
| 28 |
expect(plan.toolChoice).toBe('required');
|
| 29 |
-
expect(plan.tools?.map((tool) => tool.function.name)).toEqual(['
|
| 30 |
-
expect(plan.requiredToolName).toBe('
|
| 31 |
-
expect(plan.minimumMaxTokens).toBe(
|
| 32 |
expect(plan.minimumMaxTokens).toBe(4_096);
|
| 33 |
-
expect(plan.systemInstruction).toContain('compact
|
| 34 |
expect(plan.systemInstruction).toContain('Do not answer with a Markdown code block');
|
| 35 |
-
expect(plan.systemInstruction).toContain('
|
| 36 |
-
expect(plan.systemInstruction).toContain('until
|
| 37 |
});
|
| 38 |
|
| 39 |
it('returns control to the model with repair tools after the artifact result', () => {
|
|
@@ -41,7 +41,7 @@ describe('HTML artifact intent routing', () => {
|
|
| 41 |
expect(plan.toolChoice).toBe('auto');
|
| 42 |
expect(plan.minimumMaxTokens).toBe(0);
|
| 43 |
expect(plan.tools?.map((tool) => tool.function.name)).toEqual(expect.arrayContaining([
|
| 44 |
-
'
|
| 45 |
'artifact_test',
|
| 46 |
'artifact_inspect',
|
| 47 |
]));
|
|
|
|
| 1 |
import { describe, expect, it } from 'vitest';
|
| 2 |
+
import { ARTIFACT_DEPLOY_MIN_TOKENS, planClientTools, requestsHtmlArtifact } from './tool-routing';
|
| 3 |
|
| 4 |
describe('HTML artifact intent routing', () => {
|
| 5 |
it.each([
|
|
|
|
| 23 |
expect(requestsHtmlArtifact(prompt)).toBe(false);
|
| 24 |
});
|
| 25 |
|
| 26 |
+
it('requires only artifact_deploy on the first matching round', () => {
|
| 27 |
const plan = planClientTools('Напиши HTML-приложение для заметок', true, 0);
|
| 28 |
expect(plan.toolChoice).toBe('required');
|
| 29 |
+
expect(plan.tools?.map((tool) => tool.function.name)).toEqual(['artifact_deploy']);
|
| 30 |
+
expect(plan.requiredToolName).toBe('artifact_deploy');
|
| 31 |
+
expect(plan.minimumMaxTokens).toBe(ARTIFACT_DEPLOY_MIN_TOKENS);
|
| 32 |
expect(plan.minimumMaxTokens).toBe(4_096);
|
| 33 |
+
expect(plan.systemInstruction).toContain('compact browser-ready file tree');
|
| 34 |
expect(plan.systemInstruction).toContain('Do not answer with a Markdown code block');
|
| 35 |
+
expect(plan.systemInstruction).toContain('artifact_write');
|
| 36 |
+
expect(plan.systemInstruction).toContain('until the deployment passes');
|
| 37 |
});
|
| 38 |
|
| 39 |
it('returns control to the model with repair tools after the artifact result', () => {
|
|
|
|
| 41 |
expect(plan.toolChoice).toBe('auto');
|
| 42 |
expect(plan.minimumMaxTokens).toBe(0);
|
| 43 |
expect(plan.tools?.map((tool) => tool.function.name)).toEqual(expect.arrayContaining([
|
| 44 |
+
'artifact_write',
|
| 45 |
'artifact_test',
|
| 46 |
'artifact_inspect',
|
| 47 |
]));
|
src/lib/tool-routing.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
| 1 |
import type { EngineChatTool } from '../engine';
|
| 2 |
-
import { AGENT_TOOLS,
|
| 3 |
import { DEFAULT_MAX_TOKENS } from './runtime-defaults';
|
| 4 |
|
| 5 |
-
export const
|
| 6 |
|
| 7 |
const CREATION_VERB = /(?:\b(?:build|code|create|design|develop|generate|implement|make|write)\b|(?:созда(?:й|йте)|сдела(?:й|йте)|напиш(?:и|ите)|сгенерир(?:уй|уйте)|сверста(?:й|йте)|реализ(?:уй|уйте)|разработа(?:й|йте)|собер(?:и|ите)|постро(?:й|йте)))/iu;
|
| 8 |
const HTML_PRODUCT_TARGET = /(?:\bweb[\s-]?(?:app|application|page|site)\b|\bwebsite\b|\blanding[\s-]?page\b|(?:веб|html)[\s-]?(?:приложени\w*|страниц\w*|сайт\w*|интерфейс\w*)|(?:^|[\s,.:;!?])(?:сайт\w*|лендинг\w*))/iu;
|
|
@@ -34,10 +34,10 @@ export function planClientTools(prompt: string, enabled: boolean, completedToolR
|
|
| 34 |
return { tools: AGENT_TOOLS, toolChoice: 'auto', minimumMaxTokens: 0 };
|
| 35 |
}
|
| 36 |
return {
|
| 37 |
-
tools: [
|
| 38 |
toolChoice: 'required',
|
| 39 |
-
minimumMaxTokens:
|
| 40 |
-
requiredToolName:
|
| 41 |
-
systemInstruction: 'The user explicitly requested
|
| 42 |
};
|
| 43 |
}
|
|
|
|
| 1 |
import type { EngineChatTool } from '../engine';
|
| 2 |
+
import { AGENT_TOOLS, ARTIFACT_DEPLOY_TOOL } from './agent-tools';
|
| 3 |
import { DEFAULT_MAX_TOKENS } from './runtime-defaults';
|
| 4 |
|
| 5 |
+
export const ARTIFACT_DEPLOY_MIN_TOKENS = DEFAULT_MAX_TOKENS;
|
| 6 |
|
| 7 |
const CREATION_VERB = /(?:\b(?:build|code|create|design|develop|generate|implement|make|write)\b|(?:созда(?:й|йте)|сдела(?:й|йте)|напиш(?:и|ите)|сгенерир(?:уй|уйте)|сверста(?:й|йте)|реализ(?:уй|уйте)|разработа(?:й|йте)|собер(?:и|ите)|постро(?:й|йте)))/iu;
|
| 8 |
const HTML_PRODUCT_TARGET = /(?:\bweb[\s-]?(?:app|application|page|site)\b|\bwebsite\b|\blanding[\s-]?page\b|(?:веб|html)[\s-]?(?:приложени\w*|страниц\w*|сайт\w*|интерфейс\w*)|(?:^|[\s,.:;!?])(?:сайт\w*|лендинг\w*))/iu;
|
|
|
|
| 34 |
return { tools: AGENT_TOOLS, toolChoice: 'auto', minimumMaxTokens: 0 };
|
| 35 |
}
|
| 36 |
return {
|
| 37 |
+
tools: [ARTIFACT_DEPLOY_TOOL],
|
| 38 |
toolChoice: 'required',
|
| 39 |
+
minimumMaxTokens: ARTIFACT_DEPLOY_MIN_TOKENS,
|
| 40 |
+
requiredToolName: ARTIFACT_DEPLOY_TOOL.function.name,
|
| 41 |
+
systemInstruction: 'The user explicitly requested a web artifact. Call artifact_deploy exactly once with a compact browser-ready file tree and no build step or packages. Split HTML, CSS, JavaScript, data, and SVG when that improves maintainability. Every local resource, module import, and fetch path must be relative (./ or ../), never start with /. Do not answer with a Markdown code block instead. Read the returned evaluation before claiming success. If it reports errors, inspect the affected files and call artifact_write with only the repairs, then continue until the deployment passes or you can clearly explain the remaining limitation.',
|
| 42 |
};
|
| 43 |
}
|