tjs-lang 0.8.6 → 0.9.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/CLAUDE.md +12 -4
- package/bin/docs.js +3 -2
- package/demo/docs.json +2 -2
- package/dist/experiments/ambient/probe.d.ts +52 -0
- package/dist/index.js +115 -171
- package/dist/index.js.map +4 -4
- package/dist/scripts/build-editors.d.ts +19 -0
- package/dist/src/css/dimensions.d.ts +23 -0
- package/dist/src/css/index.d.ts +85 -0
- package/dist/src/css/predicates.d.ts +38 -0
- package/dist/src/css/shorthands.d.ts +31 -0
- package/dist/src/css/style.d.ts +48 -0
- package/dist/src/lang/emitters/js.d.ts +9 -1
- package/dist/src/lang/index.d.ts +2 -2
- package/dist/src/lang/parser-transforms.d.ts +9 -5
- package/dist/src/lang/parser.d.ts +2 -0
- package/dist/src/lang/predicate.d.ts +60 -0
- package/dist/src/lang/transpiler.d.ts +3 -2
- package/dist/src/lang/types.d.ts +16 -0
- package/dist/src/schema/index.d.ts +12 -0
- package/dist/tjs-browser-from-ts.js +20 -20
- package/dist/tjs-browser-from-ts.js.map +3 -3
- package/dist/tjs-browser.js +100 -90
- package/dist/tjs-browser.js.map +4 -4
- package/dist/tjs-css.js +193 -0
- package/dist/tjs-css.js.map +7 -0
- package/dist/tjs-eval.js +43 -42
- package/dist/tjs-eval.js.map +4 -4
- package/dist/tjs-from-ts.js +13 -13
- package/dist/tjs-from-ts.js.map +2 -2
- package/dist/tjs-lang.js +102 -92
- package/dist/tjs-lang.js.map +4 -4
- package/dist/tjs-runtime.js +10 -0
- package/dist/tjs-runtime.js.map +7 -0
- package/dist/tjs-schema.js +6 -0
- package/dist/tjs-schema.js.map +7 -0
- package/dist/tjs-vm.js +55 -54
- package/dist/tjs-vm.js.map +4 -4
- package/docs/ambient-contracts.md +261 -0
- package/editors/ace/ajs-mode.js +214 -233
- package/editors/codemirror/ajs-language.js +1570 -233
- package/editors/editors-build.test.ts +29 -0
- package/editors/monaco/ajs-monarch.js +239 -195
- package/llms.txt +4 -0
- package/package.json +35 -4
- package/src/css/css.test.ts +122 -0
- package/src/css/dimensions.test.ts +112 -0
- package/src/css/dimensions.ts +146 -0
- package/src/css/index.ts +243 -0
- package/src/css/perf.bench.test.ts +109 -0
- package/src/css/predicates.ts +232 -0
- package/src/css/property-aware.test.ts +84 -0
- package/src/css/shorthands.test.ts +90 -0
- package/src/css/shorthands.ts +113 -0
- package/src/css/style.test.ts +125 -0
- package/src/css/style.ts +134 -0
- package/src/index-tsfree.test.ts +58 -0
- package/src/lang/bare-assignments.test.ts +48 -0
- package/src/lang/doc-comment-position.test.ts +32 -0
- package/src/lang/docs.ts +6 -2
- package/src/lang/emit-verified-predicate.test.ts +95 -0
- package/src/lang/emitters/dts.test.ts +31 -0
- package/src/lang/emitters/dts.ts +23 -4
- package/src/lang/emitters/from-ts.ts +4 -1
- package/src/lang/emitters/js.ts +33 -1
- package/src/lang/from-ts.test.ts +1 -1
- package/src/lang/generic-verified-predicate.test.ts +39 -0
- package/src/lang/index.ts +14 -5
- package/src/lang/parser-transforms.ts +120 -18
- package/src/lang/parser.ts +22 -6
- package/src/lang/predicate-evaluator.test.ts +49 -0
- package/src/lang/predicate-report.test.ts +54 -0
- package/src/lang/predicate.ts +268 -0
- package/src/lang/redos-lint.test.ts +81 -0
- package/src/lang/transpiler.ts +13 -0
- package/src/lang/type-verified-predicate.test.ts +83 -0
- package/src/lang/types.ts +17 -0
- package/src/lang/typescript-syntax.test.ts +2 -1
- package/src/schema/index.ts +62 -0
- package/src/schema/schema.test.ts +66 -0
- package/src/use-cases/bootstrap.test.ts +14 -4
package/dist/tjs-css.js
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import*as _ from"acorn";import*as k from"acorn-walk";var z=new Set(["parseInt","parseFloat","isNaN","isFinite","encodeURIComponent","decodeURIComponent","String","Number","Boolean","Array","Object","Eq","NotEq","Is","IsNot","TypeOf"]),Y=new Set(["Math","JSON","Object","Array","String","Number"]),B=new Set(["Math.random","Date.now"]);function F(e,t){let r=e[t],i=0;if(r==="*"||r==="+")i=1;else if(r==="{"){let s=e.slice(t).match(/^\{\d+,\}/);s&&(i=s[0].length)}return i===0?0:(e[t+i]==="?"&&i++,i)}function K(e){let t=[],r=0,i=!1;for(;r<e.length;){let s=e[r];if(s==="\\"){r+=2;continue}if(i){s==="]"&&(i=!1),r++;continue}if(s==="["){i=!0,r++;continue}if(s==="("){t.push({hadUnbounded:!1}),r++;continue}if(s===")"){let a=t.pop()??{hadUnbounded:!1},f=F(e,r+1);if(f>0){if(a.hadUnbounded)return"an unbounded quantifier is nested inside another (e.g. `(a+)+`)";t.length&&(t[t.length-1].hadUnbounded=!0),r+=1+f;continue}a.hadUnbounded&&t.length&&(t[t.length-1].hadUnbounded=!0),r++;continue}let o=F(e,r);if(o>0){t.length&&(t[t.length-1].hadUnbounded=!0),r+=o;continue}r++}return null}var J=new Set(["startsWith","endsWith","includes","indexOf","lastIndexOf","slice","substring","substr","toLowerCase","toUpperCase","trim","trimStart","trimEnd","split","replace","replaceAll","match","matchAll","charAt","charCodeAt","codePointAt","padStart","padEnd","repeat","concat","at","normalize","search","localeCompare","every","some","map","filter","reduce","reduceRight","find","findIndex","findLast","findLastIndex","flat","flatMap","join","keys","entries","values","forEach","test","exec","toFixed","toPrecision","toString","valueOf","hasOwnProperty"]),U=["fetch","XMLHttpRequest","WebSocket","Date","console","setTimeout","setInterval","requestAnimationFrame","queueMicrotask","localStorage","sessionStorage","indexedDB","document","window","globalThis","self","process","require","eval","Function","import","crypto","performance","navigator"];function E(e,t={}){let r=t.effectful??new Set(U),i;try{i=_.parse(e,{ecmaVersion:"latest",locations:!0})}catch(a){return{safe:!1,predicates:[],diagnostics:[{predicate:"<source>",message:`parse error: ${a.message}`,line:a.loc?.line??0,column:a.loc?.column??0}]}}let s=new Set(t.knownPredicates??[]);for(let a of i.body)a.type==="FunctionDeclaration"&&a.id&&s.add(a.id.name);let o=[];for(let a of i.body){if(a.type!=="FunctionDeclaration"||!a.id)continue;let f=a.id.name,n=(u,l)=>o.push({predicate:f,message:u,line:l?.loc?.start?.line??0,column:l?.loc?.start?.column??0}),c=u=>n("loops are not allowed \u2014 iterate with recursion or array methods (every/some/map/filter/reduce) so work stays fuel-bounded",u);k.simple(a,{AwaitExpression(u){n("`await` not allowed \u2014 predicates must be synchronous",u)},NewExpression(u){n("`new` not allowed in a predicate (non-pure construction)",u)},WhileStatement:c,DoWhileStatement:c,ForStatement:c,ForInStatement:c,ForOfStatement:c,Literal(u){if(u.regex&&typeof u.regex.pattern=="string"){let l=K(u.regex.pattern);l&&n(`regex /${u.regex.pattern}/ risks catastrophic backtracking (ReDoS): ${l}. A single match is not fuel-bounded, so it can't be certified predicate-safe \u2014 simplify the pattern or validate without it.`,u)}},CallExpression(u){let l=u.callee;if(l.type==="Identifier"){let d=l.name;r.has(d)?n(`'${d}' is effectful \u2014 not allowed in a predicate`,l):s.has(d)||z.has(d)||n(`unknown reference '${d}' \u2014 not a predicate or pure builtin`,l);return}if(l.type==="MemberExpression"&&!l.computed){let d=l.property.name,p=l.object;p.type==="Identifier"&&r.has(p.name)?n(`'${p.name}.${d}' is effectful`,l):p.type==="Identifier"&&Y.has(p.name)?B.has(`${p.name}.${d}`)&&n(`'${p.name}.${d}' is nondeterministic`,l):J.has(d)||n(`method '.${d}()' is not a known pure method`,l.property);return}n("unsupported call form in a predicate",l)}})}return{safe:o.length===0,predicates:[...s],diagnostics:o}}function Q(e){return e.map(t=>` ${t.predicate} (${t.line}:${t.column}): ${t.message}`).join(`
|
|
2
|
+
`)}var b=e=>e&&e.type==="Literal"&&typeof e.value=="string";function M(e,t={}){let r;try{r=_.parse(e,{ecmaVersion:"latest"})}catch{return[]}let i=new Set,s=new Set;k.simple(r,{BinaryExpression(n){(n.operator==="=="||n.operator==="===")&&(b(n.left)&&i.add(n.left.value),b(n.right)&&i.add(n.right.value))},ArrayExpression(n){for(let c of n.elements)b(c)&&i.add(c.value)},CallExpression(n){let c=n.callee;if(c.type!=="MemberExpression"||c.computed)return;let u=c.property.name,l=n.arguments[0];b(l)&&u==="startsWith"&&s.add(l.value)}});let o=null;if(t.validate!==!1){let n=E(e,t);if(n.safe&&n.predicates.length){let c=t.entry??n.predicates[n.predicates.length-1];try{let l=v(e,[c],t)[c];o=d=>{try{return l(d)===!0}catch{return!1}}}catch{o=null}}}let a=[];for(let n of i)(!o||o(n))&&a.push({value:n,kind:"value"});for(let n of s)a.push({value:n,kind:"stub"});let f=a;if(t.prefix){let n=t.prefix;f=a.filter(c=>c.value.startsWith(n)||c.kind==="stub"&&n.startsWith(c.value))}return f.sort((n,c)=>(n.kind===c.kind?0:n.kind==="value"?-1:1)||n.value.localeCompare(c.value)),t.limit?f.slice(0,t.limit):f}var w=class extends Error{constructor(t){super(`predicate exceeded its fuel budget (${t})`),this.name="PredicateFuelExhausted"}};function X(e){let t=_.parse(e,{ecmaVersion:"latest"}),r=[],i=o=>r.push([o.body.start+1,"__fuel();"]);k.simple(t,{FunctionDeclaration:i,FunctionExpression:i,ArrowFunctionExpression(o){o.body.type==="BlockStatement"?r.push([o.body.start+1,"__fuel();"]):(r.push([o.body.start,"(__fuel(), "]),r.push([o.body.end,")"]))}}),r.sort((o,a)=>a[0]-o[0]);let s=e;for(let[o,a]of r)s=s.slice(0,o)+a+s.slice(o);return s}function v(e,t,r={}){let i=E(e,r);if(!i.safe)throw new Error(`Not predicate-safe:
|
|
3
|
+
${Q(i.diagnostics)}`);let s=r.fuel??1e6,o=X(e),a=U.filter(d=>d!=="import"&&d!=="eval"&&d!=="arguments"),f=new Function("__fuel",...a,`"use strict";
|
|
4
|
+
${o}
|
|
5
|
+
;return { ${t.join(", ")} };`),n=0,u=f(()=>{if(--n<0)throw new w(s)},...a.map(()=>{})),l={};for(let d of t){let p=u[d];l[d]=(...G)=>{n=s;try{return p(...G)}catch(R){throw R instanceof RangeError&&/stack/i.test(R.message)?new w(s):R}}}return l}var H=["transparent","currentcolor","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkgrey","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","green","greenyellow","grey","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightgrey","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen"],g=`
|
|
6
|
+
var CSS_NAMED_COLORS = ${JSON.stringify(H)}
|
|
7
|
+
|
|
8
|
+
function isNamedColor(v) {
|
|
9
|
+
return typeof v === 'string' && CSS_NAMED_COLORS.includes(v.toLowerCase())
|
|
10
|
+
}
|
|
11
|
+
function isHexColor(v) {
|
|
12
|
+
return typeof v === 'string' && /^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(v)
|
|
13
|
+
}
|
|
14
|
+
function isRgbColor(v) {
|
|
15
|
+
return typeof v === 'string' && /^rgba?\\(\\s*[-0-9.,%\\s/]+\\)$/i.test(v)
|
|
16
|
+
}
|
|
17
|
+
function isHslColor(v) {
|
|
18
|
+
return typeof v === 'string' && /^hsla?\\(\\s*[-0-9.,%\\s/adegr]+\\)$/i.test(v)
|
|
19
|
+
}
|
|
20
|
+
function isColorFn(v) {
|
|
21
|
+
if (typeof v !== 'string' || !v.endsWith(')')) { return false }
|
|
22
|
+
return v.startsWith('hwb(') || v.startsWith('lab(') || v.startsWith('lch(')
|
|
23
|
+
|| v.startsWith('oklab(') || v.startsWith('oklch(')
|
|
24
|
+
|| v.startsWith('color(') || v.startsWith('color-mix(')
|
|
25
|
+
}
|
|
26
|
+
function isColorVar(v) {
|
|
27
|
+
return typeof v === 'string' && v.startsWith('var(--') && v.endsWith(')')
|
|
28
|
+
}
|
|
29
|
+
function isColor(v) {
|
|
30
|
+
return isNamedColor(v) || isHexColor(v) || isRgbColor(v)
|
|
31
|
+
|| isHslColor(v) || isColorFn(v) || isColorVar(v)
|
|
32
|
+
}
|
|
33
|
+
function isColorValue(v) {
|
|
34
|
+
if (typeof v !== 'string') { return false }
|
|
35
|
+
var bare = v.replace(/\\s*!important\\s*$/i, '')
|
|
36
|
+
return isColor(bare)
|
|
37
|
+
}
|
|
38
|
+
`,x=["isColor","isColorValue","isNamedColor","isHexColor","isRgbColor","isHslColor"];var W=["cap","ch","em","ex","ic","lh","rcap","rch","rem","rex","ric","rlh","vw","vh","vi","vb","vmin","vmax","svw","svh","svi","svb","svmin","svmax","lvw","lvh","lvi","lvb","lvmin","lvmax","dvw","dvh","dvi","dvb","dvmin","dvmax","cqw","cqh","cqi","cqb","cqmin","cqmax","px","cm","mm","q","in","pt","pc"],j=["inherit","initial","unset","revert","revert-layer"],m=`
|
|
39
|
+
var CSS_LENGTH_UNITS = ${JSON.stringify([...W].sort((e,t)=>t.length-e.length))}
|
|
40
|
+
var CSS_GLOBAL_KEYWORDS = ${JSON.stringify(j)}
|
|
41
|
+
|
|
42
|
+
function isCssVar(v) {
|
|
43
|
+
return typeof v === 'string' && v.startsWith('var(--') && v.endsWith(')')
|
|
44
|
+
}
|
|
45
|
+
function isCssCalc(v) {
|
|
46
|
+
return typeof v === 'string' && v.startsWith('calc(') && v.endsWith(')')
|
|
47
|
+
}
|
|
48
|
+
function isNumber(v) {
|
|
49
|
+
if (typeof v === 'number') { return isFinite(v) }
|
|
50
|
+
return typeof v === 'string' && /^[+-]?(\\d*\\.\\d+|\\d+)$/.test(v)
|
|
51
|
+
}
|
|
52
|
+
function isInteger(v) {
|
|
53
|
+
if (typeof v === 'number') { return Number.isInteger(v) }
|
|
54
|
+
return typeof v === 'string' && /^[+-]?\\d+$/.test(v)
|
|
55
|
+
}
|
|
56
|
+
function isPercentage(v) {
|
|
57
|
+
return typeof v === 'string' && /^[+-]?(\\d*\\.\\d+|\\d+)%$/.test(v)
|
|
58
|
+
}
|
|
59
|
+
function isLength(v) {
|
|
60
|
+
if (v === 0 || v === '0') { return true }
|
|
61
|
+
if (isCssVar(v) || isCssCalc(v)) { return true }
|
|
62
|
+
if (typeof v !== 'string') { return false }
|
|
63
|
+
var m = v.match(/^[+-]?(\\d*\\.\\d+|\\d+)([a-z%]+)$/i)
|
|
64
|
+
if (m === null) { return false }
|
|
65
|
+
return CSS_LENGTH_UNITS.includes(m[2].toLowerCase())
|
|
66
|
+
}
|
|
67
|
+
function isAngle(v) {
|
|
68
|
+
return typeof v === 'string' && /^[+-]?(\\d*\\.\\d+|\\d+)(deg|grad|rad|turn)$/i.test(v)
|
|
69
|
+
}
|
|
70
|
+
function isTime(v) {
|
|
71
|
+
return typeof v === 'string' && /^[+-]?(\\d*\\.\\d+|\\d+)(ms|s)$/i.test(v)
|
|
72
|
+
}
|
|
73
|
+
function isResolution(v) {
|
|
74
|
+
return typeof v === 'string' && /^[+-]?(\\d*\\.\\d+|\\d+)(dpi|dpcm|dppx|x)$/i.test(v)
|
|
75
|
+
}
|
|
76
|
+
function isGlobalKeyword(v) {
|
|
77
|
+
return typeof v === 'string' && CSS_GLOBAL_KEYWORDS.includes(v.toLowerCase())
|
|
78
|
+
}
|
|
79
|
+
function isDimension(v) {
|
|
80
|
+
return isLength(v) || isPercentage(v) || isAngle(v)
|
|
81
|
+
|| isTime(v) || isResolution(v) || isNumber(v)
|
|
82
|
+
|| isCssVar(v) || isCssCalc(v)
|
|
83
|
+
}
|
|
84
|
+
`,N=["isNumber","isInteger","isPercentage","isLength","isAngle","isTime","isResolution","isGlobalKeyword","isDimension"];var T=`
|
|
85
|
+
var ANIM_TIMING = ['linear','ease','ease-in','ease-out','ease-in-out','step-start','step-end']
|
|
86
|
+
var ANIM_DIRECTION = ['normal','reverse','alternate','alternate-reverse']
|
|
87
|
+
var ANIM_FILLMODE = ['none','forwards','backwards','both']
|
|
88
|
+
var ANIM_PLAYSTATE = ['running','paused']
|
|
89
|
+
|
|
90
|
+
function isTimingFunction(t) {
|
|
91
|
+
if (typeof t !== 'string') { return false }
|
|
92
|
+
if (ANIM_TIMING.includes(t)) { return true }
|
|
93
|
+
return (t.startsWith('cubic-bezier(') || t.startsWith('steps(') || t.startsWith('linear(')) && t.endsWith(')')
|
|
94
|
+
}
|
|
95
|
+
function isIterationCount(t) {
|
|
96
|
+
return t === 'infinite' || (typeof t === 'string' && /^[0-9]*\\.?[0-9]+$/.test(t))
|
|
97
|
+
}
|
|
98
|
+
function isAnimName(t) {
|
|
99
|
+
// any custom-ident (also matches keywords, which classify earlier anyway)
|
|
100
|
+
return typeof t === 'string' && /^-?[a-z_][a-z0-9_-]*$/i.test(t)
|
|
101
|
+
}
|
|
102
|
+
// Tokenize a whole shorthand value. A function token like cubic-bezier(a, b) is
|
|
103
|
+
// kept whole (arg spaces/commas must not split it); top-level commas (layer
|
|
104
|
+
// separators) and whitespace are delimiters, so they're dropped. Loops are
|
|
105
|
+
// banned in predicates, so this is one .match with a FLAT (ReDoS-clean) regex \u2014
|
|
106
|
+
// note a paren-aware comma *splitter* would be a nested quantifier the verifier
|
|
107
|
+
// rejects, so we tokenize instead and guard empty layers separately.
|
|
108
|
+
function cssTokens(v) {
|
|
109
|
+
return typeof v === 'string' ? v.match(/[a-z-]+\\([^)]*\\)|[^\\s,]+/gi) : null
|
|
110
|
+
}
|
|
111
|
+
// Reject leading/trailing/double commas (empty layers). Flat, ReDoS-clean.
|
|
112
|
+
function hasEmptyLayer(v) {
|
|
113
|
+
return typeof v === 'string' && /^\\s*,|,\\s*$|,\\s*,/.test(v)
|
|
114
|
+
}
|
|
115
|
+
function isAnimToken(t) {
|
|
116
|
+
return isTime(t) || isIterationCount(t) || isTimingFunction(t)
|
|
117
|
+
|| ANIM_DIRECTION.includes(t) || ANIM_FILLMODE.includes(t) || ANIM_PLAYSTATE.includes(t)
|
|
118
|
+
|| isCssVar(t) || isCssCalc(t) || isAnimName(t)
|
|
119
|
+
}
|
|
120
|
+
function isAnimation(v) {
|
|
121
|
+
if (typeof v !== 'string' || v.length === 0 || hasEmptyLayer(v)) { return false }
|
|
122
|
+
var toks = cssTokens(v)
|
|
123
|
+
return toks !== null && toks.length > 0 && toks.every(isAnimToken)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function isTransitionProperty(t) {
|
|
127
|
+
return t === 'all' || t === 'none' || isAnimName(t)
|
|
128
|
+
}
|
|
129
|
+
function isTransitionToken(t) {
|
|
130
|
+
return isTime(t) || isTimingFunction(t) || isCssVar(t) || isCssCalc(t) || isTransitionProperty(t)
|
|
131
|
+
}
|
|
132
|
+
function isTransition(v) {
|
|
133
|
+
if (typeof v !== 'string' || v.length === 0 || hasEmptyLayer(v)) { return false }
|
|
134
|
+
var toks = cssTokens(v)
|
|
135
|
+
return toks !== null && toks.length > 0 && toks.every(isTransitionToken)
|
|
136
|
+
}
|
|
137
|
+
`,h=m+`
|
|
138
|
+
`+T,A=["isTimingFunction","isAnimation","isTransition"];function q(e){return{type:"string",$predicate:`${h}
|
|
139
|
+
function __entry(v) { return ${e}(v) }`}}function Z(){return{...q("isAnimation"),title:"CSSAnimation"}}function ee(){return{...q("isTransition"),title:"CSSTransition"}}var te=`
|
|
140
|
+
// Properties whose value grammar is CLOSED \u2014 a value that fails the leaf
|
|
141
|
+
// predicate is genuinely invalid, so it's safe to enforce (normalized:
|
|
142
|
+
// lower-cased, dashes stripped, so 'background-color' === 'backgroundColor').
|
|
143
|
+
var CSS_COLOR_PROPS = ['color','backgroundcolor','bordercolor','bordertopcolor','borderrightcolor','borderbottomcolor','borderleftcolor','outlinecolor','caretcolor','columnrulecolor','textdecorationcolor','accentcolor','fill','stroke','floodcolor','stopcolor','lightingcolor']
|
|
144
|
+
|
|
145
|
+
function isCssProperty(k) {
|
|
146
|
+
// custom property (--foo) OR a standard/vendor-prefixed property (-webkit-\u2026).
|
|
147
|
+
return typeof k === 'string' && /^(--[a-z0-9-]+|-?[a-z][a-z0-9-]*)$/i.test(k)
|
|
148
|
+
}
|
|
149
|
+
function isSelectorOrAtRule(k) {
|
|
150
|
+
if (typeof k !== 'string' || k.length === 0) { return false }
|
|
151
|
+
if (k.startsWith('@')) { return true }
|
|
152
|
+
return /[ :>~+.#&*\\[\\]]/.test(k)
|
|
153
|
+
}
|
|
154
|
+
function isStyleValue(val) {
|
|
155
|
+
if (typeof val === 'number') { return isFinite(val) }
|
|
156
|
+
if (typeof val !== 'string' || val.length === 0) { return false }
|
|
157
|
+
// Precise recognition for known leaves; permissive tail keeps the whole
|
|
158
|
+
// structure total (a shorthand / unmodelled value is a non-empty string).
|
|
159
|
+
return isColorValue(val) || isDimension(val) || isGlobalKeyword(val)
|
|
160
|
+
|| isCssVar(val) || isCssCalc(val) || val.length > 0
|
|
161
|
+
}
|
|
162
|
+
function cssPropNorm(prop) {
|
|
163
|
+
return typeof prop === 'string' ? prop.toLowerCase().replace(/-/g, '') : ''
|
|
164
|
+
}
|
|
165
|
+
// Property-AWARE value check: tighten only the closed value grammars (color,
|
|
166
|
+
// animation, transition) \u2014 a wrong value there is a real error; everything else
|
|
167
|
+
// stays permissive (keyword-heavy props like width/display accept idents we don't
|
|
168
|
+
// enumerate, so enforcing would false-reject valid CSS). Universal escapes
|
|
169
|
+
// (global keyword / var() / calc()) are valid on any property.
|
|
170
|
+
function isStyleValueFor(prop, val) {
|
|
171
|
+
if (isGlobalKeyword(val) || isCssVar(val) || isCssCalc(val)) { return true }
|
|
172
|
+
var p = cssPropNorm(prop)
|
|
173
|
+
if (CSS_COLOR_PROPS.includes(p)) { return isColorValue(val) }
|
|
174
|
+
if (p === 'animation') { return isAnimation(val) }
|
|
175
|
+
if (p === 'transition') { return isTransition(val) }
|
|
176
|
+
return isStyleValue(val)
|
|
177
|
+
}
|
|
178
|
+
function isStyleEntry(pair) {
|
|
179
|
+
var k = pair[0]
|
|
180
|
+
var val = pair[1]
|
|
181
|
+
if (isSelectorOrAtRule(k)) { return isStyleObject(val) }
|
|
182
|
+
if (isCssProperty(k)) { return isStyleValueFor(k, val) }
|
|
183
|
+
return false
|
|
184
|
+
}
|
|
185
|
+
function isStyleObject(o) {
|
|
186
|
+
if (typeof o !== 'object' || o === null) { return false }
|
|
187
|
+
return Object.entries(o).every(isStyleEntry)
|
|
188
|
+
}
|
|
189
|
+
`,y=g+`
|
|
190
|
+
`+m+`
|
|
191
|
+
`+T+`
|
|
192
|
+
`+te,I=["isCssProperty","isSelectorOrAtRule","isStyleValue","isStyleValueFor","isStyleObject"];function ne(){return{type:"object",title:"CSSStyleObject",description:"An open, recursive CSS style object (properties + nested selectors/at-rules).",$predicate:y}}function re(){return{type:"string",title:"CSSColor",$predicate:g}}function oe(){return{title:"CSSDimension",$predicate:m}}var ie={color:g,dimension:m,style:y,shorthand:h},L=null;function O(){return L||(L=v(g,x)),L}var P=null;function S(){return P||(P=v(m,N)),P}var D=null;function C(){return D||(D=v(y,I)),D}var V=null;function $(){return V||(V=v(h,A)),V}var _e=e=>O().isColor(e),ke=e=>O().isColorValue(e),Ee=e=>O().isNamedColor(e),Oe=e=>O().isHexColor(e),Re=e=>S().isLength(e),xe=e=>S().isPercentage(e),Ne=e=>S().isNumber(e),Te=e=>S().isInteger(e),Ae=e=>S().isAngle(e),Ie=e=>S().isTime(e),Le=e=>S().isDimension(e),Pe=e=>S().isGlobalKeyword(e),De=e=>C().isStyleObject(e),Ve=e=>C().isStyleValue(e),$e=(e,t)=>C().isStyleValueFor(e,t),Fe=e=>C().isCssProperty(e),Ue=e=>C().isSelectorOrAtRule(e),Me=e=>$().isAnimation(e),He=e=>$().isTransition(e),We=e=>$().isTimingFunction(e);function je(){let e=[],t=[];for(let[r,i]of Object.entries(ie)){let s=E(i);e.push(...s.predicates);for(let o of s.diagnostics)t.push({...o,predicate:`${r}:${o.predicate}`})}return{safe:t.length===0,predicates:e,diagnostics:t}}function qe(e="",t=50){return M(g,{entry:"isColor",prefix:e,limit:t})}export{x as CSS_COLOR_ENTRIES,g as CSS_COLOR_SOURCE,N as CSS_DIMENSION_ENTRIES,m as CSS_DIMENSION_SOURCE,j as CSS_GLOBAL_KEYWORDS,W as CSS_LENGTH_UNITS,H as CSS_NAMED_COLORS,A as CSS_SHORTHAND_ENTRIES,h as CSS_SHORTHAND_SOURCE,I as CSS_STYLE_ENTRIES,y as CSS_STYLE_SOURCE,Z as cssAnimationSchema,re as cssColorSchema,oe as cssDimensionSchema,ne as cssStyleSchema,ee as cssTransitionSchema,Ae as isAngle,Me as isAnimation,_e as isColor,ke as isColorValue,Fe as isCssProperty,Le as isDimension,Pe as isGlobalKeyword,Oe as isHexColor,Te as isInteger,Re as isLength,Ee as isNamedColor,Ne as isNumber,xe as isPercentage,Ue as isSelectorOrAtRule,De as isStyleObject,Ve as isStyleValue,$e as isStyleValueFor,Ie as isTime,We as isTimingFunction,He as isTransition,qe as suggestColor,je as verifyCss};
|
|
193
|
+
//# sourceMappingURL=tjs-css.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/lang/predicate.ts", "../src/css/predicates.ts", "../src/css/dimensions.ts", "../src/css/shorthands.ts", "../src/css/style.ts", "../src/css/index.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Predicate-safety verifier.\n *\n * A *predicate* is a pure, synchronous function of its inputs. A cluster of\n * predicates is **predicate-safe** iff every function in it uses only pure\n * constructs and calls only pure builtins, pure globals, or other\n * predicate-safe predicates \u2014 a closure property, so the cluster is safe iff\n * each function is. Verified predicates have \"earned\" the native fast path:\n * they compile to plain synchronous JS where ergonomic composition\n * (`isHex(v) || isVar(v)`, `tokens.every(isToken)`, recursion) just works.\n *\n * This is pure static analysis over the parsed source, so it has none of the VM\n * interpreter's restrictions (calls-in-expressions, named callbacks) \u2014 it\n * accepts the ergonomic source and certifies it. The serializable AJS AST stays\n * the portable form (the \"missing computational half\" of JSON Schema); native\n * JS is the execution form.\n *\n * Effect classification of atoms comes from the VM's `effects` tag \u2014 pass\n * `effectfulFromAtoms(registry)` for atom-aware checking; without it, atom calls\n * still fail closed as \"unknown reference\". See `experiments/predicates/` for\n * the CSS torture set and `src/vm/atom-effects.test.ts` for the drift guard.\n */\nimport * as acorn from 'acorn'\nimport * as walk from 'acorn-walk'\n\nexport interface PredicateDiagnostic {\n /** Name of the predicate the problem is in. */\n predicate: string\n message: string\n line: number\n column: number\n}\n\nexport interface PredicateVerifyResult {\n safe: boolean\n /** Names of the top-level functions found (the predicate cluster). */\n predicates: string[]\n diagnostics: PredicateDiagnostic[]\n}\n\nexport interface VerifyPredicateOptions {\n /**\n * Names that are effectful and must not be called \u2014 IO atoms + JS IO globals.\n * Compose from the atom registry with `effectfulFromAtoms`. The built-in JS IO\n * globals are always included.\n */\n effectful?: Set<string>\n /**\n * Externally-verified predicate names this source may compose with (a shared\n * registry), in addition to the functions declared in `source`.\n */\n knownPredicates?: Set<string>\n}\n\n// --- the safe substrate -----------------------------------------------------\n\n/** Pure deterministic globals callable by bare name. */\nconst PURE_GLOBALS = new Set([\n 'parseInt',\n 'parseFloat',\n 'isNaN',\n 'isFinite',\n 'encodeURIComponent',\n 'decodeURIComponent',\n 'String',\n 'Number',\n 'Boolean',\n 'Array',\n 'Object',\n // TJS-injected pure helpers. Native-TJS predicate bodies are rewritten before\n // they reach the verifier: `==`/`!=` \u2192 `Eq`/`NotEq`, the explicit `Is`/`IsNot`\n // operators \u2192 `Is`/`IsNot`, `typeof x` \u2192 `TypeOf(x)`. All are pure, total\n // functions (footgun-free equality / structural equality / safe typeof), so a\n // predicate that uses TJS equality still verifies as predicate-safe.\n 'Eq',\n 'NotEq',\n 'Is',\n 'IsNot',\n 'TypeOf',\n])\n\n/** Namespaces whose static methods are pure (with effectful exceptions below). */\nconst PURE_NAMESPACES = new Set([\n 'Math',\n 'JSON',\n 'Object',\n 'Array',\n 'String',\n 'Number',\n])\n\n/** Static members that are NOT pure even on a pure namespace. */\nconst EFFECTFUL_STATICS = new Set(['Math.random', 'Date.now'])\n\n/**\n * A match at `pattern[pos]` for an *unbounded* quantifier (`*`, `+`, `{n,}` and\n * their lazy `?` variants) \u2014 the repetitions that drive backtracking blowups.\n * `?`, `{n}` and `{n,m}` are bounded, so they don't count. Returns the consumed\n * length, or 0 if there's no unbounded quantifier here.\n */\nfunction unboundedQuantifierLen(pattern: string, pos: number): number {\n const c = pattern[pos]\n let len = 0\n if (c === '*' || c === '+') {\n len = 1\n } else if (c === '{') {\n // `{n,}` is unbounded; `{n}` / `{n,m}` are bounded.\n const m = pattern.slice(pos).match(/^\\{\\d+,\\}/)\n if (m) len = m[0].length\n }\n if (len === 0) return 0\n // A trailing `?` makes it lazy \u2014 still unbounded, still backtracks.\n if (pattern[pos + len] === '?') len++\n return len\n}\n\n/**\n * Conservative ReDoS detector: flags a regex whose **star height is \u2265 2** \u2014 an\n * unbounded quantifier nested inside a group that is itself unbounded-quantified\n * (the classic `(a+)+`, `(a*)*`, `([a-z]+)*`, `(.*)*` exponential-backtracking\n * shapes). A predicate verifier should fail closed: over-flagging a safe pattern\n * only costs it its \"verified\" badge (it still runs), whereas certifying a\n * dangerous one is a broken safety promise.\n *\n * Not caught (known limitation, documented): *polynomial* ReDoS from adjacent\n * overlapping quantifiers (`\\d+\\d+$`, `a.*a.*a`) and alternation-overlap\n * (`(a|a)*`). The exponential class above is the one the safety story commits to.\n *\n * @returns a reason string if risky, else null.\n */\nfunction reDoSRisk(pattern: string): string | null {\n // Per-group frame: did this group contain an unbounded quantifier?\n const stack: Array<{ hadUnbounded: boolean }> = []\n let i = 0\n let inClass = false\n while (i < pattern.length) {\n const c = pattern[i]\n if (c === '\\\\') {\n i += 2 // skip an escaped char (regex escapes are 2 chars here)\n continue\n }\n if (inClass) {\n if (c === ']') inClass = false\n i++\n continue\n }\n if (c === '[') {\n inClass = true\n i++\n continue\n }\n if (c === '(') {\n stack.push({ hadUnbounded: false })\n i++\n continue\n }\n if (c === ')') {\n const frame = stack.pop() ?? { hadUnbounded: false }\n const qlen = unboundedQuantifierLen(pattern, i + 1)\n if (qlen > 0) {\n // This group is itself unbounded-repeated. If it already contained an\n // unbounded quantifier, that's star height \u2265 2 \u2192 catastrophic.\n if (frame.hadUnbounded)\n return 'an unbounded quantifier is nested inside another (e.g. `(a+)+`)'\n // The parent group now contains an unbounded repetition (this group).\n if (stack.length) stack[stack.length - 1].hadUnbounded = true\n i += 1 + qlen\n continue\n }\n // No quantifier on this group, but if it contained an unbounded\n // repetition, that repetition lives in the parent's scope too \u2014 propagate\n // so `((a+))+` is caught the same as `(a+)+`.\n if (frame.hadUnbounded && stack.length)\n stack[stack.length - 1].hadUnbounded = true\n i++\n continue\n }\n // An unbounded quantifier on a plain atom at the current nesting level.\n const qlen = unboundedQuantifierLen(pattern, i)\n if (qlen > 0) {\n if (stack.length) stack[stack.length - 1].hadUnbounded = true\n i += qlen\n continue\n }\n i++\n }\n return null\n}\n\n/**\n * Instance methods known to be pure regardless of receiver type. A method call\n * whose method name isn't here (and whose receiver isn't a pure namespace) is\n * flagged \u2014 so `x.then()`, `obj.fetch()`, `arr.push()` (mutates) don't pass.\n */\nconst PURE_INSTANCE_METHODS = new Set([\n // string\n 'startsWith',\n 'endsWith',\n 'includes',\n 'indexOf',\n 'lastIndexOf',\n 'slice',\n 'substring',\n 'substr',\n 'toLowerCase',\n 'toUpperCase',\n 'trim',\n 'trimStart',\n 'trimEnd',\n 'split',\n 'replace',\n 'replaceAll',\n 'match',\n 'matchAll',\n 'charAt',\n 'charCodeAt',\n 'codePointAt',\n 'padStart',\n 'padEnd',\n 'repeat',\n 'concat',\n 'at',\n 'normalize',\n 'search',\n 'localeCompare',\n // array (non-mutating)\n 'every',\n 'some',\n 'map',\n 'filter',\n 'reduce',\n 'reduceRight',\n 'find',\n 'findIndex',\n 'findLast',\n 'findLastIndex',\n 'flat',\n 'flatMap',\n 'join',\n 'keys',\n 'entries',\n 'values',\n 'forEach',\n // regexp\n 'test',\n 'exec',\n // number / shared\n 'toFixed',\n 'toPrecision',\n 'toString',\n 'valueOf',\n 'hasOwnProperty',\n])\n\n/** JS globals that perform IO / are nondeterministic / have side effects. */\nconst EFFECTFUL_GLOBALS = [\n 'fetch',\n 'XMLHttpRequest',\n 'WebSocket',\n 'Date',\n 'console',\n 'setTimeout',\n 'setInterval',\n 'requestAnimationFrame',\n 'queueMicrotask',\n 'localStorage',\n 'sessionStorage',\n 'indexedDB',\n 'document',\n 'window',\n 'globalThis',\n 'self',\n 'process',\n 'require',\n 'eval',\n 'Function',\n 'import',\n 'crypto',\n 'performance',\n 'navigator',\n]\n\n/**\n * Build the effectful-name set from a VM atom registry: every atom tagged\n * `effects: 'io'`, plus the built-in JS IO globals. This is how the verifier\n * consumes the atom-effects classification (the keystone).\n */\nexport function effectfulFromAtoms(\n atoms: Record<string, { op?: string; effects?: 'pure' | 'io' }>\n): Set<string> {\n const set = new Set(EFFECTFUL_GLOBALS)\n for (const [name, atom] of Object.entries(atoms)) {\n if (atom?.effects === 'io') set.add(atom.op ?? name)\n }\n return set\n}\n\n// --- the verifier -----------------------------------------------------------\n\n/**\n * Verify every top-level function declaration in `source` is predicate-safe.\n * Returns all diagnostics; `safe` is true iff there are none (closure property).\n */\nexport function verifyPredicate(\n source: string,\n opts: VerifyPredicateOptions = {}\n): PredicateVerifyResult {\n const effectful = opts.effectful ?? new Set(EFFECTFUL_GLOBALS)\n let ast: any\n try {\n ast = acorn.parse(source, { ecmaVersion: 'latest', locations: true })\n } catch (e: any) {\n return {\n safe: false,\n predicates: [],\n diagnostics: [\n {\n predicate: '<source>',\n message: `parse error: ${e.message}`,\n line: e.loc?.line ?? 0,\n column: e.loc?.column ?? 0,\n },\n ],\n }\n }\n\n const predicateNames = new Set<string>(opts.knownPredicates ?? [])\n for (const node of ast.body) {\n if (node.type === 'FunctionDeclaration' && node.id)\n predicateNames.add(node.id.name)\n }\n\n const diagnostics: PredicateDiagnostic[] = []\n\n for (const fn of ast.body) {\n if (fn.type !== 'FunctionDeclaration' || !fn.id) continue\n const pname = fn.id.name\n const flag = (message: string, n: any) =>\n diagnostics.push({\n predicate: pname,\n message,\n line: n?.loc?.start?.line ?? 0,\n column: n?.loc?.start?.column ?? 0,\n })\n\n const loop = (n: any) =>\n flag(\n 'loops are not allowed \u2014 iterate with recursion or array methods (every/some/map/filter/reduce) so work stays fuel-bounded',\n n\n )\n walk.simple(fn, {\n AwaitExpression(n: any) {\n flag('`await` not allowed \u2014 predicates must be synchronous', n)\n },\n NewExpression(n: any) {\n flag('`new` not allowed in a predicate (non-pure construction)', n)\n },\n WhileStatement: loop,\n DoWhileStatement: loop,\n ForStatement: loop,\n ForInStatement: loop,\n ForOfStatement: loop,\n Literal(n: any) {\n // Regex literals are the one primitive fuel can't bound: a single\n // `.match`/`.test`/`.replace` is opaque to the function-entry fuel hook,\n // so a catastrophic-backtracking pattern could hang on hostile input.\n // Certifying it \"safe\" would be a false guarantee, so flag it. (Dynamic\n // `RegExp(...)` is already rejected \u2014 `RegExp` isn't a pure global and\n // `new` is banned \u2014 so only literals need analysis.)\n if (n.regex && typeof n.regex.pattern === 'string') {\n const risk = reDoSRisk(n.regex.pattern)\n if (risk)\n flag(\n `regex /${n.regex.pattern}/ risks catastrophic backtracking (ReDoS): ${risk}. A single match is not fuel-bounded, so it can't be certified predicate-safe \u2014 simplify the pattern or validate without it.`,\n n\n )\n }\n },\n CallExpression(n: any) {\n const callee = n.callee\n // Bare call: f(...)\n if (callee.type === 'Identifier') {\n const name = callee.name\n if (effectful.has(name))\n flag(`'${name}' is effectful \u2014 not allowed in a predicate`, callee)\n else if (predicateNames.has(name)) {\n /* composition with another predicate \u2014 OK */\n } else if (PURE_GLOBALS.has(name)) {\n /* pure global \u2014 OK */\n } else {\n flag(\n `unknown reference '${name}' \u2014 not a predicate or pure builtin`,\n callee\n )\n }\n return\n }\n // Method call: recv.method(...)\n if (callee.type === 'MemberExpression' && !callee.computed) {\n const method = callee.property.name\n const recv = callee.object\n if (recv.type === 'Identifier' && effectful.has(recv.name)) {\n flag(`'${recv.name}.${method}' is effectful`, callee)\n } else if (\n recv.type === 'Identifier' &&\n PURE_NAMESPACES.has(recv.name)\n ) {\n if (EFFECTFUL_STATICS.has(`${recv.name}.${method}`))\n flag(`'${recv.name}.${method}' is nondeterministic`, callee)\n // else pure namespace method \u2014 OK\n } else if (!PURE_INSTANCE_METHODS.has(method)) {\n flag(\n `method '.${method}()' is not a known pure method`,\n callee.property\n )\n }\n return\n }\n // Anything else (computed member, call-of-call, etc.) \u2014 be conservative.\n flag('unsupported call form in a predicate', callee)\n },\n })\n }\n\n return {\n safe: diagnostics.length === 0,\n predicates: [...predicateNames],\n diagnostics,\n }\n}\n\n/** Format diagnostics for a thrown error / log. */\nexport function formatPredicateDiagnostics(d: PredicateDiagnostic[]): string {\n return d\n .map((x) => ` ${x.predicate} (${x.line}:${x.column}): ${x.message}`)\n .join('\\n')\n}\n\n// --- suggestion mining (#4: autocomplete companion) -------------------------\n\nexport interface Suggestion {\n value: string\n /**\n * `'value'` \u2014 a concrete candidate (a keyword/literal the predicate accepts);\n * `'stub'` \u2014 a partial completion to keep typing (e.g. `var(--`, `calc(`),\n * mined from a `startsWith(...)` guard. TS's `string` fallback\n * offers neither; a finite TS union offers only `'value'`.\n */\n kind: 'value' | 'stub'\n}\n\nexport interface SuggestOptions extends CompilePredicateOptions {\n /** Only return candidates relevant to the text typed so far. */\n prefix?: string\n /** Cap the number of suggestions (default 50). */\n limit?: number\n /**\n * Run each mined *value* through the compiled entry predicate and keep only\n * those that actually pass \u2014 so completions are guaranteed valid, not merely\n * enumerated. Default true when the cluster is predicate-safe; stubs are never\n * validated (they're partial by construction).\n */\n validate?: boolean\n /** Entry predicate to validate against (default: last top-level function). */\n entry?: string\n}\n\nconst isStringLiteral = (n: any): n is { value: string } =>\n n && n.type === 'Literal' && typeof n.value === 'string'\n\n/**\n * Mine a predicate cluster's source for autocomplete candidates. Two sources:\n * - **values** \u2014 string literals compared with `==`/`===` and members of\n * array literals (the keyword sets a predicate checks membership against).\n * - **stubs** \u2014 the argument of a `.startsWith(...)` guard, surfaced as a\n * partial completion (`var(--`, `calc(`) the user keeps typing.\n *\n * Pure syntactic mining over the parsed source \u2014 no execution. By default the\n * mined *values* are then run through the compiled entry predicate, so the\n * returned set is exactly what the predicate accepts (a literal that only ever\n * appears in a `!=` / negative context is dropped). This is the autocomplete\n * win over a TS `string` fallback (which suggests nothing) and over a finite TS\n * union (which can't offer the open-ended `var(--`/`calc(` stubs).\n */\nexport function suggest(\n source: string,\n opts: SuggestOptions = {}\n): Suggestion[] {\n let ast: any\n try {\n ast = acorn.parse(source, { ecmaVersion: 'latest' })\n } catch {\n return []\n }\n\n const values = new Set<string>()\n const stubs = new Set<string>()\n walk.simple(ast, {\n BinaryExpression(n: any) {\n if (n.operator === '==' || n.operator === '===') {\n if (isStringLiteral(n.left)) values.add(n.left.value)\n if (isStringLiteral(n.right)) values.add(n.right.value)\n }\n },\n ArrayExpression(n: any) {\n for (const el of n.elements) if (isStringLiteral(el)) values.add(el.value)\n },\n CallExpression(n: any) {\n const callee = n.callee\n if (callee.type !== 'MemberExpression' || callee.computed) return\n const method = callee.property.name\n const arg = n.arguments[0]\n if (!isStringLiteral(arg)) return\n if (method === 'startsWith') stubs.add(arg.value)\n // `.includes('x')` / `.endsWith('x')` aren't standalone completions:\n // includes-arg is a substring, endsWith-arg is a tail \u2014 skip both.\n },\n })\n\n // Validate mined values against the predicate unless told not to / unsafe.\n let accept: ((v: string) => boolean) | null = null\n if (opts.validate !== false) {\n const verified = verifyPredicate(source, opts)\n if (verified.safe && verified.predicates.length) {\n const entry =\n opts.entry ?? verified.predicates[verified.predicates.length - 1]\n try {\n const mod = compilePredicate(source, [entry], opts)\n const fn = mod[entry]\n accept = (v) => {\n try {\n return fn(v) === true\n } catch {\n return false // fuel exhaustion / runtime miss \u2192 not a suggestion\n }\n }\n } catch {\n accept = null // not compilable \u2192 fall back to raw mining\n }\n }\n }\n\n const out: Suggestion[] = []\n for (const v of values)\n if (!accept || accept(v)) out.push({ value: v, kind: 'value' })\n for (const s of stubs) out.push({ value: s, kind: 'stub' })\n\n let filtered = out\n if (opts.prefix) {\n const p = opts.prefix\n filtered = out.filter(\n (s) =>\n s.value.startsWith(p) || (s.kind === 'stub' && p.startsWith(s.value))\n )\n }\n filtered.sort(\n (a, b) =>\n (a.kind === b.kind ? 0 : a.kind === 'value' ? -1 : 1) ||\n a.value.localeCompare(b.value)\n )\n return opts.limit ? filtered.slice(0, opts.limit) : filtered\n}\n\n/** Thrown when a predicate exceeds its fuel budget (likely a pathological input). */\nexport class PredicateFuelExhausted extends Error {\n constructor(budget: number) {\n super(`predicate exceeded its fuel budget (${budget})`)\n this.name = 'PredicateFuelExhausted'\n }\n}\n\nexport interface CompilePredicateOptions extends VerifyPredicateOptions {\n /** Max fuel per top-level predicate call (default 1,000,000). */\n fuel?: number\n}\n\n/**\n * Inject `__fuel()` at every function-body entry and comma-wrap expression-body\n * arrows, by splicing at source offsets (no codegen needed). Because loops are\n * rejected, function-entry fuel bounds all iteration: recursion costs fuel per\n * call, and array-method callbacks (`xs.every(p)`) cost fuel per element via the\n * callback's own entry.\n */\nfunction injectFuel(source: string): string {\n const ast = acorn.parse(source, { ecmaVersion: 'latest' }) as any\n // Each edit: [offset, text]. Applied descending so offsets stay valid.\n const edits: Array<[number, string]> = []\n const enterBlockBody = (n: any) => edits.push([n.body.start + 1, '__fuel();'])\n walk.simple(ast, {\n FunctionDeclaration: enterBlockBody,\n FunctionExpression: enterBlockBody,\n ArrowFunctionExpression(n: any) {\n if (n.body.type === 'BlockStatement') {\n edits.push([n.body.start + 1, '__fuel();'])\n } else {\n // expression-body arrow: `x => EXPR` \u2192 `x => (__fuel(), EXPR)`\n edits.push([n.body.start, '(__fuel(), '])\n edits.push([n.body.end, ')'])\n }\n },\n })\n edits.sort((a, b) => b[0] - a[0])\n let out = source\n for (const [off, text] of edits)\n out = out.slice(0, off) + text + out.slice(off)\n return out\n}\n\n/**\n * Verify, then compile the cluster to native synchronous JS functions \u2014\n * **fuel-bounded and global-shadowed**. Throws (with located diagnostics) at\n * definition time if not predicate-safe.\n *\n * Each compiled predicate runs with a fresh fuel budget; a runaway input throws\n * `PredicateFuelExhausted` rather than hanging. The effectful globals are\n * shadowed to `undefined` as defense-in-depth beneath the static verifier.\n *\n * NOTE: preserves JS semantics (no structural-`==` rewrite yet \u2014 a future\n * opt-in). Emission is offset-spliced source, not a full AJS-AST\u2192JS codegen.\n */\nexport function compilePredicate(\n source: string,\n exportNames: string[],\n opts: CompilePredicateOptions = {}\n): Record<string, (...args: any[]) => any> {\n const result = verifyPredicate(source, opts)\n if (!result.safe)\n throw new Error(\n `Not predicate-safe:\\n${formatPredicateDiagnostics(result.diagnostics)}`\n )\n\n const budget = opts.fuel ?? 1_000_000\n const instrumented = injectFuel(source)\n\n // Shadow the effectful globals to undefined (defense-in-depth under the\n // verifier), and inject the fuel hook. `new Function` params shadow globals.\n // Exclude reserved words that can't be parameter names (still verifier-rejected).\n const shadowed = EFFECTFUL_GLOBALS.filter(\n (g) => g !== 'import' && g !== 'eval' && g !== 'arguments'\n )\n const factory = new Function(\n '__fuel',\n ...shadowed,\n `\"use strict\";\\n${instrumented}\\n;return { ${exportNames.join(', ')} };`\n )\n\n let fuel = 0\n const fuelHook = () => {\n if (--fuel < 0) throw new PredicateFuelExhausted(budget)\n }\n const raw = factory(fuelHook, ...shadowed.map(() => undefined))\n\n // Each top-level call gets a fresh budget; inner composed calls share it.\n // A stack overflow (deep recursion past the JS frame limit before fuel runs\n // out) is the same \"runaway\" signal, so normalize it to PredicateFuelExhausted.\n const wrapped: Record<string, (...args: any[]) => any> = {}\n for (const name of exportNames) {\n const fn = raw[name]\n wrapped[name] = (...args: any[]) => {\n fuel = budget\n try {\n return fn(...args)\n } catch (e) {\n if (e instanceof RangeError && /stack/i.test(e.message))\n throw new PredicateFuelExhausted(budget)\n throw e\n }\n }\n }\n return wrapped\n}\n\nexport interface EmitPredicateResult {\n /** True iff the cluster passed predicate-safety verification. */\n safe: boolean\n /**\n * When `safe`, a self-contained JS **expression** that evaluates to the guard\n * function `(...args) => boolean`. Inline it directly into transpiler output \u2014\n * it carries its own fuel counter (no global `__fuel`, no runtime dependency\n * on the predicate engine or the `PredicateFuelExhausted` class). Undefined\n * when `!safe`.\n */\n code?: string\n /** Verifier diagnostics (the reasons, when `!safe`). */\n diagnostics: PredicateDiagnostic[]\n}\n\n/**\n * Verify a predicate cluster and, if safe, emit a **self-contained source\n * expression** for its guard \u2014 the transpile-time counterpart to\n * `compilePredicate` (which evals to live closures). This is what lets a\n * verified `Type`/`FunctionPredicate` predicate compile to a fuel-bounded native\n * guard in standalone output: no import of this module, no shared runtime.\n *\n * Fuel model mirrors `compilePredicate` (function-entry `__fuel()` bounds all\n * iteration since loops are rejected), but because a guard answers a boolean\n * question, a runaway input **returns `false`** (\"not a valid instance of this\n * type\") instead of throwing \u2014 DoS-safe validation that never crashes the caller.\n * A deep-recursion stack overflow is the same runaway signal, normalized the\n * same way.\n *\n * The runtime effectful-global shadow that `compilePredicate` applies is omitted\n * here on purpose: a `safe` cluster provably references no effectful global (the\n * static verifier guarantees it), so the shadow would only bloat emitted output.\n *\n * @param source the predicate cluster (one or more `function` declarations)\n * @param entryName which declared function is the guard entry point\n * @param opts verify options + `fuel` budget (default 1,000,000)\n */\nexport function emitVerifiedPredicate(\n source: string,\n entryName: string,\n opts: CompilePredicateOptions = {}\n): EmitPredicateResult {\n const result = verifyPredicate(source, opts)\n if (!result.safe) {\n return { safe: false, diagnostics: result.diagnostics }\n }\n if (!result.predicates.includes(entryName)) {\n return {\n safe: false,\n diagnostics: [\n {\n predicate: entryName,\n message: `entry predicate '${entryName}' not found in the verified cluster`,\n line: 0,\n column: 0,\n },\n ],\n }\n }\n\n const budget = opts.fuel ?? 1_000_000\n const instrumented = injectFuel(source)\n\n // A self-contained IIFE: fuel counter in a closure, guard entry re-armed per\n // top-level call, runaway (fuel or stack) \u2192 `false`.\n const code =\n `(() => {` +\n `let __f = 0;` +\n `const __fuel = () => { if (--__f < 0) throw new RangeError('tjs:predicate-fuel'); };` +\n `${instrumented}` +\n `return (...__a) => {` +\n `__f = ${budget};` +\n `try { return !!${entryName}(...__a); }` +\n `catch (e) {` +\n `if (e instanceof RangeError && /tjs:predicate-fuel|stack/i.test(e.message)) return false;` +\n `throw e;` +\n `}` +\n `};` +\n `})()`\n\n return { safe: true, code, diagnostics: [] }\n}\n\n// --- $predicate evaluator (#6: the tosijs-schema integration point) ---------\n\nexport interface PredicateEvaluatorOptions extends CompilePredicateOptions {\n /**\n * Called once per source that fails to verify/compile. Default: `console.warn`.\n * The evaluator fails **closed** on such a source (returns `false`), so an\n * unverifiable `$predicate` can never validate a value as `true`.\n */\n onUnsafe?: (source: string, error: Error) => void\n}\n\n/**\n * Build a pluggable `$predicate` evaluator: `(source, value) => boolean`.\n *\n * This is the bridge for a predicate-aware JSON-Schema validator that lives in\n * another package (e.g. `tosijs-schema`, which cannot depend on `tjs-lang` \u2014 the\n * dependency runs the other way). Such a validator stays zero-dep and exposes a\n * hook; a consumer that has this engine injects an evaluator built here.\n *\n * Each distinct source is verified + compiled **once** and cached, so repeated\n * validation is just a native call. Semantics match `compilePredicateSchema`:\n * the LAST top-level function is the entry; a source that isn't predicate-safe\n * (or throws / exhausts fuel at runtime) yields `false` \u2014 never a thrown error\n * mid-validation, never a silent pass.\n */\nexport function createPredicateEvaluator(\n opts: PredicateEvaluatorOptions = {}\n): (source: string, value: unknown) => boolean {\n const { onUnsafe, ...compileOpts } = opts\n const cache = new Map<string, ((value: unknown) => boolean) | null>()\n const warned = new Set<string>()\n\n return (source: string, value: unknown): boolean => {\n let fn = cache.get(source)\n if (fn === undefined) {\n try {\n const names = verifyPredicate(source, compileOpts).predicates\n const entry = names[names.length - 1]\n if (!entry) throw new Error('$predicate declares no function')\n const mod = compilePredicate(source, [entry], compileOpts)\n fn = mod[entry] as (value: unknown) => boolean\n } catch (e) {\n fn = null // fail closed\n if (!warned.has(source)) {\n warned.add(source)\n const err = e instanceof Error ? e : new Error(String(e))\n if (onUnsafe) onUnsafe(source, err)\n else\n console.warn(\n `[tjs-lang] $predicate not verifiable \u2014 failing closed: ${err.message}`\n )\n }\n }\n cache.set(source, fn)\n }\n if (fn === null) return false\n try {\n return fn(value) === true\n } catch {\n return false // fuel exhaustion / runtime miss \u2192 not valid\n }\n }\n}\n", "/**\n * The CSS predicate library \u2014 canonical **source** form.\n *\n * Predicates are authored as source strings, not native functions, because the\n * source is the serializable, portable artifact: it feeds the verifier\n * (`verifyPredicate` \u2014 certifies pure/synchronous/ReDoS-clean), compiles to the\n * native fast path (`compilePredicate`), mines autocomplete (`suggest`), and\n * embeds into JSON Schema's `$predicate` keyword. This is the \"computational\n * half\" JSON Schema and TS structural types can't express \u2014 CSS is the torture\n * test (open value grammars, order-flexible shorthands, recursive structure).\n *\n * Style rules for anything added here (so it stays verifiable):\n * - pure & synchronous: no IO, no `await`, no `new`, no loops (use\n * `every`/`some`/`map`/recursion \u2014 fuel bounds them at function entry);\n * - regexes must be ReDoS-clean (no nested unbounded quantifiers \u2014 the\n * verifier rejects `(a+)+` and friends, so keep character classes flat);\n * - compose with `||` and named predicates as callbacks (`toks.every(isX)`).\n *\n * Phase 1 ships the color grammar. Later phases add lengths/dimensions,\n * shorthands, and the recursive style-object structure \u2014 see TODO.md (#4).\n */\n\n/**\n * The CSS Color Module Level 4 named colors (+ the CSS-wide `transparent` and\n * `currentcolor`), lower-cased. Data, kept in the source so the whole cluster\n * stays serializable as one artifact.\n */\nexport const CSS_NAMED_COLORS = [\n 'transparent',\n 'currentcolor',\n 'aliceblue',\n 'antiquewhite',\n 'aqua',\n 'aquamarine',\n 'azure',\n 'beige',\n 'bisque',\n 'black',\n 'blanchedalmond',\n 'blue',\n 'blueviolet',\n 'brown',\n 'burlywood',\n 'cadetblue',\n 'chartreuse',\n 'chocolate',\n 'coral',\n 'cornflowerblue',\n 'cornsilk',\n 'crimson',\n 'cyan',\n 'darkblue',\n 'darkcyan',\n 'darkgoldenrod',\n 'darkgray',\n 'darkgreen',\n 'darkgrey',\n 'darkkhaki',\n 'darkmagenta',\n 'darkolivegreen',\n 'darkorange',\n 'darkorchid',\n 'darkred',\n 'darksalmon',\n 'darkseagreen',\n 'darkslateblue',\n 'darkslategray',\n 'darkslategrey',\n 'darkturquoise',\n 'darkviolet',\n 'deeppink',\n 'deepskyblue',\n 'dimgray',\n 'dimgrey',\n 'dodgerblue',\n 'firebrick',\n 'floralwhite',\n 'forestgreen',\n 'fuchsia',\n 'gainsboro',\n 'ghostwhite',\n 'gold',\n 'goldenrod',\n 'gray',\n 'green',\n 'greenyellow',\n 'grey',\n 'honeydew',\n 'hotpink',\n 'indianred',\n 'indigo',\n 'ivory',\n 'khaki',\n 'lavender',\n 'lavenderblush',\n 'lawngreen',\n 'lemonchiffon',\n 'lightblue',\n 'lightcoral',\n 'lightcyan',\n 'lightgoldenrodyellow',\n 'lightgray',\n 'lightgreen',\n 'lightgrey',\n 'lightpink',\n 'lightsalmon',\n 'lightseagreen',\n 'lightskyblue',\n 'lightslategray',\n 'lightslategrey',\n 'lightsteelblue',\n 'lightyellow',\n 'lime',\n 'limegreen',\n 'linen',\n 'magenta',\n 'maroon',\n 'mediumaquamarine',\n 'mediumblue',\n 'mediumorchid',\n 'mediumpurple',\n 'mediumseagreen',\n 'mediumslateblue',\n 'mediumspringgreen',\n 'mediumturquoise',\n 'mediumvioletred',\n 'midnightblue',\n 'mintcream',\n 'mistyrose',\n 'moccasin',\n 'navajowhite',\n 'navy',\n 'oldlace',\n 'olive',\n 'olivedrab',\n 'orange',\n 'orangered',\n 'orchid',\n 'palegoldenrod',\n 'palegreen',\n 'paleturquoise',\n 'palevioletred',\n 'papayawhip',\n 'peachpuff',\n 'peru',\n 'pink',\n 'plum',\n 'powderblue',\n 'purple',\n 'rebeccapurple',\n 'red',\n 'rosybrown',\n 'royalblue',\n 'saddlebrown',\n 'salmon',\n 'sandybrown',\n 'seagreen',\n 'seashell',\n 'sienna',\n 'silver',\n 'skyblue',\n 'slateblue',\n 'slategray',\n 'slategrey',\n 'snow',\n 'springgreen',\n 'steelblue',\n 'tan',\n 'teal',\n 'thistle',\n 'tomato',\n 'turquoise',\n 'violet',\n 'wheat',\n 'white',\n 'whitesmoke',\n 'yellow',\n 'yellowgreen',\n]\n\n/**\n * Color predicate cluster (source). Entry points: `isColor` (any CSS color) and\n * `isColorValue` (a color, tolerating a trailing `!important`). Regexes are\n * flat-class (ReDoS-clean). The functional-color forms (`hwb`/`lab`/`lch`/\n * `oklab`/`oklch`/`color`/`color-mix`) are matched by name + balanced parens\n * rather than validating their args \u2014 precise enough for validation, open\n * enough not to reject valid modern CSS.\n */\nexport const CSS_COLOR_SOURCE = `\nvar CSS_NAMED_COLORS = ${JSON.stringify(CSS_NAMED_COLORS)}\n\nfunction isNamedColor(v) {\n return typeof v === 'string' && CSS_NAMED_COLORS.includes(v.toLowerCase())\n}\nfunction isHexColor(v) {\n return typeof v === 'string' && /^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(v)\n}\nfunction isRgbColor(v) {\n return typeof v === 'string' && /^rgba?\\\\(\\\\s*[-0-9.,%\\\\s/]+\\\\)$/i.test(v)\n}\nfunction isHslColor(v) {\n return typeof v === 'string' && /^hsla?\\\\(\\\\s*[-0-9.,%\\\\s/adegr]+\\\\)$/i.test(v)\n}\nfunction isColorFn(v) {\n if (typeof v !== 'string' || !v.endsWith(')')) { return false }\n return v.startsWith('hwb(') || v.startsWith('lab(') || v.startsWith('lch(')\n || v.startsWith('oklab(') || v.startsWith('oklch(')\n || v.startsWith('color(') || v.startsWith('color-mix(')\n}\nfunction isColorVar(v) {\n return typeof v === 'string' && v.startsWith('var(--') && v.endsWith(')')\n}\nfunction isColor(v) {\n return isNamedColor(v) || isHexColor(v) || isRgbColor(v)\n || isHslColor(v) || isColorFn(v) || isColorVar(v)\n}\nfunction isColorValue(v) {\n if (typeof v !== 'string') { return false }\n var bare = v.replace(/\\\\s*!important\\\\s*$/i, '')\n return isColor(bare)\n}\n`\n\n/** Entry predicates exported by the color cluster (for compile/suggest). */\nexport const CSS_COLOR_ENTRIES = [\n 'isColor',\n 'isColorValue',\n 'isNamedColor',\n 'isHexColor',\n 'isRgbColor',\n 'isHslColor',\n] as const\n", "/**\n * CSS dimension / numeric value grammar (phase 2) \u2014 the other big family of leaf\n * values: lengths, percentages, angles, times, resolutions, plain numbers, and\n * the CSS-wide global keywords. Same rules as the color cluster: pure,\n * synchronous, ReDoS-clean (flat character classes / bounded alternation only),\n * with `var(--\u2026)`/`calc(\u2026)` as the open escapes.\n *\n * The numeric core `[+-]?(\\d*\\.\\d+|\\d+)` is a bounded alternation (each branch a\n * single quantifier \u2014 no nesting), so it passes the verifier's ReDoS lint.\n */\n\n/** Absolute + relative + container + viewport length units (CSS Values 4). */\nexport const CSS_LENGTH_UNITS = [\n // font-relative\n 'cap',\n 'ch',\n 'em',\n 'ex',\n 'ic',\n 'lh',\n 'rcap',\n 'rch',\n 'rem',\n 'rex',\n 'ric',\n 'rlh',\n // viewport\n 'vw',\n 'vh',\n 'vi',\n 'vb',\n 'vmin',\n 'vmax',\n 'svw',\n 'svh',\n 'svi',\n 'svb',\n 'svmin',\n 'svmax',\n 'lvw',\n 'lvh',\n 'lvi',\n 'lvb',\n 'lvmin',\n 'lvmax',\n 'dvw',\n 'dvh',\n 'dvi',\n 'dvb',\n 'dvmin',\n 'dvmax',\n // container query\n 'cqw',\n 'cqh',\n 'cqi',\n 'cqb',\n 'cqmin',\n 'cqmax',\n // absolute\n 'px',\n 'cm',\n 'mm',\n 'q',\n 'in',\n 'pt',\n 'pc',\n]\n\n/** CSS-wide keywords valid on any property. */\nexport const CSS_GLOBAL_KEYWORDS = [\n 'inherit',\n 'initial',\n 'unset',\n 'revert',\n 'revert-layer',\n]\n\n/**\n * Dimension predicate cluster (source). Entry points cover each numeric family\n * plus `isDimension` (any of them) and `isGlobalKeyword`. Units are ordered\n * longest-first inside the alternation so e.g. `rem` isn't shadowed by `em`\n * (belt-and-suspenders \u2014 the `$` anchor already forces a full match).\n */\nexport const CSS_DIMENSION_SOURCE = `\nvar CSS_LENGTH_UNITS = ${JSON.stringify(\n // longest-first for safe alternation ordering\n [...CSS_LENGTH_UNITS].sort((a, b) => b.length - a.length)\n)}\nvar CSS_GLOBAL_KEYWORDS = ${JSON.stringify(CSS_GLOBAL_KEYWORDS)}\n\nfunction isCssVar(v) {\n return typeof v === 'string' && v.startsWith('var(--') && v.endsWith(')')\n}\nfunction isCssCalc(v) {\n return typeof v === 'string' && v.startsWith('calc(') && v.endsWith(')')\n}\nfunction isNumber(v) {\n if (typeof v === 'number') { return isFinite(v) }\n return typeof v === 'string' && /^[+-]?(\\\\d*\\\\.\\\\d+|\\\\d+)$/.test(v)\n}\nfunction isInteger(v) {\n if (typeof v === 'number') { return Number.isInteger(v) }\n return typeof v === 'string' && /^[+-]?\\\\d+$/.test(v)\n}\nfunction isPercentage(v) {\n return typeof v === 'string' && /^[+-]?(\\\\d*\\\\.\\\\d+|\\\\d+)%$/.test(v)\n}\nfunction isLength(v) {\n if (v === 0 || v === '0') { return true }\n if (isCssVar(v) || isCssCalc(v)) { return true }\n if (typeof v !== 'string') { return false }\n var m = v.match(/^[+-]?(\\\\d*\\\\.\\\\d+|\\\\d+)([a-z%]+)$/i)\n if (m === null) { return false }\n return CSS_LENGTH_UNITS.includes(m[2].toLowerCase())\n}\nfunction isAngle(v) {\n return typeof v === 'string' && /^[+-]?(\\\\d*\\\\.\\\\d+|\\\\d+)(deg|grad|rad|turn)$/i.test(v)\n}\nfunction isTime(v) {\n return typeof v === 'string' && /^[+-]?(\\\\d*\\\\.\\\\d+|\\\\d+)(ms|s)$/i.test(v)\n}\nfunction isResolution(v) {\n return typeof v === 'string' && /^[+-]?(\\\\d*\\\\.\\\\d+|\\\\d+)(dpi|dpcm|dppx|x)$/i.test(v)\n}\nfunction isGlobalKeyword(v) {\n return typeof v === 'string' && CSS_GLOBAL_KEYWORDS.includes(v.toLowerCase())\n}\nfunction isDimension(v) {\n return isLength(v) || isPercentage(v) || isAngle(v)\n || isTime(v) || isResolution(v) || isNumber(v)\n || isCssVar(v) || isCssCalc(v)\n}\n`\n\n/** Entry predicates exported by the dimension cluster (for compile/suggest). */\nexport const CSS_DIMENSION_ENTRIES = [\n 'isNumber',\n 'isInteger',\n 'isPercentage',\n 'isLength',\n 'isAngle',\n 'isTime',\n 'isResolution',\n 'isGlobalKeyword',\n 'isDimension',\n] as const\n", "/**\n * CSS order-flexible shorthands (phase 3) \u2014 the second torture case from the\n * PoC: a shorthand like `animation` or `transition` is a comma-separated list of\n * layers, each a whitespace-separated bag of tokens whose *order is free*\n * (`3s ease-in 1s infinite alternate slidein` \u2261 any permutation). TS unions and\n * JSON Schema can't express \"a set of tokens, each classifiable, in any order\";\n * a predicate tokenizes and classifies (`toks.every(isAnimToken)`).\n *\n * Built on the dimension leaf cluster (for `isTime`/`isCssVar`/`isCssCalc`).\n * Same rules as the other clusters: pure, synchronous, ReDoS-clean (the split\n * regexes are single-quantifier `\\s+` / `,`; classifier regexes are flat).\n */\nimport type { PredicateSchema } from '../lang/predicate-schema'\nimport { CSS_DIMENSION_SOURCE } from './dimensions'\n\n/**\n * The shorthand classifiers alone (no leaf cluster prepended). Exported so the\n * combined style cluster (`style.ts`) can compose them for property-aware\n * validation without re-including the dimension source.\n */\nexport const CSS_SHORTHAND_FRAGMENT = `\nvar ANIM_TIMING = ['linear','ease','ease-in','ease-out','ease-in-out','step-start','step-end']\nvar ANIM_DIRECTION = ['normal','reverse','alternate','alternate-reverse']\nvar ANIM_FILLMODE = ['none','forwards','backwards','both']\nvar ANIM_PLAYSTATE = ['running','paused']\n\nfunction isTimingFunction(t) {\n if (typeof t !== 'string') { return false }\n if (ANIM_TIMING.includes(t)) { return true }\n return (t.startsWith('cubic-bezier(') || t.startsWith('steps(') || t.startsWith('linear(')) && t.endsWith(')')\n}\nfunction isIterationCount(t) {\n return t === 'infinite' || (typeof t === 'string' && /^[0-9]*\\\\.?[0-9]+$/.test(t))\n}\nfunction isAnimName(t) {\n // any custom-ident (also matches keywords, which classify earlier anyway)\n return typeof t === 'string' && /^-?[a-z_][a-z0-9_-]*$/i.test(t)\n}\n// Tokenize a whole shorthand value. A function token like cubic-bezier(a, b) is\n// kept whole (arg spaces/commas must not split it); top-level commas (layer\n// separators) and whitespace are delimiters, so they're dropped. Loops are\n// banned in predicates, so this is one .match with a FLAT (ReDoS-clean) regex \u2014\n// note a paren-aware comma *splitter* would be a nested quantifier the verifier\n// rejects, so we tokenize instead and guard empty layers separately.\nfunction cssTokens(v) {\n return typeof v === 'string' ? v.match(/[a-z-]+\\\\([^)]*\\\\)|[^\\\\s,]+/gi) : null\n}\n// Reject leading/trailing/double commas (empty layers). Flat, ReDoS-clean.\nfunction hasEmptyLayer(v) {\n return typeof v === 'string' && /^\\\\s*,|,\\\\s*$|,\\\\s*,/.test(v)\n}\nfunction isAnimToken(t) {\n return isTime(t) || isIterationCount(t) || isTimingFunction(t)\n || ANIM_DIRECTION.includes(t) || ANIM_FILLMODE.includes(t) || ANIM_PLAYSTATE.includes(t)\n || isCssVar(t) || isCssCalc(t) || isAnimName(t)\n}\nfunction isAnimation(v) {\n if (typeof v !== 'string' || v.length === 0 || hasEmptyLayer(v)) { return false }\n var toks = cssTokens(v)\n return toks !== null && toks.length > 0 && toks.every(isAnimToken)\n}\n\nfunction isTransitionProperty(t) {\n return t === 'all' || t === 'none' || isAnimName(t)\n}\nfunction isTransitionToken(t) {\n return isTime(t) || isTimingFunction(t) || isCssVar(t) || isCssCalc(t) || isTransitionProperty(t)\n}\nfunction isTransition(v) {\n if (typeof v !== 'string' || v.length === 0 || hasEmptyLayer(v)) { return false }\n var toks = cssTokens(v)\n return toks !== null && toks.length > 0 && toks.every(isTransitionToken)\n}\n`\n\n/**\n * Shorthand predicate cluster (source) = dimension leaves + the shorthand\n * classifiers. Entry predicates: `isAnimation`, `isTransition` (each accepts a\n * comma-separated list of order-free token layers).\n */\nexport const CSS_SHORTHAND_SOURCE =\n CSS_DIMENSION_SOURCE + '\\n' + CSS_SHORTHAND_FRAGMENT\n\n/** Entry predicates exported by the shorthand cluster (for compile/verify). */\nexport const CSS_SHORTHAND_ENTRIES = [\n 'isTimingFunction',\n 'isAnimation',\n 'isTransition',\n] as const\n\n/**\n * A `$predicate` schema for a CSS `animation` shorthand value (entry\n * `isAnimation`). Uses the full cluster source so the entry (last function) is\n * `isTransition` \u2014 so pin the entry via a wrapper source ending in `isAnimation`.\n */\nfunction schemaFor(entry: string): PredicateSchema {\n // The `$predicate` entry is the LAST function; append a thin alias so `entry`\n // is last regardless of its position in the cluster.\n return {\n type: 'string',\n $predicate: `${CSS_SHORTHAND_SOURCE}\\nfunction __entry(v) { return ${entry}(v) }`,\n }\n}\n\n/** `$predicate` schema for a CSS `animation` shorthand value. */\nexport function cssAnimationSchema(): PredicateSchema {\n return { ...schemaFor('isAnimation'), title: 'CSSAnimation' }\n}\n\n/** `$predicate` schema for a CSS `transition` shorthand value. */\nexport function cssTransitionSchema(): PredicateSchema {\n return { ...schemaFor('isTransition'), title: 'CSSTransition' }\n}\n", "/**\n * CSS style-object structure (phase 4) \u2014 the recursive, open shape TS structural\n * types and JSON Schema can't express, and the `$predicate` schemas that carry\n * it. This is the thesis deliverable: a JSON-Schema node whose *structural* part\n * (`type: 'object'`) a naive validator checks, and whose `$predicate` a\n * predicate-aware validator runs to validate the whole recursive CSS structure \u2014\n * progressive enhancement, one serializable artifact.\n *\n * The combined source concatenates the color + dimension leaf clusters and adds\n * the structure predicates, so `isStyleValue`/`isStyleObject` compose the leaves\n * directly. `isStyleObject` is LAST \u2014 the entry the `$predicate` schema runs.\n *\n * Value precision is intentionally two-tier (as in the PoC): the *structure* is\n * validated strictly (keys must be CSS properties or selectors/at-rules; a\n * property maps to a value, a selector to a nested rule), while a generic leaf\n * value falls back to \"non-empty string or finite number\" so a valid-but-\n * unmodelled value (a shorthand, a not-yet-covered property) is never rejected.\n * Per-property precision comes from the specific value schemas (`cssColorSchema`\n * etc.) and, later, property-aware validation (phase 3 shorthands).\n */\nimport type { PredicateSchema } from '../lang/predicate-schema'\nimport { CSS_COLOR_SOURCE } from './predicates'\nimport { CSS_DIMENSION_SOURCE } from './dimensions'\nimport { CSS_SHORTHAND_FRAGMENT } from './shorthands'\n\n/** The recursive structure predicates, layered on the leaf clusters. */\nconst CSS_STRUCTURE_FRAGMENT = `\n// Properties whose value grammar is CLOSED \u2014 a value that fails the leaf\n// predicate is genuinely invalid, so it's safe to enforce (normalized:\n// lower-cased, dashes stripped, so 'background-color' === 'backgroundColor').\nvar CSS_COLOR_PROPS = ['color','backgroundcolor','bordercolor','bordertopcolor','borderrightcolor','borderbottomcolor','borderleftcolor','outlinecolor','caretcolor','columnrulecolor','textdecorationcolor','accentcolor','fill','stroke','floodcolor','stopcolor','lightingcolor']\n\nfunction isCssProperty(k) {\n // custom property (--foo) OR a standard/vendor-prefixed property (-webkit-\u2026).\n return typeof k === 'string' && /^(--[a-z0-9-]+|-?[a-z][a-z0-9-]*)$/i.test(k)\n}\nfunction isSelectorOrAtRule(k) {\n if (typeof k !== 'string' || k.length === 0) { return false }\n if (k.startsWith('@')) { return true }\n return /[ :>~+.#&*\\\\[\\\\]]/.test(k)\n}\nfunction isStyleValue(val) {\n if (typeof val === 'number') { return isFinite(val) }\n if (typeof val !== 'string' || val.length === 0) { return false }\n // Precise recognition for known leaves; permissive tail keeps the whole\n // structure total (a shorthand / unmodelled value is a non-empty string).\n return isColorValue(val) || isDimension(val) || isGlobalKeyword(val)\n || isCssVar(val) || isCssCalc(val) || val.length > 0\n}\nfunction cssPropNorm(prop) {\n return typeof prop === 'string' ? prop.toLowerCase().replace(/-/g, '') : ''\n}\n// Property-AWARE value check: tighten only the closed value grammars (color,\n// animation, transition) \u2014 a wrong value there is a real error; everything else\n// stays permissive (keyword-heavy props like width/display accept idents we don't\n// enumerate, so enforcing would false-reject valid CSS). Universal escapes\n// (global keyword / var() / calc()) are valid on any property.\nfunction isStyleValueFor(prop, val) {\n if (isGlobalKeyword(val) || isCssVar(val) || isCssCalc(val)) { return true }\n var p = cssPropNorm(prop)\n if (CSS_COLOR_PROPS.includes(p)) { return isColorValue(val) }\n if (p === 'animation') { return isAnimation(val) }\n if (p === 'transition') { return isTransition(val) }\n return isStyleValue(val)\n}\nfunction isStyleEntry(pair) {\n var k = pair[0]\n var val = pair[1]\n if (isSelectorOrAtRule(k)) { return isStyleObject(val) }\n if (isCssProperty(k)) { return isStyleValueFor(k, val) }\n return false\n}\nfunction isStyleObject(o) {\n if (typeof o !== 'object' || o === null) { return false }\n return Object.entries(o).every(isStyleEntry)\n}\n`\n\n/**\n * The full CSS style predicate cluster: color + dimension + shorthand leaves +\n * recursive, property-aware structure. Entry = `isStyleObject` (last function).\n * Serializable \u2014 this is exactly what a `$predicate` schema carries.\n */\nexport const CSS_STYLE_SOURCE =\n CSS_COLOR_SOURCE +\n '\\n' +\n CSS_DIMENSION_SOURCE +\n '\\n' +\n CSS_SHORTHAND_FRAGMENT +\n '\\n' +\n CSS_STRUCTURE_FRAGMENT\n\n/** Entry predicates exported by the style cluster (for compile/verify). */\nexport const CSS_STYLE_ENTRIES = [\n 'isCssProperty',\n 'isSelectorOrAtRule',\n 'isStyleValue',\n 'isStyleValueFor',\n 'isStyleObject',\n] as const\n\n/**\n * A `$predicate` JSON-Schema for a CSS style object (\u00E0 la a tosijs styleSpec):\n * naive validators check only `type: 'object'`; predicate-aware validators run\n * `isStyleObject`, validating the whole recursive structure (nested selectors,\n * property/value shapes). Progressive enhancement from one serializable schema.\n */\nexport function cssStyleSchema(): PredicateSchema {\n return {\n type: 'object',\n title: 'CSSStyleObject',\n description:\n 'An open, recursive CSS style object (properties + nested selectors/at-rules).',\n $predicate: CSS_STYLE_SOURCE,\n }\n}\n\n/**\n * A `$predicate` schema for a single CSS **color** value (entry `isColorValue`,\n * so a trailing `!important` is tolerated). Naive validators check `type:\n * 'string'`; aware ones validate the color grammar.\n */\nexport function cssColorSchema(): PredicateSchema {\n return { type: 'string', title: 'CSSColor', $predicate: CSS_COLOR_SOURCE }\n}\n\n/**\n * A `$predicate` schema for a CSS **dimension** value (length/%/angle/time/\n * number; entry `isDimension`). No structural `type` \u2014 a dimension may be a\n * string (`10px`) or a number \u2014 so aware validators do all the work.\n */\nexport function cssDimensionSchema(): PredicateSchema {\n return { title: 'CSSDimension', $predicate: CSS_DIMENSION_SOURCE }\n}\n", "/**\n * `tjs-lang/css` \u2014 CSS validation built from verified-safe predicates.\n *\n * The \"computational half\" of a CSS schema: precise, total validators for the\n * open value grammars TS/JSON-Schema cave to `string` on (colors here in\n * phase 1; lengths, shorthands and the recursive style-object structure land in\n * later phases \u2014 see TODO.md #4). Every validator is compiled from a\n * predicate-safe source cluster (`./predicates`), so it is pure, synchronous,\n * fuel-bounded, and ReDoS-clean \u2014 safe to run on untrusted input.\n *\n * Autocomplete rides the same source: `suggestColor()` mines the named-color set\n * and the open functional stubs (`var(--`, `color-mix(`, \u2026), validating mined\n * values through the compiled predicate so completions are guaranteed valid.\n */\nimport {\n compilePredicate,\n verifyPredicate,\n suggest,\n type PredicateVerifyResult,\n type Suggestion,\n} from '../lang/predicate'\nimport {\n CSS_COLOR_SOURCE,\n CSS_COLOR_ENTRIES,\n CSS_NAMED_COLORS,\n} from './predicates'\nimport {\n CSS_DIMENSION_SOURCE,\n CSS_DIMENSION_ENTRIES,\n CSS_LENGTH_UNITS,\n CSS_GLOBAL_KEYWORDS,\n} from './dimensions'\nimport { CSS_STYLE_SOURCE, CSS_STYLE_ENTRIES } from './style'\nimport { CSS_SHORTHAND_SOURCE, CSS_SHORTHAND_ENTRIES } from './shorthands'\n\nexport {\n CSS_COLOR_SOURCE,\n CSS_COLOR_ENTRIES,\n CSS_NAMED_COLORS,\n} from './predicates'\nexport {\n CSS_DIMENSION_SOURCE,\n CSS_DIMENSION_ENTRIES,\n CSS_LENGTH_UNITS,\n CSS_GLOBAL_KEYWORDS,\n} from './dimensions'\nexport {\n CSS_STYLE_SOURCE,\n CSS_STYLE_ENTRIES,\n cssStyleSchema,\n cssColorSchema,\n cssDimensionSchema,\n} from './style'\nexport {\n CSS_SHORTHAND_SOURCE,\n CSS_SHORTHAND_ENTRIES,\n cssAnimationSchema,\n cssTransitionSchema,\n} from './shorthands'\n\n/** Every predicate-source cluster the library ships, keyed for verify/drift. */\nconst CSS_SOURCES: Record<string, string> = {\n color: CSS_COLOR_SOURCE,\n dimension: CSS_DIMENSION_SOURCE,\n style: CSS_STYLE_SOURCE,\n shorthand: CSS_SHORTHAND_SOURCE,\n}\n\ntype ColorValidators = Record<\n (typeof CSS_COLOR_ENTRIES)[number],\n (v: unknown) => boolean\n>\ntype DimensionValidators = Record<\n (typeof CSS_DIMENSION_ENTRIES)[number],\n (v: unknown) => boolean\n>\n\n// Compiled once, on first use (verification + `new Function` are one-time).\nlet _color: ColorValidators | null = null\nfunction colorValidators(): ColorValidators {\n if (!_color) {\n _color = compilePredicate(\n CSS_COLOR_SOURCE,\n CSS_COLOR_ENTRIES as unknown as string[]\n ) as ColorValidators\n }\n return _color\n}\n\nlet _dimension: DimensionValidators | null = null\nfunction dimensionValidators(): DimensionValidators {\n if (!_dimension) {\n _dimension = compilePredicate(\n CSS_DIMENSION_SOURCE,\n CSS_DIMENSION_ENTRIES as unknown as string[]\n ) as DimensionValidators\n }\n return _dimension\n}\n\ntype StyleValidators = Record<\n (typeof CSS_STYLE_ENTRIES)[number],\n (v: unknown) => boolean\n>\nlet _style: StyleValidators | null = null\nfunction styleValidators(): StyleValidators {\n if (!_style) {\n _style = compilePredicate(\n CSS_STYLE_SOURCE,\n CSS_STYLE_ENTRIES as unknown as string[]\n ) as StyleValidators\n }\n return _style\n}\n\ntype ShorthandValidators = Record<\n (typeof CSS_SHORTHAND_ENTRIES)[number],\n (v: unknown) => boolean\n>\nlet _shorthand: ShorthandValidators | null = null\nfunction shorthandValidators(): ShorthandValidators {\n if (!_shorthand) {\n _shorthand = compilePredicate(\n CSS_SHORTHAND_SOURCE,\n CSS_SHORTHAND_ENTRIES as unknown as string[]\n ) as ShorthandValidators\n }\n return _shorthand\n}\n\n/** Is `v` a valid CSS color (named, hex, rgb/hsl, modern fn, or `var(--\u2026)`)? */\nexport const isColor = (v: unknown): boolean => colorValidators().isColor(v)\n/** Like {@link isColor}, but tolerates a trailing `!important`. */\nexport const isColorValue = (v: unknown): boolean =>\n colorValidators().isColorValue(v)\n/** Is `v` a CSS named color (incl. `transparent`/`currentcolor`)? */\nexport const isNamedColor = (v: unknown): boolean =>\n colorValidators().isNamedColor(v)\n/** Is `v` a CSS hex color (`#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`)? */\nexport const isHexColor = (v: unknown): boolean =>\n colorValidators().isHexColor(v)\n\n// --- dimensions / numbers / keywords (phase 2) ------------------------------\n\n/** Is `v` a CSS `<length>` (unit'd, unitless `0`, or `var()`/`calc()`)? */\nexport const isLength = (v: unknown): boolean =>\n dimensionValidators().isLength(v)\n/** Is `v` a CSS `<percentage>` (`50%`)? */\nexport const isPercentage = (v: unknown): boolean =>\n dimensionValidators().isPercentage(v)\n/** Is `v` a CSS `<number>` (numeric, or a numeric string)? */\nexport const isNumber = (v: unknown): boolean =>\n dimensionValidators().isNumber(v)\n/** Is `v` a CSS `<integer>`? */\nexport const isInteger = (v: unknown): boolean =>\n dimensionValidators().isInteger(v)\n/** Is `v` a CSS `<angle>` (`45deg`, `1turn`, `1.5rad`, `100grad`)? */\nexport const isAngle = (v: unknown): boolean => dimensionValidators().isAngle(v)\n/** Is `v` a CSS `<time>` (`200ms`, `1s`)? */\nexport const isTime = (v: unknown): boolean => dimensionValidators().isTime(v)\n/** Is `v` any CSS dimension/number (length, %, angle, time, resolution, number)? */\nexport const isDimension = (v: unknown): boolean =>\n dimensionValidators().isDimension(v)\n/** Is `v` a CSS-wide keyword (`inherit`/`initial`/`unset`/`revert`/`revert-layer`)? */\nexport const isGlobalKeyword = (v: unknown): boolean =>\n dimensionValidators().isGlobalKeyword(v)\n\n// --- recursive style-object structure (phase 4) -----------------------------\n\n/**\n * Is `v` a valid CSS **style object** \u2014 an open, recursive map of CSS properties\n * to values and selectors/at-rules to nested style objects? Validates the whole\n * structure (keys are properties or selectors; property values are style values,\n * selector values are nested rules), recursively and fuel-bounded. This is the\n * shape TS/JSON-Schema can't express.\n */\nexport const isStyleObject = (v: unknown): boolean =>\n styleValidators().isStyleObject(v)\n/** Is `v` a valid leaf CSS value (a known color/dimension/keyword, else a non-empty string / finite number)? */\nexport const isStyleValue = (v: unknown): boolean =>\n styleValidators().isStyleValue(v)\n/**\n * Property-AWARE leaf check: given the property name, tightens the closed value\n * grammars (color/animation/transition) so `isStyleValueFor('color', 'notacolor')`\n * is `false` while `isStyleValueFor('padding', 'anything')` stays permissive.\n * This is what makes {@link isStyleObject} catch real value errors.\n */\nexport const isStyleValueFor = (prop: unknown, val: unknown): boolean =>\n (styleValidators().isStyleValueFor as (p: unknown, v: unknown) => boolean)(\n prop,\n val\n )\n/** Is `k` a CSS property name (`color`, `--custom`, `-webkit-foo`)? */\nexport const isCssProperty = (k: unknown): boolean =>\n styleValidators().isCssProperty(k)\n/** Is `k` a selector or at-rule key (nests a rule) rather than a property? */\nexport const isSelectorOrAtRule = (k: unknown): boolean =>\n styleValidators().isSelectorOrAtRule(k)\n\n// --- order-flexible shorthands (phase 3) ------------------------------------\n\n/** Is `v` a valid CSS `animation` shorthand (comma-separated, order-free tokens)? */\nexport const isAnimation = (v: unknown): boolean =>\n shorthandValidators().isAnimation(v)\n/** Is `v` a valid CSS `transition` shorthand (comma-separated layers)? */\nexport const isTransition = (v: unknown): boolean =>\n shorthandValidators().isTransition(v)\n/** Is `v` a CSS `<easing-function>` (keyword, `cubic-bezier(\u2026)`, `steps(\u2026)`, `linear(\u2026)`)? */\nexport const isTimingFunction = (v: unknown): boolean =>\n shorthandValidators().isTimingFunction(v)\n\n/**\n * Verify every CSS predicate-source cluster is predicate-safe (pure,\n * synchronous, ReDoS-clean). Returns the combined result (safe iff all clusters\n * are; diagnostics carry the cluster name). Always safe for the shipped source \u2014\n * exposed so downstream tools (and the drift test) can assert it, and so a\n * consumer embedding a source in a `$predicate` schema can re-check before\n * trusting it.\n */\nexport function verifyCss(): PredicateVerifyResult {\n const predicates: string[] = []\n const diagnostics: PredicateVerifyResult['diagnostics'] = []\n for (const [name, source] of Object.entries(CSS_SOURCES)) {\n const r = verifyPredicate(source)\n predicates.push(...r.predicates)\n for (const d of r.diagnostics)\n diagnostics.push({ ...d, predicate: `${name}:${d.predicate}` })\n }\n return { safe: diagnostics.length === 0, predicates, diagnostics }\n}\n\n/**\n * Autocomplete candidates for a CSS color value. Returns concrete named colors\n * (validated through the compiled predicate) plus open-ended stubs mined from\n * the functional forms (`var(--`, `color-mix(`, `oklch(`, \u2026). Prefix-filtered.\n */\nexport function suggestColor(prefix = '', limit = 50): Suggestion[] {\n return suggest(CSS_COLOR_SOURCE, {\n entry: 'isColor',\n prefix,\n limit,\n })\n}\n"],
|
|
5
|
+
"mappings": "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UACA,aACA,eACA,gBACA,gBACA,gBACA,gBACA,aACA,WACA,cACA,UACA,UACA,aACA,YACA,cACA,cACA,UACA,YACA,aACA,OACA,YACA,OACA,QACA,cACA,OACA,WACA,UACA,YACA,SACA,QACA,QACA,WACA,gBACA,YACA,eACA,YACA,aACA,YACA,uBACA,YACA,aACA,YACA,YACA,cACA,gBACA,eACA,iBACA,iBACA,iBACA,cACA,OACA,YACA,QACA,UACA,SACA,mBACA,aACA,eACA,eACA,iBACA,kBACA,oBACA,kBACA,kBACA,eACA,YACA,YACA,WACA,cACA,OACA,UACA,QACA,YACA,SACA,YACA,SACA,gBACA,YACA,gBACA,gBACA,aACA,YACA,OACA,OACA,OACA,aACA,SACA,gBACA,MACA,YACA,YACA,cACA,SACA,aACA,WACA,WACA,SACA,SACA,UACA,YACA,YACA,YACA,OACA,cACA,YACA,MACA,OACA,UACA,SACA,YACA,SACA,QACA,QACA,aACA,SACA,aACF,EAUaC,EAAmB;AAAA,yBACP,KAAK,UAAUD,CAAgB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmC5CE,EAAoB,CAC/B,UACA,eACA,eACA,aACA,aACA,YACF,EC3NO,IAAMC,EAAmB,CAE9B,MACA,KACA,KACA,KACA,KACA,KACA,OACA,MACA,MACA,MACA,MACA,MAEA,KACA,KACA,KACA,KACA,OACA,OACA,MACA,MACA,MACA,MACA,QACA,QACA,MACA,MACA,MACA,MACA,QACA,QACA,MACA,MACA,MACA,MACA,QACA,QAEA,MACA,MACA,MACA,MACA,QACA,QAEA,KACA,KACA,KACA,IACA,KACA,KACA,IACF,EAGaC,EAAsB,CACjC,UACA,UACA,QACA,SACA,cACF,EAQaC,EAAuB;AAAA,yBACX,KAAK,UAE5B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",
|
|
6
|
+
"names": ["acorn", "walk", "PURE_GLOBALS", "PURE_NAMESPACES", "EFFECTFUL_STATICS", "unboundedQuantifierLen", "pattern", "pos", "c", "len", "m", "reDoSRisk", "stack", "i", "inClass", "frame", "qlen", "PURE_INSTANCE_METHODS", "EFFECTFUL_GLOBALS", "verifyPredicate", "source", "opts", "effectful", "EFFECTFUL_GLOBALS", "ast", "e", "predicateNames", "node", "diagnostics", "fn", "pname", "flag", "message", "n", "loop", "risk", "reDoSRisk", "callee", "name", "PURE_GLOBALS", "method", "recv", "PURE_NAMESPACES", "EFFECTFUL_STATICS", "PURE_INSTANCE_METHODS", "formatPredicateDiagnostics", "d", "x", "isStringLiteral", "suggest", "values", "stubs", "el", "arg", "accept", "verified", "entry", "compilePredicate", "v", "out", "s", "filtered", "p", "a", "b", "PredicateFuelExhausted", "budget", "injectFuel", "edits", "enterBlockBody", "off", "text", "exportNames", "result", "instrumented", "shadowed", "g", "factory", "fuel", "raw", "wrapped", "args", "CSS_NAMED_COLORS", "CSS_COLOR_SOURCE", "CSS_COLOR_ENTRIES", "CSS_LENGTH_UNITS", "CSS_GLOBAL_KEYWORDS", "CSS_DIMENSION_SOURCE", "a", "b", "CSS_DIMENSION_ENTRIES", "CSS_SHORTHAND_FRAGMENT", "CSS_SHORTHAND_SOURCE", "CSS_DIMENSION_SOURCE", "CSS_SHORTHAND_ENTRIES", "schemaFor", "entry", "cssAnimationSchema", "cssTransitionSchema", "CSS_STRUCTURE_FRAGMENT", "CSS_STYLE_SOURCE", "CSS_COLOR_SOURCE", "CSS_DIMENSION_SOURCE", "CSS_SHORTHAND_FRAGMENT", "CSS_STYLE_ENTRIES", "cssStyleSchema", "cssColorSchema", "cssDimensionSchema", "CSS_SOURCES", "CSS_COLOR_SOURCE", "CSS_DIMENSION_SOURCE", "CSS_STYLE_SOURCE", "CSS_SHORTHAND_SOURCE", "_color", "colorValidators", "compilePredicate", "CSS_COLOR_ENTRIES", "_dimension", "dimensionValidators", "CSS_DIMENSION_ENTRIES", "_style", "styleValidators", "CSS_STYLE_ENTRIES", "_shorthand", "shorthandValidators", "CSS_SHORTHAND_ENTRIES", "isColor", "v", "isColorValue", "isNamedColor", "isHexColor", "isLength", "isPercentage", "isNumber", "isInteger", "isAngle", "isTime", "isDimension", "isGlobalKeyword", "isStyleObject", "isStyleValue", "isStyleValueFor", "prop", "val", "isCssProperty", "k", "isSelectorOrAtRule", "isAnimation", "isTransition", "isTimingFunction", "verifyCss", "predicates", "diagnostics", "name", "source", "r", "verifyPredicate", "d", "suggestColor", "prefix", "limit", "suggest"]
|
|
7
|
+
}
|