@lokascript/semantic 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +686 -0
- package/dist/browser-ar.ar.global.js +2 -0
- package/dist/browser-core.core.global.js +2 -0
- package/dist/browser-de.de.global.js +2 -0
- package/dist/browser-east-asian.east-asian.global.js +2 -0
- package/dist/browser-en-tr.en-tr.global.js +2 -0
- package/dist/browser-en.en.global.js +2 -0
- package/dist/browser-es-en.es-en.global.js +2 -0
- package/dist/browser-es.es.global.js +2 -0
- package/dist/browser-fr.fr.global.js +2 -0
- package/dist/browser-id.id.global.js +2 -0
- package/dist/browser-ja.ja.global.js +2 -0
- package/dist/browser-ko.ko.global.js +2 -0
- package/dist/browser-lazy.lazy.global.js +2 -0
- package/dist/browser-priority.priority.global.js +2 -0
- package/dist/browser-pt.pt.global.js +2 -0
- package/dist/browser-qu.qu.global.js +2 -0
- package/dist/browser-sw.sw.global.js +2 -0
- package/dist/browser-tr.tr.global.js +2 -0
- package/dist/browser-western.western.global.js +2 -0
- package/dist/browser-zh.zh.global.js +2 -0
- package/dist/browser.global.js +3 -0
- package/dist/browser.global.js.map +1 -0
- package/dist/index.cjs +35051 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +3426 -0
- package/dist/index.d.ts +3426 -0
- package/dist/index.js +34890 -0
- package/dist/index.js.map +1 -0
- package/dist/languages/ar.d.ts +78 -0
- package/dist/languages/ar.js +1622 -0
- package/dist/languages/ar.js.map +1 -0
- package/dist/languages/de.d.ts +38 -0
- package/dist/languages/de.js +1168 -0
- package/dist/languages/de.js.map +1 -0
- package/dist/languages/en.d.ts +44 -0
- package/dist/languages/en.js +3491 -0
- package/dist/languages/en.js.map +1 -0
- package/dist/languages/es.d.ts +52 -0
- package/dist/languages/es.js +1493 -0
- package/dist/languages/es.js.map +1 -0
- package/dist/languages/fr.d.ts +37 -0
- package/dist/languages/fr.js +1159 -0
- package/dist/languages/fr.js.map +1 -0
- package/dist/languages/id.d.ts +35 -0
- package/dist/languages/id.js +1152 -0
- package/dist/languages/id.js.map +1 -0
- package/dist/languages/ja.d.ts +53 -0
- package/dist/languages/ja.js +1430 -0
- package/dist/languages/ja.js.map +1 -0
- package/dist/languages/ko.d.ts +51 -0
- package/dist/languages/ko.js +1729 -0
- package/dist/languages/ko.js.map +1 -0
- package/dist/languages/pt.d.ts +37 -0
- package/dist/languages/pt.js +1127 -0
- package/dist/languages/pt.js.map +1 -0
- package/dist/languages/qu.d.ts +36 -0
- package/dist/languages/qu.js +1143 -0
- package/dist/languages/qu.js.map +1 -0
- package/dist/languages/sw.d.ts +35 -0
- package/dist/languages/sw.js +1147 -0
- package/dist/languages/sw.js.map +1 -0
- package/dist/languages/tr.d.ts +45 -0
- package/dist/languages/tr.js +1529 -0
- package/dist/languages/tr.js.map +1 -0
- package/dist/languages/zh.d.ts +58 -0
- package/dist/languages/zh.js +1257 -0
- package/dist/languages/zh.js.map +1 -0
- package/dist/types-C4dcj53L.d.ts +600 -0
- package/package.json +202 -0
- package/src/__test-utils__/index.ts +7 -0
- package/src/__test-utils__/test-helpers.ts +8 -0
- package/src/__types__/test-helpers.ts +122 -0
- package/src/analysis/index.ts +479 -0
- package/src/ast-builder/command-mappers.ts +1133 -0
- package/src/ast-builder/expression-parser/index.ts +41 -0
- package/src/ast-builder/expression-parser/parser.ts +563 -0
- package/src/ast-builder/expression-parser/tokenizer.ts +394 -0
- package/src/ast-builder/expression-parser/types.ts +208 -0
- package/src/ast-builder/index.ts +536 -0
- package/src/ast-builder/value-converters.ts +172 -0
- package/src/bridge.ts +275 -0
- package/src/browser-ar.ts +162 -0
- package/src/browser-core.ts +231 -0
- package/src/browser-de.ts +162 -0
- package/src/browser-east-asian.ts +173 -0
- package/src/browser-en-tr.ts +165 -0
- package/src/browser-en.ts +157 -0
- package/src/browser-es-en.ts +200 -0
- package/src/browser-es.ts +170 -0
- package/src/browser-fr.ts +162 -0
- package/src/browser-id.ts +162 -0
- package/src/browser-ja.ts +162 -0
- package/src/browser-ko.ts +162 -0
- package/src/browser-lazy.ts +189 -0
- package/src/browser-priority.ts +214 -0
- package/src/browser-pt.ts +162 -0
- package/src/browser-qu.ts +162 -0
- package/src/browser-sw.ts +162 -0
- package/src/browser-tr.ts +162 -0
- package/src/browser-western.ts +181 -0
- package/src/browser-zh.ts +162 -0
- package/src/browser.ts +268 -0
- package/src/cache/index.ts +14 -0
- package/src/cache/semantic-cache.ts +344 -0
- package/src/core-bridge.ts +372 -0
- package/src/explicit/converter.ts +258 -0
- package/src/explicit/index.ts +18 -0
- package/src/explicit/parser.ts +236 -0
- package/src/explicit/renderer.ts +424 -0
- package/src/generators/command-schemas.ts +1636 -0
- package/src/generators/event-handler-generator.ts +109 -0
- package/src/generators/index.ts +117 -0
- package/src/generators/language-profiles.ts +139 -0
- package/src/generators/pattern-generator.ts +537 -0
- package/src/generators/profiles/arabic.ts +131 -0
- package/src/generators/profiles/bengali.ts +132 -0
- package/src/generators/profiles/chinese.ts +124 -0
- package/src/generators/profiles/english.ts +113 -0
- package/src/generators/profiles/french.ts +125 -0
- package/src/generators/profiles/german.ts +126 -0
- package/src/generators/profiles/hindi.ts +146 -0
- package/src/generators/profiles/index.ts +46 -0
- package/src/generators/profiles/indonesian.ts +125 -0
- package/src/generators/profiles/italian.ts +139 -0
- package/src/generators/profiles/japanese.ts +149 -0
- package/src/generators/profiles/korean.ts +127 -0
- package/src/generators/profiles/marker-templates.ts +288 -0
- package/src/generators/profiles/ms.ts +130 -0
- package/src/generators/profiles/polish.ts +249 -0
- package/src/generators/profiles/portuguese.ts +115 -0
- package/src/generators/profiles/quechua.ts +113 -0
- package/src/generators/profiles/russian.ts +260 -0
- package/src/generators/profiles/spanish.ts +130 -0
- package/src/generators/profiles/swahili.ts +129 -0
- package/src/generators/profiles/thai.ts +132 -0
- package/src/generators/profiles/tl.ts +128 -0
- package/src/generators/profiles/turkish.ts +124 -0
- package/src/generators/profiles/types.ts +165 -0
- package/src/generators/profiles/ukrainian.ts +270 -0
- package/src/generators/profiles/vietnamese.ts +133 -0
- package/src/generators/schema-error-codes.ts +160 -0
- package/src/generators/schema-validator.ts +391 -0
- package/src/index.ts +429 -0
- package/src/language-building-schema.ts +3170 -0
- package/src/language-loader.ts +394 -0
- package/src/languages/_all.ts +65 -0
- package/src/languages/ar.ts +15 -0
- package/src/languages/bn.ts +16 -0
- package/src/languages/de.ts +15 -0
- package/src/languages/en.ts +29 -0
- package/src/languages/es.ts +15 -0
- package/src/languages/fr.ts +15 -0
- package/src/languages/hi.ts +26 -0
- package/src/languages/id.ts +15 -0
- package/src/languages/index.ts +18 -0
- package/src/languages/it.ts +15 -0
- package/src/languages/ja.ts +15 -0
- package/src/languages/ko.ts +15 -0
- package/src/languages/ms.ts +16 -0
- package/src/languages/pl.ts +18 -0
- package/src/languages/pt.ts +15 -0
- package/src/languages/qu.ts +15 -0
- package/src/languages/ru.ts +26 -0
- package/src/languages/sw.ts +15 -0
- package/src/languages/th.ts +16 -0
- package/src/languages/tl.ts +16 -0
- package/src/languages/tr.ts +15 -0
- package/src/languages/uk.ts +26 -0
- package/src/languages/vi.ts +16 -0
- package/src/languages/zh.ts +15 -0
- package/src/parser/index.ts +15 -0
- package/src/parser/pattern-matcher.ts +1181 -0
- package/src/parser/semantic-parser.ts +573 -0
- package/src/parser/utils/index.ts +35 -0
- package/src/parser/utils/marker-resolution.ts +111 -0
- package/src/parser/utils/possessive-keywords.ts +43 -0
- package/src/parser/utils/role-positioning.ts +70 -0
- package/src/parser/utils/type-validation.ts +134 -0
- package/src/patterns/add/ar.ts +71 -0
- package/src/patterns/add/bn.ts +70 -0
- package/src/patterns/add/hi.ts +69 -0
- package/src/patterns/add/index.ts +87 -0
- package/src/patterns/add/it.ts +61 -0
- package/src/patterns/add/ja.ts +93 -0
- package/src/patterns/add/ko.ts +74 -0
- package/src/patterns/add/ms.ts +30 -0
- package/src/patterns/add/pl.ts +62 -0
- package/src/patterns/add/ru.ts +62 -0
- package/src/patterns/add/th.ts +49 -0
- package/src/patterns/add/tl.ts +30 -0
- package/src/patterns/add/tr.ts +71 -0
- package/src/patterns/add/uk.ts +62 -0
- package/src/patterns/add/vi.ts +61 -0
- package/src/patterns/add/zh.ts +71 -0
- package/src/patterns/builders.ts +207 -0
- package/src/patterns/decrement/bn.ts +70 -0
- package/src/patterns/decrement/de.ts +42 -0
- package/src/patterns/decrement/hi.ts +68 -0
- package/src/patterns/decrement/index.ts +79 -0
- package/src/patterns/decrement/it.ts +69 -0
- package/src/patterns/decrement/ms.ts +30 -0
- package/src/patterns/decrement/pl.ts +58 -0
- package/src/patterns/decrement/ru.ts +58 -0
- package/src/patterns/decrement/th.ts +49 -0
- package/src/patterns/decrement/tl.ts +30 -0
- package/src/patterns/decrement/tr.ts +48 -0
- package/src/patterns/decrement/uk.ts +58 -0
- package/src/patterns/decrement/vi.ts +61 -0
- package/src/patterns/decrement/zh.ts +32 -0
- package/src/patterns/en.ts +302 -0
- package/src/patterns/event-handler/ar.ts +151 -0
- package/src/patterns/event-handler/bn.ts +72 -0
- package/src/patterns/event-handler/de.ts +117 -0
- package/src/patterns/event-handler/en.ts +117 -0
- package/src/patterns/event-handler/es.ts +136 -0
- package/src/patterns/event-handler/fr.ts +117 -0
- package/src/patterns/event-handler/hi.ts +64 -0
- package/src/patterns/event-handler/id.ts +117 -0
- package/src/patterns/event-handler/index.ts +119 -0
- package/src/patterns/event-handler/it.ts +54 -0
- package/src/patterns/event-handler/ja.ts +118 -0
- package/src/patterns/event-handler/ko.ts +133 -0
- package/src/patterns/event-handler/ms.ts +30 -0
- package/src/patterns/event-handler/pl.ts +62 -0
- package/src/patterns/event-handler/pt.ts +117 -0
- package/src/patterns/event-handler/qu.ts +66 -0
- package/src/patterns/event-handler/ru.ts +62 -0
- package/src/patterns/event-handler/shared.ts +270 -0
- package/src/patterns/event-handler/sw.ts +117 -0
- package/src/patterns/event-handler/th.ts +53 -0
- package/src/patterns/event-handler/tl.ts +30 -0
- package/src/patterns/event-handler/tr.ts +170 -0
- package/src/patterns/event-handler/uk.ts +62 -0
- package/src/patterns/event-handler/vi.ts +61 -0
- package/src/patterns/event-handler/zh.ts +150 -0
- package/src/patterns/get/ar.ts +49 -0
- package/src/patterns/get/bn.ts +47 -0
- package/src/patterns/get/de.ts +32 -0
- package/src/patterns/get/hi.ts +52 -0
- package/src/patterns/get/index.ts +83 -0
- package/src/patterns/get/it.ts +56 -0
- package/src/patterns/get/ja.ts +53 -0
- package/src/patterns/get/ko.ts +53 -0
- package/src/patterns/get/ms.ts +30 -0
- package/src/patterns/get/pl.ts +57 -0
- package/src/patterns/get/ru.ts +57 -0
- package/src/patterns/get/th.ts +29 -0
- package/src/patterns/get/tl.ts +30 -0
- package/src/patterns/get/uk.ts +57 -0
- package/src/patterns/get/vi.ts +48 -0
- package/src/patterns/grammar-transformed/index.ts +39 -0
- package/src/patterns/grammar-transformed/ja.ts +1713 -0
- package/src/patterns/grammar-transformed/ko.ts +1311 -0
- package/src/patterns/grammar-transformed/tr.ts +1067 -0
- package/src/patterns/hide/ar.ts +67 -0
- package/src/patterns/hide/bn.ts +47 -0
- package/src/patterns/hide/de.ts +36 -0
- package/src/patterns/hide/hi.ts +61 -0
- package/src/patterns/hide/index.ts +91 -0
- package/src/patterns/hide/it.ts +56 -0
- package/src/patterns/hide/ja.ts +69 -0
- package/src/patterns/hide/ko.ts +69 -0
- package/src/patterns/hide/ms.ts +30 -0
- package/src/patterns/hide/pl.ts +57 -0
- package/src/patterns/hide/ru.ts +57 -0
- package/src/patterns/hide/th.ts +29 -0
- package/src/patterns/hide/tl.ts +30 -0
- package/src/patterns/hide/tr.ts +65 -0
- package/src/patterns/hide/uk.ts +57 -0
- package/src/patterns/hide/vi.ts +56 -0
- package/src/patterns/hide/zh.ts +68 -0
- package/src/patterns/increment/bn.ts +70 -0
- package/src/patterns/increment/de.ts +36 -0
- package/src/patterns/increment/hi.ts +68 -0
- package/src/patterns/increment/index.ts +79 -0
- package/src/patterns/increment/it.ts +69 -0
- package/src/patterns/increment/ms.ts +30 -0
- package/src/patterns/increment/pl.ts +58 -0
- package/src/patterns/increment/ru.ts +58 -0
- package/src/patterns/increment/th.ts +49 -0
- package/src/patterns/increment/tl.ts +30 -0
- package/src/patterns/increment/tr.ts +52 -0
- package/src/patterns/increment/uk.ts +58 -0
- package/src/patterns/increment/vi.ts +61 -0
- package/src/patterns/increment/zh.ts +32 -0
- package/src/patterns/index.ts +84 -0
- package/src/patterns/languages/en/control-flow.ts +93 -0
- package/src/patterns/languages/en/fetch.ts +62 -0
- package/src/patterns/languages/en/index.ts +42 -0
- package/src/patterns/languages/en/repeat.ts +67 -0
- package/src/patterns/languages/en/set.ts +48 -0
- package/src/patterns/languages/en/swap.ts +38 -0
- package/src/patterns/languages/en/temporal.ts +57 -0
- package/src/patterns/put/ar.ts +74 -0
- package/src/patterns/put/bn.ts +53 -0
- package/src/patterns/put/en.ts +74 -0
- package/src/patterns/put/es.ts +74 -0
- package/src/patterns/put/hi.ts +69 -0
- package/src/patterns/put/id.ts +96 -0
- package/src/patterns/put/index.ts +99 -0
- package/src/patterns/put/it.ts +56 -0
- package/src/patterns/put/ja.ts +75 -0
- package/src/patterns/put/ko.ts +67 -0
- package/src/patterns/put/ms.ts +30 -0
- package/src/patterns/put/pl.ts +81 -0
- package/src/patterns/put/ru.ts +85 -0
- package/src/patterns/put/th.ts +32 -0
- package/src/patterns/put/tl.ts +30 -0
- package/src/patterns/put/tr.ts +67 -0
- package/src/patterns/put/uk.ts +85 -0
- package/src/patterns/put/vi.ts +72 -0
- package/src/patterns/put/zh.ts +62 -0
- package/src/patterns/registry.ts +163 -0
- package/src/patterns/remove/ar.ts +71 -0
- package/src/patterns/remove/bn.ts +68 -0
- package/src/patterns/remove/hi.ts +69 -0
- package/src/patterns/remove/index.ts +87 -0
- package/src/patterns/remove/it.ts +69 -0
- package/src/patterns/remove/ja.ts +74 -0
- package/src/patterns/remove/ko.ts +78 -0
- package/src/patterns/remove/ms.ts +30 -0
- package/src/patterns/remove/pl.ts +62 -0
- package/src/patterns/remove/ru.ts +62 -0
- package/src/patterns/remove/th.ts +49 -0
- package/src/patterns/remove/tl.ts +30 -0
- package/src/patterns/remove/tr.ts +78 -0
- package/src/patterns/remove/uk.ts +62 -0
- package/src/patterns/remove/vi.ts +61 -0
- package/src/patterns/remove/zh.ts +72 -0
- package/src/patterns/set/ar.ts +84 -0
- package/src/patterns/set/bn.ts +53 -0
- package/src/patterns/set/de.ts +84 -0
- package/src/patterns/set/es.ts +92 -0
- package/src/patterns/set/fr.ts +88 -0
- package/src/patterns/set/hi.ts +56 -0
- package/src/patterns/set/id.ts +84 -0
- package/src/patterns/set/index.ts +107 -0
- package/src/patterns/set/it.ts +56 -0
- package/src/patterns/set/ja.ts +86 -0
- package/src/patterns/set/ko.ts +85 -0
- package/src/patterns/set/ms.ts +30 -0
- package/src/patterns/set/pl.ts +57 -0
- package/src/patterns/set/pt.ts +84 -0
- package/src/patterns/set/ru.ts +57 -0
- package/src/patterns/set/th.ts +31 -0
- package/src/patterns/set/tl.ts +30 -0
- package/src/patterns/set/tr.ts +107 -0
- package/src/patterns/set/uk.ts +57 -0
- package/src/patterns/set/vi.ts +53 -0
- package/src/patterns/set/zh.ts +84 -0
- package/src/patterns/show/ar.ts +67 -0
- package/src/patterns/show/bn.ts +47 -0
- package/src/patterns/show/de.ts +32 -0
- package/src/patterns/show/fr.ts +32 -0
- package/src/patterns/show/hi.ts +61 -0
- package/src/patterns/show/index.ts +95 -0
- package/src/patterns/show/it.ts +56 -0
- package/src/patterns/show/ja.ts +69 -0
- package/src/patterns/show/ko.ts +73 -0
- package/src/patterns/show/ms.ts +30 -0
- package/src/patterns/show/pl.ts +57 -0
- package/src/patterns/show/ru.ts +57 -0
- package/src/patterns/show/th.ts +29 -0
- package/src/patterns/show/tl.ts +30 -0
- package/src/patterns/show/tr.ts +65 -0
- package/src/patterns/show/uk.ts +57 -0
- package/src/patterns/show/vi.ts +56 -0
- package/src/patterns/show/zh.ts +68 -0
- package/src/patterns/take/ar.ts +51 -0
- package/src/patterns/take/index.ts +31 -0
- package/src/patterns/toggle/ar.ts +61 -0
- package/src/patterns/toggle/bn.ts +70 -0
- package/src/patterns/toggle/en.ts +61 -0
- package/src/patterns/toggle/es.ts +61 -0
- package/src/patterns/toggle/hi.ts +80 -0
- package/src/patterns/toggle/index.ts +95 -0
- package/src/patterns/toggle/it.ts +69 -0
- package/src/patterns/toggle/ja.ts +156 -0
- package/src/patterns/toggle/ko.ts +113 -0
- package/src/patterns/toggle/ms.ts +30 -0
- package/src/patterns/toggle/pl.ts +62 -0
- package/src/patterns/toggle/ru.ts +62 -0
- package/src/patterns/toggle/th.ts +50 -0
- package/src/patterns/toggle/tl.ts +30 -0
- package/src/patterns/toggle/tr.ts +88 -0
- package/src/patterns/toggle/uk.ts +62 -0
- package/src/patterns/toggle/vi.ts +61 -0
- package/src/patterns/toggle/zh.ts +99 -0
- package/src/public-api.ts +286 -0
- package/src/registry.ts +441 -0
- package/src/tokenizers/arabic.ts +723 -0
- package/src/tokenizers/base.ts +1300 -0
- package/src/tokenizers/bengali.ts +289 -0
- package/src/tokenizers/chinese.ts +481 -0
- package/src/tokenizers/english.ts +416 -0
- package/src/tokenizers/french.ts +326 -0
- package/src/tokenizers/german.ts +324 -0
- package/src/tokenizers/hindi.ts +319 -0
- package/src/tokenizers/index.ts +127 -0
- package/src/tokenizers/indonesian.ts +306 -0
- package/src/tokenizers/italian.ts +458 -0
- package/src/tokenizers/japanese.ts +447 -0
- package/src/tokenizers/korean.ts +642 -0
- package/src/tokenizers/morphology/arabic-normalizer.ts +242 -0
- package/src/tokenizers/morphology/french-normalizer.ts +268 -0
- package/src/tokenizers/morphology/german-normalizer.ts +256 -0
- package/src/tokenizers/morphology/index.ts +46 -0
- package/src/tokenizers/morphology/italian-normalizer.ts +329 -0
- package/src/tokenizers/morphology/japanese-normalizer.ts +288 -0
- package/src/tokenizers/morphology/korean-normalizer.ts +428 -0
- package/src/tokenizers/morphology/polish-normalizer.ts +264 -0
- package/src/tokenizers/morphology/portuguese-normalizer.ts +310 -0
- package/src/tokenizers/morphology/spanish-normalizer.ts +327 -0
- package/src/tokenizers/morphology/turkish-normalizer.ts +412 -0
- package/src/tokenizers/morphology/types.ts +211 -0
- package/src/tokenizers/ms.ts +198 -0
- package/src/tokenizers/polish.ts +354 -0
- package/src/tokenizers/portuguese.ts +304 -0
- package/src/tokenizers/quechua.ts +339 -0
- package/src/tokenizers/russian.ts +375 -0
- package/src/tokenizers/spanish.ts +403 -0
- package/src/tokenizers/swahili.ts +303 -0
- package/src/tokenizers/thai.ts +236 -0
- package/src/tokenizers/tl.ts +198 -0
- package/src/tokenizers/turkish.ts +411 -0
- package/src/tokenizers/ukrainian.ts +369 -0
- package/src/tokenizers/vietnamese.ts +410 -0
- package/src/types/grammar-types.ts +617 -0
- package/src/types/unified-profile.ts +267 -0
- package/src/types.ts +709 -0
- package/src/utils/confidence-calculator.ts +147 -0
- package/src/validators/command-validator.ts +380 -0
- package/src/validators/index.ts +15 -0
|
@@ -0,0 +1,3491 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __esm = (fn, res) => function __init() {
|
|
4
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
5
|
+
};
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
// src/generators/schema-error-codes.ts
|
|
12
|
+
function interpolate(template, params) {
|
|
13
|
+
return template.replace(/\{(\w+)\}/g, (_, key) => String(params[key] ?? `{${key}}`));
|
|
14
|
+
}
|
|
15
|
+
function createSchemaValidationItem(code, severity, params = {}, role) {
|
|
16
|
+
const messageTemplate = SchemaErrorMessages[code];
|
|
17
|
+
const message = interpolate(messageTemplate, params);
|
|
18
|
+
const suggestionTemplate = SchemaErrorSuggestions[code];
|
|
19
|
+
const suggestion = suggestionTemplate ? interpolate(suggestionTemplate, params) : void 0;
|
|
20
|
+
return {
|
|
21
|
+
code,
|
|
22
|
+
message,
|
|
23
|
+
severity,
|
|
24
|
+
...role && { role },
|
|
25
|
+
...suggestion && { suggestion }
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
var SchemaErrorCodes, SchemaErrorMessages, SchemaErrorSuggestions;
|
|
29
|
+
var init_schema_error_codes = __esm({
|
|
30
|
+
"src/generators/schema-error-codes.ts"() {
|
|
31
|
+
"use strict";
|
|
32
|
+
SchemaErrorCodes = {
|
|
33
|
+
// Type ambiguity issues
|
|
34
|
+
AMBIGUOUS_TYPE_LITERAL_SELECTOR: "SCHEMA_AMBIGUOUS_TYPE_LITERAL_SELECTOR",
|
|
35
|
+
TOO_MANY_EXPECTED_TYPES: "SCHEMA_TOO_MANY_EXPECTED_TYPES",
|
|
36
|
+
MULTI_TYPE_PATIENT_EXPECTED: "SCHEMA_MULTI_TYPE_PATIENT_EXPECTED",
|
|
37
|
+
// Role issues
|
|
38
|
+
NO_REQUIRED_ROLES: "SCHEMA_NO_REQUIRED_ROLES",
|
|
39
|
+
NO_REQUIRED_ROLES_EXPECTED: "SCHEMA_NO_REQUIRED_ROLES_EXPECTED",
|
|
40
|
+
// Transition command
|
|
41
|
+
TRANSITION_PATIENT_ACCEPTS_SELECTOR: "SCHEMA_TRANSITION_PATIENT_ACCEPTS_SELECTOR",
|
|
42
|
+
TRANSITION_MISSING_GOAL: "SCHEMA_TRANSITION_MISSING_GOAL",
|
|
43
|
+
// Event handler command
|
|
44
|
+
EVENT_HANDLER_MISSING_EVENT: "SCHEMA_EVENT_HANDLER_MISSING_EVENT",
|
|
45
|
+
EVENT_HANDLER_EVENT_NOT_REQUIRED: "SCHEMA_EVENT_HANDLER_EVENT_NOT_REQUIRED",
|
|
46
|
+
// Conditional commands
|
|
47
|
+
CONDITIONAL_MISSING_CONDITION: "SCHEMA_CONDITIONAL_MISSING_CONDITION",
|
|
48
|
+
CONDITIONAL_CONDITION_NOT_REQUIRED: "SCHEMA_CONDITIONAL_CONDITION_NOT_REQUIRED",
|
|
49
|
+
// Loop commands
|
|
50
|
+
FOR_LOOP_MISSING_SOURCE: "SCHEMA_FOR_LOOP_MISSING_SOURCE",
|
|
51
|
+
WHILE_LOOP_MISSING_CONDITION: "SCHEMA_WHILE_LOOP_MISSING_CONDITION"
|
|
52
|
+
};
|
|
53
|
+
SchemaErrorMessages = {
|
|
54
|
+
// Type ambiguity
|
|
55
|
+
[SchemaErrorCodes.AMBIGUOUS_TYPE_LITERAL_SELECTOR]: "Role '{role}' accepts both 'literal' and 'selector'. This may cause ambiguous type inference for values starting with special characters (* . # etc.).",
|
|
56
|
+
[SchemaErrorCodes.TOO_MANY_EXPECTED_TYPES]: "Role '{role}' accepts {count} different types. This may make type inference unreliable.",
|
|
57
|
+
[SchemaErrorCodes.MULTI_TYPE_PATIENT_EXPECTED]: "Role '{role}' accepts multiple types (expected for {command} command).",
|
|
58
|
+
// Role issues
|
|
59
|
+
[SchemaErrorCodes.NO_REQUIRED_ROLES]: "Command has no required roles. Is this intentional?",
|
|
60
|
+
[SchemaErrorCodes.NO_REQUIRED_ROLES_EXPECTED]: "Command has no required roles (expected for {command}).",
|
|
61
|
+
// Transition
|
|
62
|
+
[SchemaErrorCodes.TRANSITION_PATIENT_ACCEPTS_SELECTOR]: "Transition command 'patient' role (CSS property name) should only accept 'literal', not 'selector'. CSS property names like 'background-color' are strings, not CSS selectors.",
|
|
63
|
+
[SchemaErrorCodes.TRANSITION_MISSING_GOAL]: "Transition command requires a 'goal' role for the target value (to <value>). Without it, there's no way to specify what value to transition to.",
|
|
64
|
+
// Event handler
|
|
65
|
+
[SchemaErrorCodes.EVENT_HANDLER_MISSING_EVENT]: "Event handler command should have an 'event' role to specify which event to listen for.",
|
|
66
|
+
[SchemaErrorCodes.EVENT_HANDLER_EVENT_NOT_REQUIRED]: "Event role should be required - every event handler needs an event to listen for.",
|
|
67
|
+
// Conditionals
|
|
68
|
+
[SchemaErrorCodes.CONDITIONAL_MISSING_CONDITION]: "Conditional command should have a 'condition' role for the boolean expression.",
|
|
69
|
+
[SchemaErrorCodes.CONDITIONAL_CONDITION_NOT_REQUIRED]: "Condition role should be required - conditionals need a condition to evaluate.",
|
|
70
|
+
// Loops
|
|
71
|
+
[SchemaErrorCodes.FOR_LOOP_MISSING_SOURCE]: "For-loop should have a 'source' role for the collection to iterate over.",
|
|
72
|
+
[SchemaErrorCodes.WHILE_LOOP_MISSING_CONDITION]: "While-loop should have a 'condition' role for the loop condition."
|
|
73
|
+
};
|
|
74
|
+
SchemaErrorSuggestions = {
|
|
75
|
+
[SchemaErrorCodes.AMBIGUOUS_TYPE_LITERAL_SELECTOR]: "Consider being more specific about which type is expected, or use explicit type markers.",
|
|
76
|
+
[SchemaErrorCodes.TOO_MANY_EXPECTED_TYPES]: "Consider narrowing the accepted types to improve type inference reliability.",
|
|
77
|
+
[SchemaErrorCodes.TRANSITION_PATIENT_ACCEPTS_SELECTOR]: "Remove 'selector' from expectedTypes and only accept 'literal'.",
|
|
78
|
+
[SchemaErrorCodes.TRANSITION_MISSING_GOAL]: "Add a 'goal' role with expectedTypes ['literal', 'variable'].",
|
|
79
|
+
[SchemaErrorCodes.EVENT_HANDLER_MISSING_EVENT]: "Add an 'event' role with expectedTypes ['literal'].",
|
|
80
|
+
[SchemaErrorCodes.EVENT_HANDLER_EVENT_NOT_REQUIRED]: "Set required: true on the 'event' role.",
|
|
81
|
+
[SchemaErrorCodes.CONDITIONAL_MISSING_CONDITION]: "Add a 'condition' role with expectedTypes ['expression'].",
|
|
82
|
+
[SchemaErrorCodes.CONDITIONAL_CONDITION_NOT_REQUIRED]: "Set required: true on the 'condition' role.",
|
|
83
|
+
[SchemaErrorCodes.FOR_LOOP_MISSING_SOURCE]: "Add a 'source' role for the collection to iterate over.",
|
|
84
|
+
[SchemaErrorCodes.WHILE_LOOP_MISSING_CONDITION]: "Add a 'condition' role for the loop continuation condition."
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// src/generators/schema-validator.ts
|
|
90
|
+
var schema_validator_exports = {};
|
|
91
|
+
__export(schema_validator_exports, {
|
|
92
|
+
SchemaErrorCodes: () => SchemaErrorCodes,
|
|
93
|
+
formatValidationResults: () => formatValidationResults,
|
|
94
|
+
getValidationStats: () => getValidationStats,
|
|
95
|
+
validateAllSchemas: () => validateAllSchemas,
|
|
96
|
+
validateCommandSchema: () => validateCommandSchema
|
|
97
|
+
});
|
|
98
|
+
function createValidationResult(action, items) {
|
|
99
|
+
return {
|
|
100
|
+
action,
|
|
101
|
+
items,
|
|
102
|
+
get notes() {
|
|
103
|
+
return items.filter((i) => i.severity === "note").map((i) => i.message);
|
|
104
|
+
},
|
|
105
|
+
get warnings() {
|
|
106
|
+
return items.filter((i) => i.severity === "warning").map((i) => i.message);
|
|
107
|
+
},
|
|
108
|
+
get errors() {
|
|
109
|
+
return items.filter((i) => i.severity === "error").map((i) => i.message);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function validateCommandSchema(schema) {
|
|
114
|
+
const items = [];
|
|
115
|
+
for (const role of schema.roles) {
|
|
116
|
+
if (role.expectedTypes.includes("literal") && role.expectedTypes.includes("selector")) {
|
|
117
|
+
if (role.role === "patient" && MULTI_TYPE_PATIENT_COMMANDS.has(schema.action)) {
|
|
118
|
+
items.push(
|
|
119
|
+
createSchemaValidationItem(
|
|
120
|
+
SchemaErrorCodes.MULTI_TYPE_PATIENT_EXPECTED,
|
|
121
|
+
"note",
|
|
122
|
+
{ role: role.role, command: schema.action },
|
|
123
|
+
role.role
|
|
124
|
+
)
|
|
125
|
+
);
|
|
126
|
+
} else {
|
|
127
|
+
items.push(
|
|
128
|
+
createSchemaValidationItem(
|
|
129
|
+
SchemaErrorCodes.AMBIGUOUS_TYPE_LITERAL_SELECTOR,
|
|
130
|
+
"warning",
|
|
131
|
+
{ role: role.role },
|
|
132
|
+
role.role
|
|
133
|
+
)
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (role.expectedTypes.length > 3 && !MULTI_TYPE_PATIENT_COMMANDS.has(schema.action)) {
|
|
138
|
+
items.push(
|
|
139
|
+
createSchemaValidationItem(
|
|
140
|
+
SchemaErrorCodes.TOO_MANY_EXPECTED_TYPES,
|
|
141
|
+
"warning",
|
|
142
|
+
{ role: role.role, count: role.expectedTypes.length },
|
|
143
|
+
role.role
|
|
144
|
+
)
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
switch (schema.action) {
|
|
149
|
+
case "transition":
|
|
150
|
+
validateTransitionSchema(schema, items);
|
|
151
|
+
break;
|
|
152
|
+
case "on":
|
|
153
|
+
validateEventHandlerSchema(schema, items);
|
|
154
|
+
break;
|
|
155
|
+
case "if":
|
|
156
|
+
case "unless":
|
|
157
|
+
validateConditionalSchema(schema, items);
|
|
158
|
+
break;
|
|
159
|
+
case "repeat":
|
|
160
|
+
case "for":
|
|
161
|
+
case "while":
|
|
162
|
+
validateLoopSchema(schema, items);
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
const requiredRoles = schema.roles.filter((r) => r.required);
|
|
166
|
+
if (requiredRoles.length === 0) {
|
|
167
|
+
if (NO_REQUIRED_ROLES_COMMANDS.has(schema.action)) {
|
|
168
|
+
items.push(
|
|
169
|
+
createSchemaValidationItem(SchemaErrorCodes.NO_REQUIRED_ROLES_EXPECTED, "note", {
|
|
170
|
+
command: schema.action
|
|
171
|
+
})
|
|
172
|
+
);
|
|
173
|
+
} else {
|
|
174
|
+
items.push(createSchemaValidationItem(SchemaErrorCodes.NO_REQUIRED_ROLES, "warning", {}));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return createValidationResult(schema.action, items);
|
|
178
|
+
}
|
|
179
|
+
function validateTransitionSchema(schema, items) {
|
|
180
|
+
const patientRole = schema.roles.find((r) => r.role === "patient");
|
|
181
|
+
const goalRole = schema.roles.find((r) => r.role === "goal");
|
|
182
|
+
if (patientRole && patientRole.expectedTypes.includes("selector")) {
|
|
183
|
+
items.push(
|
|
184
|
+
createSchemaValidationItem(
|
|
185
|
+
SchemaErrorCodes.TRANSITION_PATIENT_ACCEPTS_SELECTOR,
|
|
186
|
+
"warning",
|
|
187
|
+
{},
|
|
188
|
+
"patient"
|
|
189
|
+
)
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
if (patientRole && !goalRole) {
|
|
193
|
+
items.push(createSchemaValidationItem(SchemaErrorCodes.TRANSITION_MISSING_GOAL, "error", {}));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
function validateEventHandlerSchema(schema, items) {
|
|
197
|
+
const eventRole = schema.roles.find((r) => r.role === "event");
|
|
198
|
+
if (!eventRole) {
|
|
199
|
+
items.push(
|
|
200
|
+
createSchemaValidationItem(SchemaErrorCodes.EVENT_HANDLER_MISSING_EVENT, "warning", {})
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
if (eventRole && !eventRole.required) {
|
|
204
|
+
items.push(
|
|
205
|
+
createSchemaValidationItem(SchemaErrorCodes.EVENT_HANDLER_EVENT_NOT_REQUIRED, "warning", {})
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
function validateConditionalSchema(schema, items) {
|
|
210
|
+
const conditionRole = schema.roles.find((r) => r.role === "condition");
|
|
211
|
+
if (!conditionRole) {
|
|
212
|
+
items.push(
|
|
213
|
+
createSchemaValidationItem(SchemaErrorCodes.CONDITIONAL_MISSING_CONDITION, "warning", {})
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
if (conditionRole && !conditionRole.required) {
|
|
217
|
+
items.push(
|
|
218
|
+
createSchemaValidationItem(SchemaErrorCodes.CONDITIONAL_CONDITION_NOT_REQUIRED, "warning", {})
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
function validateLoopSchema(schema, items) {
|
|
223
|
+
if (schema.action === "for") {
|
|
224
|
+
const sourceRole = schema.roles.find((r) => r.role === "source");
|
|
225
|
+
if (!sourceRole) {
|
|
226
|
+
items.push(
|
|
227
|
+
createSchemaValidationItem(SchemaErrorCodes.FOR_LOOP_MISSING_SOURCE, "warning", {})
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
} else if (schema.action === "while") {
|
|
231
|
+
const conditionRole = schema.roles.find((r) => r.role === "condition");
|
|
232
|
+
if (!conditionRole) {
|
|
233
|
+
items.push(
|
|
234
|
+
createSchemaValidationItem(SchemaErrorCodes.WHILE_LOOP_MISSING_CONDITION, "warning", {})
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
function validateAllSchemas(schemas, options = {}) {
|
|
240
|
+
const results = /* @__PURE__ */ new Map();
|
|
241
|
+
const { includeNotes = false } = options;
|
|
242
|
+
for (const [action, schema] of Object.entries(schemas)) {
|
|
243
|
+
const validation = validateCommandSchema(schema);
|
|
244
|
+
const hasWarningsOrErrors = validation.items.some(
|
|
245
|
+
(i) => i.severity === "warning" || i.severity === "error"
|
|
246
|
+
);
|
|
247
|
+
const hasNotes = includeNotes && validation.items.some((i) => i.severity === "note");
|
|
248
|
+
if (hasWarningsOrErrors || hasNotes) {
|
|
249
|
+
results.set(action, validation);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return results;
|
|
253
|
+
}
|
|
254
|
+
function formatValidationResults(validations, options = {}) {
|
|
255
|
+
const lines = [];
|
|
256
|
+
const { showNotes = false, showCodes = true } = options;
|
|
257
|
+
for (const [action, result] of validations) {
|
|
258
|
+
const errors = result.items.filter((i) => i.severity === "error");
|
|
259
|
+
const warnings = result.items.filter((i) => i.severity === "warning");
|
|
260
|
+
const notes = result.items.filter((i) => i.severity === "note");
|
|
261
|
+
if (errors.length > 0) {
|
|
262
|
+
lines.push(` \u274C ${action}:`);
|
|
263
|
+
for (const item of errors) {
|
|
264
|
+
const codeStr = showCodes ? ` [${item.code}]` : "";
|
|
265
|
+
lines.push(` ERROR${codeStr}: ${item.message}`);
|
|
266
|
+
if (item.suggestion) {
|
|
267
|
+
lines.push(` \u{1F4A1} Suggestion: ${item.suggestion}`);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
if (warnings.length > 0) {
|
|
272
|
+
lines.push(` \u26A0\uFE0F ${action}:`);
|
|
273
|
+
for (const item of warnings) {
|
|
274
|
+
const codeStr = showCodes ? ` [${item.code}]` : "";
|
|
275
|
+
lines.push(` ${codeStr ? `${item.code}: ` : ""}${item.message}`);
|
|
276
|
+
if (item.suggestion) {
|
|
277
|
+
lines.push(` \u{1F4A1} ${item.suggestion}`);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (showNotes && notes.length > 0) {
|
|
282
|
+
lines.push(` \u2139\uFE0F ${action}:`);
|
|
283
|
+
for (const item of notes) {
|
|
284
|
+
const codeStr = showCodes ? ` [${item.code}]` : "";
|
|
285
|
+
lines.push(` ${codeStr ? `${item.code}: ` : ""}${item.message}`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return lines.join("\n");
|
|
290
|
+
}
|
|
291
|
+
function getValidationStats(validations) {
|
|
292
|
+
let errors = 0;
|
|
293
|
+
let warnings = 0;
|
|
294
|
+
let notes = 0;
|
|
295
|
+
const byCode = {};
|
|
296
|
+
for (const result of validations.values()) {
|
|
297
|
+
for (const item of result.items) {
|
|
298
|
+
if (item.severity === "error") errors++;
|
|
299
|
+
else if (item.severity === "warning") warnings++;
|
|
300
|
+
else if (item.severity === "note") notes++;
|
|
301
|
+
byCode[item.code] = (byCode[item.code] || 0) + 1;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return {
|
|
305
|
+
totalCommands: validations.size,
|
|
306
|
+
errors,
|
|
307
|
+
warnings,
|
|
308
|
+
notes,
|
|
309
|
+
byCode
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
var MULTI_TYPE_PATIENT_COMMANDS, NO_REQUIRED_ROLES_COMMANDS;
|
|
313
|
+
var init_schema_validator = __esm({
|
|
314
|
+
"src/generators/schema-validator.ts"() {
|
|
315
|
+
"use strict";
|
|
316
|
+
init_schema_error_codes();
|
|
317
|
+
MULTI_TYPE_PATIENT_COMMANDS = /* @__PURE__ */ new Set([
|
|
318
|
+
"put",
|
|
319
|
+
"append",
|
|
320
|
+
"prepend",
|
|
321
|
+
"log",
|
|
322
|
+
"throw",
|
|
323
|
+
"make",
|
|
324
|
+
"measure",
|
|
325
|
+
"return",
|
|
326
|
+
"swap",
|
|
327
|
+
"morph"
|
|
328
|
+
// DOM manipulation commands that accept various content types
|
|
329
|
+
]);
|
|
330
|
+
NO_REQUIRED_ROLES_COMMANDS = /* @__PURE__ */ new Set([
|
|
331
|
+
"compound",
|
|
332
|
+
"else",
|
|
333
|
+
"halt",
|
|
334
|
+
"continue",
|
|
335
|
+
"async",
|
|
336
|
+
"init",
|
|
337
|
+
"settle",
|
|
338
|
+
"focus",
|
|
339
|
+
"blur",
|
|
340
|
+
"return",
|
|
341
|
+
"js",
|
|
342
|
+
"measure"
|
|
343
|
+
// Commands with optional-only roles
|
|
344
|
+
]);
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
// src/registry.ts
|
|
349
|
+
var tokenizers = /* @__PURE__ */ new Map();
|
|
350
|
+
var profiles = /* @__PURE__ */ new Map();
|
|
351
|
+
var patternCache = /* @__PURE__ */ new Map();
|
|
352
|
+
function registerLanguage(code, tokenizer, profile) {
|
|
353
|
+
tokenizers.set(code, tokenizer);
|
|
354
|
+
profiles.set(code, profile);
|
|
355
|
+
patternCache.delete(code);
|
|
356
|
+
}
|
|
357
|
+
var registeredPatterns = /* @__PURE__ */ new Map();
|
|
358
|
+
function registerPatterns(code, patterns) {
|
|
359
|
+
registeredPatterns.set(code, patterns);
|
|
360
|
+
patternCache.delete(code);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// src/tokenizers/base.ts
|
|
364
|
+
var TokenStreamImpl = class {
|
|
365
|
+
constructor(tokens, language) {
|
|
366
|
+
this.pos = 0;
|
|
367
|
+
this.tokens = tokens;
|
|
368
|
+
this.language = language;
|
|
369
|
+
}
|
|
370
|
+
peek(offset = 0) {
|
|
371
|
+
const index = this.pos + offset;
|
|
372
|
+
if (index < 0 || index >= this.tokens.length) {
|
|
373
|
+
return null;
|
|
374
|
+
}
|
|
375
|
+
return this.tokens[index];
|
|
376
|
+
}
|
|
377
|
+
advance() {
|
|
378
|
+
if (this.isAtEnd()) {
|
|
379
|
+
throw new Error("Unexpected end of token stream");
|
|
380
|
+
}
|
|
381
|
+
return this.tokens[this.pos++];
|
|
382
|
+
}
|
|
383
|
+
isAtEnd() {
|
|
384
|
+
return this.pos >= this.tokens.length;
|
|
385
|
+
}
|
|
386
|
+
mark() {
|
|
387
|
+
return { position: this.pos };
|
|
388
|
+
}
|
|
389
|
+
reset(mark) {
|
|
390
|
+
this.pos = mark.position;
|
|
391
|
+
}
|
|
392
|
+
position() {
|
|
393
|
+
return this.pos;
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Get remaining tokens as an array.
|
|
397
|
+
*/
|
|
398
|
+
remaining() {
|
|
399
|
+
return this.tokens.slice(this.pos);
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Consume tokens while predicate is true.
|
|
403
|
+
*/
|
|
404
|
+
takeWhile(predicate) {
|
|
405
|
+
const result = [];
|
|
406
|
+
while (!this.isAtEnd() && predicate(this.peek())) {
|
|
407
|
+
result.push(this.advance());
|
|
408
|
+
}
|
|
409
|
+
return result;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Skip tokens while predicate is true.
|
|
413
|
+
*/
|
|
414
|
+
skipWhile(predicate) {
|
|
415
|
+
while (!this.isAtEnd() && predicate(this.peek())) {
|
|
416
|
+
this.advance();
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
function createPosition(start, end) {
|
|
421
|
+
return { start, end };
|
|
422
|
+
}
|
|
423
|
+
function createToken(value, kind, position, normalizedOrOptions) {
|
|
424
|
+
if (typeof normalizedOrOptions === "string") {
|
|
425
|
+
return { value, kind, position, normalized: normalizedOrOptions };
|
|
426
|
+
}
|
|
427
|
+
if (normalizedOrOptions) {
|
|
428
|
+
const { normalized, stem, stemConfidence } = normalizedOrOptions;
|
|
429
|
+
const token = { value, kind, position };
|
|
430
|
+
if (normalized !== void 0) {
|
|
431
|
+
token.normalized = normalized;
|
|
432
|
+
}
|
|
433
|
+
if (stem !== void 0) {
|
|
434
|
+
token.stem = stem;
|
|
435
|
+
if (stemConfidence !== void 0) {
|
|
436
|
+
token.stemConfidence = stemConfidence;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
return token;
|
|
440
|
+
}
|
|
441
|
+
return { value, kind, position };
|
|
442
|
+
}
|
|
443
|
+
function isWhitespace(char) {
|
|
444
|
+
return /\s/.test(char);
|
|
445
|
+
}
|
|
446
|
+
function isSelectorStart(char) {
|
|
447
|
+
return char === "#" || char === "." || char === "[" || char === "@" || char === "*" || char === "<";
|
|
448
|
+
}
|
|
449
|
+
function isQuote(char) {
|
|
450
|
+
return char === '"' || char === "'" || char === "`" || char === "\u300C" || char === "\u300D";
|
|
451
|
+
}
|
|
452
|
+
function isDigit(char) {
|
|
453
|
+
return /\d/.test(char);
|
|
454
|
+
}
|
|
455
|
+
function isAsciiLetter(char) {
|
|
456
|
+
return /[a-zA-Z]/.test(char);
|
|
457
|
+
}
|
|
458
|
+
function isAsciiIdentifierChar(char) {
|
|
459
|
+
return /[a-zA-Z0-9_-]/.test(char);
|
|
460
|
+
}
|
|
461
|
+
function extractCssSelector(input, startPos) {
|
|
462
|
+
if (startPos >= input.length) return null;
|
|
463
|
+
const char = input[startPos];
|
|
464
|
+
if (!isSelectorStart(char)) return null;
|
|
465
|
+
let pos = startPos;
|
|
466
|
+
let selector = "";
|
|
467
|
+
if (char === "#" || char === ".") {
|
|
468
|
+
selector += input[pos++];
|
|
469
|
+
while (pos < input.length && isAsciiIdentifierChar(input[pos])) {
|
|
470
|
+
selector += input[pos++];
|
|
471
|
+
}
|
|
472
|
+
if (selector.length <= 1) return null;
|
|
473
|
+
if (pos < input.length && input[pos] === "." && char === "#") {
|
|
474
|
+
const methodStart = pos + 1;
|
|
475
|
+
let methodEnd = methodStart;
|
|
476
|
+
while (methodEnd < input.length && isAsciiIdentifierChar(input[methodEnd])) {
|
|
477
|
+
methodEnd++;
|
|
478
|
+
}
|
|
479
|
+
if (methodEnd < input.length && input[methodEnd] === "(") {
|
|
480
|
+
return selector;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
} else if (char === "[") {
|
|
484
|
+
let depth = 1;
|
|
485
|
+
let inQuote = false;
|
|
486
|
+
let quoteChar = null;
|
|
487
|
+
let escaped = false;
|
|
488
|
+
selector += input[pos++];
|
|
489
|
+
while (pos < input.length && depth > 0) {
|
|
490
|
+
const c = input[pos];
|
|
491
|
+
selector += c;
|
|
492
|
+
if (escaped) {
|
|
493
|
+
escaped = false;
|
|
494
|
+
} else if (c === "\\") {
|
|
495
|
+
escaped = true;
|
|
496
|
+
} else if (inQuote) {
|
|
497
|
+
if (c === quoteChar) {
|
|
498
|
+
inQuote = false;
|
|
499
|
+
quoteChar = null;
|
|
500
|
+
}
|
|
501
|
+
} else {
|
|
502
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
503
|
+
inQuote = true;
|
|
504
|
+
quoteChar = c;
|
|
505
|
+
} else if (c === "[") {
|
|
506
|
+
depth++;
|
|
507
|
+
} else if (c === "]") {
|
|
508
|
+
depth--;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
pos++;
|
|
512
|
+
}
|
|
513
|
+
if (depth !== 0) return null;
|
|
514
|
+
} else if (char === "@") {
|
|
515
|
+
selector += input[pos++];
|
|
516
|
+
while (pos < input.length && isAsciiIdentifierChar(input[pos])) {
|
|
517
|
+
selector += input[pos++];
|
|
518
|
+
}
|
|
519
|
+
if (selector.length <= 1) return null;
|
|
520
|
+
} else if (char === "*") {
|
|
521
|
+
selector += input[pos++];
|
|
522
|
+
while (pos < input.length && isAsciiIdentifierChar(input[pos])) {
|
|
523
|
+
selector += input[pos++];
|
|
524
|
+
}
|
|
525
|
+
if (selector.length <= 1) return null;
|
|
526
|
+
} else if (char === "<") {
|
|
527
|
+
selector += input[pos++];
|
|
528
|
+
if (pos >= input.length || !isAsciiLetter(input[pos])) return null;
|
|
529
|
+
while (pos < input.length && isAsciiIdentifierChar(input[pos])) {
|
|
530
|
+
selector += input[pos++];
|
|
531
|
+
}
|
|
532
|
+
while (pos < input.length) {
|
|
533
|
+
const modChar = input[pos];
|
|
534
|
+
if (modChar === ".") {
|
|
535
|
+
selector += input[pos++];
|
|
536
|
+
if (pos >= input.length || !isAsciiIdentifierChar(input[pos])) {
|
|
537
|
+
return null;
|
|
538
|
+
}
|
|
539
|
+
while (pos < input.length && isAsciiIdentifierChar(input[pos])) {
|
|
540
|
+
selector += input[pos++];
|
|
541
|
+
}
|
|
542
|
+
} else if (modChar === "#") {
|
|
543
|
+
selector += input[pos++];
|
|
544
|
+
if (pos >= input.length || !isAsciiIdentifierChar(input[pos])) {
|
|
545
|
+
return null;
|
|
546
|
+
}
|
|
547
|
+
while (pos < input.length && isAsciiIdentifierChar(input[pos])) {
|
|
548
|
+
selector += input[pos++];
|
|
549
|
+
}
|
|
550
|
+
} else if (modChar === "[") {
|
|
551
|
+
let depth = 1;
|
|
552
|
+
let inQuote = false;
|
|
553
|
+
let quoteChar = null;
|
|
554
|
+
let escaped = false;
|
|
555
|
+
selector += input[pos++];
|
|
556
|
+
while (pos < input.length && depth > 0) {
|
|
557
|
+
const c = input[pos];
|
|
558
|
+
selector += c;
|
|
559
|
+
if (escaped) {
|
|
560
|
+
escaped = false;
|
|
561
|
+
} else if (c === "\\") {
|
|
562
|
+
escaped = true;
|
|
563
|
+
} else if (inQuote) {
|
|
564
|
+
if (c === quoteChar) {
|
|
565
|
+
inQuote = false;
|
|
566
|
+
quoteChar = null;
|
|
567
|
+
}
|
|
568
|
+
} else {
|
|
569
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
570
|
+
inQuote = true;
|
|
571
|
+
quoteChar = c;
|
|
572
|
+
} else if (c === "[") {
|
|
573
|
+
depth++;
|
|
574
|
+
} else if (c === "]") {
|
|
575
|
+
depth--;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
pos++;
|
|
579
|
+
}
|
|
580
|
+
if (depth !== 0) return null;
|
|
581
|
+
} else {
|
|
582
|
+
break;
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
while (pos < input.length && isWhitespace(input[pos])) {
|
|
586
|
+
selector += input[pos++];
|
|
587
|
+
}
|
|
588
|
+
if (pos < input.length && input[pos] === "/") {
|
|
589
|
+
selector += input[pos++];
|
|
590
|
+
while (pos < input.length && isWhitespace(input[pos])) {
|
|
591
|
+
selector += input[pos++];
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
if (pos >= input.length || input[pos] !== ">") return null;
|
|
595
|
+
selector += input[pos++];
|
|
596
|
+
}
|
|
597
|
+
return selector || null;
|
|
598
|
+
}
|
|
599
|
+
function isPossessiveMarker(input, pos) {
|
|
600
|
+
if (pos >= input.length || input[pos] !== "'") return false;
|
|
601
|
+
if (pos + 1 >= input.length) return false;
|
|
602
|
+
const nextChar = input[pos + 1].toLowerCase();
|
|
603
|
+
if (nextChar !== "s") return false;
|
|
604
|
+
if (pos + 2 >= input.length) return true;
|
|
605
|
+
const afterS = input[pos + 2];
|
|
606
|
+
return isWhitespace(afterS) || afterS === "*" || !isAsciiIdentifierChar(afterS);
|
|
607
|
+
}
|
|
608
|
+
function extractStringLiteral(input, startPos) {
|
|
609
|
+
if (startPos >= input.length) return null;
|
|
610
|
+
const openQuote = input[startPos];
|
|
611
|
+
if (!isQuote(openQuote)) return null;
|
|
612
|
+
if (openQuote === "'" && isPossessiveMarker(input, startPos)) {
|
|
613
|
+
return null;
|
|
614
|
+
}
|
|
615
|
+
const closeQuoteMap = {
|
|
616
|
+
'"': '"',
|
|
617
|
+
"'": "'",
|
|
618
|
+
"`": "`",
|
|
619
|
+
"\u300C": "\u300D"
|
|
620
|
+
};
|
|
621
|
+
const closeQuote = closeQuoteMap[openQuote];
|
|
622
|
+
if (!closeQuote) return null;
|
|
623
|
+
let pos = startPos + 1;
|
|
624
|
+
let literal = openQuote;
|
|
625
|
+
let escaped = false;
|
|
626
|
+
while (pos < input.length) {
|
|
627
|
+
const char = input[pos];
|
|
628
|
+
literal += char;
|
|
629
|
+
if (escaped) {
|
|
630
|
+
escaped = false;
|
|
631
|
+
} else if (char === "\\") {
|
|
632
|
+
escaped = true;
|
|
633
|
+
} else if (char === closeQuote) {
|
|
634
|
+
return literal;
|
|
635
|
+
}
|
|
636
|
+
pos++;
|
|
637
|
+
}
|
|
638
|
+
return literal;
|
|
639
|
+
}
|
|
640
|
+
function isUrlStart(input, pos) {
|
|
641
|
+
if (pos >= input.length) return false;
|
|
642
|
+
const char = input[pos];
|
|
643
|
+
const next = input[pos + 1] || "";
|
|
644
|
+
const third = input[pos + 2] || "";
|
|
645
|
+
if (char === "/" && next !== "/" && /[a-zA-Z0-9._-]/.test(next)) {
|
|
646
|
+
return true;
|
|
647
|
+
}
|
|
648
|
+
if (char === "/" && next === "/" && /[a-zA-Z]/.test(third)) {
|
|
649
|
+
return true;
|
|
650
|
+
}
|
|
651
|
+
if (char === "." && (next === "/" || next === "." && third === "/")) {
|
|
652
|
+
return true;
|
|
653
|
+
}
|
|
654
|
+
const slice = input.slice(pos, pos + 8).toLowerCase();
|
|
655
|
+
if (slice.startsWith("http://") || slice.startsWith("https://")) {
|
|
656
|
+
return true;
|
|
657
|
+
}
|
|
658
|
+
return false;
|
|
659
|
+
}
|
|
660
|
+
function extractUrl(input, startPos) {
|
|
661
|
+
if (!isUrlStart(input, startPos)) return null;
|
|
662
|
+
let pos = startPos;
|
|
663
|
+
let url = "";
|
|
664
|
+
const urlChars = /[a-zA-Z0-9/:._\-?&=%@+~!$'()*,;[\]]/;
|
|
665
|
+
while (pos < input.length) {
|
|
666
|
+
const char = input[pos];
|
|
667
|
+
if (char === "#") {
|
|
668
|
+
if (url.length > 0 && /[a-zA-Z0-9/.]$/.test(url)) {
|
|
669
|
+
url += char;
|
|
670
|
+
pos++;
|
|
671
|
+
while (pos < input.length && /[a-zA-Z0-9_-]/.test(input[pos])) {
|
|
672
|
+
url += input[pos++];
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
break;
|
|
676
|
+
}
|
|
677
|
+
if (urlChars.test(char)) {
|
|
678
|
+
url += char;
|
|
679
|
+
pos++;
|
|
680
|
+
} else {
|
|
681
|
+
break;
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
if (url.length < 2) return null;
|
|
685
|
+
return url;
|
|
686
|
+
}
|
|
687
|
+
function extractNumber(input, startPos) {
|
|
688
|
+
if (startPos >= input.length) return null;
|
|
689
|
+
const char = input[startPos];
|
|
690
|
+
if (!isDigit(char) && char !== "-" && char !== "+") return null;
|
|
691
|
+
let pos = startPos;
|
|
692
|
+
let number = "";
|
|
693
|
+
if (input[pos] === "-" || input[pos] === "+") {
|
|
694
|
+
number += input[pos++];
|
|
695
|
+
}
|
|
696
|
+
if (pos >= input.length || !isDigit(input[pos])) {
|
|
697
|
+
return null;
|
|
698
|
+
}
|
|
699
|
+
while (pos < input.length && isDigit(input[pos])) {
|
|
700
|
+
number += input[pos++];
|
|
701
|
+
}
|
|
702
|
+
if (pos < input.length && input[pos] === ".") {
|
|
703
|
+
number += input[pos++];
|
|
704
|
+
while (pos < input.length && isDigit(input[pos])) {
|
|
705
|
+
number += input[pos++];
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
if (pos < input.length) {
|
|
709
|
+
const suffix = input.slice(pos, pos + 2);
|
|
710
|
+
if (suffix === "ms") {
|
|
711
|
+
number += "ms";
|
|
712
|
+
} else if (input[pos] === "s" || input[pos] === "m" || input[pos] === "h") {
|
|
713
|
+
number += input[pos];
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
return number;
|
|
717
|
+
}
|
|
718
|
+
var _BaseTokenizer = class _BaseTokenizer {
|
|
719
|
+
constructor() {
|
|
720
|
+
/** Keywords derived from profile, sorted longest-first for greedy matching */
|
|
721
|
+
this.profileKeywords = [];
|
|
722
|
+
/** Map for O(1) keyword lookups by lowercase native word */
|
|
723
|
+
this.profileKeywordMap = /* @__PURE__ */ new Map();
|
|
724
|
+
}
|
|
725
|
+
/**
|
|
726
|
+
* Initialize keyword mappings from a language profile.
|
|
727
|
+
* Builds a list of native→english mappings from:
|
|
728
|
+
* - profile.keywords (primary + alternatives)
|
|
729
|
+
* - profile.references (me, it, you, etc.)
|
|
730
|
+
* - profile.roleMarkers (into, from, with, etc.)
|
|
731
|
+
*
|
|
732
|
+
* Results are sorted longest-first for greedy matching (important for non-space languages).
|
|
733
|
+
* Extras take precedence over profile entries when there are duplicates.
|
|
734
|
+
*
|
|
735
|
+
* @param profile - Language profile containing keyword translations
|
|
736
|
+
* @param extras - Additional keyword entries to include (literals, positional, events)
|
|
737
|
+
*/
|
|
738
|
+
initializeKeywordsFromProfile(profile, extras = []) {
|
|
739
|
+
const keywordMap = /* @__PURE__ */ new Map();
|
|
740
|
+
if (profile.keywords) {
|
|
741
|
+
for (const [normalized, translation] of Object.entries(profile.keywords)) {
|
|
742
|
+
keywordMap.set(translation.primary, {
|
|
743
|
+
native: translation.primary,
|
|
744
|
+
normalized: translation.normalized || normalized
|
|
745
|
+
});
|
|
746
|
+
if (translation.alternatives) {
|
|
747
|
+
for (const alt of translation.alternatives) {
|
|
748
|
+
keywordMap.set(alt, {
|
|
749
|
+
native: alt,
|
|
750
|
+
normalized: translation.normalized || normalized
|
|
751
|
+
});
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
if (profile.references) {
|
|
757
|
+
for (const [normalized, native] of Object.entries(profile.references)) {
|
|
758
|
+
keywordMap.set(native, { native, normalized });
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
if (profile.roleMarkers) {
|
|
762
|
+
for (const [role, marker] of Object.entries(profile.roleMarkers)) {
|
|
763
|
+
if (marker.primary) {
|
|
764
|
+
keywordMap.set(marker.primary, { native: marker.primary, normalized: role });
|
|
765
|
+
}
|
|
766
|
+
if (marker.alternatives) {
|
|
767
|
+
for (const alt of marker.alternatives) {
|
|
768
|
+
keywordMap.set(alt, { native: alt, normalized: role });
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
for (const extra of extras) {
|
|
774
|
+
keywordMap.set(extra.native, extra);
|
|
775
|
+
}
|
|
776
|
+
this.profileKeywords = Array.from(keywordMap.values()).sort(
|
|
777
|
+
(a, b) => b.native.length - a.native.length
|
|
778
|
+
);
|
|
779
|
+
this.profileKeywordMap = /* @__PURE__ */ new Map();
|
|
780
|
+
for (const keyword of this.profileKeywords) {
|
|
781
|
+
this.profileKeywordMap.set(keyword.native.toLowerCase(), keyword);
|
|
782
|
+
const normalized = this.removeDiacritics(keyword.native);
|
|
783
|
+
if (normalized !== keyword.native && !this.profileKeywordMap.has(normalized.toLowerCase())) {
|
|
784
|
+
this.profileKeywordMap.set(normalized.toLowerCase(), keyword);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
/**
|
|
789
|
+
* Remove diacritical marks from a word for normalization.
|
|
790
|
+
* Primarily for Arabic (shadda, fatha, kasra, damma, sukun, etc.)
|
|
791
|
+
* but could be extended for other languages.
|
|
792
|
+
*
|
|
793
|
+
* @param word - Word to normalize
|
|
794
|
+
* @returns Word without diacritics
|
|
795
|
+
*/
|
|
796
|
+
removeDiacritics(word) {
|
|
797
|
+
return word.replace(/[\u064B-\u0652\u0670]/g, "");
|
|
798
|
+
}
|
|
799
|
+
/**
|
|
800
|
+
* Try to match a keyword from profile at the current position.
|
|
801
|
+
* Uses longest-first greedy matching (important for non-space languages).
|
|
802
|
+
*
|
|
803
|
+
* @param input - Input string
|
|
804
|
+
* @param pos - Current position
|
|
805
|
+
* @returns Token if matched, null otherwise
|
|
806
|
+
*/
|
|
807
|
+
tryProfileKeyword(input, pos) {
|
|
808
|
+
for (const entry of this.profileKeywords) {
|
|
809
|
+
if (input.slice(pos).startsWith(entry.native)) {
|
|
810
|
+
return createToken(
|
|
811
|
+
entry.native,
|
|
812
|
+
"keyword",
|
|
813
|
+
createPosition(pos, pos + entry.native.length),
|
|
814
|
+
entry.normalized
|
|
815
|
+
);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
return null;
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* Check if the remaining input starts with any known keyword.
|
|
822
|
+
* Useful for non-space languages to detect word boundaries.
|
|
823
|
+
*
|
|
824
|
+
* @param input - Input string
|
|
825
|
+
* @param pos - Current position
|
|
826
|
+
* @returns true if a keyword starts at this position
|
|
827
|
+
*/
|
|
828
|
+
isKeywordStart(input, pos) {
|
|
829
|
+
const remaining = input.slice(pos);
|
|
830
|
+
return this.profileKeywords.some((entry) => remaining.startsWith(entry.native));
|
|
831
|
+
}
|
|
832
|
+
/**
|
|
833
|
+
* Look up a keyword by native word (case-insensitive).
|
|
834
|
+
* O(1) lookup using the keyword map.
|
|
835
|
+
*
|
|
836
|
+
* @param native - Native word to look up
|
|
837
|
+
* @returns KeywordEntry if found, undefined otherwise
|
|
838
|
+
*/
|
|
839
|
+
lookupKeyword(native) {
|
|
840
|
+
return this.profileKeywordMap.get(native.toLowerCase());
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* Check if a word is a known keyword (case-insensitive).
|
|
844
|
+
* O(1) lookup using the keyword map.
|
|
845
|
+
*
|
|
846
|
+
* @param native - Native word to check
|
|
847
|
+
* @returns true if the word is a keyword
|
|
848
|
+
*/
|
|
849
|
+
isKeyword(native) {
|
|
850
|
+
return this.profileKeywordMap.has(native.toLowerCase());
|
|
851
|
+
}
|
|
852
|
+
/**
|
|
853
|
+
* Set the morphological normalizer for this tokenizer.
|
|
854
|
+
*/
|
|
855
|
+
setNormalizer(normalizer) {
|
|
856
|
+
this.normalizer = normalizer;
|
|
857
|
+
}
|
|
858
|
+
/**
|
|
859
|
+
* Try to normalize a word using the morphological normalizer.
|
|
860
|
+
* Returns null if no normalizer is set or normalization fails.
|
|
861
|
+
*
|
|
862
|
+
* Note: We don't check isNormalizable() here because the individual tokenizers
|
|
863
|
+
* historically called normalize() directly without that check. The normalize()
|
|
864
|
+
* method itself handles returning noChange() for words that can't be normalized.
|
|
865
|
+
*/
|
|
866
|
+
tryNormalize(word) {
|
|
867
|
+
if (!this.normalizer) return null;
|
|
868
|
+
const result = this.normalizer.normalize(word);
|
|
869
|
+
if (result.stem !== word && result.confidence >= 0.7) {
|
|
870
|
+
return result;
|
|
871
|
+
}
|
|
872
|
+
return null;
|
|
873
|
+
}
|
|
874
|
+
/**
|
|
875
|
+
* Try morphological normalization and keyword lookup.
|
|
876
|
+
*
|
|
877
|
+
* If the word can be normalized to a stem that matches a known keyword,
|
|
878
|
+
* returns a keyword token with morphological metadata (stem, stemConfidence).
|
|
879
|
+
*
|
|
880
|
+
* This is the common pattern for handling conjugated verbs across languages:
|
|
881
|
+
* 1. Normalize the word (e.g., "toggled" → "toggle")
|
|
882
|
+
* 2. Look up the stem in the keyword map
|
|
883
|
+
* 3. Create a token with both the original form and stem metadata
|
|
884
|
+
*
|
|
885
|
+
* @param word - The word to normalize and look up
|
|
886
|
+
* @param startPos - Start position for the token
|
|
887
|
+
* @param endPos - End position for the token
|
|
888
|
+
* @returns Token if stem matches a keyword, null otherwise
|
|
889
|
+
*/
|
|
890
|
+
tryMorphKeywordMatch(word, startPos, endPos) {
|
|
891
|
+
const result = this.tryNormalize(word);
|
|
892
|
+
if (!result) return null;
|
|
893
|
+
const stemEntry = this.lookupKeyword(result.stem);
|
|
894
|
+
if (!stemEntry) return null;
|
|
895
|
+
const tokenOptions = {
|
|
896
|
+
normalized: stemEntry.normalized,
|
|
897
|
+
stem: result.stem,
|
|
898
|
+
stemConfidence: result.confidence
|
|
899
|
+
};
|
|
900
|
+
return createToken(word, "keyword", createPosition(startPos, endPos), tokenOptions);
|
|
901
|
+
}
|
|
902
|
+
/**
|
|
903
|
+
* Try to extract a CSS selector at the current position.
|
|
904
|
+
*/
|
|
905
|
+
trySelector(input, pos) {
|
|
906
|
+
const selector = extractCssSelector(input, pos);
|
|
907
|
+
if (selector) {
|
|
908
|
+
return createToken(selector, "selector", createPosition(pos, pos + selector.length));
|
|
909
|
+
}
|
|
910
|
+
return null;
|
|
911
|
+
}
|
|
912
|
+
/**
|
|
913
|
+
* Try to extract an event modifier at the current position.
|
|
914
|
+
* Event modifiers are .once, .debounce(N), .throttle(N), .queue(strategy)
|
|
915
|
+
*/
|
|
916
|
+
tryEventModifier(input, pos) {
|
|
917
|
+
if (input[pos] !== ".") {
|
|
918
|
+
return null;
|
|
919
|
+
}
|
|
920
|
+
const match = input.slice(pos).match(/^\.(?:once|debounce|throttle|queue)(?:\(([^)]+)\))?(?:\s|$|\.)/);
|
|
921
|
+
if (!match) {
|
|
922
|
+
return null;
|
|
923
|
+
}
|
|
924
|
+
const fullMatch = match[0].replace(/(\s|\.)$/, "");
|
|
925
|
+
const modifierName = fullMatch.slice(1).split("(")[0];
|
|
926
|
+
const value = match[1];
|
|
927
|
+
const token = createToken(
|
|
928
|
+
fullMatch,
|
|
929
|
+
"event-modifier",
|
|
930
|
+
createPosition(pos, pos + fullMatch.length)
|
|
931
|
+
);
|
|
932
|
+
return {
|
|
933
|
+
...token,
|
|
934
|
+
metadata: {
|
|
935
|
+
modifierName,
|
|
936
|
+
value: value ? modifierName === "queue" ? value : parseInt(value, 10) : void 0
|
|
937
|
+
}
|
|
938
|
+
};
|
|
939
|
+
}
|
|
940
|
+
/**
|
|
941
|
+
* Try to extract a string literal at the current position.
|
|
942
|
+
*/
|
|
943
|
+
tryString(input, pos) {
|
|
944
|
+
const literal = extractStringLiteral(input, pos);
|
|
945
|
+
if (literal) {
|
|
946
|
+
return createToken(literal, "literal", createPosition(pos, pos + literal.length));
|
|
947
|
+
}
|
|
948
|
+
return null;
|
|
949
|
+
}
|
|
950
|
+
/**
|
|
951
|
+
* Try to extract a number at the current position.
|
|
952
|
+
*/
|
|
953
|
+
tryNumber(input, pos) {
|
|
954
|
+
const number = extractNumber(input, pos);
|
|
955
|
+
if (number) {
|
|
956
|
+
return createToken(number, "literal", createPosition(pos, pos + number.length));
|
|
957
|
+
}
|
|
958
|
+
return null;
|
|
959
|
+
}
|
|
960
|
+
/**
|
|
961
|
+
* Try to match a time unit from a list of patterns.
|
|
962
|
+
*
|
|
963
|
+
* @param input - Input string
|
|
964
|
+
* @param pos - Position after the number
|
|
965
|
+
* @param timeUnits - Array of time unit mappings (native pattern → standard suffix)
|
|
966
|
+
* @param skipWhitespace - Whether to skip whitespace before time unit (default: false)
|
|
967
|
+
* @returns Object with matched suffix and new position, or null if no match
|
|
968
|
+
*/
|
|
969
|
+
tryMatchTimeUnit(input, pos, timeUnits, skipWhitespace = false) {
|
|
970
|
+
let unitPos = pos;
|
|
971
|
+
if (skipWhitespace) {
|
|
972
|
+
while (unitPos < input.length && isWhitespace(input[unitPos])) {
|
|
973
|
+
unitPos++;
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
const remaining = input.slice(unitPos);
|
|
977
|
+
for (const unit of timeUnits) {
|
|
978
|
+
const candidate = remaining.slice(0, unit.length);
|
|
979
|
+
const matches = unit.caseInsensitive ? candidate.toLowerCase() === unit.pattern.toLowerCase() : candidate === unit.pattern;
|
|
980
|
+
if (matches) {
|
|
981
|
+
if (unit.notFollowedBy) {
|
|
982
|
+
const nextChar = remaining[unit.length] || "";
|
|
983
|
+
if (nextChar === unit.notFollowedBy) continue;
|
|
984
|
+
}
|
|
985
|
+
if (unit.checkBoundary) {
|
|
986
|
+
const nextChar = remaining[unit.length] || "";
|
|
987
|
+
if (isAsciiIdentifierChar(nextChar)) continue;
|
|
988
|
+
}
|
|
989
|
+
return { suffix: unit.suffix, endPos: unitPos + unit.length };
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
return null;
|
|
993
|
+
}
|
|
994
|
+
/**
|
|
995
|
+
* Parse a base number (sign, integer, decimal) without time units.
|
|
996
|
+
* Returns the number string and end position.
|
|
997
|
+
*
|
|
998
|
+
* @param input - Input string
|
|
999
|
+
* @param startPos - Start position
|
|
1000
|
+
* @param allowSign - Whether to allow +/- sign (default: true)
|
|
1001
|
+
* @returns Object with number string and end position, or null
|
|
1002
|
+
*/
|
|
1003
|
+
parseBaseNumber(input, startPos, allowSign = true) {
|
|
1004
|
+
let pos = startPos;
|
|
1005
|
+
let number = "";
|
|
1006
|
+
if (allowSign && (input[pos] === "-" || input[pos] === "+")) {
|
|
1007
|
+
number += input[pos++];
|
|
1008
|
+
}
|
|
1009
|
+
if (pos >= input.length || !isDigit(input[pos])) {
|
|
1010
|
+
return null;
|
|
1011
|
+
}
|
|
1012
|
+
while (pos < input.length && isDigit(input[pos])) {
|
|
1013
|
+
number += input[pos++];
|
|
1014
|
+
}
|
|
1015
|
+
if (pos < input.length && input[pos] === ".") {
|
|
1016
|
+
number += input[pos++];
|
|
1017
|
+
while (pos < input.length && isDigit(input[pos])) {
|
|
1018
|
+
number += input[pos++];
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
if (!number || number === "-" || number === "+") return null;
|
|
1022
|
+
return { number, endPos: pos };
|
|
1023
|
+
}
|
|
1024
|
+
/**
|
|
1025
|
+
* Try to extract a number with native language time units.
|
|
1026
|
+
*
|
|
1027
|
+
* This is a template method that handles the common pattern:
|
|
1028
|
+
* 1. Parse the base number (sign, integer, decimal)
|
|
1029
|
+
* 2. Try to match native language time units
|
|
1030
|
+
* 3. Fall back to standard time units (ms, s, m, h)
|
|
1031
|
+
*
|
|
1032
|
+
* @param input - Input string
|
|
1033
|
+
* @param pos - Start position
|
|
1034
|
+
* @param nativeTimeUnits - Language-specific time unit mappings
|
|
1035
|
+
* @param options - Configuration options
|
|
1036
|
+
* @returns Token if number found, null otherwise
|
|
1037
|
+
*/
|
|
1038
|
+
tryNumberWithTimeUnits(input, pos, nativeTimeUnits, options = {}) {
|
|
1039
|
+
const { allowSign = true, skipWhitespace = false } = options;
|
|
1040
|
+
const baseResult = this.parseBaseNumber(input, pos, allowSign);
|
|
1041
|
+
if (!baseResult) return null;
|
|
1042
|
+
let { number, endPos } = baseResult;
|
|
1043
|
+
const allUnits = [...nativeTimeUnits, ..._BaseTokenizer.STANDARD_TIME_UNITS];
|
|
1044
|
+
const timeMatch = this.tryMatchTimeUnit(input, endPos, allUnits, skipWhitespace);
|
|
1045
|
+
if (timeMatch) {
|
|
1046
|
+
number += timeMatch.suffix;
|
|
1047
|
+
endPos = timeMatch.endPos;
|
|
1048
|
+
}
|
|
1049
|
+
return createToken(number, "literal", createPosition(pos, endPos));
|
|
1050
|
+
}
|
|
1051
|
+
/**
|
|
1052
|
+
* Try to extract a URL at the current position.
|
|
1053
|
+
* Handles /path, ./path, ../path, //domain.com, http://, https://
|
|
1054
|
+
*/
|
|
1055
|
+
tryUrl(input, pos) {
|
|
1056
|
+
const url = extractUrl(input, pos);
|
|
1057
|
+
if (url) {
|
|
1058
|
+
return createToken(url, "url", createPosition(pos, pos + url.length));
|
|
1059
|
+
}
|
|
1060
|
+
return null;
|
|
1061
|
+
}
|
|
1062
|
+
/**
|
|
1063
|
+
* Try to extract a variable reference (:varname) at the current position.
|
|
1064
|
+
* In hyperscript, :x refers to a local variable named x.
|
|
1065
|
+
*/
|
|
1066
|
+
tryVariableRef(input, pos) {
|
|
1067
|
+
if (input[pos] !== ":") return null;
|
|
1068
|
+
if (pos + 1 >= input.length) return null;
|
|
1069
|
+
if (!isAsciiIdentifierChar(input[pos + 1])) return null;
|
|
1070
|
+
let endPos = pos + 1;
|
|
1071
|
+
while (endPos < input.length && isAsciiIdentifierChar(input[endPos])) {
|
|
1072
|
+
endPos++;
|
|
1073
|
+
}
|
|
1074
|
+
const varRef = input.slice(pos, endPos);
|
|
1075
|
+
return createToken(varRef, "identifier", createPosition(pos, endPos));
|
|
1076
|
+
}
|
|
1077
|
+
/**
|
|
1078
|
+
* Try to extract an operator or punctuation token at the current position.
|
|
1079
|
+
* Handles two-character operators (==, !=, etc.) and single-character operators.
|
|
1080
|
+
*/
|
|
1081
|
+
tryOperator(input, pos) {
|
|
1082
|
+
const twoChar = input.slice(pos, pos + 2);
|
|
1083
|
+
if (["==", "!=", "<=", ">=", "&&", "||", "->"].includes(twoChar)) {
|
|
1084
|
+
return createToken(twoChar, "operator", createPosition(pos, pos + 2));
|
|
1085
|
+
}
|
|
1086
|
+
const oneChar = input[pos];
|
|
1087
|
+
if (["<", ">", "!", "+", "-", "*", "/", "="].includes(oneChar)) {
|
|
1088
|
+
return createToken(oneChar, "operator", createPosition(pos, pos + 1));
|
|
1089
|
+
}
|
|
1090
|
+
if (["(", ")", "{", "}", ",", ";", ":"].includes(oneChar)) {
|
|
1091
|
+
return createToken(oneChar, "punctuation", createPosition(pos, pos + 1));
|
|
1092
|
+
}
|
|
1093
|
+
return null;
|
|
1094
|
+
}
|
|
1095
|
+
/**
|
|
1096
|
+
* Try to match a multi-character particle from a list.
|
|
1097
|
+
*
|
|
1098
|
+
* Used by languages like Japanese, Korean, and Chinese that have
|
|
1099
|
+
* multi-character particles (e.g., Japanese から, まで, より).
|
|
1100
|
+
*
|
|
1101
|
+
* @param input - Input string
|
|
1102
|
+
* @param pos - Current position
|
|
1103
|
+
* @param particles - Array of multi-character particles to match
|
|
1104
|
+
* @returns Token if matched, null otherwise
|
|
1105
|
+
*/
|
|
1106
|
+
tryMultiCharParticle(input, pos, particles) {
|
|
1107
|
+
for (const particle of particles) {
|
|
1108
|
+
if (input.slice(pos, pos + particle.length) === particle) {
|
|
1109
|
+
return createToken(particle, "particle", createPosition(pos, pos + particle.length));
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
return null;
|
|
1113
|
+
}
|
|
1114
|
+
};
|
|
1115
|
+
/**
|
|
1116
|
+
* Configuration for native language time units.
|
|
1117
|
+
* Maps patterns to their standard suffix (ms, s, m, h).
|
|
1118
|
+
*/
|
|
1119
|
+
_BaseTokenizer.STANDARD_TIME_UNITS = [
|
|
1120
|
+
{ pattern: "ms", suffix: "ms", length: 2 },
|
|
1121
|
+
{ pattern: "s", suffix: "s", length: 1, checkBoundary: true },
|
|
1122
|
+
{ pattern: "m", suffix: "m", length: 1, checkBoundary: true, notFollowedBy: "s" },
|
|
1123
|
+
{ pattern: "h", suffix: "h", length: 1, checkBoundary: true }
|
|
1124
|
+
];
|
|
1125
|
+
var BaseTokenizer = _BaseTokenizer;
|
|
1126
|
+
|
|
1127
|
+
// src/generators/profiles/english.ts
|
|
1128
|
+
var englishProfile = {
|
|
1129
|
+
code: "en",
|
|
1130
|
+
name: "English",
|
|
1131
|
+
nativeName: "English",
|
|
1132
|
+
direction: "ltr",
|
|
1133
|
+
wordOrder: "SVO",
|
|
1134
|
+
markingStrategy: "preposition",
|
|
1135
|
+
usesSpaces: true,
|
|
1136
|
+
// English infinitive and imperative are identical ("toggle", "save", "open")
|
|
1137
|
+
defaultVerbForm: "base",
|
|
1138
|
+
verb: {
|
|
1139
|
+
position: "start",
|
|
1140
|
+
subjectDrop: false
|
|
1141
|
+
},
|
|
1142
|
+
references: {
|
|
1143
|
+
me: "me",
|
|
1144
|
+
it: "it",
|
|
1145
|
+
you: "you",
|
|
1146
|
+
result: "result",
|
|
1147
|
+
event: "event",
|
|
1148
|
+
target: "target",
|
|
1149
|
+
body: "body"
|
|
1150
|
+
},
|
|
1151
|
+
possessive: {
|
|
1152
|
+
marker: "'s",
|
|
1153
|
+
markerPosition: "after-object",
|
|
1154
|
+
specialForms: {
|
|
1155
|
+
me: "my",
|
|
1156
|
+
it: "its",
|
|
1157
|
+
you: "your"
|
|
1158
|
+
},
|
|
1159
|
+
keywords: {
|
|
1160
|
+
my: "me",
|
|
1161
|
+
your: "you",
|
|
1162
|
+
its: "it"
|
|
1163
|
+
}
|
|
1164
|
+
},
|
|
1165
|
+
roleMarkers: {
|
|
1166
|
+
destination: { primary: "on", alternatives: ["to", "from"], position: "before" },
|
|
1167
|
+
source: { primary: "from", position: "before" },
|
|
1168
|
+
patient: { primary: "", position: "before" },
|
|
1169
|
+
style: { primary: "with", alternatives: ["by", "using"], position: "before" },
|
|
1170
|
+
responseType: { primary: "as", position: "before" },
|
|
1171
|
+
method: { primary: "via", alternatives: ["using"], position: "before" }
|
|
1172
|
+
},
|
|
1173
|
+
keywords: {
|
|
1174
|
+
toggle: { primary: "toggle" },
|
|
1175
|
+
add: { primary: "add" },
|
|
1176
|
+
remove: { primary: "remove" },
|
|
1177
|
+
put: { primary: "put" },
|
|
1178
|
+
append: { primary: "append" },
|
|
1179
|
+
prepend: { primary: "prepend" },
|
|
1180
|
+
take: { primary: "take" },
|
|
1181
|
+
make: { primary: "make" },
|
|
1182
|
+
clone: { primary: "clone" },
|
|
1183
|
+
swap: { primary: "swap" },
|
|
1184
|
+
morph: { primary: "morph" },
|
|
1185
|
+
set: { primary: "set" },
|
|
1186
|
+
get: { primary: "get" },
|
|
1187
|
+
increment: { primary: "increment" },
|
|
1188
|
+
decrement: { primary: "decrement" },
|
|
1189
|
+
log: { primary: "log" },
|
|
1190
|
+
show: { primary: "show" },
|
|
1191
|
+
hide: { primary: "hide" },
|
|
1192
|
+
transition: { primary: "transition" },
|
|
1193
|
+
on: { primary: "on" },
|
|
1194
|
+
trigger: { primary: "trigger" },
|
|
1195
|
+
send: { primary: "send" },
|
|
1196
|
+
focus: { primary: "focus" },
|
|
1197
|
+
blur: { primary: "blur" },
|
|
1198
|
+
go: { primary: "go" },
|
|
1199
|
+
wait: { primary: "wait" },
|
|
1200
|
+
fetch: { primary: "fetch" },
|
|
1201
|
+
settle: { primary: "settle" },
|
|
1202
|
+
if: { primary: "if" },
|
|
1203
|
+
when: { primary: "when", normalized: "when" },
|
|
1204
|
+
where: { primary: "where", normalized: "where" },
|
|
1205
|
+
else: { primary: "else" },
|
|
1206
|
+
repeat: { primary: "repeat" },
|
|
1207
|
+
for: { primary: "for" },
|
|
1208
|
+
while: { primary: "while" },
|
|
1209
|
+
continue: { primary: "continue" },
|
|
1210
|
+
halt: { primary: "halt" },
|
|
1211
|
+
throw: { primary: "throw" },
|
|
1212
|
+
call: { primary: "call" },
|
|
1213
|
+
return: { primary: "return" },
|
|
1214
|
+
then: { primary: "then" },
|
|
1215
|
+
and: { primary: "and" },
|
|
1216
|
+
end: { primary: "end" },
|
|
1217
|
+
js: { primary: "js" },
|
|
1218
|
+
async: { primary: "async" },
|
|
1219
|
+
tell: { primary: "tell" },
|
|
1220
|
+
default: { primary: "default" },
|
|
1221
|
+
init: { primary: "init" },
|
|
1222
|
+
behavior: { primary: "behavior" },
|
|
1223
|
+
install: { primary: "install" },
|
|
1224
|
+
measure: { primary: "measure" },
|
|
1225
|
+
into: { primary: "into" },
|
|
1226
|
+
before: { primary: "before" },
|
|
1227
|
+
after: { primary: "after" },
|
|
1228
|
+
until: { primary: "until" },
|
|
1229
|
+
event: { primary: "event" },
|
|
1230
|
+
from: { primary: "from" }
|
|
1231
|
+
}
|
|
1232
|
+
};
|
|
1233
|
+
|
|
1234
|
+
// src/tokenizers/english.ts
|
|
1235
|
+
var ENGLISH_EXTRAS = [
|
|
1236
|
+
// Values/Literals
|
|
1237
|
+
{ native: "true", normalized: "true" },
|
|
1238
|
+
{ native: "false", normalized: "false" },
|
|
1239
|
+
{ native: "null", normalized: "null" },
|
|
1240
|
+
{ native: "undefined", normalized: "undefined" },
|
|
1241
|
+
// Positional
|
|
1242
|
+
{ native: "first", normalized: "first" },
|
|
1243
|
+
{ native: "last", normalized: "last" },
|
|
1244
|
+
{ native: "next", normalized: "next" },
|
|
1245
|
+
{ native: "previous", normalized: "previous" },
|
|
1246
|
+
{ native: "closest", normalized: "closest" },
|
|
1247
|
+
// Events
|
|
1248
|
+
{ native: "click", normalized: "click" },
|
|
1249
|
+
{ native: "dblclick", normalized: "dblclick" },
|
|
1250
|
+
{ native: "mousedown", normalized: "mousedown" },
|
|
1251
|
+
{ native: "mouseup", normalized: "mouseup" },
|
|
1252
|
+
{ native: "mouseover", normalized: "mouseover" },
|
|
1253
|
+
{ native: "mouseout", normalized: "mouseout" },
|
|
1254
|
+
{ native: "mouseenter", normalized: "mouseenter" },
|
|
1255
|
+
{ native: "mouseleave", normalized: "mouseleave" },
|
|
1256
|
+
{ native: "mousemove", normalized: "mousemove" },
|
|
1257
|
+
{ native: "keydown", normalized: "keydown" },
|
|
1258
|
+
{ native: "keyup", normalized: "keyup" },
|
|
1259
|
+
{ native: "keypress", normalized: "keypress" },
|
|
1260
|
+
{ native: "input", normalized: "input" },
|
|
1261
|
+
{ native: "change", normalized: "change" },
|
|
1262
|
+
{ native: "submit", normalized: "submit" },
|
|
1263
|
+
{ native: "reset", normalized: "reset" },
|
|
1264
|
+
{ native: "load", normalized: "load" },
|
|
1265
|
+
{ native: "unload", normalized: "unload" },
|
|
1266
|
+
{ native: "scroll", normalized: "scroll" },
|
|
1267
|
+
{ native: "resize", normalized: "resize" },
|
|
1268
|
+
{ native: "dragstart", normalized: "dragstart" },
|
|
1269
|
+
{ native: "drag", normalized: "drag" },
|
|
1270
|
+
{ native: "dragend", normalized: "dragend" },
|
|
1271
|
+
{ native: "dragenter", normalized: "dragenter" },
|
|
1272
|
+
{ native: "dragleave", normalized: "dragleave" },
|
|
1273
|
+
{ native: "dragover", normalized: "dragover" },
|
|
1274
|
+
{ native: "drop", normalized: "drop" },
|
|
1275
|
+
{ native: "touchstart", normalized: "touchstart" },
|
|
1276
|
+
{ native: "touchmove", normalized: "touchmove" },
|
|
1277
|
+
{ native: "touchend", normalized: "touchend" },
|
|
1278
|
+
{ native: "touchcancel", normalized: "touchcancel" },
|
|
1279
|
+
// Prepositions/modifiers not in profile
|
|
1280
|
+
{ native: "in", normalized: "in" },
|
|
1281
|
+
{ native: "to", normalized: "to" },
|
|
1282
|
+
{ native: "at", normalized: "at" },
|
|
1283
|
+
{ native: "by", normalized: "by" },
|
|
1284
|
+
{ native: "with", normalized: "with" },
|
|
1285
|
+
{ native: "without", normalized: "without" },
|
|
1286
|
+
{ native: "of", normalized: "of" },
|
|
1287
|
+
{ native: "as", normalized: "as" },
|
|
1288
|
+
// Event handling keywords
|
|
1289
|
+
{ native: "every", normalized: "every" },
|
|
1290
|
+
{ native: "upon", normalized: "upon" },
|
|
1291
|
+
// Control flow helpers not in profile
|
|
1292
|
+
{ native: "unless", normalized: "unless" },
|
|
1293
|
+
{ native: "forever", normalized: "forever" },
|
|
1294
|
+
{ native: "times", normalized: "times" },
|
|
1295
|
+
// Logical
|
|
1296
|
+
{ native: "and", normalized: "and" },
|
|
1297
|
+
{ native: "or", normalized: "or" },
|
|
1298
|
+
{ native: "not", normalized: "not" },
|
|
1299
|
+
{ native: "is", normalized: "is" },
|
|
1300
|
+
{ native: "exists", normalized: "exists" },
|
|
1301
|
+
{ native: "empty", normalized: "empty" },
|
|
1302
|
+
// References not in profile
|
|
1303
|
+
{ native: "my", normalized: "my" },
|
|
1304
|
+
{ native: "your", normalized: "your" },
|
|
1305
|
+
{ native: "its", normalized: "its" },
|
|
1306
|
+
{ native: "the", normalized: "the" },
|
|
1307
|
+
{ native: "a", normalized: "a" },
|
|
1308
|
+
{ native: "an", normalized: "an" },
|
|
1309
|
+
// Swap strategies
|
|
1310
|
+
{ native: "delete", normalized: "delete" },
|
|
1311
|
+
{ native: "innerHTML", normalized: "innerHTML" },
|
|
1312
|
+
{ native: "outerHTML", normalized: "outerHTML" },
|
|
1313
|
+
{ native: "beforebegin", normalized: "beforebegin" },
|
|
1314
|
+
{ native: "afterend", normalized: "afterend" },
|
|
1315
|
+
{ native: "beforeend", normalized: "beforeend" },
|
|
1316
|
+
{ native: "afterbegin", normalized: "afterbegin" },
|
|
1317
|
+
// Command synonyms with normalized forms
|
|
1318
|
+
{ native: "flip", normalized: "toggle" },
|
|
1319
|
+
{ native: "switch", normalized: "toggle" },
|
|
1320
|
+
{ native: "increase", normalized: "increment" },
|
|
1321
|
+
{ native: "decrease", normalized: "decrement" },
|
|
1322
|
+
{ native: "display", normalized: "show" },
|
|
1323
|
+
{ native: "reveal", normalized: "show" },
|
|
1324
|
+
{ native: "conceal", normalized: "hide" },
|
|
1325
|
+
// British spelling aliases
|
|
1326
|
+
{ native: "colour", normalized: "color" },
|
|
1327
|
+
{ native: "grey", normalized: "gray" },
|
|
1328
|
+
{ native: "centre", normalized: "center" },
|
|
1329
|
+
{ native: "behaviour", normalized: "behavior" },
|
|
1330
|
+
{ native: "initialise", normalized: "initialize" },
|
|
1331
|
+
{ native: "favourite", normalized: "favorite" }
|
|
1332
|
+
];
|
|
1333
|
+
var EnglishTokenizer = class extends BaseTokenizer {
|
|
1334
|
+
constructor() {
|
|
1335
|
+
super();
|
|
1336
|
+
this.language = "en";
|
|
1337
|
+
this.direction = "ltr";
|
|
1338
|
+
this.initializeKeywordsFromProfile(englishProfile, ENGLISH_EXTRAS);
|
|
1339
|
+
}
|
|
1340
|
+
tokenize(input) {
|
|
1341
|
+
const tokens = [];
|
|
1342
|
+
let pos = 0;
|
|
1343
|
+
while (pos < input.length) {
|
|
1344
|
+
if (isWhitespace(input[pos])) {
|
|
1345
|
+
pos++;
|
|
1346
|
+
continue;
|
|
1347
|
+
}
|
|
1348
|
+
if (isSelectorStart(input[pos])) {
|
|
1349
|
+
const modifierToken = this.tryEventModifier(input, pos);
|
|
1350
|
+
if (modifierToken) {
|
|
1351
|
+
tokens.push(modifierToken);
|
|
1352
|
+
pos = modifierToken.position.end;
|
|
1353
|
+
continue;
|
|
1354
|
+
}
|
|
1355
|
+
if (input[pos] === ".") {
|
|
1356
|
+
const lastToken = tokens[tokens.length - 1];
|
|
1357
|
+
const hasWhitespaceBefore = lastToken && lastToken.position.end < pos;
|
|
1358
|
+
const isPropertyAccess = lastToken && !hasWhitespaceBefore && (lastToken.kind === "identifier" || lastToken.kind === "keyword" || lastToken.kind === "selector");
|
|
1359
|
+
if (isPropertyAccess) {
|
|
1360
|
+
tokens.push(createToken(".", "operator", createPosition(pos, pos + 1)));
|
|
1361
|
+
pos++;
|
|
1362
|
+
continue;
|
|
1363
|
+
}
|
|
1364
|
+
const methodStart = pos + 1;
|
|
1365
|
+
let methodEnd = methodStart;
|
|
1366
|
+
while (methodEnd < input.length && isAsciiIdentifierChar(input[methodEnd])) {
|
|
1367
|
+
methodEnd++;
|
|
1368
|
+
}
|
|
1369
|
+
if (methodEnd < input.length && input[methodEnd] === "(") {
|
|
1370
|
+
tokens.push(createToken(".", "operator", createPosition(pos, pos + 1)));
|
|
1371
|
+
pos++;
|
|
1372
|
+
continue;
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
const selectorToken = this.trySelector(input, pos);
|
|
1376
|
+
if (selectorToken) {
|
|
1377
|
+
tokens.push(selectorToken);
|
|
1378
|
+
pos = selectorToken.position.end;
|
|
1379
|
+
continue;
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
if (isQuote(input[pos])) {
|
|
1383
|
+
if (input[pos] === "'" && isPossessiveMarker(input, pos)) {
|
|
1384
|
+
tokens.push(createToken("'s", "punctuation", createPosition(pos, pos + 2)));
|
|
1385
|
+
pos += 2;
|
|
1386
|
+
continue;
|
|
1387
|
+
}
|
|
1388
|
+
const stringToken = this.tryString(input, pos);
|
|
1389
|
+
if (stringToken) {
|
|
1390
|
+
tokens.push(stringToken);
|
|
1391
|
+
pos = stringToken.position.end;
|
|
1392
|
+
continue;
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
if (isUrlStart(input, pos)) {
|
|
1396
|
+
const urlToken = this.tryUrl(input, pos);
|
|
1397
|
+
if (urlToken) {
|
|
1398
|
+
tokens.push(urlToken);
|
|
1399
|
+
pos = urlToken.position.end;
|
|
1400
|
+
continue;
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
if (isDigit(input[pos]) || input[pos] === "-" && pos + 1 < input.length && isDigit(input[pos + 1])) {
|
|
1404
|
+
const numberToken = this.tryNumber(input, pos);
|
|
1405
|
+
if (numberToken) {
|
|
1406
|
+
tokens.push(numberToken);
|
|
1407
|
+
pos = numberToken.position.end;
|
|
1408
|
+
continue;
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
const varToken = this.tryVariableRef(input, pos);
|
|
1412
|
+
if (varToken) {
|
|
1413
|
+
tokens.push(varToken);
|
|
1414
|
+
pos = varToken.position.end;
|
|
1415
|
+
continue;
|
|
1416
|
+
}
|
|
1417
|
+
if (isAsciiIdentifierChar(input[pos])) {
|
|
1418
|
+
const wordToken = this.extractWord(input, pos);
|
|
1419
|
+
if (wordToken) {
|
|
1420
|
+
tokens.push(wordToken);
|
|
1421
|
+
pos = wordToken.position.end;
|
|
1422
|
+
continue;
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
const operatorToken = this.tryOperator(input, pos);
|
|
1426
|
+
if (operatorToken) {
|
|
1427
|
+
tokens.push(operatorToken);
|
|
1428
|
+
pos = operatorToken.position.end;
|
|
1429
|
+
continue;
|
|
1430
|
+
}
|
|
1431
|
+
pos++;
|
|
1432
|
+
}
|
|
1433
|
+
return new TokenStreamImpl(tokens, "en");
|
|
1434
|
+
}
|
|
1435
|
+
classifyToken(token) {
|
|
1436
|
+
if (this.isKeyword(token)) return "keyword";
|
|
1437
|
+
if (token.startsWith("#") || token.startsWith(".") || token.startsWith("[")) return "selector";
|
|
1438
|
+
if (token.startsWith('"') || token.startsWith("'")) return "literal";
|
|
1439
|
+
if (/^\d/.test(token)) return "literal";
|
|
1440
|
+
if (["==", "!=", "<=", ">=", "<", ">", "&&", "||", "!"].includes(token)) return "operator";
|
|
1441
|
+
if (token.startsWith("/") || token.startsWith("./") || token.startsWith("http")) return "url";
|
|
1442
|
+
return "identifier";
|
|
1443
|
+
}
|
|
1444
|
+
/**
|
|
1445
|
+
* Extract a word (identifier or keyword) from the input.
|
|
1446
|
+
* Handles namespaced event names like "draggable:start".
|
|
1447
|
+
*/
|
|
1448
|
+
extractWord(input, startPos) {
|
|
1449
|
+
let pos = startPos;
|
|
1450
|
+
let word = "";
|
|
1451
|
+
while (pos < input.length && isAsciiIdentifierChar(input[pos])) {
|
|
1452
|
+
word += input[pos++];
|
|
1453
|
+
}
|
|
1454
|
+
if (!word) return null;
|
|
1455
|
+
if (pos < input.length && input[pos] === ":") {
|
|
1456
|
+
const colonPos = pos;
|
|
1457
|
+
pos++;
|
|
1458
|
+
let namespace = "";
|
|
1459
|
+
while (pos < input.length && isAsciiIdentifierChar(input[pos])) {
|
|
1460
|
+
namespace += input[pos++];
|
|
1461
|
+
}
|
|
1462
|
+
if (namespace) {
|
|
1463
|
+
word = word + ":" + namespace;
|
|
1464
|
+
} else {
|
|
1465
|
+
pos = colonPos;
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
const kind = this.classifyToken(word);
|
|
1469
|
+
const keywordEntry = this.lookupKeyword(word);
|
|
1470
|
+
const normalized = keywordEntry && keywordEntry.normalized !== keywordEntry.native ? keywordEntry.normalized : void 0;
|
|
1471
|
+
if (kind === "identifier") {
|
|
1472
|
+
const classConversion = this.tryConvertToClassSelector(input, pos, word);
|
|
1473
|
+
if (classConversion) {
|
|
1474
|
+
return classConversion.token;
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
return createToken(
|
|
1478
|
+
word,
|
|
1479
|
+
kind,
|
|
1480
|
+
createPosition(startPos, pos),
|
|
1481
|
+
normalized
|
|
1482
|
+
// Will be undefined if not a synonym, which is fine
|
|
1483
|
+
);
|
|
1484
|
+
}
|
|
1485
|
+
/**
|
|
1486
|
+
* Try to convert an identifier followed by "class" to a class selector.
|
|
1487
|
+
* E.g., "active class" → ".active"
|
|
1488
|
+
*
|
|
1489
|
+
* This enables natural English syntax like:
|
|
1490
|
+
* - "toggle the active class" → "toggle .active"
|
|
1491
|
+
* - "add the visible class" → "add .visible"
|
|
1492
|
+
*/
|
|
1493
|
+
tryConvertToClassSelector(input, pos, word) {
|
|
1494
|
+
let checkPos = pos;
|
|
1495
|
+
while (checkPos < input.length && /\s/.test(input[checkPos])) {
|
|
1496
|
+
checkPos++;
|
|
1497
|
+
}
|
|
1498
|
+
if (input.slice(checkPos, checkPos + 5).toLowerCase() === "class") {
|
|
1499
|
+
const afterClass = checkPos + 5;
|
|
1500
|
+
if (afterClass >= input.length || !isAsciiIdentifierChar(input[afterClass])) {
|
|
1501
|
+
const selectorValue = "." + word;
|
|
1502
|
+
return {
|
|
1503
|
+
token: createToken(selectorValue, "selector", createPosition(pos - word.length, pos)),
|
|
1504
|
+
endPos: pos
|
|
1505
|
+
};
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
return null;
|
|
1509
|
+
}
|
|
1510
|
+
};
|
|
1511
|
+
var englishTokenizer = new EnglishTokenizer();
|
|
1512
|
+
|
|
1513
|
+
// src/generators/command-schemas.ts
|
|
1514
|
+
var toggleSchema = {
|
|
1515
|
+
action: "toggle",
|
|
1516
|
+
description: "Toggle a class or attribute on/off",
|
|
1517
|
+
category: "dom-class",
|
|
1518
|
+
primaryRole: "patient",
|
|
1519
|
+
roles: [
|
|
1520
|
+
{
|
|
1521
|
+
role: "patient",
|
|
1522
|
+
description: "The class or attribute to toggle",
|
|
1523
|
+
required: true,
|
|
1524
|
+
expectedTypes: ["selector"],
|
|
1525
|
+
svoPosition: 1,
|
|
1526
|
+
sovPosition: 2
|
|
1527
|
+
},
|
|
1528
|
+
{
|
|
1529
|
+
role: "destination",
|
|
1530
|
+
description: "The target element (defaults to me)",
|
|
1531
|
+
required: false,
|
|
1532
|
+
expectedTypes: ["selector", "reference"],
|
|
1533
|
+
default: { type: "reference", value: "me" },
|
|
1534
|
+
svoPosition: 2,
|
|
1535
|
+
sovPosition: 1
|
|
1536
|
+
}
|
|
1537
|
+
],
|
|
1538
|
+
// Runtime error documentation
|
|
1539
|
+
errorCodes: ["MISSING_ARGUMENT", "NO_VALID_CLASS_NAMES", "INVALID_CSS_PROPERTY"],
|
|
1540
|
+
preconditions: [
|
|
1541
|
+
{
|
|
1542
|
+
condition: "Command has at least one argument",
|
|
1543
|
+
errorCode: "MISSING_ARGUMENT",
|
|
1544
|
+
message: "toggle command requires an argument"
|
|
1545
|
+
},
|
|
1546
|
+
{
|
|
1547
|
+
condition: "Class names are valid CSS identifiers",
|
|
1548
|
+
errorCode: "NO_VALID_CLASS_NAMES",
|
|
1549
|
+
message: "toggle command: no valid class names found"
|
|
1550
|
+
}
|
|
1551
|
+
],
|
|
1552
|
+
recoveryHints: {
|
|
1553
|
+
MISSING_ARGUMENT: "Add a class selector (.classname) or attribute to toggle",
|
|
1554
|
+
NO_VALID_CLASS_NAMES: "Ensure class names start with a dot (.) and are valid CSS identifiers",
|
|
1555
|
+
INVALID_CSS_PROPERTY: "Check CSS property name syntax (use kebab-case)"
|
|
1556
|
+
}
|
|
1557
|
+
};
|
|
1558
|
+
var addSchema = {
|
|
1559
|
+
action: "add",
|
|
1560
|
+
description: "Add a class or attribute to an element",
|
|
1561
|
+
category: "dom-class",
|
|
1562
|
+
primaryRole: "patient",
|
|
1563
|
+
roles: [
|
|
1564
|
+
{
|
|
1565
|
+
role: "patient",
|
|
1566
|
+
description: "The class or attribute to add",
|
|
1567
|
+
required: true,
|
|
1568
|
+
expectedTypes: ["selector"],
|
|
1569
|
+
svoPosition: 1,
|
|
1570
|
+
sovPosition: 2
|
|
1571
|
+
},
|
|
1572
|
+
{
|
|
1573
|
+
role: "destination",
|
|
1574
|
+
description: "The target element (defaults to me)",
|
|
1575
|
+
required: false,
|
|
1576
|
+
expectedTypes: ["selector", "reference"],
|
|
1577
|
+
default: { type: "reference", value: "me" },
|
|
1578
|
+
svoPosition: 2,
|
|
1579
|
+
sovPosition: 1
|
|
1580
|
+
}
|
|
1581
|
+
],
|
|
1582
|
+
// Runtime error documentation
|
|
1583
|
+
errorCodes: ["MISSING_ARGUMENT", "NO_VALID_CLASS_NAMES", "PROPERTY_REQUIRES_VALUE"],
|
|
1584
|
+
preconditions: [
|
|
1585
|
+
{
|
|
1586
|
+
condition: "Command has at least one argument",
|
|
1587
|
+
errorCode: "MISSING_ARGUMENT",
|
|
1588
|
+
message: "add command requires an argument"
|
|
1589
|
+
}
|
|
1590
|
+
],
|
|
1591
|
+
recoveryHints: {
|
|
1592
|
+
MISSING_ARGUMENT: "Add a class selector (.classname) or attribute to add",
|
|
1593
|
+
NO_VALID_CLASS_NAMES: "Ensure class names start with a dot (.) and are valid CSS identifiers",
|
|
1594
|
+
PROPERTY_REQUIRES_VALUE: "When adding a property (*prop), provide a value argument"
|
|
1595
|
+
}
|
|
1596
|
+
};
|
|
1597
|
+
var removeSchema = {
|
|
1598
|
+
action: "remove",
|
|
1599
|
+
description: "Remove a class or attribute from an element",
|
|
1600
|
+
category: "dom-class",
|
|
1601
|
+
primaryRole: "patient",
|
|
1602
|
+
roles: [
|
|
1603
|
+
{
|
|
1604
|
+
role: "patient",
|
|
1605
|
+
description: "The class or attribute to remove",
|
|
1606
|
+
required: true,
|
|
1607
|
+
expectedTypes: ["selector"],
|
|
1608
|
+
svoPosition: 1,
|
|
1609
|
+
sovPosition: 2
|
|
1610
|
+
},
|
|
1611
|
+
{
|
|
1612
|
+
role: "source",
|
|
1613
|
+
description: "The element to remove from (defaults to me)",
|
|
1614
|
+
required: false,
|
|
1615
|
+
expectedTypes: ["selector", "reference"],
|
|
1616
|
+
default: { type: "reference", value: "me" },
|
|
1617
|
+
svoPosition: 2,
|
|
1618
|
+
sovPosition: 1
|
|
1619
|
+
}
|
|
1620
|
+
],
|
|
1621
|
+
// Runtime error documentation
|
|
1622
|
+
errorCodes: ["MISSING_ARGUMENT", "NO_VALID_CLASS_NAMES"],
|
|
1623
|
+
preconditions: [
|
|
1624
|
+
{
|
|
1625
|
+
condition: "Command has at least one argument",
|
|
1626
|
+
errorCode: "MISSING_ARGUMENT",
|
|
1627
|
+
message: "remove command requires an argument"
|
|
1628
|
+
}
|
|
1629
|
+
],
|
|
1630
|
+
recoveryHints: {
|
|
1631
|
+
MISSING_ARGUMENT: "Add a class selector (.classname) or attribute to remove",
|
|
1632
|
+
NO_VALID_CLASS_NAMES: "Ensure class names start with a dot (.) and are valid CSS identifiers"
|
|
1633
|
+
}
|
|
1634
|
+
};
|
|
1635
|
+
var putSchema = {
|
|
1636
|
+
action: "put",
|
|
1637
|
+
description: "Put content into a target element or variable",
|
|
1638
|
+
category: "dom-content",
|
|
1639
|
+
primaryRole: "patient",
|
|
1640
|
+
roles: [
|
|
1641
|
+
{
|
|
1642
|
+
role: "patient",
|
|
1643
|
+
description: "The content to put",
|
|
1644
|
+
required: true,
|
|
1645
|
+
expectedTypes: ["literal", "selector", "reference", "expression"],
|
|
1646
|
+
svoPosition: 1,
|
|
1647
|
+
sovPosition: 2
|
|
1648
|
+
},
|
|
1649
|
+
{
|
|
1650
|
+
role: "destination",
|
|
1651
|
+
description: "Where to put the content",
|
|
1652
|
+
required: true,
|
|
1653
|
+
expectedTypes: ["selector", "reference"],
|
|
1654
|
+
svoPosition: 2,
|
|
1655
|
+
sovPosition: 1
|
|
1656
|
+
}
|
|
1657
|
+
],
|
|
1658
|
+
// Runtime error documentation
|
|
1659
|
+
errorCodes: [
|
|
1660
|
+
"MISSING_ARGUMENTS",
|
|
1661
|
+
"MISSING_CONTENT",
|
|
1662
|
+
"MISSING_POSITION",
|
|
1663
|
+
"INVALID_POSITION",
|
|
1664
|
+
"NO_TARGET",
|
|
1665
|
+
"NO_ELEMENTS"
|
|
1666
|
+
],
|
|
1667
|
+
preconditions: [
|
|
1668
|
+
{
|
|
1669
|
+
condition: "Command has content and position arguments",
|
|
1670
|
+
errorCode: "MISSING_ARGUMENTS",
|
|
1671
|
+
message: "put requires arguments"
|
|
1672
|
+
},
|
|
1673
|
+
{
|
|
1674
|
+
condition: "Content to put is specified",
|
|
1675
|
+
errorCode: "MISSING_CONTENT",
|
|
1676
|
+
message: "put requires content"
|
|
1677
|
+
},
|
|
1678
|
+
{
|
|
1679
|
+
condition: "Position keyword is specified (into, before, after, etc.)",
|
|
1680
|
+
errorCode: "MISSING_POSITION",
|
|
1681
|
+
message: "put requires position keyword"
|
|
1682
|
+
}
|
|
1683
|
+
],
|
|
1684
|
+
recoveryHints: {
|
|
1685
|
+
MISSING_ARGUMENTS: "Use syntax: put <content> into/before/after <target>",
|
|
1686
|
+
MISSING_CONTENT: "Add content to put (string, element, or expression)",
|
|
1687
|
+
MISSING_POSITION: "Add position keyword: into, before, after, at start of, at end of",
|
|
1688
|
+
INVALID_POSITION: "Valid positions: into, before, after, at start of, at end of",
|
|
1689
|
+
NO_TARGET: 'Ensure target element exists or use "me" reference',
|
|
1690
|
+
NO_ELEMENTS: "Check that the selector matches existing elements"
|
|
1691
|
+
}
|
|
1692
|
+
};
|
|
1693
|
+
var setSchema = {
|
|
1694
|
+
action: "set",
|
|
1695
|
+
description: "Set a property or variable to a value",
|
|
1696
|
+
category: "variable",
|
|
1697
|
+
primaryRole: "destination",
|
|
1698
|
+
roles: [
|
|
1699
|
+
{
|
|
1700
|
+
role: "destination",
|
|
1701
|
+
description: "The property or variable to set",
|
|
1702
|
+
required: true,
|
|
1703
|
+
expectedTypes: ["selector", "reference"],
|
|
1704
|
+
svoPosition: 1,
|
|
1705
|
+
sovPosition: 1,
|
|
1706
|
+
// Override destination marker for English (remove 'on', use no marker)
|
|
1707
|
+
// Other languages keep their default destination markers
|
|
1708
|
+
markerOverride: {
|
|
1709
|
+
en: ""
|
|
1710
|
+
// No marker before destination in English: "set :x to 5"
|
|
1711
|
+
}
|
|
1712
|
+
},
|
|
1713
|
+
{
|
|
1714
|
+
role: "patient",
|
|
1715
|
+
description: "The value to set",
|
|
1716
|
+
required: true,
|
|
1717
|
+
expectedTypes: ["literal", "expression", "reference"],
|
|
1718
|
+
svoPosition: 2,
|
|
1719
|
+
sovPosition: 2,
|
|
1720
|
+
// Override patient marker for SVO languages with their native prepositions
|
|
1721
|
+
// SOV languages (Korean, Japanese, Turkish) use their default object markers
|
|
1722
|
+
markerOverride: {
|
|
1723
|
+
en: "to",
|
|
1724
|
+
// "set :x to 5"
|
|
1725
|
+
es: "a",
|
|
1726
|
+
// "establecer x a 10"
|
|
1727
|
+
pt: "para",
|
|
1728
|
+
// "definir x para 10"
|
|
1729
|
+
fr: "\xE0",
|
|
1730
|
+
// "définir x à 10"
|
|
1731
|
+
de: "auf",
|
|
1732
|
+
// "setze x auf 10"
|
|
1733
|
+
id: "ke"
|
|
1734
|
+
// "atur x ke 10"
|
|
1735
|
+
}
|
|
1736
|
+
}
|
|
1737
|
+
],
|
|
1738
|
+
// Runtime error documentation
|
|
1739
|
+
errorCodes: ["MISSING_TARGET", "INVALID_TARGET", "MISSING_VALUE", "INVALID_SYNTAX"],
|
|
1740
|
+
preconditions: [
|
|
1741
|
+
{
|
|
1742
|
+
condition: "Command has a target variable or property",
|
|
1743
|
+
errorCode: "MISSING_TARGET",
|
|
1744
|
+
message: "set command requires a target"
|
|
1745
|
+
},
|
|
1746
|
+
{
|
|
1747
|
+
condition: "Target is a valid variable or property reference",
|
|
1748
|
+
errorCode: "INVALID_TARGET",
|
|
1749
|
+
message: "set command target must be a string or object literal"
|
|
1750
|
+
},
|
|
1751
|
+
{
|
|
1752
|
+
condition: 'Value is specified with "to" keyword',
|
|
1753
|
+
errorCode: "MISSING_VALUE",
|
|
1754
|
+
message: 'set command requires a value (use "to" keyword)'
|
|
1755
|
+
}
|
|
1756
|
+
],
|
|
1757
|
+
recoveryHints: {
|
|
1758
|
+
MISSING_TARGET: "Add a target: set :variable to value OR set element.property to value",
|
|
1759
|
+
INVALID_TARGET: 'Use local variable (:name), element property (el.prop), or "the X of Y" syntax',
|
|
1760
|
+
MISSING_VALUE: 'Add "to <value>" to specify what to set',
|
|
1761
|
+
INVALID_SYNTAX: "Use syntax: set <target> to <value>"
|
|
1762
|
+
}
|
|
1763
|
+
};
|
|
1764
|
+
var showSchema = {
|
|
1765
|
+
action: "show",
|
|
1766
|
+
description: "Make an element visible",
|
|
1767
|
+
category: "dom-visibility",
|
|
1768
|
+
primaryRole: "patient",
|
|
1769
|
+
roles: [
|
|
1770
|
+
{
|
|
1771
|
+
role: "patient",
|
|
1772
|
+
description: "The element to show",
|
|
1773
|
+
required: true,
|
|
1774
|
+
// Changed from false - patient is primary role
|
|
1775
|
+
expectedTypes: ["selector", "reference"],
|
|
1776
|
+
default: { type: "reference", value: "me" },
|
|
1777
|
+
svoPosition: 1,
|
|
1778
|
+
sovPosition: 1
|
|
1779
|
+
},
|
|
1780
|
+
{
|
|
1781
|
+
role: "style",
|
|
1782
|
+
description: "Animation style (fade, slide, etc.)",
|
|
1783
|
+
required: false,
|
|
1784
|
+
expectedTypes: ["literal"],
|
|
1785
|
+
svoPosition: 2,
|
|
1786
|
+
sovPosition: 2
|
|
1787
|
+
}
|
|
1788
|
+
]
|
|
1789
|
+
};
|
|
1790
|
+
var hideSchema = {
|
|
1791
|
+
action: "hide",
|
|
1792
|
+
description: "Make an element invisible",
|
|
1793
|
+
category: "dom-visibility",
|
|
1794
|
+
primaryRole: "patient",
|
|
1795
|
+
roles: [
|
|
1796
|
+
{
|
|
1797
|
+
role: "patient",
|
|
1798
|
+
description: "The element to hide",
|
|
1799
|
+
required: true,
|
|
1800
|
+
// Changed from false - patient is primary role
|
|
1801
|
+
expectedTypes: ["selector", "reference"],
|
|
1802
|
+
default: { type: "reference", value: "me" },
|
|
1803
|
+
svoPosition: 1,
|
|
1804
|
+
sovPosition: 1
|
|
1805
|
+
},
|
|
1806
|
+
{
|
|
1807
|
+
role: "style",
|
|
1808
|
+
description: "Animation style (fade, slide, etc.)",
|
|
1809
|
+
required: false,
|
|
1810
|
+
expectedTypes: ["literal"],
|
|
1811
|
+
svoPosition: 2,
|
|
1812
|
+
sovPosition: 2
|
|
1813
|
+
}
|
|
1814
|
+
]
|
|
1815
|
+
};
|
|
1816
|
+
var onSchema = {
|
|
1817
|
+
action: "on",
|
|
1818
|
+
description: "Handle an event",
|
|
1819
|
+
category: "event",
|
|
1820
|
+
primaryRole: "event",
|
|
1821
|
+
hasBody: true,
|
|
1822
|
+
roles: [
|
|
1823
|
+
{
|
|
1824
|
+
role: "event",
|
|
1825
|
+
description: "The event to handle",
|
|
1826
|
+
required: true,
|
|
1827
|
+
expectedTypes: ["literal"],
|
|
1828
|
+
svoPosition: 1,
|
|
1829
|
+
sovPosition: 2
|
|
1830
|
+
},
|
|
1831
|
+
{
|
|
1832
|
+
role: "source",
|
|
1833
|
+
description: "The element to listen on (defaults to me)",
|
|
1834
|
+
required: false,
|
|
1835
|
+
expectedTypes: ["selector", "reference"],
|
|
1836
|
+
default: { type: "reference", value: "me" },
|
|
1837
|
+
svoPosition: 2,
|
|
1838
|
+
sovPosition: 1
|
|
1839
|
+
}
|
|
1840
|
+
]
|
|
1841
|
+
};
|
|
1842
|
+
var triggerSchema = {
|
|
1843
|
+
action: "trigger",
|
|
1844
|
+
description: "Trigger/dispatch an event",
|
|
1845
|
+
category: "event",
|
|
1846
|
+
primaryRole: "event",
|
|
1847
|
+
roles: [
|
|
1848
|
+
{
|
|
1849
|
+
role: "event",
|
|
1850
|
+
description: "The event to trigger (supports namespaced events like draggable:start)",
|
|
1851
|
+
required: true,
|
|
1852
|
+
expectedTypes: ["literal", "expression"],
|
|
1853
|
+
// expression for custom/namespaced event names
|
|
1854
|
+
svoPosition: 1,
|
|
1855
|
+
sovPosition: 2
|
|
1856
|
+
},
|
|
1857
|
+
{
|
|
1858
|
+
role: "destination",
|
|
1859
|
+
description: "The target element (defaults to me)",
|
|
1860
|
+
required: false,
|
|
1861
|
+
expectedTypes: ["selector", "reference"],
|
|
1862
|
+
default: { type: "reference", value: "me" },
|
|
1863
|
+
svoPosition: 2,
|
|
1864
|
+
sovPosition: 1
|
|
1865
|
+
}
|
|
1866
|
+
]
|
|
1867
|
+
};
|
|
1868
|
+
var waitSchema = {
|
|
1869
|
+
action: "wait",
|
|
1870
|
+
description: "Wait for a duration or event",
|
|
1871
|
+
category: "async",
|
|
1872
|
+
primaryRole: "patient",
|
|
1873
|
+
roles: [
|
|
1874
|
+
{
|
|
1875
|
+
role: "patient",
|
|
1876
|
+
description: "Duration or event to wait for",
|
|
1877
|
+
required: true,
|
|
1878
|
+
expectedTypes: ["literal", "expression"],
|
|
1879
|
+
svoPosition: 1,
|
|
1880
|
+
sovPosition: 1
|
|
1881
|
+
}
|
|
1882
|
+
]
|
|
1883
|
+
};
|
|
1884
|
+
var fetchSchema = {
|
|
1885
|
+
action: "fetch",
|
|
1886
|
+
description: "Fetch data from a URL",
|
|
1887
|
+
category: "async",
|
|
1888
|
+
primaryRole: "source",
|
|
1889
|
+
roles: [
|
|
1890
|
+
{
|
|
1891
|
+
role: "source",
|
|
1892
|
+
description: "The URL to fetch from",
|
|
1893
|
+
required: true,
|
|
1894
|
+
expectedTypes: ["literal", "expression"],
|
|
1895
|
+
svoPosition: 1,
|
|
1896
|
+
sovPosition: 1
|
|
1897
|
+
},
|
|
1898
|
+
{
|
|
1899
|
+
role: "responseType",
|
|
1900
|
+
description: "Response format (json, text, html, blob, etc.)",
|
|
1901
|
+
required: false,
|
|
1902
|
+
expectedTypes: ["literal", "expression"],
|
|
1903
|
+
// json/text/html are identifiers → expression type
|
|
1904
|
+
svoPosition: 2,
|
|
1905
|
+
sovPosition: 2
|
|
1906
|
+
},
|
|
1907
|
+
{
|
|
1908
|
+
role: "method",
|
|
1909
|
+
description: "HTTP method (GET, POST, etc.)",
|
|
1910
|
+
required: false,
|
|
1911
|
+
expectedTypes: ["literal"],
|
|
1912
|
+
svoPosition: 3,
|
|
1913
|
+
sovPosition: 3
|
|
1914
|
+
},
|
|
1915
|
+
{
|
|
1916
|
+
role: "destination",
|
|
1917
|
+
description: "Where to store the result",
|
|
1918
|
+
required: false,
|
|
1919
|
+
expectedTypes: ["selector", "reference"],
|
|
1920
|
+
svoPosition: 4,
|
|
1921
|
+
sovPosition: 4
|
|
1922
|
+
}
|
|
1923
|
+
]
|
|
1924
|
+
};
|
|
1925
|
+
var incrementSchema = {
|
|
1926
|
+
action: "increment",
|
|
1927
|
+
description: "Increment a numeric value",
|
|
1928
|
+
category: "variable",
|
|
1929
|
+
primaryRole: "patient",
|
|
1930
|
+
roles: [
|
|
1931
|
+
{
|
|
1932
|
+
role: "patient",
|
|
1933
|
+
description: "The value to increment",
|
|
1934
|
+
required: true,
|
|
1935
|
+
expectedTypes: ["selector", "reference", "expression"],
|
|
1936
|
+
svoPosition: 1,
|
|
1937
|
+
sovPosition: 1
|
|
1938
|
+
},
|
|
1939
|
+
{
|
|
1940
|
+
role: "quantity",
|
|
1941
|
+
description: "Amount to increment by (defaults to 1)",
|
|
1942
|
+
required: false,
|
|
1943
|
+
expectedTypes: ["literal"],
|
|
1944
|
+
default: { type: "literal", value: 1, dataType: "number" },
|
|
1945
|
+
svoPosition: 2,
|
|
1946
|
+
sovPosition: 2
|
|
1947
|
+
}
|
|
1948
|
+
]
|
|
1949
|
+
};
|
|
1950
|
+
var decrementSchema = {
|
|
1951
|
+
action: "decrement",
|
|
1952
|
+
description: "Decrement a numeric value",
|
|
1953
|
+
category: "variable",
|
|
1954
|
+
primaryRole: "patient",
|
|
1955
|
+
roles: [
|
|
1956
|
+
{
|
|
1957
|
+
role: "patient",
|
|
1958
|
+
description: "The value to decrement",
|
|
1959
|
+
required: true,
|
|
1960
|
+
expectedTypes: ["selector", "reference", "expression"],
|
|
1961
|
+
svoPosition: 1,
|
|
1962
|
+
sovPosition: 1
|
|
1963
|
+
},
|
|
1964
|
+
{
|
|
1965
|
+
role: "quantity",
|
|
1966
|
+
description: "Amount to decrement by (defaults to 1)",
|
|
1967
|
+
required: false,
|
|
1968
|
+
expectedTypes: ["literal"],
|
|
1969
|
+
default: { type: "literal", value: 1, dataType: "number" },
|
|
1970
|
+
svoPosition: 2,
|
|
1971
|
+
sovPosition: 2
|
|
1972
|
+
}
|
|
1973
|
+
]
|
|
1974
|
+
};
|
|
1975
|
+
var appendSchema = {
|
|
1976
|
+
action: "append",
|
|
1977
|
+
description: "Append content to an element",
|
|
1978
|
+
category: "dom-content",
|
|
1979
|
+
primaryRole: "patient",
|
|
1980
|
+
roles: [
|
|
1981
|
+
{
|
|
1982
|
+
role: "patient",
|
|
1983
|
+
description: "The content to append",
|
|
1984
|
+
required: true,
|
|
1985
|
+
expectedTypes: ["literal", "selector", "expression"],
|
|
1986
|
+
svoPosition: 1,
|
|
1987
|
+
sovPosition: 2
|
|
1988
|
+
},
|
|
1989
|
+
{
|
|
1990
|
+
role: "destination",
|
|
1991
|
+
description: "The element to append to",
|
|
1992
|
+
required: true,
|
|
1993
|
+
expectedTypes: ["selector", "reference"],
|
|
1994
|
+
svoPosition: 2,
|
|
1995
|
+
sovPosition: 1
|
|
1996
|
+
}
|
|
1997
|
+
]
|
|
1998
|
+
};
|
|
1999
|
+
var prependSchema = {
|
|
2000
|
+
action: "prepend",
|
|
2001
|
+
description: "Prepend content to an element",
|
|
2002
|
+
category: "dom-content",
|
|
2003
|
+
primaryRole: "patient",
|
|
2004
|
+
roles: [
|
|
2005
|
+
{
|
|
2006
|
+
role: "patient",
|
|
2007
|
+
description: "The content to prepend",
|
|
2008
|
+
required: true,
|
|
2009
|
+
expectedTypes: ["literal", "selector", "expression"],
|
|
2010
|
+
svoPosition: 1,
|
|
2011
|
+
sovPosition: 2
|
|
2012
|
+
},
|
|
2013
|
+
{
|
|
2014
|
+
role: "destination",
|
|
2015
|
+
description: "The element to prepend to",
|
|
2016
|
+
required: true,
|
|
2017
|
+
expectedTypes: ["selector", "reference"],
|
|
2018
|
+
svoPosition: 2,
|
|
2019
|
+
sovPosition: 1
|
|
2020
|
+
}
|
|
2021
|
+
]
|
|
2022
|
+
};
|
|
2023
|
+
var logSchema = {
|
|
2024
|
+
action: "log",
|
|
2025
|
+
description: "Log a value to the console",
|
|
2026
|
+
category: "variable",
|
|
2027
|
+
primaryRole: "patient",
|
|
2028
|
+
roles: [
|
|
2029
|
+
{
|
|
2030
|
+
role: "patient",
|
|
2031
|
+
description: "The value to log",
|
|
2032
|
+
required: true,
|
|
2033
|
+
expectedTypes: ["literal", "selector", "reference", "expression"],
|
|
2034
|
+
svoPosition: 1,
|
|
2035
|
+
sovPosition: 1
|
|
2036
|
+
}
|
|
2037
|
+
]
|
|
2038
|
+
};
|
|
2039
|
+
var getCommandSchema = {
|
|
2040
|
+
action: "get",
|
|
2041
|
+
description: "Get a value from a source",
|
|
2042
|
+
category: "variable",
|
|
2043
|
+
primaryRole: "source",
|
|
2044
|
+
roles: [
|
|
2045
|
+
{
|
|
2046
|
+
role: "source",
|
|
2047
|
+
description: "The source to get from",
|
|
2048
|
+
required: true,
|
|
2049
|
+
expectedTypes: ["selector", "reference", "expression"],
|
|
2050
|
+
svoPosition: 1,
|
|
2051
|
+
sovPosition: 2,
|
|
2052
|
+
// No marker before source for simple GET pattern: "get #element" not "get from #element"
|
|
2053
|
+
markerOverride: {
|
|
2054
|
+
en: "",
|
|
2055
|
+
es: "",
|
|
2056
|
+
pt: "",
|
|
2057
|
+
fr: "",
|
|
2058
|
+
de: "",
|
|
2059
|
+
ja: "",
|
|
2060
|
+
zh: "",
|
|
2061
|
+
ko: "",
|
|
2062
|
+
ar: "",
|
|
2063
|
+
tr: "",
|
|
2064
|
+
id: ""
|
|
2065
|
+
}
|
|
2066
|
+
},
|
|
2067
|
+
{
|
|
2068
|
+
role: "destination",
|
|
2069
|
+
description: "Where to store the result (optional)",
|
|
2070
|
+
required: false,
|
|
2071
|
+
expectedTypes: ["reference"],
|
|
2072
|
+
svoPosition: 2,
|
|
2073
|
+
sovPosition: 1
|
|
2074
|
+
}
|
|
2075
|
+
]
|
|
2076
|
+
};
|
|
2077
|
+
var takeSchema = {
|
|
2078
|
+
action: "take",
|
|
2079
|
+
description: "Take content from a source element",
|
|
2080
|
+
category: "dom-content",
|
|
2081
|
+
primaryRole: "patient",
|
|
2082
|
+
roles: [
|
|
2083
|
+
{
|
|
2084
|
+
role: "patient",
|
|
2085
|
+
description: "The class or element to take",
|
|
2086
|
+
required: true,
|
|
2087
|
+
expectedTypes: ["selector"],
|
|
2088
|
+
svoPosition: 1,
|
|
2089
|
+
sovPosition: 2
|
|
2090
|
+
},
|
|
2091
|
+
{
|
|
2092
|
+
role: "source",
|
|
2093
|
+
description: "The element to take from (defaults to me)",
|
|
2094
|
+
required: false,
|
|
2095
|
+
expectedTypes: ["selector", "reference"],
|
|
2096
|
+
default: { type: "reference", value: "me" },
|
|
2097
|
+
svoPosition: 2,
|
|
2098
|
+
sovPosition: 1
|
|
2099
|
+
}
|
|
2100
|
+
]
|
|
2101
|
+
};
|
|
2102
|
+
var makeSchema = {
|
|
2103
|
+
action: "make",
|
|
2104
|
+
description: "Create a new element",
|
|
2105
|
+
category: "dom-content",
|
|
2106
|
+
primaryRole: "patient",
|
|
2107
|
+
roles: [
|
|
2108
|
+
{
|
|
2109
|
+
role: "patient",
|
|
2110
|
+
description: "The element type or selector to create",
|
|
2111
|
+
required: true,
|
|
2112
|
+
expectedTypes: ["literal", "selector"],
|
|
2113
|
+
svoPosition: 1,
|
|
2114
|
+
sovPosition: 1
|
|
2115
|
+
}
|
|
2116
|
+
]
|
|
2117
|
+
};
|
|
2118
|
+
var haltSchema = {
|
|
2119
|
+
action: "halt",
|
|
2120
|
+
description: "Halt/stop execution or event propagation",
|
|
2121
|
+
category: "control-flow",
|
|
2122
|
+
primaryRole: "patient",
|
|
2123
|
+
roles: [
|
|
2124
|
+
{
|
|
2125
|
+
role: "patient",
|
|
2126
|
+
description: "What to halt (event, default, bubbling, etc.)",
|
|
2127
|
+
required: false,
|
|
2128
|
+
// Plain "halt" is valid
|
|
2129
|
+
expectedTypes: ["literal", "reference", "expression"],
|
|
2130
|
+
svoPosition: 1,
|
|
2131
|
+
sovPosition: 1
|
|
2132
|
+
}
|
|
2133
|
+
]
|
|
2134
|
+
};
|
|
2135
|
+
var settleSchema = {
|
|
2136
|
+
action: "settle",
|
|
2137
|
+
description: "Wait for animations/transitions to settle",
|
|
2138
|
+
category: "async",
|
|
2139
|
+
primaryRole: "patient",
|
|
2140
|
+
roles: [
|
|
2141
|
+
{
|
|
2142
|
+
role: "patient",
|
|
2143
|
+
description: "The element to settle (defaults to me)",
|
|
2144
|
+
required: false,
|
|
2145
|
+
expectedTypes: ["selector", "reference"],
|
|
2146
|
+
default: { type: "reference", value: "me" },
|
|
2147
|
+
svoPosition: 1,
|
|
2148
|
+
sovPosition: 1
|
|
2149
|
+
}
|
|
2150
|
+
]
|
|
2151
|
+
};
|
|
2152
|
+
var throwSchema = {
|
|
2153
|
+
action: "throw",
|
|
2154
|
+
description: "Throw an error",
|
|
2155
|
+
category: "control-flow",
|
|
2156
|
+
primaryRole: "patient",
|
|
2157
|
+
roles: [
|
|
2158
|
+
{
|
|
2159
|
+
role: "patient",
|
|
2160
|
+
description: "The error message or object to throw",
|
|
2161
|
+
required: true,
|
|
2162
|
+
expectedTypes: ["literal", "expression"],
|
|
2163
|
+
svoPosition: 1,
|
|
2164
|
+
sovPosition: 1
|
|
2165
|
+
}
|
|
2166
|
+
]
|
|
2167
|
+
};
|
|
2168
|
+
var sendSchema = {
|
|
2169
|
+
action: "send",
|
|
2170
|
+
description: "Send an event to an element",
|
|
2171
|
+
category: "event",
|
|
2172
|
+
primaryRole: "event",
|
|
2173
|
+
roles: [
|
|
2174
|
+
{
|
|
2175
|
+
role: "event",
|
|
2176
|
+
description: "The event to send",
|
|
2177
|
+
required: true,
|
|
2178
|
+
expectedTypes: ["literal", "expression"],
|
|
2179
|
+
// identifiers tokenize as expression
|
|
2180
|
+
svoPosition: 1,
|
|
2181
|
+
sovPosition: 2
|
|
2182
|
+
},
|
|
2183
|
+
{
|
|
2184
|
+
role: "destination",
|
|
2185
|
+
description: "The target element (defaults to me)",
|
|
2186
|
+
required: false,
|
|
2187
|
+
expectedTypes: ["selector", "reference"],
|
|
2188
|
+
default: { type: "reference", value: "me" },
|
|
2189
|
+
svoPosition: 2,
|
|
2190
|
+
sovPosition: 1,
|
|
2191
|
+
// send uses "to" not "on" for destination: send foo to #target
|
|
2192
|
+
markerOverride: {
|
|
2193
|
+
en: "to",
|
|
2194
|
+
ja: "\u306B",
|
|
2195
|
+
ar: "\u0625\u0644\u0649",
|
|
2196
|
+
es: "a",
|
|
2197
|
+
ko: "\uC5D0\uAC8C",
|
|
2198
|
+
zh: "\u5230",
|
|
2199
|
+
tr: "-e",
|
|
2200
|
+
pt: "para",
|
|
2201
|
+
fr: "\xE0",
|
|
2202
|
+
de: "an",
|
|
2203
|
+
id: "ke",
|
|
2204
|
+
qu: "-man",
|
|
2205
|
+
sw: "kwa"
|
|
2206
|
+
}
|
|
2207
|
+
}
|
|
2208
|
+
]
|
|
2209
|
+
};
|
|
2210
|
+
var ifSchema = {
|
|
2211
|
+
action: "if",
|
|
2212
|
+
description: "Conditional execution",
|
|
2213
|
+
category: "control-flow",
|
|
2214
|
+
primaryRole: "condition",
|
|
2215
|
+
hasBody: true,
|
|
2216
|
+
roles: [
|
|
2217
|
+
{
|
|
2218
|
+
role: "condition",
|
|
2219
|
+
description: "The condition to evaluate",
|
|
2220
|
+
required: true,
|
|
2221
|
+
expectedTypes: ["expression"],
|
|
2222
|
+
svoPosition: 1,
|
|
2223
|
+
sovPosition: 1
|
|
2224
|
+
}
|
|
2225
|
+
]
|
|
2226
|
+
};
|
|
2227
|
+
var unlessSchema = {
|
|
2228
|
+
action: "unless",
|
|
2229
|
+
description: "Negated conditional execution (executes when condition is false)",
|
|
2230
|
+
category: "control-flow",
|
|
2231
|
+
primaryRole: "condition",
|
|
2232
|
+
hasBody: true,
|
|
2233
|
+
roles: [
|
|
2234
|
+
{
|
|
2235
|
+
role: "condition",
|
|
2236
|
+
description: "The condition to evaluate (body executes when false)",
|
|
2237
|
+
required: true,
|
|
2238
|
+
expectedTypes: ["expression"],
|
|
2239
|
+
svoPosition: 1,
|
|
2240
|
+
sovPosition: 1
|
|
2241
|
+
}
|
|
2242
|
+
]
|
|
2243
|
+
};
|
|
2244
|
+
var elseSchema = {
|
|
2245
|
+
action: "else",
|
|
2246
|
+
description: "Else branch of conditional",
|
|
2247
|
+
category: "control-flow",
|
|
2248
|
+
primaryRole: "patient",
|
|
2249
|
+
hasBody: true,
|
|
2250
|
+
roles: []
|
|
2251
|
+
// No roles - follows an if
|
|
2252
|
+
};
|
|
2253
|
+
var repeatSchema = {
|
|
2254
|
+
action: "repeat",
|
|
2255
|
+
description: "Repeat a block of commands",
|
|
2256
|
+
category: "control-flow",
|
|
2257
|
+
primaryRole: "loopType",
|
|
2258
|
+
hasBody: true,
|
|
2259
|
+
roles: [
|
|
2260
|
+
{
|
|
2261
|
+
role: "loopType",
|
|
2262
|
+
description: "Loop variant: forever, times, for, while, until, until-event",
|
|
2263
|
+
required: true,
|
|
2264
|
+
expectedTypes: ["literal"],
|
|
2265
|
+
svoPosition: 0,
|
|
2266
|
+
sovPosition: 0
|
|
2267
|
+
},
|
|
2268
|
+
{
|
|
2269
|
+
role: "quantity",
|
|
2270
|
+
description: "Number of times to repeat",
|
|
2271
|
+
required: false,
|
|
2272
|
+
expectedTypes: ["literal", "expression"],
|
|
2273
|
+
svoPosition: 1,
|
|
2274
|
+
sovPosition: 1
|
|
2275
|
+
},
|
|
2276
|
+
{
|
|
2277
|
+
role: "event",
|
|
2278
|
+
description: "Event to wait for (terminates loop)",
|
|
2279
|
+
required: false,
|
|
2280
|
+
expectedTypes: ["literal", "expression"],
|
|
2281
|
+
svoPosition: 2,
|
|
2282
|
+
sovPosition: 2
|
|
2283
|
+
},
|
|
2284
|
+
{
|
|
2285
|
+
role: "source",
|
|
2286
|
+
description: "Element to listen for event on",
|
|
2287
|
+
required: false,
|
|
2288
|
+
expectedTypes: ["selector", "reference"],
|
|
2289
|
+
svoPosition: 3,
|
|
2290
|
+
sovPosition: 3
|
|
2291
|
+
}
|
|
2292
|
+
],
|
|
2293
|
+
notes: 'Can also use "repeat forever", "repeat until condition", or "repeat until event X from Y"'
|
|
2294
|
+
};
|
|
2295
|
+
var forSchema = {
|
|
2296
|
+
action: "for",
|
|
2297
|
+
description: "Iterate over a collection",
|
|
2298
|
+
category: "control-flow",
|
|
2299
|
+
primaryRole: "patient",
|
|
2300
|
+
hasBody: true,
|
|
2301
|
+
roles: [
|
|
2302
|
+
{
|
|
2303
|
+
role: "patient",
|
|
2304
|
+
description: "The iteration variable",
|
|
2305
|
+
required: true,
|
|
2306
|
+
expectedTypes: ["reference"],
|
|
2307
|
+
svoPosition: 1,
|
|
2308
|
+
sovPosition: 2
|
|
2309
|
+
},
|
|
2310
|
+
{
|
|
2311
|
+
role: "source",
|
|
2312
|
+
description: "The collection to iterate over",
|
|
2313
|
+
required: true,
|
|
2314
|
+
expectedTypes: ["selector", "reference", "expression"],
|
|
2315
|
+
svoPosition: 2,
|
|
2316
|
+
sovPosition: 1
|
|
2317
|
+
}
|
|
2318
|
+
]
|
|
2319
|
+
};
|
|
2320
|
+
var whileSchema = {
|
|
2321
|
+
action: "while",
|
|
2322
|
+
description: "Loop while condition is true",
|
|
2323
|
+
category: "control-flow",
|
|
2324
|
+
primaryRole: "condition",
|
|
2325
|
+
hasBody: true,
|
|
2326
|
+
roles: [
|
|
2327
|
+
{
|
|
2328
|
+
role: "condition",
|
|
2329
|
+
description: "The condition to check",
|
|
2330
|
+
required: true,
|
|
2331
|
+
expectedTypes: ["expression"],
|
|
2332
|
+
svoPosition: 1,
|
|
2333
|
+
sovPosition: 1
|
|
2334
|
+
}
|
|
2335
|
+
]
|
|
2336
|
+
};
|
|
2337
|
+
var continueSchema = {
|
|
2338
|
+
action: "continue",
|
|
2339
|
+
description: "Continue to next loop iteration",
|
|
2340
|
+
category: "control-flow",
|
|
2341
|
+
primaryRole: "patient",
|
|
2342
|
+
roles: []
|
|
2343
|
+
// No roles
|
|
2344
|
+
};
|
|
2345
|
+
var goSchema = {
|
|
2346
|
+
action: "go",
|
|
2347
|
+
description: "Navigate to a URL",
|
|
2348
|
+
category: "navigation",
|
|
2349
|
+
primaryRole: "destination",
|
|
2350
|
+
roles: [
|
|
2351
|
+
{
|
|
2352
|
+
role: "destination",
|
|
2353
|
+
description: "The URL to navigate to",
|
|
2354
|
+
required: true,
|
|
2355
|
+
expectedTypes: ["literal", "expression"],
|
|
2356
|
+
svoPosition: 1,
|
|
2357
|
+
sovPosition: 1
|
|
2358
|
+
}
|
|
2359
|
+
]
|
|
2360
|
+
};
|
|
2361
|
+
var transitionSchema = {
|
|
2362
|
+
action: "transition",
|
|
2363
|
+
description: "Transition an element with animation",
|
|
2364
|
+
category: "dom-visibility",
|
|
2365
|
+
primaryRole: "patient",
|
|
2366
|
+
roles: [
|
|
2367
|
+
{
|
|
2368
|
+
role: "patient",
|
|
2369
|
+
description: "The property to transition (opacity, *background-color, etc.)",
|
|
2370
|
+
required: true,
|
|
2371
|
+
expectedTypes: ["literal"],
|
|
2372
|
+
// Only literal - CSS properties are strings, not selectors
|
|
2373
|
+
svoPosition: 1,
|
|
2374
|
+
sovPosition: 2
|
|
2375
|
+
},
|
|
2376
|
+
{
|
|
2377
|
+
role: "goal",
|
|
2378
|
+
description: "The target value to transition to",
|
|
2379
|
+
required: true,
|
|
2380
|
+
expectedTypes: ["literal", "expression"],
|
|
2381
|
+
svoPosition: 2,
|
|
2382
|
+
sovPosition: 3
|
|
2383
|
+
},
|
|
2384
|
+
{
|
|
2385
|
+
role: "destination",
|
|
2386
|
+
description: "The target element (defaults to me)",
|
|
2387
|
+
required: false,
|
|
2388
|
+
expectedTypes: ["selector", "reference"],
|
|
2389
|
+
default: { type: "reference", value: "me" },
|
|
2390
|
+
svoPosition: 3,
|
|
2391
|
+
sovPosition: 1
|
|
2392
|
+
},
|
|
2393
|
+
{
|
|
2394
|
+
role: "duration",
|
|
2395
|
+
description: "Transition duration (over 500ms, for 2 seconds)",
|
|
2396
|
+
required: false,
|
|
2397
|
+
expectedTypes: ["literal"],
|
|
2398
|
+
svoPosition: 4,
|
|
2399
|
+
sovPosition: 4
|
|
2400
|
+
},
|
|
2401
|
+
{
|
|
2402
|
+
role: "style",
|
|
2403
|
+
description: "Easing function (ease-in, linear, etc.)",
|
|
2404
|
+
required: false,
|
|
2405
|
+
expectedTypes: ["literal"],
|
|
2406
|
+
svoPosition: 5,
|
|
2407
|
+
sovPosition: 5
|
|
2408
|
+
}
|
|
2409
|
+
]
|
|
2410
|
+
};
|
|
2411
|
+
var cloneSchema = {
|
|
2412
|
+
action: "clone",
|
|
2413
|
+
description: "Clone an element",
|
|
2414
|
+
category: "dom-content",
|
|
2415
|
+
primaryRole: "patient",
|
|
2416
|
+
roles: [
|
|
2417
|
+
{
|
|
2418
|
+
role: "patient",
|
|
2419
|
+
description: "The element to clone",
|
|
2420
|
+
required: true,
|
|
2421
|
+
expectedTypes: ["selector", "reference"],
|
|
2422
|
+
svoPosition: 1,
|
|
2423
|
+
sovPosition: 2
|
|
2424
|
+
},
|
|
2425
|
+
{
|
|
2426
|
+
role: "destination",
|
|
2427
|
+
description: "Where to put the clone",
|
|
2428
|
+
required: false,
|
|
2429
|
+
expectedTypes: ["selector", "reference"],
|
|
2430
|
+
svoPosition: 2,
|
|
2431
|
+
sovPosition: 1
|
|
2432
|
+
}
|
|
2433
|
+
]
|
|
2434
|
+
};
|
|
2435
|
+
var focusSchema = {
|
|
2436
|
+
action: "focus",
|
|
2437
|
+
description: "Focus an element",
|
|
2438
|
+
category: "dom-content",
|
|
2439
|
+
primaryRole: "patient",
|
|
2440
|
+
roles: [
|
|
2441
|
+
{
|
|
2442
|
+
role: "patient",
|
|
2443
|
+
description: "The element to focus (defaults to me)",
|
|
2444
|
+
required: false,
|
|
2445
|
+
expectedTypes: ["selector", "reference"],
|
|
2446
|
+
default: { type: "reference", value: "me" },
|
|
2447
|
+
svoPosition: 1,
|
|
2448
|
+
sovPosition: 1
|
|
2449
|
+
}
|
|
2450
|
+
]
|
|
2451
|
+
};
|
|
2452
|
+
var blurSchema = {
|
|
2453
|
+
action: "blur",
|
|
2454
|
+
description: "Remove focus from an element",
|
|
2455
|
+
category: "dom-content",
|
|
2456
|
+
primaryRole: "patient",
|
|
2457
|
+
roles: [
|
|
2458
|
+
{
|
|
2459
|
+
role: "patient",
|
|
2460
|
+
description: "The element to blur (defaults to me)",
|
|
2461
|
+
required: false,
|
|
2462
|
+
expectedTypes: ["selector", "reference"],
|
|
2463
|
+
default: { type: "reference", value: "me" },
|
|
2464
|
+
svoPosition: 1,
|
|
2465
|
+
sovPosition: 1
|
|
2466
|
+
}
|
|
2467
|
+
]
|
|
2468
|
+
};
|
|
2469
|
+
var callSchema = {
|
|
2470
|
+
action: "call",
|
|
2471
|
+
description: "Call a function",
|
|
2472
|
+
category: "control-flow",
|
|
2473
|
+
primaryRole: "patient",
|
|
2474
|
+
roles: [
|
|
2475
|
+
{
|
|
2476
|
+
role: "patient",
|
|
2477
|
+
description: "The function to call",
|
|
2478
|
+
required: true,
|
|
2479
|
+
expectedTypes: ["expression", "reference"],
|
|
2480
|
+
svoPosition: 1,
|
|
2481
|
+
sovPosition: 1
|
|
2482
|
+
}
|
|
2483
|
+
]
|
|
2484
|
+
};
|
|
2485
|
+
var returnSchema = {
|
|
2486
|
+
action: "return",
|
|
2487
|
+
description: "Return a value from a function",
|
|
2488
|
+
category: "control-flow",
|
|
2489
|
+
primaryRole: "patient",
|
|
2490
|
+
roles: [
|
|
2491
|
+
{
|
|
2492
|
+
role: "patient",
|
|
2493
|
+
description: "The value to return",
|
|
2494
|
+
required: false,
|
|
2495
|
+
expectedTypes: ["literal", "expression", "reference"],
|
|
2496
|
+
svoPosition: 1,
|
|
2497
|
+
sovPosition: 1
|
|
2498
|
+
}
|
|
2499
|
+
]
|
|
2500
|
+
};
|
|
2501
|
+
var jsSchema = {
|
|
2502
|
+
action: "js",
|
|
2503
|
+
description: "Execute raw JavaScript code",
|
|
2504
|
+
category: "control-flow",
|
|
2505
|
+
primaryRole: "patient",
|
|
2506
|
+
hasBody: true,
|
|
2507
|
+
roles: [
|
|
2508
|
+
{
|
|
2509
|
+
role: "patient",
|
|
2510
|
+
description: "The JavaScript code to execute",
|
|
2511
|
+
required: false,
|
|
2512
|
+
expectedTypes: ["expression"],
|
|
2513
|
+
svoPosition: 1,
|
|
2514
|
+
sovPosition: 1
|
|
2515
|
+
}
|
|
2516
|
+
]
|
|
2517
|
+
};
|
|
2518
|
+
var asyncSchema = {
|
|
2519
|
+
action: "async",
|
|
2520
|
+
description: "Execute commands asynchronously",
|
|
2521
|
+
category: "async",
|
|
2522
|
+
primaryRole: "patient",
|
|
2523
|
+
hasBody: true,
|
|
2524
|
+
roles: []
|
|
2525
|
+
};
|
|
2526
|
+
var tellSchema = {
|
|
2527
|
+
action: "tell",
|
|
2528
|
+
description: "Execute commands in context of another element",
|
|
2529
|
+
category: "control-flow",
|
|
2530
|
+
primaryRole: "destination",
|
|
2531
|
+
hasBody: true,
|
|
2532
|
+
roles: [
|
|
2533
|
+
{
|
|
2534
|
+
role: "destination",
|
|
2535
|
+
description: "The element to tell",
|
|
2536
|
+
required: true,
|
|
2537
|
+
expectedTypes: ["selector", "reference"],
|
|
2538
|
+
svoPosition: 1,
|
|
2539
|
+
sovPosition: 1
|
|
2540
|
+
}
|
|
2541
|
+
]
|
|
2542
|
+
};
|
|
2543
|
+
var defaultSchema = {
|
|
2544
|
+
action: "default",
|
|
2545
|
+
description: "Set a default value for a variable",
|
|
2546
|
+
category: "variable",
|
|
2547
|
+
primaryRole: "destination",
|
|
2548
|
+
roles: [
|
|
2549
|
+
{
|
|
2550
|
+
role: "destination",
|
|
2551
|
+
description: "The variable to set default for",
|
|
2552
|
+
required: true,
|
|
2553
|
+
expectedTypes: ["reference"],
|
|
2554
|
+
svoPosition: 1,
|
|
2555
|
+
sovPosition: 1
|
|
2556
|
+
},
|
|
2557
|
+
{
|
|
2558
|
+
role: "patient",
|
|
2559
|
+
description: "The default value",
|
|
2560
|
+
required: true,
|
|
2561
|
+
expectedTypes: ["literal", "expression"],
|
|
2562
|
+
svoPosition: 2,
|
|
2563
|
+
sovPosition: 2
|
|
2564
|
+
}
|
|
2565
|
+
]
|
|
2566
|
+
};
|
|
2567
|
+
var initSchema = {
|
|
2568
|
+
action: "init",
|
|
2569
|
+
description: "Initialization block that runs once",
|
|
2570
|
+
category: "control-flow",
|
|
2571
|
+
primaryRole: "patient",
|
|
2572
|
+
hasBody: true,
|
|
2573
|
+
roles: []
|
|
2574
|
+
};
|
|
2575
|
+
var behaviorSchema = {
|
|
2576
|
+
action: "behavior",
|
|
2577
|
+
description: "Define a reusable behavior",
|
|
2578
|
+
category: "control-flow",
|
|
2579
|
+
primaryRole: "patient",
|
|
2580
|
+
hasBody: true,
|
|
2581
|
+
roles: [
|
|
2582
|
+
{
|
|
2583
|
+
role: "patient",
|
|
2584
|
+
description: "The behavior name (PascalCase identifier)",
|
|
2585
|
+
required: true,
|
|
2586
|
+
expectedTypes: ["literal", "reference", "expression"],
|
|
2587
|
+
// expression for PascalCase identifiers
|
|
2588
|
+
svoPosition: 1,
|
|
2589
|
+
sovPosition: 1
|
|
2590
|
+
}
|
|
2591
|
+
]
|
|
2592
|
+
};
|
|
2593
|
+
var installSchema = {
|
|
2594
|
+
action: "install",
|
|
2595
|
+
description: "Install a behavior on an element",
|
|
2596
|
+
category: "control-flow",
|
|
2597
|
+
primaryRole: "patient",
|
|
2598
|
+
roles: [
|
|
2599
|
+
{
|
|
2600
|
+
role: "patient",
|
|
2601
|
+
description: "The behavior name to install",
|
|
2602
|
+
required: true,
|
|
2603
|
+
expectedTypes: ["literal", "reference", "expression"],
|
|
2604
|
+
svoPosition: 1,
|
|
2605
|
+
sovPosition: 2
|
|
2606
|
+
},
|
|
2607
|
+
{
|
|
2608
|
+
role: "destination",
|
|
2609
|
+
description: "Element to install on (defaults to me)",
|
|
2610
|
+
required: false,
|
|
2611
|
+
expectedTypes: ["selector", "reference"],
|
|
2612
|
+
default: { type: "reference", value: "me" },
|
|
2613
|
+
svoPosition: 2,
|
|
2614
|
+
sovPosition: 1
|
|
2615
|
+
}
|
|
2616
|
+
]
|
|
2617
|
+
};
|
|
2618
|
+
var measureSchema = {
|
|
2619
|
+
action: "measure",
|
|
2620
|
+
description: "Measure element dimensions (x, y, width, height, etc.)",
|
|
2621
|
+
category: "dom-content",
|
|
2622
|
+
primaryRole: "patient",
|
|
2623
|
+
roles: [
|
|
2624
|
+
{
|
|
2625
|
+
role: "patient",
|
|
2626
|
+
description: "Property to measure (x, y, width, height, top, left, etc.)",
|
|
2627
|
+
required: false,
|
|
2628
|
+
// Plain "measure" is valid, defaults to bounds
|
|
2629
|
+
expectedTypes: ["literal", "expression"],
|
|
2630
|
+
svoPosition: 1,
|
|
2631
|
+
sovPosition: 1
|
|
2632
|
+
},
|
|
2633
|
+
{
|
|
2634
|
+
role: "source",
|
|
2635
|
+
description: "Element to measure (defaults to me)",
|
|
2636
|
+
required: false,
|
|
2637
|
+
expectedTypes: ["selector", "reference"],
|
|
2638
|
+
default: { type: "reference", value: "me" },
|
|
2639
|
+
svoPosition: 2,
|
|
2640
|
+
sovPosition: 2
|
|
2641
|
+
}
|
|
2642
|
+
]
|
|
2643
|
+
};
|
|
2644
|
+
var swapSchema = {
|
|
2645
|
+
action: "swap",
|
|
2646
|
+
description: "Swap DOM content using various strategies (innerHTML, outerHTML, delete, etc.)",
|
|
2647
|
+
category: "dom-content",
|
|
2648
|
+
primaryRole: "destination",
|
|
2649
|
+
roles: [
|
|
2650
|
+
{
|
|
2651
|
+
role: "method",
|
|
2652
|
+
description: "The swap strategy (innerHTML, outerHTML, beforebegin, afterend, delete)",
|
|
2653
|
+
required: false,
|
|
2654
|
+
expectedTypes: ["literal"],
|
|
2655
|
+
svoPosition: 1,
|
|
2656
|
+
sovPosition: 3
|
|
2657
|
+
},
|
|
2658
|
+
{
|
|
2659
|
+
role: "destination",
|
|
2660
|
+
description: "The element to swap content in/for",
|
|
2661
|
+
required: true,
|
|
2662
|
+
expectedTypes: ["selector", "reference"],
|
|
2663
|
+
svoPosition: 2,
|
|
2664
|
+
sovPosition: 1
|
|
2665
|
+
},
|
|
2666
|
+
{
|
|
2667
|
+
role: "patient",
|
|
2668
|
+
description: "The content to swap in (optional for delete)",
|
|
2669
|
+
required: false,
|
|
2670
|
+
expectedTypes: ["literal", "expression", "selector"],
|
|
2671
|
+
svoPosition: 3,
|
|
2672
|
+
sovPosition: 2
|
|
2673
|
+
}
|
|
2674
|
+
]
|
|
2675
|
+
};
|
|
2676
|
+
var morphSchema = {
|
|
2677
|
+
action: "morph",
|
|
2678
|
+
description: "Morph an element into another using DOM diffing",
|
|
2679
|
+
category: "dom-content",
|
|
2680
|
+
primaryRole: "destination",
|
|
2681
|
+
roles: [
|
|
2682
|
+
{
|
|
2683
|
+
role: "destination",
|
|
2684
|
+
description: "The element to morph",
|
|
2685
|
+
required: true,
|
|
2686
|
+
expectedTypes: ["selector", "reference"],
|
|
2687
|
+
svoPosition: 1,
|
|
2688
|
+
sovPosition: 1
|
|
2689
|
+
},
|
|
2690
|
+
{
|
|
2691
|
+
role: "patient",
|
|
2692
|
+
description: "The target content/element to morph into",
|
|
2693
|
+
required: true,
|
|
2694
|
+
expectedTypes: ["literal", "expression", "selector"],
|
|
2695
|
+
svoPosition: 2,
|
|
2696
|
+
sovPosition: 2
|
|
2697
|
+
}
|
|
2698
|
+
]
|
|
2699
|
+
};
|
|
2700
|
+
var commandSchemas = {
|
|
2701
|
+
// Original schemas
|
|
2702
|
+
toggle: toggleSchema,
|
|
2703
|
+
add: addSchema,
|
|
2704
|
+
remove: removeSchema,
|
|
2705
|
+
put: putSchema,
|
|
2706
|
+
set: setSchema,
|
|
2707
|
+
show: showSchema,
|
|
2708
|
+
hide: hideSchema,
|
|
2709
|
+
on: onSchema,
|
|
2710
|
+
trigger: triggerSchema,
|
|
2711
|
+
wait: waitSchema,
|
|
2712
|
+
fetch: fetchSchema,
|
|
2713
|
+
increment: incrementSchema,
|
|
2714
|
+
decrement: decrementSchema,
|
|
2715
|
+
append: appendSchema,
|
|
2716
|
+
prepend: prependSchema,
|
|
2717
|
+
// Batch 1 - Simple Commands
|
|
2718
|
+
log: logSchema,
|
|
2719
|
+
get: getCommandSchema,
|
|
2720
|
+
take: takeSchema,
|
|
2721
|
+
make: makeSchema,
|
|
2722
|
+
halt: haltSchema,
|
|
2723
|
+
settle: settleSchema,
|
|
2724
|
+
throw: throwSchema,
|
|
2725
|
+
send: sendSchema,
|
|
2726
|
+
// Batch 2 - Control Flow
|
|
2727
|
+
if: ifSchema,
|
|
2728
|
+
unless: unlessSchema,
|
|
2729
|
+
else: elseSchema,
|
|
2730
|
+
repeat: repeatSchema,
|
|
2731
|
+
for: forSchema,
|
|
2732
|
+
while: whileSchema,
|
|
2733
|
+
continue: continueSchema,
|
|
2734
|
+
// Batch 3 - DOM & Navigation
|
|
2735
|
+
go: goSchema,
|
|
2736
|
+
transition: transitionSchema,
|
|
2737
|
+
clone: cloneSchema,
|
|
2738
|
+
focus: focusSchema,
|
|
2739
|
+
blur: blurSchema,
|
|
2740
|
+
// Batch 4 - Advanced
|
|
2741
|
+
call: callSchema,
|
|
2742
|
+
return: returnSchema,
|
|
2743
|
+
js: jsSchema,
|
|
2744
|
+
async: asyncSchema,
|
|
2745
|
+
tell: tellSchema,
|
|
2746
|
+
default: defaultSchema,
|
|
2747
|
+
init: initSchema,
|
|
2748
|
+
behavior: behaviorSchema,
|
|
2749
|
+
install: installSchema,
|
|
2750
|
+
measure: measureSchema,
|
|
2751
|
+
// Batch 5 - DOM Content Manipulation
|
|
2752
|
+
swap: swapSchema,
|
|
2753
|
+
morph: morphSchema,
|
|
2754
|
+
// Meta commands (for compound structures)
|
|
2755
|
+
compound: {
|
|
2756
|
+
action: "compound",
|
|
2757
|
+
description: "A compound node representing chained statements",
|
|
2758
|
+
primaryRole: "patient",
|
|
2759
|
+
// Compound nodes don't have a traditional primary role
|
|
2760
|
+
category: "control-flow",
|
|
2761
|
+
hasBody: true,
|
|
2762
|
+
roles: []
|
|
2763
|
+
}
|
|
2764
|
+
};
|
|
2765
|
+
function getDefinedSchemas() {
|
|
2766
|
+
return Object.values(commandSchemas).filter((s) => s.roles.length > 0);
|
|
2767
|
+
}
|
|
2768
|
+
if (typeof process !== "undefined" && process.env.NODE_ENV !== "production") {
|
|
2769
|
+
Promise.resolve().then(() => (init_schema_validator(), schema_validator_exports)).then(({ validateAllSchemas: validateAllSchemas2, formatValidationResults: formatValidationResults2 }) => {
|
|
2770
|
+
const validations = validateAllSchemas2(commandSchemas);
|
|
2771
|
+
if (validations.size > 0) {
|
|
2772
|
+
console.warn("[SCHEMA VALIDATION] Found issues in command schemas:");
|
|
2773
|
+
console.warn(formatValidationResults2(validations));
|
|
2774
|
+
console.warn("\nThese warnings help identify potential schema design issues.");
|
|
2775
|
+
console.warn("Fix them to improve type inference and avoid runtime bugs.");
|
|
2776
|
+
}
|
|
2777
|
+
}).catch((err) => {
|
|
2778
|
+
console.debug("Schema validation skipped:", err);
|
|
2779
|
+
});
|
|
2780
|
+
}
|
|
2781
|
+
|
|
2782
|
+
// src/parser/utils/role-positioning.ts
|
|
2783
|
+
function sortRolesByWordOrder(roles, wordOrder) {
|
|
2784
|
+
const sortKey = wordOrder === "SOV" ? "sovPosition" : "svoPosition";
|
|
2785
|
+
return [...roles].sort((a, b) => {
|
|
2786
|
+
const aPos = a[sortKey] ?? 99;
|
|
2787
|
+
const bPos = b[sortKey] ?? 99;
|
|
2788
|
+
return aPos - bPos;
|
|
2789
|
+
});
|
|
2790
|
+
}
|
|
2791
|
+
|
|
2792
|
+
// src/parser/utils/marker-resolution.ts
|
|
2793
|
+
function resolveMarkerForRole(roleSpec, profile) {
|
|
2794
|
+
const overrideMarker = roleSpec.markerOverride?.[profile.code];
|
|
2795
|
+
const defaultMarker = profile.roleMarkers[roleSpec.role];
|
|
2796
|
+
if (overrideMarker !== void 0) {
|
|
2797
|
+
return {
|
|
2798
|
+
primary: overrideMarker,
|
|
2799
|
+
position: defaultMarker?.position ?? "before",
|
|
2800
|
+
isOverride: true
|
|
2801
|
+
};
|
|
2802
|
+
}
|
|
2803
|
+
if (defaultMarker && defaultMarker.primary) {
|
|
2804
|
+
const result = {
|
|
2805
|
+
primary: defaultMarker.primary,
|
|
2806
|
+
position: defaultMarker.position,
|
|
2807
|
+
isOverride: false
|
|
2808
|
+
};
|
|
2809
|
+
if (defaultMarker.alternatives) {
|
|
2810
|
+
result.alternatives = defaultMarker.alternatives;
|
|
2811
|
+
}
|
|
2812
|
+
return result;
|
|
2813
|
+
}
|
|
2814
|
+
return null;
|
|
2815
|
+
}
|
|
2816
|
+
|
|
2817
|
+
// src/generators/pattern-generator.ts
|
|
2818
|
+
var defaultConfig = {
|
|
2819
|
+
basePriority: 100,
|
|
2820
|
+
generateSimpleVariants: true,
|
|
2821
|
+
generateAlternatives: true
|
|
2822
|
+
};
|
|
2823
|
+
function generatePattern(schema, profile, config = defaultConfig) {
|
|
2824
|
+
const id = `${schema.action}-${profile.code}-generated`;
|
|
2825
|
+
const priority = config.basePriority ?? 100;
|
|
2826
|
+
const keyword = profile.keywords[schema.action];
|
|
2827
|
+
if (!keyword) {
|
|
2828
|
+
throw new Error(`No keyword translation for '${schema.action}' in ${profile.code}`);
|
|
2829
|
+
}
|
|
2830
|
+
const tokens = buildTokens(schema, profile, keyword);
|
|
2831
|
+
const extraction = buildExtractionRulesWithDefaults(schema, profile);
|
|
2832
|
+
const format = buildFormatString(schema, profile, keyword);
|
|
2833
|
+
return {
|
|
2834
|
+
id,
|
|
2835
|
+
language: profile.code,
|
|
2836
|
+
command: schema.action,
|
|
2837
|
+
priority,
|
|
2838
|
+
template: {
|
|
2839
|
+
format,
|
|
2840
|
+
tokens
|
|
2841
|
+
},
|
|
2842
|
+
extraction
|
|
2843
|
+
};
|
|
2844
|
+
}
|
|
2845
|
+
function generateSimplePattern(schema, profile, config = defaultConfig) {
|
|
2846
|
+
const optionalRoles = schema.roles.filter((r) => !r.required);
|
|
2847
|
+
if (optionalRoles.length === 0) {
|
|
2848
|
+
return null;
|
|
2849
|
+
}
|
|
2850
|
+
const requiredRoles = schema.roles.filter((r) => r.required);
|
|
2851
|
+
const simpleSchema = {
|
|
2852
|
+
...schema,
|
|
2853
|
+
roles: requiredRoles
|
|
2854
|
+
};
|
|
2855
|
+
const pattern = generatePattern(simpleSchema, profile, config);
|
|
2856
|
+
return {
|
|
2857
|
+
...pattern,
|
|
2858
|
+
id: `${schema.action}-${profile.code}-simple`,
|
|
2859
|
+
priority: (config.basePriority ?? 100) - 5,
|
|
2860
|
+
// Lower priority than full pattern (was -10)
|
|
2861
|
+
extraction: buildExtractionRulesWithDefaults(schema, profile)
|
|
2862
|
+
};
|
|
2863
|
+
}
|
|
2864
|
+
function generatePatternVariants(schema, profile, config = defaultConfig) {
|
|
2865
|
+
const patterns = [];
|
|
2866
|
+
patterns.push(generatePattern(schema, profile, config));
|
|
2867
|
+
if (config.generateSimpleVariants) {
|
|
2868
|
+
const simple = generateSimplePattern(schema, profile, config);
|
|
2869
|
+
if (simple) {
|
|
2870
|
+
patterns.push(simple);
|
|
2871
|
+
}
|
|
2872
|
+
}
|
|
2873
|
+
return patterns;
|
|
2874
|
+
}
|
|
2875
|
+
function generatePatternsForLanguage(profile, config = defaultConfig) {
|
|
2876
|
+
const patterns = [];
|
|
2877
|
+
const schemas = getDefinedSchemas();
|
|
2878
|
+
for (const schema of schemas) {
|
|
2879
|
+
if (!profile.keywords[schema.action]) {
|
|
2880
|
+
continue;
|
|
2881
|
+
}
|
|
2882
|
+
const variants = generatePatternVariants(schema, profile, config);
|
|
2883
|
+
patterns.push(...variants);
|
|
2884
|
+
}
|
|
2885
|
+
return patterns;
|
|
2886
|
+
}
|
|
2887
|
+
function buildTokens(schema, profile, keyword) {
|
|
2888
|
+
const tokens = [];
|
|
2889
|
+
const verbToken = keyword.alternatives ? { type: "literal", value: keyword.primary, alternatives: keyword.alternatives } : { type: "literal", value: keyword.primary };
|
|
2890
|
+
const roleTokens = buildRoleTokens(schema, profile);
|
|
2891
|
+
switch (profile.wordOrder) {
|
|
2892
|
+
case "SVO":
|
|
2893
|
+
tokens.push(verbToken);
|
|
2894
|
+
tokens.push(...roleTokens);
|
|
2895
|
+
break;
|
|
2896
|
+
case "SOV":
|
|
2897
|
+
tokens.push(...roleTokens);
|
|
2898
|
+
tokens.push(verbToken);
|
|
2899
|
+
break;
|
|
2900
|
+
case "VSO":
|
|
2901
|
+
tokens.push(verbToken);
|
|
2902
|
+
tokens.push(...roleTokens);
|
|
2903
|
+
break;
|
|
2904
|
+
default:
|
|
2905
|
+
tokens.push(verbToken);
|
|
2906
|
+
tokens.push(...roleTokens);
|
|
2907
|
+
}
|
|
2908
|
+
return tokens;
|
|
2909
|
+
}
|
|
2910
|
+
function buildRoleTokens(schema, profile) {
|
|
2911
|
+
const tokens = [];
|
|
2912
|
+
const sortedRoles = sortRolesByWordOrder(schema.roles, profile.wordOrder);
|
|
2913
|
+
for (const roleSpec of sortedRoles) {
|
|
2914
|
+
const roleToken = buildRoleToken(roleSpec, profile);
|
|
2915
|
+
if (!roleSpec.required) {
|
|
2916
|
+
tokens.push({
|
|
2917
|
+
type: "group",
|
|
2918
|
+
optional: true,
|
|
2919
|
+
tokens: roleToken
|
|
2920
|
+
});
|
|
2921
|
+
} else {
|
|
2922
|
+
tokens.push(...roleToken);
|
|
2923
|
+
}
|
|
2924
|
+
}
|
|
2925
|
+
return tokens;
|
|
2926
|
+
}
|
|
2927
|
+
function buildRoleToken(roleSpec, profile) {
|
|
2928
|
+
const tokens = [];
|
|
2929
|
+
const overrideMarker = roleSpec.markerOverride?.[profile.code];
|
|
2930
|
+
const defaultMarker = profile.roleMarkers[roleSpec.role];
|
|
2931
|
+
const roleValueToken = {
|
|
2932
|
+
type: "role",
|
|
2933
|
+
role: roleSpec.role,
|
|
2934
|
+
optional: !roleSpec.required,
|
|
2935
|
+
expectedTypes: roleSpec.expectedTypes
|
|
2936
|
+
};
|
|
2937
|
+
if (overrideMarker !== void 0) {
|
|
2938
|
+
const position = defaultMarker?.position ?? "before";
|
|
2939
|
+
if (position === "before") {
|
|
2940
|
+
if (overrideMarker) {
|
|
2941
|
+
tokens.push({ type: "literal", value: overrideMarker });
|
|
2942
|
+
}
|
|
2943
|
+
tokens.push(roleValueToken);
|
|
2944
|
+
} else {
|
|
2945
|
+
tokens.push(roleValueToken);
|
|
2946
|
+
if (overrideMarker) {
|
|
2947
|
+
tokens.push({ type: "literal", value: overrideMarker });
|
|
2948
|
+
}
|
|
2949
|
+
}
|
|
2950
|
+
} else if (defaultMarker) {
|
|
2951
|
+
if (defaultMarker.position === "before") {
|
|
2952
|
+
if (defaultMarker.primary) {
|
|
2953
|
+
const markerToken = defaultMarker.alternatives ? {
|
|
2954
|
+
type: "literal",
|
|
2955
|
+
value: defaultMarker.primary,
|
|
2956
|
+
alternatives: defaultMarker.alternatives
|
|
2957
|
+
} : { type: "literal", value: defaultMarker.primary };
|
|
2958
|
+
tokens.push(markerToken);
|
|
2959
|
+
}
|
|
2960
|
+
tokens.push(roleValueToken);
|
|
2961
|
+
} else {
|
|
2962
|
+
tokens.push(roleValueToken);
|
|
2963
|
+
const markerToken = defaultMarker.alternatives ? {
|
|
2964
|
+
type: "literal",
|
|
2965
|
+
value: defaultMarker.primary,
|
|
2966
|
+
alternatives: defaultMarker.alternatives
|
|
2967
|
+
} : { type: "literal", value: defaultMarker.primary };
|
|
2968
|
+
tokens.push(markerToken);
|
|
2969
|
+
}
|
|
2970
|
+
} else {
|
|
2971
|
+
tokens.push(roleValueToken);
|
|
2972
|
+
}
|
|
2973
|
+
return tokens;
|
|
2974
|
+
}
|
|
2975
|
+
function buildExtractionRules(schema, profile) {
|
|
2976
|
+
const rules = {};
|
|
2977
|
+
for (const roleSpec of schema.roles) {
|
|
2978
|
+
const overrideMarker = roleSpec.markerOverride?.[profile.code];
|
|
2979
|
+
const defaultMarker = profile.roleMarkers[roleSpec.role];
|
|
2980
|
+
if (overrideMarker !== void 0) {
|
|
2981
|
+
rules[roleSpec.role] = overrideMarker ? { marker: overrideMarker } : {};
|
|
2982
|
+
} else if (defaultMarker && defaultMarker.primary) {
|
|
2983
|
+
rules[roleSpec.role] = defaultMarker.alternatives ? { marker: defaultMarker.primary, markerAlternatives: defaultMarker.alternatives } : { marker: defaultMarker.primary };
|
|
2984
|
+
} else {
|
|
2985
|
+
rules[roleSpec.role] = {};
|
|
2986
|
+
}
|
|
2987
|
+
}
|
|
2988
|
+
return rules;
|
|
2989
|
+
}
|
|
2990
|
+
function buildExtractionRulesWithDefaults(schema, profile) {
|
|
2991
|
+
const baseRules = buildExtractionRules(schema, profile);
|
|
2992
|
+
const rules = {};
|
|
2993
|
+
for (const roleSpec of schema.roles) {
|
|
2994
|
+
const baseRule = baseRules[roleSpec.role] || {};
|
|
2995
|
+
if (!roleSpec.required && roleSpec.default) {
|
|
2996
|
+
rules[roleSpec.role] = { ...baseRule, default: roleSpec.default };
|
|
2997
|
+
} else {
|
|
2998
|
+
rules[roleSpec.role] = baseRule;
|
|
2999
|
+
}
|
|
3000
|
+
}
|
|
3001
|
+
return rules;
|
|
3002
|
+
}
|
|
3003
|
+
function buildFormatString(schema, profile, keyword) {
|
|
3004
|
+
const parts = [];
|
|
3005
|
+
const sortedRoles = sortRolesByWordOrder(schema.roles, profile.wordOrder);
|
|
3006
|
+
const roleParts = sortedRoles.map((roleSpec) => {
|
|
3007
|
+
const resolved = resolveMarkerForRole(roleSpec, profile);
|
|
3008
|
+
let part = "";
|
|
3009
|
+
if (resolved && resolved.primary) {
|
|
3010
|
+
if (resolved.position === "before") {
|
|
3011
|
+
part = `${resolved.primary} {${roleSpec.role}}`;
|
|
3012
|
+
} else {
|
|
3013
|
+
part = `{${roleSpec.role}} ${resolved.primary}`;
|
|
3014
|
+
}
|
|
3015
|
+
} else {
|
|
3016
|
+
part = `{${roleSpec.role}}`;
|
|
3017
|
+
}
|
|
3018
|
+
return roleSpec.required ? part : `[${part}]`;
|
|
3019
|
+
});
|
|
3020
|
+
switch (profile.wordOrder) {
|
|
3021
|
+
case "SVO":
|
|
3022
|
+
case "VSO":
|
|
3023
|
+
parts.push(keyword.primary, ...roleParts);
|
|
3024
|
+
break;
|
|
3025
|
+
case "SOV":
|
|
3026
|
+
parts.push(...roleParts, keyword.primary);
|
|
3027
|
+
break;
|
|
3028
|
+
default:
|
|
3029
|
+
parts.push(keyword.primary, ...roleParts);
|
|
3030
|
+
}
|
|
3031
|
+
return parts.join(" ");
|
|
3032
|
+
}
|
|
3033
|
+
|
|
3034
|
+
// src/patterns/toggle/en.ts
|
|
3035
|
+
function getTogglePatternsEn() {
|
|
3036
|
+
return [
|
|
3037
|
+
{
|
|
3038
|
+
id: "toggle-en-full",
|
|
3039
|
+
language: "en",
|
|
3040
|
+
command: "toggle",
|
|
3041
|
+
priority: 100,
|
|
3042
|
+
template: {
|
|
3043
|
+
format: "toggle {patient} on {target}",
|
|
3044
|
+
tokens: [
|
|
3045
|
+
{ type: "literal", value: "toggle" },
|
|
3046
|
+
{ type: "role", role: "patient" },
|
|
3047
|
+
{
|
|
3048
|
+
type: "group",
|
|
3049
|
+
optional: true,
|
|
3050
|
+
tokens: [
|
|
3051
|
+
{ type: "literal", value: "on", alternatives: ["from"] },
|
|
3052
|
+
{ type: "role", role: "destination" }
|
|
3053
|
+
]
|
|
3054
|
+
}
|
|
3055
|
+
]
|
|
3056
|
+
},
|
|
3057
|
+
extraction: {
|
|
3058
|
+
patient: { position: 1 },
|
|
3059
|
+
destination: {
|
|
3060
|
+
marker: "on",
|
|
3061
|
+
markerAlternatives: ["from"],
|
|
3062
|
+
default: { type: "reference", value: "me" }
|
|
3063
|
+
}
|
|
3064
|
+
}
|
|
3065
|
+
},
|
|
3066
|
+
{
|
|
3067
|
+
id: "toggle-en-simple",
|
|
3068
|
+
language: "en",
|
|
3069
|
+
command: "toggle",
|
|
3070
|
+
priority: 90,
|
|
3071
|
+
template: {
|
|
3072
|
+
format: "toggle {patient}",
|
|
3073
|
+
tokens: [
|
|
3074
|
+
{ type: "literal", value: "toggle" },
|
|
3075
|
+
{ type: "role", role: "patient" }
|
|
3076
|
+
]
|
|
3077
|
+
},
|
|
3078
|
+
extraction: {
|
|
3079
|
+
patient: { position: 1 },
|
|
3080
|
+
destination: { default: { type: "reference", value: "me" } }
|
|
3081
|
+
}
|
|
3082
|
+
}
|
|
3083
|
+
];
|
|
3084
|
+
}
|
|
3085
|
+
|
|
3086
|
+
// src/patterns/put/en.ts
|
|
3087
|
+
function getPutPatternsEn() {
|
|
3088
|
+
return [
|
|
3089
|
+
{
|
|
3090
|
+
id: "put-en-into",
|
|
3091
|
+
language: "en",
|
|
3092
|
+
command: "put",
|
|
3093
|
+
priority: 100,
|
|
3094
|
+
template: {
|
|
3095
|
+
format: "put {patient} into {destination}",
|
|
3096
|
+
tokens: [
|
|
3097
|
+
{ type: "literal", value: "put" },
|
|
3098
|
+
{ type: "role", role: "patient" },
|
|
3099
|
+
{ type: "literal", value: "into", alternatives: ["in", "to"] },
|
|
3100
|
+
{ type: "role", role: "destination" }
|
|
3101
|
+
]
|
|
3102
|
+
},
|
|
3103
|
+
extraction: {
|
|
3104
|
+
patient: { position: 1 },
|
|
3105
|
+
destination: { marker: "into", markerAlternatives: ["in", "to"] }
|
|
3106
|
+
}
|
|
3107
|
+
},
|
|
3108
|
+
{
|
|
3109
|
+
id: "put-en-before",
|
|
3110
|
+
language: "en",
|
|
3111
|
+
command: "put",
|
|
3112
|
+
priority: 95,
|
|
3113
|
+
template: {
|
|
3114
|
+
format: "put {patient} before {destination}",
|
|
3115
|
+
tokens: [
|
|
3116
|
+
{ type: "literal", value: "put" },
|
|
3117
|
+
{ type: "role", role: "patient" },
|
|
3118
|
+
{ type: "literal", value: "before" },
|
|
3119
|
+
{ type: "role", role: "destination" }
|
|
3120
|
+
]
|
|
3121
|
+
},
|
|
3122
|
+
extraction: {
|
|
3123
|
+
patient: { position: 1 },
|
|
3124
|
+
destination: { marker: "before" },
|
|
3125
|
+
manner: { default: { type: "literal", value: "before" } }
|
|
3126
|
+
}
|
|
3127
|
+
},
|
|
3128
|
+
{
|
|
3129
|
+
id: "put-en-after",
|
|
3130
|
+
language: "en",
|
|
3131
|
+
command: "put",
|
|
3132
|
+
priority: 95,
|
|
3133
|
+
template: {
|
|
3134
|
+
format: "put {patient} after {destination}",
|
|
3135
|
+
tokens: [
|
|
3136
|
+
{ type: "literal", value: "put" },
|
|
3137
|
+
{ type: "role", role: "patient" },
|
|
3138
|
+
{ type: "literal", value: "after" },
|
|
3139
|
+
{ type: "role", role: "destination" }
|
|
3140
|
+
]
|
|
3141
|
+
},
|
|
3142
|
+
extraction: {
|
|
3143
|
+
patient: { position: 1 },
|
|
3144
|
+
destination: { marker: "after" },
|
|
3145
|
+
manner: { default: { type: "literal", value: "after" } }
|
|
3146
|
+
}
|
|
3147
|
+
}
|
|
3148
|
+
];
|
|
3149
|
+
}
|
|
3150
|
+
|
|
3151
|
+
// src/patterns/event-handler/en.ts
|
|
3152
|
+
function getEventHandlerPatternsEn() {
|
|
3153
|
+
return [
|
|
3154
|
+
{
|
|
3155
|
+
id: "event-en-when-source",
|
|
3156
|
+
language: "en",
|
|
3157
|
+
command: "on",
|
|
3158
|
+
priority: 115,
|
|
3159
|
+
template: {
|
|
3160
|
+
format: "when {event} from {source} {body}",
|
|
3161
|
+
tokens: [
|
|
3162
|
+
{ type: "literal", value: "when" },
|
|
3163
|
+
{ type: "role", role: "event" },
|
|
3164
|
+
{ type: "literal", value: "from" },
|
|
3165
|
+
{ type: "role", role: "source" }
|
|
3166
|
+
]
|
|
3167
|
+
},
|
|
3168
|
+
extraction: {
|
|
3169
|
+
event: { position: 1 },
|
|
3170
|
+
source: { marker: "from" }
|
|
3171
|
+
}
|
|
3172
|
+
},
|
|
3173
|
+
{
|
|
3174
|
+
id: "event-en-when",
|
|
3175
|
+
language: "en",
|
|
3176
|
+
command: "on",
|
|
3177
|
+
priority: 105,
|
|
3178
|
+
template: {
|
|
3179
|
+
format: "when {event} {body}",
|
|
3180
|
+
tokens: [
|
|
3181
|
+
{ type: "literal", value: "when" },
|
|
3182
|
+
{ type: "role", role: "event" }
|
|
3183
|
+
]
|
|
3184
|
+
},
|
|
3185
|
+
extraction: {
|
|
3186
|
+
event: { position: 1 }
|
|
3187
|
+
}
|
|
3188
|
+
},
|
|
3189
|
+
{
|
|
3190
|
+
id: "event-en-source",
|
|
3191
|
+
language: "en",
|
|
3192
|
+
command: "on",
|
|
3193
|
+
priority: 110,
|
|
3194
|
+
template: {
|
|
3195
|
+
format: "on {event} from {source} {body}",
|
|
3196
|
+
tokens: [
|
|
3197
|
+
{ type: "literal", value: "on" },
|
|
3198
|
+
{ type: "role", role: "event" },
|
|
3199
|
+
{ type: "literal", value: "from" },
|
|
3200
|
+
{ type: "role", role: "source" }
|
|
3201
|
+
]
|
|
3202
|
+
},
|
|
3203
|
+
extraction: {
|
|
3204
|
+
event: { position: 1 },
|
|
3205
|
+
source: { marker: "from" }
|
|
3206
|
+
}
|
|
3207
|
+
},
|
|
3208
|
+
{
|
|
3209
|
+
id: "event-en-standard",
|
|
3210
|
+
language: "en",
|
|
3211
|
+
command: "on",
|
|
3212
|
+
priority: 100,
|
|
3213
|
+
template: {
|
|
3214
|
+
format: "on {event} {body}",
|
|
3215
|
+
tokens: [
|
|
3216
|
+
{ type: "literal", value: "on" },
|
|
3217
|
+
{ type: "role", role: "event" }
|
|
3218
|
+
]
|
|
3219
|
+
},
|
|
3220
|
+
extraction: {
|
|
3221
|
+
event: { position: 1 }
|
|
3222
|
+
}
|
|
3223
|
+
},
|
|
3224
|
+
{
|
|
3225
|
+
id: "event-en-upon",
|
|
3226
|
+
language: "en",
|
|
3227
|
+
command: "on",
|
|
3228
|
+
priority: 98,
|
|
3229
|
+
template: {
|
|
3230
|
+
format: "upon {event} {body}",
|
|
3231
|
+
tokens: [
|
|
3232
|
+
{ type: "literal", value: "upon" },
|
|
3233
|
+
{ type: "role", role: "event" }
|
|
3234
|
+
]
|
|
3235
|
+
},
|
|
3236
|
+
extraction: {
|
|
3237
|
+
event: { position: 1 }
|
|
3238
|
+
}
|
|
3239
|
+
},
|
|
3240
|
+
{
|
|
3241
|
+
id: "event-en-if",
|
|
3242
|
+
language: "en",
|
|
3243
|
+
command: "on",
|
|
3244
|
+
priority: 95,
|
|
3245
|
+
template: {
|
|
3246
|
+
format: "if {event} {body}",
|
|
3247
|
+
tokens: [
|
|
3248
|
+
{ type: "literal", value: "if" },
|
|
3249
|
+
{ type: "role", role: "event" }
|
|
3250
|
+
]
|
|
3251
|
+
},
|
|
3252
|
+
extraction: {
|
|
3253
|
+
event: { position: 1 }
|
|
3254
|
+
}
|
|
3255
|
+
}
|
|
3256
|
+
];
|
|
3257
|
+
}
|
|
3258
|
+
|
|
3259
|
+
// src/patterns/en.ts
|
|
3260
|
+
var fetchWithResponseTypeEnglish = {
|
|
3261
|
+
id: "fetch-en-with-response-type",
|
|
3262
|
+
language: "en",
|
|
3263
|
+
command: "fetch",
|
|
3264
|
+
priority: 90,
|
|
3265
|
+
template: {
|
|
3266
|
+
format: "fetch {source} as {responseType}",
|
|
3267
|
+
tokens: [
|
|
3268
|
+
{ type: "literal", value: "fetch" },
|
|
3269
|
+
{ type: "role", role: "source", expectedTypes: ["literal", "expression"] },
|
|
3270
|
+
{ type: "literal", value: "as" },
|
|
3271
|
+
{ type: "role", role: "responseType", expectedTypes: ["literal", "expression"] }
|
|
3272
|
+
]
|
|
3273
|
+
},
|
|
3274
|
+
extraction: {
|
|
3275
|
+
source: { position: 1 },
|
|
3276
|
+
responseType: { marker: "as" }
|
|
3277
|
+
}
|
|
3278
|
+
};
|
|
3279
|
+
var fetchSimpleEnglish = {
|
|
3280
|
+
id: "fetch-en-simple",
|
|
3281
|
+
language: "en",
|
|
3282
|
+
command: "fetch",
|
|
3283
|
+
priority: 80,
|
|
3284
|
+
template: {
|
|
3285
|
+
format: "fetch {source}",
|
|
3286
|
+
tokens: [
|
|
3287
|
+
{ type: "literal", value: "fetch" },
|
|
3288
|
+
{ type: "role", role: "source" }
|
|
3289
|
+
]
|
|
3290
|
+
},
|
|
3291
|
+
extraction: {
|
|
3292
|
+
source: { position: 1 }
|
|
3293
|
+
}
|
|
3294
|
+
};
|
|
3295
|
+
var swapSimpleEnglish = {
|
|
3296
|
+
id: "swap-en-handcrafted",
|
|
3297
|
+
language: "en",
|
|
3298
|
+
command: "swap",
|
|
3299
|
+
priority: 110,
|
|
3300
|
+
template: {
|
|
3301
|
+
format: "swap {method} {destination}",
|
|
3302
|
+
tokens: [
|
|
3303
|
+
{ type: "literal", value: "swap" },
|
|
3304
|
+
{ type: "role", role: "method" },
|
|
3305
|
+
{ type: "role", role: "destination" }
|
|
3306
|
+
]
|
|
3307
|
+
},
|
|
3308
|
+
extraction: {
|
|
3309
|
+
method: { position: 1 },
|
|
3310
|
+
destination: { position: 2 }
|
|
3311
|
+
}
|
|
3312
|
+
};
|
|
3313
|
+
var repeatUntilEventFromEnglish = {
|
|
3314
|
+
id: "repeat-en-until-event-from",
|
|
3315
|
+
language: "en",
|
|
3316
|
+
command: "repeat",
|
|
3317
|
+
priority: 120,
|
|
3318
|
+
template: {
|
|
3319
|
+
format: "repeat until event {event} from {source}",
|
|
3320
|
+
tokens: [
|
|
3321
|
+
{ type: "literal", value: "repeat" },
|
|
3322
|
+
{ type: "literal", value: "until" },
|
|
3323
|
+
{ type: "literal", value: "event" },
|
|
3324
|
+
{ type: "role", role: "event", expectedTypes: ["literal", "expression"] },
|
|
3325
|
+
{ type: "literal", value: "from" },
|
|
3326
|
+
{ type: "role", role: "source", expectedTypes: ["selector", "reference", "expression"] }
|
|
3327
|
+
]
|
|
3328
|
+
},
|
|
3329
|
+
extraction: {
|
|
3330
|
+
event: { marker: "event" },
|
|
3331
|
+
source: { marker: "from" },
|
|
3332
|
+
loopType: { default: { type: "literal", value: "until-event" } }
|
|
3333
|
+
}
|
|
3334
|
+
};
|
|
3335
|
+
var repeatUntilEventEnglish = {
|
|
3336
|
+
id: "repeat-en-until-event",
|
|
3337
|
+
language: "en",
|
|
3338
|
+
command: "repeat",
|
|
3339
|
+
priority: 110,
|
|
3340
|
+
template: {
|
|
3341
|
+
format: "repeat until event {event}",
|
|
3342
|
+
tokens: [
|
|
3343
|
+
{ type: "literal", value: "repeat" },
|
|
3344
|
+
{ type: "literal", value: "until" },
|
|
3345
|
+
{ type: "literal", value: "event" },
|
|
3346
|
+
{ type: "role", role: "event", expectedTypes: ["literal", "expression"] }
|
|
3347
|
+
]
|
|
3348
|
+
},
|
|
3349
|
+
extraction: {
|
|
3350
|
+
event: { marker: "event" },
|
|
3351
|
+
loopType: { default: { type: "literal", value: "until-event" } }
|
|
3352
|
+
}
|
|
3353
|
+
};
|
|
3354
|
+
var setPossessiveEnglish = {
|
|
3355
|
+
id: "set-en-possessive",
|
|
3356
|
+
language: "en",
|
|
3357
|
+
command: "set",
|
|
3358
|
+
priority: 100,
|
|
3359
|
+
template: {
|
|
3360
|
+
format: "set {destination} to {patient}",
|
|
3361
|
+
tokens: [
|
|
3362
|
+
{ type: "literal", value: "set" },
|
|
3363
|
+
{
|
|
3364
|
+
type: "role",
|
|
3365
|
+
role: "destination",
|
|
3366
|
+
expectedTypes: ["property-path", "selector", "reference", "expression"]
|
|
3367
|
+
},
|
|
3368
|
+
{ type: "literal", value: "to" },
|
|
3369
|
+
{ type: "role", role: "patient", expectedTypes: ["literal", "expression", "reference"] }
|
|
3370
|
+
]
|
|
3371
|
+
},
|
|
3372
|
+
extraction: {
|
|
3373
|
+
destination: { position: 1 },
|
|
3374
|
+
patient: { marker: "to" }
|
|
3375
|
+
}
|
|
3376
|
+
};
|
|
3377
|
+
var forEnglish = {
|
|
3378
|
+
id: "for-en-basic",
|
|
3379
|
+
language: "en",
|
|
3380
|
+
command: "for",
|
|
3381
|
+
priority: 100,
|
|
3382
|
+
template: {
|
|
3383
|
+
format: "for {patient} in {source}",
|
|
3384
|
+
tokens: [
|
|
3385
|
+
{ type: "literal", value: "for" },
|
|
3386
|
+
{ type: "role", role: "patient", expectedTypes: ["expression", "reference"] },
|
|
3387
|
+
{ type: "literal", value: "in" },
|
|
3388
|
+
{ type: "role", role: "source", expectedTypes: ["selector", "expression", "reference"] }
|
|
3389
|
+
]
|
|
3390
|
+
},
|
|
3391
|
+
extraction: {
|
|
3392
|
+
patient: { position: 1 },
|
|
3393
|
+
source: { marker: "in" },
|
|
3394
|
+
loopType: { default: { type: "literal", value: "for" } }
|
|
3395
|
+
}
|
|
3396
|
+
};
|
|
3397
|
+
var ifEnglish = {
|
|
3398
|
+
id: "if-en-basic",
|
|
3399
|
+
language: "en",
|
|
3400
|
+
command: "if",
|
|
3401
|
+
priority: 100,
|
|
3402
|
+
template: {
|
|
3403
|
+
format: "if {condition}",
|
|
3404
|
+
tokens: [
|
|
3405
|
+
{ type: "literal", value: "if" },
|
|
3406
|
+
{ type: "role", role: "condition", expectedTypes: ["expression", "reference", "selector"] }
|
|
3407
|
+
]
|
|
3408
|
+
},
|
|
3409
|
+
extraction: {
|
|
3410
|
+
condition: { position: 1 }
|
|
3411
|
+
}
|
|
3412
|
+
};
|
|
3413
|
+
var unlessEnglish = {
|
|
3414
|
+
id: "unless-en-basic",
|
|
3415
|
+
language: "en",
|
|
3416
|
+
command: "unless",
|
|
3417
|
+
priority: 100,
|
|
3418
|
+
template: {
|
|
3419
|
+
format: "unless {condition}",
|
|
3420
|
+
tokens: [
|
|
3421
|
+
{ type: "literal", value: "unless" },
|
|
3422
|
+
{ type: "role", role: "condition", expectedTypes: ["expression", "reference", "selector"] }
|
|
3423
|
+
]
|
|
3424
|
+
},
|
|
3425
|
+
extraction: {
|
|
3426
|
+
condition: { position: 1 }
|
|
3427
|
+
}
|
|
3428
|
+
};
|
|
3429
|
+
var temporalInEnglish = {
|
|
3430
|
+
id: "temporal-en-in",
|
|
3431
|
+
language: "en",
|
|
3432
|
+
command: "wait",
|
|
3433
|
+
priority: 95,
|
|
3434
|
+
template: {
|
|
3435
|
+
format: "in {duration}",
|
|
3436
|
+
tokens: [
|
|
3437
|
+
{ type: "literal", value: "in" },
|
|
3438
|
+
{ type: "role", role: "duration", expectedTypes: ["literal", "expression"] }
|
|
3439
|
+
]
|
|
3440
|
+
},
|
|
3441
|
+
extraction: {
|
|
3442
|
+
duration: { position: 1 }
|
|
3443
|
+
}
|
|
3444
|
+
};
|
|
3445
|
+
var temporalAfterEnglish = {
|
|
3446
|
+
id: "temporal-en-after",
|
|
3447
|
+
language: "en",
|
|
3448
|
+
command: "wait",
|
|
3449
|
+
priority: 95,
|
|
3450
|
+
template: {
|
|
3451
|
+
format: "after {duration}",
|
|
3452
|
+
tokens: [
|
|
3453
|
+
{ type: "literal", value: "after" },
|
|
3454
|
+
{ type: "role", role: "duration", expectedTypes: ["literal", "expression"] }
|
|
3455
|
+
]
|
|
3456
|
+
},
|
|
3457
|
+
extraction: {
|
|
3458
|
+
duration: { position: 1 }
|
|
3459
|
+
}
|
|
3460
|
+
};
|
|
3461
|
+
function buildEnglishPatterns() {
|
|
3462
|
+
const patterns = [];
|
|
3463
|
+
patterns.push(...getTogglePatternsEn());
|
|
3464
|
+
patterns.push(...getPutPatternsEn());
|
|
3465
|
+
patterns.push(...getEventHandlerPatternsEn());
|
|
3466
|
+
patterns.push(
|
|
3467
|
+
fetchWithResponseTypeEnglish,
|
|
3468
|
+
fetchSimpleEnglish,
|
|
3469
|
+
swapSimpleEnglish,
|
|
3470
|
+
repeatUntilEventFromEnglish,
|
|
3471
|
+
repeatUntilEventEnglish,
|
|
3472
|
+
setPossessiveEnglish,
|
|
3473
|
+
forEnglish,
|
|
3474
|
+
ifEnglish,
|
|
3475
|
+
unlessEnglish,
|
|
3476
|
+
temporalInEnglish,
|
|
3477
|
+
temporalAfterEnglish
|
|
3478
|
+
);
|
|
3479
|
+
const generatedPatterns = generatePatternsForLanguage(englishProfile);
|
|
3480
|
+
patterns.push(...generatedPatterns);
|
|
3481
|
+
return patterns;
|
|
3482
|
+
}
|
|
3483
|
+
|
|
3484
|
+
// src/languages/en.ts
|
|
3485
|
+
registerLanguage("en", englishTokenizer, englishProfile);
|
|
3486
|
+
registerPatterns("en", buildEnglishPatterns());
|
|
3487
|
+
export {
|
|
3488
|
+
englishProfile,
|
|
3489
|
+
englishTokenizer
|
|
3490
|
+
};
|
|
3491
|
+
//# sourceMappingURL=en.js.map
|