fscss 1.1.21 → 1.1.23

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/exec.js CHANGED
@@ -1,2 +1,1733 @@
1
- /* Figsh-fscss light, source v3., fscss.devtem.org */
2
- function exec({type:e="text",content:n,onError:r,onSuccess:t}){if(!n){const e="No CSS content or URL provided.";return console.error(`[FSCSS] ${e}`),void(r&&r(e))}const s=document.createElement("style"),o=e=>{s.textContent=e,document.head.appendChild(s),t&&t(s),xfscssProcessorWrap()},c=["text","auto","text/fscss","text/css"].includes(e),i=["fromUrl","URL","fromURL","link"].includes(e);if(c)o(n);else if(i)fetch(n).then((e=>{if(!e.ok)throw new Error(`HTTP ${e.status}: ${e.statusText}`);return e.text()})).then(o).catch((e=>{const t=`Failed to load CSS from: ${n}. ${e.message}`;console.error(`[FSCSS] ${t}`),r&&r(t)}));else{const n=`Unsupported type "${e}". Use "text" or "fromUrl".`;console.error(`[FSCSS] ${n}`),r&&r(n)}}function xfscssProcessorWrap(){(async()=>{function e(e){return e.replace(/count\(\s*([\d\.]+)\s*(?:,\s*([\d\.]+)?)?\)/g,((e,n,r)=>{return null===r&&(r=1),t=parseInt(n),s=parseInt(r||1),`${Array(t).fill().map(((e,n)=>(n+1)*s))}`;var t,s}))}function n(e){return e.replace(/length\((?:([^\)]+)|\s*"([^"]*)"\s*|\s*'([^']*)'\s*)\)/g,((e,n,r,t)=>(n||r||t).length))}function r(e){return e.replace(/num\((.*?)\)/g,((e,n)=>{try{return function(e){const n=e.replace(/\s+/g,"");let r=0;function t(){let e=s();for(;r<n.length&&("+"===n[r]||"-"===n[r]);){const t=n[r++],o=s();e="+"===t?e+o:e-o}return e}function s(){let e=o();for(;r<n.length&&("*"===n[r]||"/"===n[r]);){const t=n[r++],s=o();e="*"===t?e*s:e/s}return e}function o(){let e=c();if(r<n.length&&"*"===n[r]&&"*"===n[r+1]){r+=2;const n=c();return Math.pow(e,n)}return e}function c(){return"-"===n[r]?(r++,-i()):"+"===n[r]?(r++,i()):i()}function i(){if("("===n[r]){r++;const e=t();if(")"!==n[r])throw new Error("Missing closing )");return r++,e}const e=n.slice(r).match(/^[0-9]*\.?[0-9]+/);if(!e)throw new Error(`Unexpected token at pos ${r}: "${n[r]}"`);return r+=e[0].length,parseFloat(e[0])}const a=t();if(r!==n.length)throw new Error(`Unexpected token: "${n[r]}"`);return a}(n)}catch(e){return console.error("Invalid math expression:",n),n}}))}const t={},s={},o={},c=new Set,i=new Set;function a(e,n){let r=0,t=n;for(;t<e.length&&("{"===e[t]?r++:"}"===e[t]&&r--,0!==r);)t++;return e.slice(n,t+1)}function l(e){const n=[],r=/(if|el-if|el)\s*([^{}]*?)\s*\{([\s\S]*?)\}/g;let t;for(;null!==(t=r.exec(e));)n.push({type:t[1],condition:t[2].trim(),block:t[3].trim()});return n}function f(e){let n="";const r=e.replace(/exec\((_log|_error|_warn|_info),\s*(?:"([^"]*)"|'([^']*)'|([^)]*))\)/g,((e,r,t,s,o)=>{const c=t||s||o;return["_log","_error","_warn","_info"].includes(r)?c?(n+=`console.${r.slice(1)}("${c.replace(/"/g,'\\"')}");\n`,""):(console.warn(`fscss[exec(console)]: Empty argument for method: ${r}`),""):(console.warn(`fscss[exec(console)]: Unsupported method: ${r}`),"")}));if(n)try{new Function(n)()}catch(e){console.error("fscss[exec(console)]: Error executing transformed code:",e)}return r}function u(e){const n={},r=/@event\s+([\w-]+)\(([^)]*)\)\s*:?{/g;let t,s=e;const o=[];for(;null!==(t=r.exec(e));){const r=t[1],s=t[2],c=t.index+t[0].length-1;if(c>=e.length){console.warn(`fscss[parsing] Warning: Unexpected end of CSS after @event ${r} definition.`);continue}const i=a(e,c);if(0===i.length||"}"!==i[i.length-1]){console.warn(`fscss[parsing] Warning: Malformed block for @event '${r}'. Missing closing '}'.`);continue}e.slice(t.index,c+i.length);const f=l(i),u=s.split(",").map((e=>e.trim())).filter((e=>""!==e));n[r]&&console.warn(`fscss[definition] Warning: Duplicate @event definition for '${r}'. The last one will be used.`),n[r]={args:u,conditionBlocks:f},o.push([t.index,c+i.length])}for(let e=o.length-1;e>=0;e--){const[n,r]=o[e];s=s.slice(0,n)+s.slice(r)}return s=s.replace(/@event\.([\w-]+)\(([^)]*)\)/g,((e,r,t)=>{const s=n[r];if(!s)return console.warn(`fscss[call] Warning: @event function '${r}' not found during call.`),e;const o={},c=t.split(",").map((e=>e.trim())).filter((e=>""!==e));c.length!==s.args.length&&console.warn(`fscss[call] Warning: Argument count mismatch for @event '${r}'. Expected ${s.args.length}, got ${c.length}.`),s.args.forEach(((e,n)=>{void 0!==c[n]?o[e]=c[n]:console.warn(`fscss[call] Warning: Missing value for argument '${e}' in @event '${r}' call.`)}));let i="",a=!1,l=!1;for(const e of s.conditionBlocks)if("el"===e.type&&(l&&console.warn(`fscss[logic] Warning: Multiple 'el' (else) blocks found in @event '${r}'. Only the first 'el' block will be considered.`),l=!0),!a||"el"===e.type){if("el"===e.type){if(a)continue;a=!0}else{const n=e.condition.split(",").map((e=>e.trim())).filter((e=>""!==e));0===n.length?(console.warn(`fscss[logic] Warning: Empty condition in '${e.type}' block for @event '${r}'.`),a=!0):a=n.every((e=>{const n=e.match(/^(\w+)\s*(==|!=|>=|<=|>|<)\s*([^]+)$/);if(!n){const n=e.split(":").map((e=>e.trim()));if(2!==n.length)return console.warn(`fscss[logic] Warning: Malformed condition '${e}' in @event '${r}'. Expected 'variable operator value' or 'variable:value'.`),!1;const[t,s]=n;return t in o?o[t]===s:(console.warn(`fscss[logic] Warning: Condition variable '${t}' not provided in @event '${r}' context. Treating as false.`),!1)}{const[,e,t,s]=n;if(!(e in o))return console.warn(`fscss[logic] Warning: Condition variable '${e}' not provided in @event '${r}' context. Treating as false.`),!1;const c=o[e],i=isNaN(c)?c:Number(c),a=isNaN(s)?s:Number(s);switch(t){case"==":return i==a;case"!=":return i!=a;case">":return i>a;case"<":return i<a;case">=":return i>=a;case"<=":return i<=a;default:return!1}}}))}if(a){const n=e.block.match(/(\w+)\s*(?:\:\s*([^;]*);?|\|([^\|]+)\|?)/);n&&n[2]?i=n[2].trim():n&&n[3]?i=n[3].trim():console.warn(`fscss[logic] Warning: No valid CSS property assignment found in matched block for @event '${r}'. Block content: '${e.block}'.`);break}}return!i&&s.conditionBlocks.length>0&&!a?console.warn(`fscss[call] Warning: No condition matched for @event '${r}' with provided arguments. Returning original call string.`):i||0!==s.conditionBlocks.length||console.warn(`fscss[definition] Warning: @event '${r}' has no condition blocks defined. Returning original call string.`),i||e})),s.trim()}async function p(e){return(e=(e=(e=(e=e.replace(/exec\(\s*_init\sisjs\s*\)/g,"exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/isjs.fscss)")).replace(/exec\(\s*_init\sthemes\s*\)/g,"exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/trshapes.fthemes.fscss)")).replace(/exec\(_init\sarray1to500\s*\)/g,"exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/1to500.fscss)")).replace(/exec\(_init\s+([\w\d\._—\-\%\*\+\&\$\=]+)(?:\/([\w\-]+))?\s*\)/g,((e,n,r)=>r?`exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${n}.${r})`:`exec(https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${n}.fscss)`))).replace(/(\@import\((?:\s+)?(?:exec)?\((?:[\w\d\.\@\—\-_*\#\$\s\,]+)\)(?:\s+)?from(?:\s+)?)([\w\d\._—\-\%\*\+\&\$\=]+)(?:\/([\w\-]+))?(?:\s+)?\)/g,((e,n,r,t)=>t?`${n}'https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${r}.${t}')`:`${n}'https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/${r}.fscss')`))}function $(e){const n=/@define\s+([\w\_\-\—]+)\s*\(([^)]*)\)\s*\$?\{\s*(?:"([^"]*)"|'([^']*)'|`([^`]*)`|([^\}^\{]*?))\s*\}/g;let r=e.replace(n,((e,n,r,t,s,c,i)=>{const a=r.split(",").map((e=>e.trim())).filter((e=>e)),l=t??s??c??i??"";return o[n]={params:a,body:l},""}));return r=r.replace(/@([\w\_\-\—]+)\s*\(([\s\S]*?)\)/g,((e,n,r)=>{const t=o[n];if(!t)return e;const s=r?.split(",").map((e=>e.trim()));""===s[0]&&(s[0]=void 0);let c=t.body,i=[];return t.params.forEach(((e,n)=>{const r=t.params[n];r&&r.includes(":")&&(i=r?.split(":")?.map((e=>e.trim())).filter((e=>e)));const o=i[1]?i[1]:"",a=void 0!==s[n]?s[n]:o,l=new RegExp(`@use\\(\\s*${e.replace(/(\s+)?(\:(\s+)?.*)/g,"")}\\s*\\)`,"g");c=c.replace(l,a)})),c})),n.test(r)?$(r):r}function d(e){let n={},r=e;return r=r.replace(/("(?:[^"\\]|\\.)*")|('(?:[^'\\]|\\.)*')/g,(function(e){let r=e[0],t=e.slice(1,-1);const s=/@ext\((-?\d+),(\d+):\s*([^)]+)\)/g;let o,c=[];for(;null!==(o=s.exec(t));)c.push({fullMatch:o[0],start:parseInt(o[1]),length:parseInt(o[2]),varName:o[3].trim(),index:o.index});for(let e=c.length-1;e>=0;e--){let r=c[e],s=r.start<0?t.length+r.start:r.start;s=Math.max(0,s);let o=t.substring(s,s+r.length);(s+r.length>t.length||s<0)&&console.warn(`fscss:[@ext]Warning: @ext directive for variable '${r.varName}' in string literal specifies an out-of-bounds range. Extraction may be incomplete or incorrect.`),void 0!==n[r.varName]&&console.warn(`fscss:[@ext]Warning: Duplicate variable name '${r.varName}' found in string literal. The last extracted value will be used.`),n[r.varName]=o,t=t.slice(0,r.index)+t.slice(r.index+r.fullMatch.length)}return r+t+r})),r=r.replace(/([#.\w-]+)\s*@ext\((-?\d+),(\d+):\s*([^)]+)\)/g,(function(e,r,t,s,o){t=parseInt(t),s=parseInt(s),o=o.trim();let c=t<0?r.length+t:t;c=Math.max(0,c);let i=r.substring(c,c+s);return(c+s>r.length||c<0)&&console.warn(`fscss:[@ext]Warning: @ext directive for variable '${o}' on token '${r}' specifies an out-of-bounds range. Extraction may be incomplete or incorrect.`),void 0!==n[o]&&console.warn(`fscss:[@ext]Warning: Duplicate variable name '${o}' found outside string literals. The last extracted value will be used.`),n[o]=i,r})),r=r.replace(/@ext\.(\w+)\!?/g,(function(e,r){return void 0===n[r]?(console.warn(`fscss:[@ext]Warning: Reference to undefined variable '@ext.${r}'. It will not be replaced.`),e):n[r]})),r}function g(e){const n=/@arr\(?\s*([\w\-_—0-9]+)\)?\[([^\]]+)\]\)?/g;let r;for(;null!==(r=n.exec(e));){const e=r[1],n=r[2].split(",").map((e=>e.trim()));t[e]=n}let s=e;return s=s.replace(/@arr\.([\w\-_—0-9]+)(?:\!\s*\+\s*\[([^\]]+)?\])/g,((e,n,r)=>t[n]?r?(newItems=r.split(",").map((e=>e.trim())),t[n].push(...newItems),""):(console.warn(`[FSCSS Warning] @arr push failed → Invalid or empty value at "${e}"`),e):(console.warn(`fscss[@arr] Warning: Array '${n}' not found.`),e))),s=s.replace(/@arr\.([\w\-_—0-9]+)(?:\!\s*\-\s*\[([\d\w\-_—\s]+)?\])/g,((e,n,r)=>{const s=t[n];return s?!(r=Number(r?.trim()))||r<1||!Number(r)?(console.warn(`[FSCSS Warning] @arr splice failed → Invalid or empty index at "${e}"`),e):r>s.length?(console.warn(`[FSCSS Warning] @arr → @arr.${n}[${r}] is undefined at "${e}"`),""):(r-=1,s.splice(r,1),""):(console.warn(`fscss[@arr] Warning: Array '${n}' not found.`),e)})),s=s.replace(/@arr\.([\w\-_—0-9]+)(?:\!\s*\.(length|last|reverse|first|list|indices|randint|segment|sum|unique|sort|shuffle|min|max))/g,((e,n,r)=>{const s=t[n];if(!s)return console.warn(`fscss[@arr] Warning: Array '${n}' not found.`),e;if(r){if("length"===r)return s.length;if("first"===r)return s[0];if("last"===r)return s.at(-1);if("indices"===r)return Array(s.length).fill().map(((e,n)=>1*(n+1)));if("list"===r)return s.join(",");if("reverse"===r)return s.toReversed().join(",");if("randint"===r)return s[Math.floor(Math.random()*s.length)];if("segment"===r)return s.map((e=>`[${e}]`)).join("");if("unique"===r)return[...new Set(s)].join(",");if("sort"===r)return s.slice().sort().join(",");if("shuffle"===r)return s.slice().sort((()=>Math.random()-.5)).join(",");if("sum"===r)return s.reduce(((e,n)=>e+Number(n)),0);if("min"===r)return Math.min(...s.map(Number));if("max"===r)return Math.max(...s.map(Number))}})),s=s.replace(/([^\{\}]+)\{\s*([^}]*@arr\.([\w\-_—0-9]+)\[\][^}]*)\s*\}/g,((e,n,r,s)=>{const o=t[s];return o?o.map(((e,t)=>{const o=n.replace(new RegExp(`@arr\\.${s}\\[\\]`,"g"),t+1),c=r.replace(new RegExp(`@arr\\.${s}\\[\\]`,"g"),e);return`${o.trim()} {\n ${c.trim()}\n}`})).join("\n"):(console.warn(`fscss[@arr] Warning: Array '${s}' not found for loop processing.`),e)})),s=s.replace(/@arr\.([\w\-_—0-9]+)\[(\d+)\]/g,((e,n,r)=>{const s=parseInt(r)-1,o=t[n];return o?void 0!==o[s]?o[s]:e:(console.warn(`fscss[@arr] Warning: Array '${n}' not found.`),e)})),s=s.replace(/@arr\.([\w\-_—0-9]+)(?:!\s*\.unit)(?:\(([^)]*)\))/g,((e,n,r)=>{const s=t[n];if(!s)return console.warn(`fscss[@arr] Warning: Array '${n}' not found for direct access.`),e;const o=void 0!==r&&""!==r?r:" ";return s.map((e=>`${e+o}`)).join(",")})),s=s.replace(/@arr\.([\w\-_—0-9]+)(?:!\s*\.prefix)(?:\(([^)]*)\))/g,((e,n,r)=>{const s=t[n];if(!s)return console.warn(`fscss[@arr] Warning: Array '${n}' not found for direct access.`),e;const o=void 0!==r&&""!==r?r:" ";return s.map((e=>`${o+e}`)).join(",")})),s=s.replace(/@arr\.([\w\-_—0-9]+)(?:!\s*\.surround)(?:\(([^)]+)\))/g,((e,n,r)=>{const s=t[n];return s?r&&void 0!==r&&""!==r&&r.includes(",")?(surArr=r.split(","),s.map((e=>`${surArr[0]+e+surArr.at(-1)}`)).join(" ")):(console.warn(`[FSCSS Warning] @arr surround failed → Invalid or empty value at "${e}"`),e):(console.warn(`fscss[@arr] Warning: Array '${n}' not found for direct access.`),e)})),s=s.replace(/@arr\.([\w\-_—0-9]+)(?:!\s*\.join)?(?:\(([^)]*)\))/g,((e,n,r)=>{const s=t[n];if(!s)return console.warn(`fscss[@arr] Warning: Array '${n}' not found for direct access.`),e;const o=void 0!==r&&""!==r?r:" ";return s.join(o)})),s=s.replace(/@arr\.([\w\-_—0-9]+)(!)?/g,((e,n,r)=>{const s=t[n];return s?r?e:`[${s.join(",")}]`:(console.warn(`fscss[@arr] Warning: Array '${n}' not found for direct access.`),e)})),s.replace(n,"").replace(/\n{3,}/g,"\n\n").trim()}function m(e){const n={},r=/@fun\(([\w\-\_\—0-9]+)\)\s*\{([\s\S]*?)\}\s*/g;function t(e){const n={},r=e.split(";");for(let e of r){if(e=e.trim(),!e)continue;const r=e.indexOf(":");if(-1===r){console.warn(`fscss[@fun] Invalid style line (missing colon): "${e}"`);continue}const t=e.substring(0,r).trim(),s=e.substring(r+1).trim();t?n[t]=s:console.warn(`fscss[@fun] Empty property name in line: "${e}"`)}return n}let s;for(;null!==(s=r.exec(e));){const e=s[1],r=s[2].trim();n[e]&&console.warn(`fscss[@fun] Duplicate @fun variable declaration: "${e}". The last one will overwrite previous declarations.`),n[e]={raw:r,props:t(r)}}let o=e;return o=o.replace(/@fun\.([\w\-\_\—0-9]+)\.([\w\-\_\—0-9]+)\.value\!?/g,((e,r,t)=>n[r]&&n[r].props[t]?n[r].props[t]:(console.warn(`fscss[@fun] Value extraction failed for "@fun.${r}.${t}.value". Variable or property not found.`),e))),o=o.replace(/@fun\.([\w\-\_\—0-9]+)\.([\w\-\_\—0-9]+)\!?/g,((e,r,t)=>n[r]&&n[r].props[t]?`${t}: ${n[r].props[t]};`:(console.warn(`fscss[@fun] Single property rule failed for "@fun.${r}.${t}". Variable or property not found.`),e))),o=o.replace(/@fun\.([\w\-\_\—0-9]+)(?=[\s;}])\!?/g,((e,r)=>n[r]?n[r].raw:(console.warn(`[@fun] Full variable block replacement failed for "@fun.${r}". Variable not found.`),e))),o=o.replace(r,""),o=o.replace(/^\s*[\r\n]/gm,""),o=o.trim(),o}function w(e){const n={},r=/@obj\s+([\w\-\_\—0-9]+)\s*\{([\s\S]*?)\}\s*/g;function t(e){const n={},r=e.split(";");for(let e of r){if(e=e.trim(),!e)continue;const r=e.indexOf(":");if(-1===r){console.warn(`fscss[@obj] Invalid style line (missing colon): "${e}"`);continue}const t=e.substring(0,r).trim(),s=e.substring(r+1).trim();t?n[t]=s:console.warn(`fscss[@obj] Empty property name in line: "${e}"`)}return n}let s;for(;null!==(s=r.exec(e));){const e=s[1],r=s[2].trim();n[e]&&console.warn(`fscss[@obj] Duplicate @obj variable declaration: "${e}". The last one will overwrite previous declarations.`),n[e]={raw:r,props:t(r)}}let o=e;return o=o.replace(/@obj\.([\w\-\_\—0-9]+)\.([\w\-\_\—0-9]+)\.value\!?/g,((e,r,t)=>n[r]&&n[r].props[t]?n[r].props[t]:(console.warn(`fscss[@obj] Value extraction failed for "@obj.${r}.${t}.value". Variable or property not found.`),e))),o=o.replace(/@obj\.([\w\-\_\—0-9]+)\.([\w\-\_\—0-9]+)\!?/g,((e,r,t)=>n[r]&&n[r].props[t]?`${t}: ${n[r].props[t]};`:(console.warn(`fscss[@obj] Single property rule failed for "@obj.${r}.${t}". Variable or property not found.`),e))),o=o.replace(/@obj\.([\w\-\_\—0-9]+)(?=[\s;}])\!?/g,((e,r)=>n[r]?n[r].raw:(console.warn(`[@obj] Full variable block replacement failed for "@obj.${r}". Variable not found.`),e))),o=o.replace(r,""),o=o.replace(/^\s*[\r\n]/gm,""),o=o.trim(),o}function h(e){const n=new Set,r=e.replace(/(:\s*)(["']?)(.*?)(["']?)\s*copy\(([-]?\d+),\s*([^\;^\)^\(^,^ ]*)\)/g,((e,r,t,s,o,c,i)=>{const a=parseInt(c),l=i.replace(/[^a-zA-Z0-9_-]/g,"");let f="";return f=a>=0?s.substring(0,a):s.substring(s.length+a),n.add(`--${l}:${f};`),`${r}${t}${s}${o}`}));return n.size>0?r+`\n:root{${Array.from(n).join("\n")}\n}`:r}function x(e){const n=new Map;let r,t=e.replace(/(?:store|str|re)\(\s*([^:,]+)\s*[,:]\s*(?:"([^"]*)"|'([^']*)')\s*\)/gi,((e,r,t,s)=>{const o=t||s;return r=r.trim(),n.set(r,o),""}));if(0===n.size)return t;let s=0,o=t;do{r=!1;for(const[e,t]of n.entries()){const n=new RegExp(`\\b${c=e,c.replace(/[.*+?^${}|[\]\\]/g,"\\$&")}\\b`,"g"),s=o.replace(n,t);s!==o&&(r=!0,o=s)}s++}while(r&&s<100);var c;return s>=100&&console.warn("Maximum iterations reached. Possible circular dependency."),o}function b(e){return e=e.replace(/(?:mxs|\$p)\((([^\,]*)\,)?(([^\,]*)\,)?(([^\,]*)\,)?(([^\,]*)\,)?(([^\,]*)\,)?(([^\,]*)\,\s*)?("([^"]*)"|'([^']*)')\)/gi,"$2:$14$15;$4:$14$15;$6:$14$15;$8:$14$15;$10:$14$15;$12:$14$15;").replace(/(?:mx|\$m)\((([^\,]*)\,)?(([^\,]*)\,)?(([^\,]*)\,)?(([^\,]*)\,)?(([^\,]*)\,)?(([^\,]*)\,\s*)?("([^"]*)"|'([^']*)')\)/gi,"$2$14$15$4$14$15$6$14$15$8$14$15$10$14$15$12$14$15").replace(/rpt\((\d+)\,\s*("([^"]*)"|'([^']*)')\)/gi,((e,n,r)=>function(e,n){return e.replace(/^['"]|['"]$/g,"").repeat(Math.max(0,parseInt(n)))}(r,n))).replace(/\$(([\_\-\d\w]+)\:(\"[^\"]*\"|\'[^\']*\'|[^\;]*)\;)/gi,":root{--$1}").replace(/\$([^\!\s]+)!/gi,"var(--$1)").replace(/\$([\w\-\_\d]+)/gi,"var(--$1)").replace(/\-\*\-(([^\:]+)\:(\"[^\"]*\"|\'[^\']*\'|[^\;]*)\;)/gi,"-webkit-$1-moz-$1-ms-$1-o-$1").replace(/%i\((([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\]\[]*)\,)?(([^\,\]\[]*)\,)?(([^\,\[\]]*))?\s*\[([^\]\[]*)\]\)/gi,"$2$21$4$21$6$21$8$21$10$21$12$21$14$21$16$21$18$21$20$21").replace(/%6\((([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\]\[]*)\,)?(([^\,\]\[]*)\,)?(([^\,\[\]]*))?\s*\[([^\]\[]*)\]\)/gi,"$2$13$4$13$6$13$8$13$10$13$12$13").replace(/%5\((([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\]\[]*)\,)?(([^\,\]\[]*))?\s*\[([^\]\[]*)\]\)/gi,"$2$11$4$11$6$11$8$11$10$11").replace(/%4\((([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\[\]]*))?\s*\[([^\]\[]*)\]\)/gi,"$2$9$4$9$6$9$8$9").replace(/%3\((([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\[\]]*))?\s*\[([^\]\[]*)\]\)/gi,"$2$7$4$7$6$7").replace(/%2\((([^\,\[\]]*)\,)?(([^\,\]\[]*))?\s*\[([^\]\[]*)\]\)/gi,"$2$5$4$5").replace(/%1\((([^\,\]\[]*))?\s*\[([^\]\[]*)\]\)/gi,"$2$3"),(e=e.replace(/%(\d+)\(([^[]+)\[\s*([^\]]+)\]\)/g,((e,n,r,t)=>{const s=r.split(",").map((e=>e.trim()));return s.length!=n?(console.warn(`Number of properties ${s.length} does not match %${n}`),e):s.map((e=>`${e}${t}`)).join("")}))).replace(/\$\(\s*@keyframes\s*(\S+)\)/gi,"$1{animation-name:$1;}@keyframes $1").replace(/\$\(\s*(\@[\w\-\*]*)\s*([^\{\}\,&]*)(\s*,\s*[^\{\}&]*)?&?(\[([^\{\}]*)\])?\s*\)/gi,"$2$3{animation:$2 $5;}$1 $2").replace(/\$\(\s*--([^\{\}]*)\)/gi,"$1").replace(/\$\(([^\:]*):\s*([^\)\:]*)\)/gi,"[$1='$2']").replace(/g\(([^"'\s]*)\,\s*(("([^"]*)"|'([^']*)')\,\s*)?("([^"]*)"|'([^']*)')\s*\)/gi,"$1 $4$5$1 $7$8").replace(/\$\(([^\:]*):\s*([^\)\:]*)\)/gi,"[$1='$2']").replace(/\$\(([^\:^\)]*)\)/gi,"[$1]")}async function v(e){const n=[".fscss",".css",".txt",".scss",".less","xfscss"],r=/@import\(exec\(([^)]+)\)\s*\.\s*(?:pick|find)\(([^)]+)\)\)/g,t=[...(e=await p(e)).matchAll(r)];let s=e,o=null;for(const r of t){const[t,c,a]=r;if(o=c,i.has(o)){const e=o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=new RegExp("@import\\(exec\\(("+e+")\\)\\s*\\.\\s*(?:pick|find)\\(([^)]+)\\)\\)","g");s=s.replace(n,`/* Can't import ${o} multiple times */`),console.warn(`[FSCSS Warning] Can't import ${o} multiple times at `)}try{const e=c.replace(/["']/g,""),r=e.slice(e.lastIndexOf(".")).toLowerCase();if(e.trim().startsWith("_init")&&e.includes(" "))return void console.warn(`fscss[@import] library not found for: ${e}`);if(!n.includes(r))return void console.warn(`fscss[@import] invalid extension for: ${e}`);const o=await fetch(e);if(!o.ok)throw new Error(`fscss[@import] HTTP ${o.status} for ${c}`);const i=S(await o.text(),a.trim());s=s.replace(t,i)}catch(e){console.error(`fscss[@import] Failed: ${c} `,e),s=s.replace(t,`/* Failed import: ${c} */`)}}return s.match(r)?(i.add(o),v(s)):s}function S(e,n){const r=new RegExp(`${n}\\s*{[^}]*}`,"g"),t=e.match(r);return t?t.join("\n"):console.warn(`fscss[@import pick] No block matches: ${n} `)}const y=new Set;async function j(e){const n=/\@import\((?:\s+)?exec\((?:\s+)?(?:"([^"]+)"|'([^']+)'|`([^`]+)`|([^\)]+)(?:\s+)?)\)(?:\s+)?\)/g,r=[...(e=await p(e)).matchAll(n)];let t=e,s=null;for(const n of r){let[r,o,c,i,a]=n;const l=(o||c||i||a).trim();if(s=l,y.has(s)){const e=s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=new RegExp('\\@import\\((?:\\s+)?exec\\((?:\\s+)?(?:"('+e+")\"|'("+e+")'|`("+e+")`|("+e+")(?:\\s+)?)\\)(?:\\s+)?\\)","g");t=t.replace(n,`/* Can't import ${s} multiple times */`),console.warn(`[FSCSS Warning] Can't import ${s} multiple times at `)}try{const e=await fetch(l);if(!e.ok)throw new Error(`fscss[@import] HTTP ${e.status} for ${l}`);const n=await e.text();t=t.replace(r,n)}catch(e){console.error(`fscss[@import] Failed: ${l} `,e),t=t.replace(r,`/* Failed import: ${l} */`)}}return t.match(n)?(y.add(s),j(t)):t}async function k(e){const n=/\@import\((?:\s+)?(?:exec)?\(([\w\d\.\@\—\-_*\#\$\s\,]+)\)(?:\s+)?from(?:\s+)?(?:"([^"]+)"|'([^']+)'|`([^`]+)`)(?:\s+)?\)/g,r=[...(e=await p(e)).matchAll(n)];let t=e,s=null;for(const n of r){let[r,o,i,a,l]=n;o=o.trim();const f=(i||a||l).trim();if(s=f,c.has(s)){const e=s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=new RegExp('\\@import\\((?:\\s+)?(?:exec)?\\(([\\w\\d\\.\\@\\—\\-_*\\#\\$\\s\\,]+)\\)(?:\\s+)?from(?:\\s+)?(?:"((?:\\s+)?'+e+"(?:\\s+)?)\"|'((?:\\s+)?"+e+"(?:\\s+)?)'|`((?:\\s+)?"+e+"(?:\\s+)?)`)(?:\\s+)?\\)","g");t=t.replace(n,`/* Can't import ${s} multiple times */`),console.warn(`[FSCSS Warning] Can't import ${s} multiple times at `)}try{const e=await fetch(f);if(!e.ok)throw new Error(`fscss[@import] HTTP ${e.status} for ${f}`);const n=await e.text();if("*"===o&&(t=t.replace(r,n)),"*"!==o&&o.includes("*")&&(console.warn(`[FSCSS Warning] syntax error at ${r}: unexpected *`),t=t.replace(r,"/* syntax error: unexpected * */")),"*"!==o&&!o.includes("*")){const e=_(n,o.split(",").map((e=>e.trim())));t=t.replace(r,e)}}catch(e){console.error(`fscss[@import] Failed: ${f} `,e),t=t.replace(r,`/* Failed import: ${f} */`)}}return t.match(n)?(c.add(s),k(t)):t}function _(e,n=[]){if(!e||""===e||"string"!=typeof e)return console.warn("FSCSS >Invalid input");if(!n||0===n.length)return console.warn("FSCSS >Invalid input");let r="";return n.forEach((n=>{let t="",s=n;const o=n.trim().match(/([^\s]+)(?:\s+as\s+([^\s]+))?/);if(o){const[e,r,c]=o;s=r,c?t=c:n.includes(" as")?(console.warn(`[FSCSS Warning] Can't assign @${r} to invalid or empty value`),t=r):t=r}const c=new RegExp("@define\\s+("+s+")\\s*\\(([^)]*)\\)\\s*\\$?\\{\\s*(?:\"([^\"]*)\"|'([^']*)'|`([^`]*)`|([^\\}^\\{]*?))\\s*\\}","g"),i=e.match(c);if(!i)return console.warn(`[FSCSS Warning] @${s} is undefined for import`);const a=new RegExp("(@define\\s+)("+s+")(\\s*\\(([^)]*)\\)\\s*\\$?\\{\\s*(?:\"([^\"]*)\"|'([^']*)'|`([^`]*)`|([^\\}^\\{]*?))\\s*\\})","g");r+=i.join("\n").replace(a,((e,n,r,s)=>`${n}${t}${s}`))+"\n"})),r.trim()}try{await async function(){const t=document.querySelectorAll("style");if(t.length)for(const o of t){let t=o.textContent;t.includes("exec.obj.block(all)")||(t.includes("exec.obj.block(f import)")&&t.includes("exec.obj.block(f import pick)")||(t=await v(t)),t.includes("exec.obj.block(f import)")&&t.includes("exec.obj.block(f import from)")||(t=await k(t)),t.includes("exec.obj.block(f import)")||(t=await j(t)),t.includes("exec.obj.block(vfc)")||(t=t.replace(/([\w-]+:\s*)(\$\/?[\w-]+!?)(\s*\|\|\s*([^\n\};]+))?/g,((e,n,r,t,s)=>/^\$\/[\w-]+!?$/.test(r)?(r.endsWith("!")&&s&&console.warn(`fscss[VFC]: Required variable "${r}" should not have fallback (${s})`),t&&!s?.trim()?(console.warn(`fscss[VFC]: Empty fallback in -> ${e}`),e):(s?.includes("$/")&&!/^\$\/[\w-]+!?$/.test(s.trim())&&console.warn(`fscss[VFC]: Invalid fallback variable syntax -> ${s}`),s?`${n}${s.trim()};${n}${r}`:`${n}${r}`)):(console.warn(`fscss[VFC]: Invalid variable escape syntax -> ${r} at ${e}`),e)))),t.includes("exec.obj.block(store:before)")&&t.includes("exec.obj.block(store)")||(t=x(t)),t.includes("exec.obj.block(ext:before)")&&t.includes("exec.obj.block(ext)")||(t=d(t)),t.includes("exec.obj.block(f var)")||(t=function(e){const n={},r=[],t=e.split("\n");let s=!1;const o={};for(let e=0;e<t.length;e++){let c=t[e].trim();if(c.includes("{")){s=!0,r.push(c);continue}if(c.includes("}")){s=!1;for(const e in o)delete o[e];r.push(c);continue}const i=/^\s*\$([a-zA-Z0-9_-]+)\s*:\s*([^;]+);/,a=c.match(i);if(a){const[,e,t]=a;s?o[e]=t.trim():(n[e]=t.trim(),r.push(c));continue}const l=/\$\/?([a-zA-Z0-9_-]+)(!)?/g;c=c.replace(l,((e,r)=>void 0!==o[r]?o[r]:void 0!==n[r]?n[r]:e)),r.push(c)}return{css:r.join("\n"),getVariable:function(e){return n[e]||null}}}(t).css),t.includes("exec.obj.block(fun)")||(t=m(t)),t.includes("exec.obj.block(obj)")||(t=w(t)),t.includes("exec.obj.block(length)")||(t=n(t)),t.includes("exec.obj.block(count)")||(t=e(t)),t.includes("exec.obj.block(define)")||(t=$(t)),t.includes("exec.obj.block(arr)")||(t=g(t)),t.includes("exec.obj.block(event)")||(t=u(t)),t.includes("exec.obj.block(random)")||(t=t.replace(/@random\(\[([^\]]+)\](?:, *ordered)?\)/g,((e,n)=>{const r=/, *ordered\)/.test(e),t=n.split(",").map((e=>e.trim()));if(0===t.length)return console.warn("fscss[@random] Warning: Empty array provided for @random. Returning empty string."),"";if(r){const e=t.join(":");s[e]||(s[e]={values:t,index:0},console.warn(`fscss[@random] Warning: New ordered sequence created for [${n}].`));const r=s[e],o=r.values[r.index%r.values.length];return r.index>=r.values.length&&r.index%r.values.length==0&&console.warn(`fscss[@random] Warning: Ordered sequence [${n}] is looping back to the beginning.`),r.index++,o}return t[Math.floor(Math.random()*t.length)]}))),t.includes("exec.obj.block(copy)")||(t=h(t)),t.includes("exec.obj.block(store:after)")&&t.includes("exec.obj.block(store)")||(t=x(t)),t.includes("exec.obj.block(num)")||(t=r(t)),t.includes("exec.obj.block(ext:after)")&&t.includes("exec.obj.block(ext)")||(t=d(t)),t.includes("exec.obj.block(t group)")||(t=b(t)),t.includes("exec.obj.block(length)")||(t=n(t)),t.includes("exec.obj.block(count)")||(t=e(t)),t.includes("exec.obj.block(debug)")||(t=f(t))),t=t.replace(/exec\.obj\.block\([^\)\n]*\)\;?/g,""),o.innerHTML=t}else console.warn("fscss[Obj]\n No <style> elements found.")}(),await void document.querySelectorAll(".draw").forEach((e=>{const n=e.style.color||"#000";e.style.color="transparent",e.style.webkitTextStroke=`2px ${n}`}))}catch(e){console.error("Error processing styles or draw elements:",e)}})()}function applyFscssStyles(){document.querySelectorAll('[type*="fscss"]').forEach((e=>{fetch(e.href).then((e=>e.text())).then((e=>{const n=document.createElement("style");n.textContent=e,document.head.appendChild(n),xfscssProcessorWrap()})).catch((n=>{console.error(`Failed to load FSCSS from ${e.href}`,n)}))}))}function inf({host:e,path:n}){if(!e||!n)return void console.error("Both 'host' and 'path' are required.");const r=e.replace(/github/gi,"gh"),t=n.replace(/\s*->\s*/g,"/").replace(/\n/g,"");loadFScript(`https://cdn.jsdelivr.net/${r}/${t}`)}xfscssProcessorWrap(),applyFscssStyles();
1
+ function exec({ type = 'text', content, onError, onSuccess }) {
2
+
3
+ // 1. Validation
4
+ if (!content) {
5
+ const errorText = 'No CSS content or URL provided.';
6
+ console.error(`[FSCSS] ${errorText}`);
7
+ if (onError) onError(errorText);
8
+ return;
9
+ }
10
+
11
+ const style = document.createElement('style');
12
+
13
+ const appendStyle = (cssText) => {
14
+ style.textContent = cssText;
15
+ document.head.appendChild(style);
16
+ if (onSuccess) onSuccess(style);
17
+ xfscssProcessorWrap();
18
+ };
19
+
20
+ // 2. Normalizing Types
21
+ const isText = ['text', 'auto', 'text/fscss', 'text/css'].includes(type);
22
+ const isUrl = ['fromUrl', 'URL', 'fromURL', 'link'].includes(type);
23
+
24
+ // 3. Logic Execution
25
+ if (isText) {
26
+ appendStyle(content);
27
+ } else if (isUrl) {
28
+ fetch(content)
29
+ .then(res => {
30
+ if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);
31
+ return res.text();
32
+ })
33
+ .then(appendStyle)
34
+ .catch(err => {
35
+ const msg = `Failed to load CSS from: ${content}. ${err.message}`;
36
+ console.error(`[FSCSS] ${msg}`);
37
+ if (onError) onError(msg);
38
+ });
39
+ } else {
40
+ const errorText = `Unsupported type "${type}". Use "text" or "fromUrl".`;
41
+ console.error(`[FSCSS] ${errorText}`);
42
+ if (onError) onError(errorText);
43
+ }
44
+ }
45
+
46
+
47
+
48
+ function xfscssProcessorWrap(){(async ()=>{
49
+ /**
50
+ * FSCSS Processing Script
51
+ */
52
+
53
+ function procCntInit(ntc,stc){
54
+ const nu = Array(ntc).fill().map((_, i)=>(i+1)*stc);
55
+ return `${nu}`;
56
+ }
57
+ function procCnt(text){
58
+ const reg=/count\(\s*([\d\.]+)\s*(?:,\s*([\d\.]+)?)?\)/g;
59
+ text = text.replace(reg, (March, num, step)=>{
60
+ if(step===null)step=1;
61
+ return procCntInit(parseInt(num), parseInt(step?step:1));
62
+ })
63
+ return text;
64
+ }
65
+ function procChe(text) {
66
+ const reg = /length\((?:([^\)]+)|\s*"([^"]*)"\s*|\s*'([^']*)'\s*)\)/g;
67
+ text = text.replace(reg, (match, txt, txt2, txt3) => {
68
+ const resTxt = txt || txt2 || txt3;
69
+ return resTxt.length;
70
+ })
71
+ return text;
72
+ }
73
+ function parseMath(expr) {
74
+ const str = expr.replace(/\s+/g, '');
75
+ let pos = 0;
76
+
77
+ function parseExpr() {
78
+ let left = parseTerm();
79
+ while (pos < str.length && (str[pos] === '+' || str[pos] === '-')) {
80
+ const op = str[pos++];
81
+ const right = parseTerm();
82
+ left = op === '+' ? left + right : left - right;
83
+ }
84
+ return left;
85
+ }
86
+
87
+ function parseTerm() {
88
+ let left = parsePower();
89
+ while (pos < str.length && (str[pos] === '*' || str[pos] === '/')) {
90
+ const op = str[pos++];
91
+ const right = parsePower();
92
+ left = op === '*' ? left * right : left / right;
93
+ }
94
+ return left;
95
+ }
96
+
97
+ function parsePower() {
98
+ let base = parseUnary();
99
+ if (pos < str.length && str[pos] === '*' && str[pos + 1] === '*') {
100
+ pos += 2;
101
+ const exp = parseUnary(); // right-associative
102
+ return Math.pow(base, exp);
103
+ }
104
+ return base;
105
+ }
106
+
107
+ function parseUnary() {
108
+ if (str[pos] === '-') { pos++; return -parsePrimary(); }
109
+ if (str[pos] === '+') { pos++; return parsePrimary(); }
110
+ return parsePrimary();
111
+ }
112
+
113
+ function parsePrimary() {
114
+ if (str[pos] === '(') {
115
+ pos++; // skip '('
116
+ const val = parseExpr();
117
+ if (str[pos] !== ')') throw new Error('Missing closing )');
118
+ pos++; // skip ')'
119
+ return val;
120
+ }
121
+
122
+ const numMatch = str.slice(pos).match(/^[0-9]*\.?[0-9]+/);
123
+ if (!numMatch) throw new Error(`Unexpected token at pos ${pos}: "${str[pos]}"`);
124
+ pos += numMatch[0].length;
125
+ return parseFloat(numMatch[0]);
126
+ }
127
+
128
+ const result = parseExpr();
129
+ if (pos !== str.length) throw new Error(`Unexpected token: "${str[pos]}"`);
130
+ return result;
131
+ }
132
+
133
+ function procNum(css) {
134
+ const regex = /num\((.*?)\)/g;
135
+
136
+ return css.replace(regex, (match, expression) => {
137
+ try {
138
+ return parseMath(expression);
139
+ } catch (e) {
140
+ console.error('Invalid math expression:', expression);
141
+ return expression;
142
+ }
143
+ });
144
+ }
145
+
146
+ const arraysExfscss = {}; // global variable
147
+ const orderedxFscssRandom = {};
148
+
149
+ const exfMAX_DEPTH = 10; // Prevent infinite recursion
150
+ const defExfscss = {}; // Stores definitions globally. FIGSH-FSCSS
151
+ const runnedSet = new Set();
152
+ const runnedSetS = new Set();
153
+
154
+ function extractBlock(css, startIndex) {
155
+ let depth = 0;
156
+ let i = startIndex;
157
+ while (i < css.length) {
158
+ if (css[i] === '{') depth++;
159
+ else if (css[i] === '}') depth--;
160
+ if (depth === 0) break;
161
+ i++;
162
+ }
163
+ return css.slice(startIndex, i + 1);
164
+ }
165
+
166
+ function parseConditionBlocks(block) {
167
+ const blocks = [];
168
+ // Adjusted regex to correctly capture the block content within curly braces
169
+ const conditionRegex = /(if|el-if|el)\s*([^{}]*?)\s*\{([\s\S]*?)\}/g;
170
+ let match;
171
+ while ((match = conditionRegex.exec(block)) !== null) {
172
+ blocks.push({
173
+ type: match[1],
174
+ condition: match[2].trim(),
175
+ block: match[3].trim()
176
+ });
177
+ }
178
+ return blocks;
179
+ }
180
+
181
+
182
+ function procExC(css) {
183
+ const regex = /exec\((_log|_error|_warn|_info),\s*(?:"([^"]*)"|'([^']*)'|([^)]*))\)/g;
184
+
185
+ const methodMap = {
186
+ _log: console.log,
187
+ _error: console.error,
188
+ _warn: console.warn,
189
+ _info: console.info,
190
+ };
191
+
192
+ const cleanedCSS = css.replace(regex, (full, method, dQ, sQ, raw) => {
193
+ const arg = dQ ?? sQ ?? raw;
194
+
195
+ if (!methodMap[method]) {
196
+ console.warn(`fscss[exec(console)]: Unsupported method: ${method}`);
197
+ return '';
198
+ }
199
+
200
+ if (!arg) {
201
+ console.warn(`fscss[exec(console)]: Empty argument for method: ${method}`);
202
+ return '';
203
+ }
204
+
205
+ methodMap[method](arg);
206
+ return '';
207
+ });
208
+
209
+ return cleanedCSS;
210
+ }
211
+
212
+ function procEv(css) {
213
+ const functionMap = {};
214
+ const funcDefRegex = /@event\s+([\w-]+)\(([^)]*)\)\s*:?{/g;
215
+ let funcMatch;
216
+ let modifiedCSS = css;
217
+ const removalRanges = [];
218
+
219
+ // First pass: extract and mark function definitions
220
+ while ((funcMatch = funcDefRegex.exec(css)) !== null) {
221
+ const funcName = funcMatch[1];
222
+ const argsStr = funcMatch[2];
223
+ const blockStart = funcMatch.index + funcMatch[0].length - 1;
224
+
225
+ if (blockStart >= css.length) {
226
+ console.warn(`fscss[parsing] Warning: Unexpected end of CSS after @event ${funcName} definition.`);
227
+ continue;
228
+ }
229
+
230
+ const fullBlock = extractBlock(css, blockStart);
231
+
232
+ if (fullBlock.length === 0 || fullBlock[fullBlock.length - 1] !== '}') {
233
+ console.warn(`fscss[parsing] Warning: Malformed block for @event '${funcName}'. Missing closing '}'.`);
234
+ continue;
235
+ }
236
+
237
+ const fullFunc = css.slice(funcMatch.index, blockStart + fullBlock.length);
238
+
239
+ const conditionBlocks = parseConditionBlocks(fullBlock);
240
+ const args = argsStr.split(',').map(arg => arg.trim()).filter(arg => arg !== '');
241
+
242
+ if (functionMap[funcName]) {
243
+ console.warn(`fscss[definition] Warning: Duplicate @event definition for '${funcName}'. The last one will be used.`);
244
+ }
245
+ functionMap[funcName] = { args, conditionBlocks };
246
+
247
+ removalRanges.push([funcMatch.index, blockStart + fullBlock.length]);
248
+ }
249
+ for (let i = removalRanges.length - 1; i >= 0; i--) {
250
+ const [start, end] = removalRanges[i];
251
+ modifiedCSS = modifiedCSS.slice(0, start) + modifiedCSS.slice(end);
252
+ }
253
+ modifiedCSS = modifiedCSS.replace(/@event\.([\w-]+)\(([^)]*)\)/g, (match, funcName, argValuesStr) => {
254
+ const func = functionMap[funcName];
255
+ if (!func) {
256
+ console.warn(`fscss[call] Warning: @event function '${funcName}' not found during call.`);
257
+ return match;
258
+ }
259
+
260
+ const context = {};
261
+ const argValues = argValuesStr.split(',').map(v => v.trim()).filter(v => v !== '');
262
+
263
+ if (argValues.length !== func.args.length) {
264
+ console.warn(`fscss[call] Warning: Argument count mismatch for @event '${funcName}'. Expected ${func.args.length}, got ${argValues.length}.`);
265
+ }
266
+
267
+ func.args.forEach((argName, i) => {
268
+ if (argValues[i] !== undefined) {
269
+ context[argName] = argValues[i];
270
+ } else {
271
+ console.warn(`fscss[call] Warning: Missing value for argument '${argName}' in @event '${funcName}' call.`);
272
+ }
273
+ });
274
+
275
+ let result = '';
276
+ let matched = false;
277
+ let elBlockFound = false;
278
+
279
+ for (const block of func.conditionBlocks) {
280
+ if (block.type === 'el') {
281
+ if (elBlockFound) {
282
+ console.warn(`fscss[logic] Warning: Multiple 'el' (else) blocks found in @event '${funcName}'. Only the first 'el' block will be considered.`);
283
+ }
284
+ elBlockFound = true;
285
+ }
286
+
287
+ if (matched && block.type !== 'el') {
288
+ continue;
289
+ }
290
+
291
+ if (block.type === 'el') {
292
+ if (!matched) {
293
+ matched = true;
294
+ } else {
295
+ continue;
296
+ }
297
+ } else {
298
+ const conditions = block.condition.split(',').map(c => c.trim()).filter(c => c !== '');
299
+ if (conditions.length === 0) {
300
+ console.warn(`fscss[logic] Warning: Empty condition in '${block.type}' block for @event '${funcName}'.`);
301
+ matched = true;
302
+ } else {
303
+ matched = conditions.every(cond => {
304
+ const comparisonMatch = cond.match(/^(\w+)\s*(==|!=|>=|<=|>|<)\s*([^]+)$/);
305
+ if (comparisonMatch) {
306
+ const [, varName, operator, expected] = comparisonMatch;
307
+ if (!(varName in context)) {
308
+ console.warn(`fscss[logic] Warning: Condition variable '${varName}' not provided in @event '${funcName}' context. Treating as false.`);
309
+ return false;
310
+ }
311
+ const actual = context[varName];
312
+
313
+ const numActual = isNaN(actual) ? actual : Number(actual);
314
+ const numExpected = isNaN(expected) ? expected : Number(expected);
315
+ switch (operator) {
316
+ case '==': return numActual == numExpected;
317
+ case '!=': return numActual != numExpected;
318
+ case '>': return numActual > numExpected;
319
+ case '<': return numActual < numExpected;
320
+ case '>=': return numActual >= numExpected;
321
+ case '<=': return numActual <= numExpected;
322
+ default: return false;
323
+ }
324
+ } else {
325
+ const parts = cond.split(':').map(s => s.trim());
326
+ if (parts.length !== 2) {
327
+ console.warn(`fscss[logic] Warning: Malformed condition '${cond}' in @event '${funcName}'. Expected 'variable operator value' or 'variable:value'.`);
328
+ return false;
329
+ }
330
+ const [varName, expected] = parts;
331
+ if (!(varName in context)) {
332
+ console.warn(`fscss[logic] Warning: Condition variable '${varName}' not provided in @event '${funcName}' context. Treating as false.`);
333
+ return false;
334
+ }
335
+ return context[varName] === expected;
336
+ }
337
+ });
338
+ }
339
+ }
340
+
341
+ if (matched) {
342
+ const assignMatch = block.block.match(/(\w+)\s*(?:\:\s*([^;]*);?|\|([^\|]+)\|?)/);
343
+ if (assignMatch && assignMatch[2]) {
344
+ result = assignMatch[2].trim();
345
+ }
346
+ else if (assignMatch && assignMatch[3]) {
347
+ result = assignMatch[3].trim();
348
+ }
349
+ else {
350
+ console.warn(`fscss[logic] Warning: No valid CSS property assignment found in matched block for @event '${funcName}'. Block content: '${block.block}'.`);
351
+ }
352
+ break;
353
+ }
354
+ }
355
+
356
+
357
+ if (!result && func.conditionBlocks.length > 0 && !matched) {
358
+ console.warn(`fscss[call] Warning: No condition matched for @event '${funcName}' with provided arguments. Returning original call string.`);
359
+ } else if (!result && func.conditionBlocks.length === 0) {
360
+ console.warn(`fscss[definition] Warning: @event '${funcName}' has no condition blocks defined. Returning original call string.`);
361
+ }
362
+
363
+ return result || match;
364
+ });
365
+
366
+ return modifiedCSS.trim();
367
+ }
368
+
369
+ async function initlibraries(css) {
370
+ const xfr = 'https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/';
371
+ css = css.replace(/exec\(_init\s+([\w\d\._—\-\%\*\+\@\&\$\=]+)(?:\/([\w\-]+))?\s*\)/g, (match, impName, impType) => {
372
+ if (!impType) {
373
+ //`
374
+ return `exec(${xfr+impName}.fscss)`;
375
+ }
376
+ return `exec(${xfr+impName}.${impType})`;
377
+ });
378
+ css = css.replace(/(\@import\((?:\s+)?(?:exec)?\((?:[\w\d\.\@\—\-_*\#\$\s\,]+)\)(?:\s+)?from(?:\s+)?)([\w\d\._—\-\%\*\+\@\&\$\=]+)(?:\/([\w\-]+))?(?:\s+)?\)/g, (match, state, impName, impType) => {
379
+ if (!impType) {
380
+ return `${state}'${xfr+impName}.fscss')`;
381
+ }
382
+ return `${state}'${xfr+impName}.${impType}')`;
383
+ });
384
+ return css;
385
+ }
386
+
387
+ function procVar(vcss) {
388
+ function processSCSS(scssCode) {
389
+ const globalVars = {};
390
+ const processedLines = [];
391
+ const lines = scssCode.split('\n');
392
+
393
+ let inBlock = false;
394
+ const blockVars = {};
395
+
396
+ for (let i = 0; i < lines.length; i++) {
397
+ let line = lines[i].trim();
398
+
399
+ if (line.includes('{')) {
400
+ inBlock = true;
401
+ processedLines.push(line);
402
+ continue;
403
+ }
404
+
405
+ if (line.includes('}')) {
406
+ inBlock = false;
407
+ for (const varName in blockVars) {
408
+ delete blockVars[varName];
409
+ }
410
+ processedLines.push(line);
411
+ continue;
412
+ }
413
+
414
+ const varDeclarationRegex = /^\s*\$([a-zA-Z0-9_-]+)\s*:\s*([^;]+);/;
415
+ const varMatch = line.match(varDeclarationRegex);
416
+
417
+ if (varMatch) {
418
+ const [, varName, varValue] = varMatch;
419
+ if (inBlock) {
420
+ blockVars[varName] = varValue.trim();
421
+ // Do not include block-scoped declarations in the final CSS
422
+ } else {
423
+ globalVars[varName] = varValue.trim();
424
+ // Include global variable declarations in the final CSS
425
+ processedLines.push(line);
426
+ }
427
+ continue;
428
+ }
429
+
430
+ const varUsageRegex = /\$\/?([a-zA-Z0-9_-]+)(!)?/g;
431
+
432
+ line = line.replace(varUsageRegex, (match, varName) => {
433
+ if (blockVars[varName] !== undefined) {
434
+ return blockVars[varName];
435
+ } else if (globalVars[varName] !== undefined) {
436
+ return globalVars[varName];
437
+ }
438
+ return match;
439
+ });
440
+
441
+ processedLines.push(line);
442
+ }
443
+
444
+ function getVariable(varName) {
445
+ return globalVars[varName] || null;
446
+ }
447
+ const finalCss = processedLines.join('\n');
448
+
449
+ return {
450
+ css: finalCss,
451
+ getVariable
452
+ };
453
+ }
454
+
455
+ const result = processSCSS(vcss);
456
+ return result.css;
457
+ }
458
+
459
+ let defExdepth = 0;
460
+
461
+ function procDef(fscss) {
462
+
463
+ const pRegex = /@define\s+([\w\_\-\—]+)\s*\(([^)]*)\)\s*\$?\{\s*(?:"([^"]*)"|'([^']*)'|`([^`]*)`|([^\}^\{]*?))\s*\}/g;
464
+
465
+ // First, extract all @define blocks and store them in defExfscss. FIGSH-FSCSS
466
+
467
+ let processed = fscss.replace(pRegex,
468
+ (match, name, paramsStr, body1, body2, body3, body4) => {
469
+ const params = paramsStr.split(',').map(p =>p.trim()).filter(p =>p);
470
+ const body = body1 ?? body2 ?? body3 ?? body4 ?? '';
471
+ defExfscss[name] = { params, body };
472
+ return ''; // Remove the define block from the output. FIGSH-FSCSS
473
+ }
474
+ );
475
+
476
+ // Now replace all @name(...) usages with their expanded bodies. FIGSH-FSCSS
477
+
478
+ processed = processed.replace(
479
+ /@([\w\_\-\—]+)\s*\(([\s\S]*?)\)/g,
480
+ (match, name, argsStr) => {
481
+ const def = defExfscss[name];
482
+ if (!def){
483
+ return match;
484
+ }// Leave unknown Def macros unchanged. FIGSH-FSCSS
485
+
486
+ const args = argsStr?.split(',').map(a => a.trim());
487
+ if(args[0]==='') args[0] = undefined;
488
+ let result = def.body;
489
+
490
+ /* Replace each @use(param) with the corresponding argument. FIGSH-FSCSS */
491
+ let xfVal = [];
492
+ def.params.forEach((param, index) => {
493
+ const df = def.params[index];
494
+ if(df&&df.includes(':')){
495
+ xfVal = df?.split(':')?.map(i=>i.trim()).filter(i=>i);
496
+ }
497
+
498
+ const dfv = xfVal[1]?xfVal[1]:'';
499
+
500
+ const arg = args[index] !== (undefined) ? args[index] : dfv;
501
+ const regex = new RegExp(`@use\\(\\s*${param.replace(/(\s+)?(\:(\s+)?.*)/g, '')}\\s*\\)`, 'g');
502
+ result = result.replace(regex, arg);
503
+ });
504
+
505
+ return result;
506
+ }
507
+ );
508
+
509
+
510
+ if (!pRegex.test(processed)||defExdepth >= 10) {
511
+ for(let g=0;g<10;g++){
512
+ processed = processed.replace(
513
+ /@([\w\_\-\—]+)\s*\(([\s\S]*?)\)/g,
514
+ (match, name, argsStr) => {
515
+ const def = defExfscss[name];
516
+ if (!def){
517
+ return match;
518
+ }// Leave unknown Def macros unchanged. FIGSH-FSCSS
519
+
520
+ const args = argsStr?.split(',').map(a => a.trim());
521
+ if(args[0]==='') args[0] = undefined;
522
+ let result = def.body;
523
+
524
+ /* Replace each @use(param) with the corresponding argument. FIGSH-FSCSS */
525
+ let xfVal = [];
526
+ def.params.forEach((param, index) => {
527
+ const df = def.params[index];
528
+ if(df&&df.includes(':')){
529
+ xfVal = df?.split(':')?.map(i=>i.trim()).filter(i=>i);
530
+ }
531
+
532
+ const dfv = xfVal[1]?xfVal[1]:'';
533
+
534
+ const arg = args[index] !== (undefined) ? args[index] : dfv;
535
+ const regex = new RegExp(`@use\\(\\s*${param.replace(/(\s+)?(\:(\s+)?.*)/g, '')}\\s*\\)`, 'g');
536
+ result = result.replace(regex, arg);
537
+ });
538
+
539
+ return result;
540
+ }
541
+ );
542
+ }
543
+ return processed;
544
+ }
545
+ defExdepth++;
546
+
547
+ return procDef(processed);
548
+ }
549
+
550
+ function procExt(css) {
551
+ let extractedVariables = {};
552
+ let tempCSS = css;
553
+
554
+ // Step 1: Process string literals
555
+ tempCSS = tempCSS.replace(/("(?:[^"\\]|\\.)*")|('(?:[^'\\]|\\.)*')/g, function(fullMatch) {
556
+ let quote = fullMatch[0];
557
+ let content = fullMatch.slice(1, -1);
558
+ const directiveRegex = /@ext\((?:\s+)?(-?\d+)(?:\s+)?,(?:\s+)?(\d+)(?:\s+)?:\s*([^)]+)(?:\s+)?\)/g;
559
+ let match;
560
+ let directivesToProcess = [];
561
+
562
+ while ((match = directiveRegex.exec(content)) !== null) {
563
+ directivesToProcess.push({
564
+ fullMatch: match[0],
565
+ start: parseInt(match[1]),
566
+ length: parseInt(match[2]),
567
+ varName: match[3].trim(),
568
+ index: match.index
569
+ });
570
+ }
571
+
572
+ for (let i = directivesToProcess.length - 1; i >= 0; i--) {
573
+ let d = directivesToProcess[i];
574
+ let s = d.start < 0 ? content.length + d.start : d.start;
575
+ s = Math.max(0, s);
576
+ let extracted = content.substring(s, s + d.length);
577
+
578
+ if (s + d.length > content.length || s < 0) {
579
+ console.warn(`fscss:[@ext]Warning: @ext directive for variable '${d.varName}' in string literal specifies an out-of-bounds range. Extraction may be incomplete or incorrect.`);
580
+ }
581
+
582
+ if (extractedVariables[d.varName] !== undefined) {
583
+ console.warn(`fscss:[@ext]Warning: Duplicate variable name '${d.varName}' found in string literal. The last extracted value will be used.`);
584
+ }
585
+ extractedVariables[d.varName] = extracted;
586
+
587
+ // Remove @ext from content
588
+ content = content.slice(0, d.index) + content.slice(d.index + d.fullMatch.length);
589
+ }
590
+
591
+ return quote + content + quote;
592
+ });
593
+
594
+ // Step 2: Outside strings
595
+ tempCSS = tempCSS.replace(/([#.\w-]+)\s*@ext\((?:\s+)?(-?\d+)(?:\s+)?,(?:\s+)?(\d+)(?:\s+)?:\s*([^)]+)(?:\s+)?\)/g, function(match, token, start, len, varName) {
596
+ start = parseInt(start);
597
+ len = parseInt(len);
598
+ varName = varName.trim();
599
+ let s = start < 0 ? token.length + start : start;
600
+ s = Math.max(0, s);
601
+ let extracted = token.substring(s, s + len);
602
+
603
+ if (s + len > token.length || s < 0) {
604
+ console.warn(`fscss:[@ext]Warning: @ext directive for variable '${varName}' on token '${token}' specifies an out-of-bounds range. Extraction may be incomplete or incorrect.`);
605
+ }
606
+
607
+ if (extractedVariables[varName] !== undefined) {
608
+ console.warn(`fscss:[@ext]Warning: Duplicate variable name '${varName}' found outside string literals. The last extracted value will be used.`);
609
+ }
610
+ extractedVariables[varName] = extracted;
611
+ return token;
612
+ });
613
+
614
+ // Step 3: Replace @ext.varName references
615
+ tempCSS = tempCSS.replace(/@ext\.(\w+)\!?/g, function(match, varName) {
616
+ if (extractedVariables[varName] === undefined) {
617
+ console.warn(`fscss:[@ext]Warning: Reference to undefined variable '@ext.${varName}'. It will not be replaced.`);
618
+ return match;
619
+ }
620
+ return extractedVariables[varName];
621
+ });
622
+
623
+ return tempCSS;
624
+ }
625
+
626
+ function procRan(input) {
627
+ return input.replace(/@random\(\[([^\]]+)\](?:, *ordered)?\)/g, (match, valuesStr) => {
628
+ const isOrdered = /, *ordered\)/.test(match);
629
+ const values = valuesStr.split(',').map(v => v.trim());
630
+
631
+ if (values.length === 0) {
632
+ console.warn("fscss[@random] Warning: Empty array provided for @random. Returning empty string.");
633
+ return '';
634
+ }
635
+
636
+ if (isOrdered) {
637
+ // Create consistent key for value sequences
638
+ const sequenceKey = values.join(':');
639
+
640
+ if (!orderedxFscssRandom[sequenceKey]) {
641
+ orderedxFscssRandom[sequenceKey] = {
642
+ values,
643
+ index: 0,
644
+ };
645
+ console.warn(`fscss[@random] Warning: New ordered sequence created for [${valuesStr}].`);
646
+ }
647
+
648
+ const store = orderedxFscssRandom[sequenceKey];
649
+ const val = store.values[store.index % store.values.length];
650
+
651
+ if (store.index >= store.values.length && store.index % store.values.length === 0) {
652
+ console.warn(`fscss[@random] Warning: Ordered sequence [${valuesStr}] is looping back to the beginning.`);
653
+ }
654
+
655
+ store.index++;
656
+ return val;
657
+ } else {
658
+ // Regular random selection
659
+ const randIndex = Math.floor(Math.random() * values.length);
660
+ return values[randIndex];
661
+ }
662
+ });
663
+ }
664
+
665
+
666
+
667
+ function procArr(input) {
668
+ // 1. Parse array declarations
669
+ const arrayDeclarationRegex = /@arr\(?\s*([\w\-_—0-9]+)\)?\[([^\]]+)\]\)?/g;
670
+ let match;
671
+ while ((match = arrayDeclarationRegex.exec(input)) !== null) {
672
+ const arrayName = match[1];
673
+ const arrayValues = match[2].split(',').map(item => item.trim());
674
+ arraysExfscss[arrayName] = arrayValues;
675
+ }
676
+
677
+ let output = input;
678
+
679
+ output = output.replace(/@arr\.([\w\-_—0-9]+)(?:\!\s*\+\s*\[([^\]]+)?\])/g, (match, arrName, newArr) => {
680
+ const arr = arraysExfscss[arrName];
681
+ if (!arr) {
682
+ console.warn(`fscss[@arr] Warning: Array '${arrName}' not found.`);
683
+ return match;
684
+ }
685
+ if (!newArr) {
686
+ console.warn(
687
+ `[FSCSS Warning] @arr push failed → Invalid or empty value at "${match}"`
688
+ );
689
+ return match;
690
+ }
691
+ newItems = newArr.split(',').map(item => item.trim());
692
+ arraysExfscss[arrName].push(...newItems);
693
+ return "";
694
+ })
695
+
696
+ output = output.replace(/@arr\.([\w\-_—0-9]+)(?:\!\s*\-\s*\[([\d\w\-_—\s]+)?\])/g, (match, arrName, ind) => {
697
+ const arr = arraysExfscss[arrName];
698
+ if (!arr) {
699
+ console.warn(`fscss[@arr] Warning: Array '${arrName}' not found.`);
700
+ return match;
701
+ }
702
+ ind = Number(ind?.trim());
703
+ if (!ind||ind<1||!Number(ind)) {
704
+ console.warn(
705
+ `[FSCSS Warning] @arr splice failed → Invalid or empty index at "${match}"`
706
+ );
707
+ return match;
708
+ }
709
+ if(ind>arr.length){
710
+ console.warn(
711
+ `[FSCSS Warning] @arr → @arr.${arrName}[${ind}] is undefined at "${match}"`);
712
+ return "";
713
+ }
714
+ ind = (ind-1);
715
+ arr.splice(ind,1);
716
+ return "";
717
+ })
718
+
719
+
720
+ output = output.replace(/@arr\.([\w\-_—0-9]+)(?:\!\s*\.(length|last|reverse|first|list|indices|randint|segment|sum|unique|sort|shuffle|min|max))/g, (match, arrName, obj) => {
721
+ const arr = arraysExfscss[arrName];
722
+ if (!arr) {
723
+ console.warn(`fscss[@arr] Warning: Array '${arrName}' not found.`);
724
+ return match;
725
+ }
726
+ if(obj){
727
+ if (obj==="length") {
728
+ return arr.length;
729
+ }
730
+ if(obj==="first"){
731
+ return arr[0];
732
+ }
733
+ if (obj==="last") {
734
+ return arr.at(-1);
735
+ }
736
+ if (obj==="indices") {
737
+ return Array(arr.length).fill().map((_, i)=>(i+1)*1);
738
+ }
739
+ if (obj==="list") {
740
+ return arr.join(',');
741
+ }
742
+ if (obj==="reverse") {
743
+ return arr.toReversed().join(',');
744
+ }
745
+ if (obj==="randint") {
746
+ return arr[Math.floor(Math.random() * arr.length)];
747
+ }
748
+ if(obj==="segment") {
749
+ return arr.map(u => `[${u}]`).join('')
750
+ }
751
+ if (obj === "unique") {
752
+ return [...new Set(arr)].join(',');
753
+ }
754
+ if (obj === "sort") {
755
+ return arr.slice().sort().join(',');
756
+ }
757
+ if (obj === "shuffle") {
758
+ return arr.slice().sort(() => Math.random() - 0.5).join(',');
759
+ }
760
+ if (obj === "sum") {
761
+ return arr.reduce((a, b) => a + Number(b), 0);
762
+ }
763
+ if (obj === "min") {
764
+ return Math.min(...arr.map(Number));
765
+ }
766
+ if (obj === "max") {
767
+ return Math.max(...arr.map(Number));
768
+ }
769
+ }
770
+ })
771
+
772
+ // 2. Process loops using @arr.name[]
773
+ output = output.replace(/([^\{\}]+)\{\s*([^}]*@arr\.([\w\-_—0-9]+)\[\][^}]*)\s*\}/g,
774
+ (fullMatch, selector, content, arrayName) => {
775
+ const arr = arraysExfscss[arrayName];
776
+ if (!arr) {
777
+ console.warn(`fscss[@arr] Warning: Array '${arrayName}' not found for loop processing.`);
778
+ return fullMatch;
779
+ }
780
+
781
+ return arr.map((value, index) => {
782
+ const sel = selector.replace(new RegExp(`@arr\\.${arrayName}\\[\\]`, 'g'), index + 1);
783
+ const body = content.replace(new RegExp(`@arr\\.${arrayName}\\[\\]`, 'g'), value);
784
+ return `${sel.trim()} {\n ${body.trim()}\n}`;
785
+ }).join('\n');
786
+ });
787
+
788
+ // 3. Specific array access: @arr.name[index]
789
+ output = output.replace(/@arr\.([\w\-_—0-9]+)\[(\d+)\]/g,
790
+ (fullMatch, arrayName, index) => {
791
+ const idx = parseInt(index) - 1;
792
+ const arr = arraysExfscss[arrayName];
793
+ if (!arr) {
794
+ console.warn(`fscss[@arr] Warning: Array '${arrayName}' not found.`);
795
+ return fullMatch;
796
+ }
797
+ return arr[idx] !== undefined ? arr[idx] : fullMatch;
798
+ });
799
+
800
+ output = output.replace(/@arr\.([\w\-_—0-9]+)(?:!\s*\.unit)(?:\(([^)]*)\))/g,
801
+ (fullMatch, arrayName, pl) => {
802
+ const arr = arraysExfscss[arrayName];
803
+ if (!arr) {
804
+ console.warn(`fscss[@arr] Warning: Array '${arrayName}' not found for direct access.`);
805
+ return fullMatch;
806
+ }
807
+ const sep = (pl !== undefined && pl !== "") ? pl : ' ';
808
+ return arr.map(u=>`${u+sep}`).join(',');
809
+ });
810
+
811
+ output = output.replace(/@arr\.([\w\-_—0-9]+)(?:!\s*\.prefix)(?:\(([^)]*)\))/g,
812
+ (fullMatch, arrayName, pl) => {
813
+ const arr = arraysExfscss[arrayName];
814
+ if (!arr) {
815
+ console.warn(`fscss[@arr] Warning: Array '${arrayName}' not found for direct access.`);
816
+ return fullMatch;
817
+ }
818
+ const sep = (pl !== undefined && pl !== "") ? pl : ' ';
819
+ return arr.map(u=>`${sep+u}`).join(',');
820
+ });
821
+
822
+
823
+
824
+ output = output.replace(/@arr\.([\w\-_—0-9]+)(?:!\s*\.surround)(?:\(([^)]+)\))/g,
825
+ (fullMatch, arrayName, sur) => {
826
+ const arr = arraysExfscss[arrayName];
827
+ if (!arr) {
828
+ console.warn(`fscss[@arr] Warning: Array '${arrayName}' not found for direct access.`);
829
+ return fullMatch;
830
+ }
831
+ if(!sur||sur===undefined||sur===""||!sur.includes(",")){
832
+ console.warn(
833
+ `[FSCSS Warning] @arr surround failed → Invalid or empty value at "${fullMatch}"`);
834
+ return fullMatch;
835
+ }
836
+ surArr = sur.split(',');
837
+ return arr.map(u=>`${surArr[0]+u+surArr.at(-1)}`).join(' ');
838
+ });
839
+
840
+
841
+ // 4. Direct array access: @arr.name or @arr.name(separator)
842
+ output = output.replace(/@arr\.([\w\-_—0-9]+)(?:!\s*\.join)?(?:\(([^)]*)\))/g,
843
+ (fullMatch, arrayName, separator) => {
844
+ const arr = arraysExfscss[arrayName];
845
+ if (!arr) {
846
+ console.warn(`fscss[@arr] Warning: Array '${arrayName}' not found for direct access.`);
847
+ return fullMatch;
848
+ }
849
+ const sep = (separator !== undefined && separator !== "") ? separator : ' ';
850
+ return arr.join(sep);
851
+ });
852
+ output = output.replace(/@arr\.([\w\-_—0-9]+)(!)?/g, (match, arrName, fos)=>{
853
+ const arr = arraysExfscss[arrName];
854
+ if (!arr) {
855
+ console.warn(`fscss[@arr] Warning: Array '${arrName}' not found for direct access.`);
856
+ return match;
857
+ }
858
+ if(fos){
859
+ return match;
860
+ }
861
+ return `[${arr.join(',')}]`;
862
+ })
863
+ // Clean up array declarations
864
+ return output
865
+ .replace(arrayDeclarationRegex, '')
866
+ .replace(/\n{3,}/g, '\n\n')
867
+ .trim();
868
+ }
869
+
870
+ function procFun(code) {
871
+ const variables = {};
872
+ const funRegex = /@fun\(([\w\-\_\—0-9]+)\)\s*\{([\s\S]*?)\}\s*/g;
873
+
874
+ function parseStyle(styleStr) {
875
+ const props = {};
876
+ const lines = styleStr.split(';');
877
+ for (let line of lines) {
878
+ line = line.trim();
879
+ if (!line) continue;
880
+ const colonIdx = line.indexOf(':');
881
+ if (colonIdx === -1) {
882
+ console.warn(`fscss[@fun] Invalid style line (missing colon): "${line}"`);
883
+ continue;
884
+ }
885
+ const prop = line.substring(0, colonIdx).trim();
886
+ const value = line.substring(colonIdx + 1).trim();
887
+ if (prop) {
888
+ props[prop] = value;
889
+ } else {
890
+ console.warn(`fscss[@fun] Empty property name in line: "${line}"`);
891
+ }
892
+ }
893
+ return props;
894
+ }
895
+
896
+
897
+ let funMatch;
898
+ while ((funMatch = funRegex.exec(code)) !== null) {
899
+ const varName = funMatch[1];
900
+ const rawStyles = funMatch[2].trim();
901
+ if (variables[varName]) {
902
+ console.warn(`fscss[@fun] Duplicate @fun variable declaration: "${varName}". The last one will overwrite previous declarations.`);
903
+ }
904
+ variables[varName] = {
905
+ raw: rawStyles,
906
+ props: parseStyle(rawStyles)
907
+ };
908
+ }
909
+
910
+ let processedCode = code;
911
+
912
+ // Handle value extraction (e.g., @fun.varname2.bg.value)
913
+ processedCode = processedCode.replace(/@fun\.([\w\-\_\—0-9]+)\.([\w\-\_\—0-9]+)\.value\!?/g, (match, varName, prop) => {
914
+ if (variables[varName] && variables[varName].props[prop]) {
915
+ return variables[varName].props[prop];
916
+ } else {
917
+ console.warn(`fscss[@fun] Value extraction failed for "@fun.${varName}.${prop}.value". Variable or property not found.`);
918
+ }
919
+ return match;
920
+ });
921
+
922
+ // Handle single property rule (e.g., @fun.varname2.background)
923
+ processedCode = processedCode.replace(/@fun\.([\w\-\_\—0-9]+)\.([\w\-\_\—0-9]+)\!?/g, (match, varName, prop) => {
924
+ if (variables[varName] && variables[varName].props[prop]) {
925
+ return `${prop}: ${variables[varName].props[prop]};`;
926
+ } else {
927
+ console.warn(`fscss[@fun] Single property rule failed for "@fun.${varName}.${prop}". Variable or property not found.`);
928
+ }
929
+ return match;
930
+ });
931
+
932
+ // Handle full variable block (e.g., @fun.varname2)
933
+ processedCode = processedCode.replace(/@fun\.([\w\-\_\—0-9]+)(?=[\s;}])\!?/g, (match, varName) => {
934
+ if (variables[varName]) {
935
+ return variables[varName].raw;
936
+ } else {
937
+ console.warn(`[@fun] Full variable block replacement failed for "@fun.${varName}". Variable not found.`);
938
+ }
939
+ return match;
940
+ });
941
+
942
+ // Clean up code
943
+ processedCode = processedCode.replace(funRegex, '');
944
+ processedCode = processedCode.replace(/^\s*[\r\n]/gm, '');
945
+ processedCode = processedCode.trim();
946
+
947
+ return processedCode;
948
+ }
949
+
950
+ function procFunObj(code) {
951
+ const variables = {};
952
+ const funRegex = /@obj\s+([\w\-\_\—0-9]+)\s*\{([\s\S]*?)\}\s*/g;
953
+
954
+ function parseStyle(styleStr) {
955
+ const props = {};
956
+ const lines = styleStr.split(';');
957
+ for (let line of lines) {
958
+ line = line.trim();
959
+ if (!line) continue;
960
+ const colonIdx = line.indexOf(':');
961
+ if (colonIdx === -1) {
962
+ console.warn(`fscss[@obj] Invalid style line (missing colon): "${line}"`);
963
+ continue;
964
+ }
965
+ const prop = line.substring(0, colonIdx).trim();
966
+ const value = line.substring(colonIdx + 1).trim();
967
+ if (prop) {
968
+ props[prop] = value;
969
+ } else {
970
+ console.warn(`fscss[@obj] Empty property name in line: "${line}"`);
971
+ }
972
+ }
973
+ return props;
974
+ }
975
+
976
+
977
+ let funMatch;
978
+ while ((funMatch = funRegex.exec(code)) !== null) {
979
+ const varName = funMatch[1];
980
+ const rawStyles = funMatch[2].trim();
981
+ if (variables[varName]) {
982
+ console.warn(`fscss[@obj] Duplicate @obj variable declaration: "${varName}". The last one will overwrite previous declarations.`);
983
+ }
984
+ variables[varName] = {
985
+ raw: rawStyles,
986
+ props: parseStyle(rawStyles)
987
+ };
988
+ }
989
+
990
+ let processedCode = code;
991
+
992
+ // Handle value extraction (e.g., @fun.varname2.bg.value)
993
+ processedCode = processedCode.replace(/@obj\.([\w\-\_\—0-9]+)\.([\w\-\_\—0-9]+)\.value\!?/g, (match, varName, prop) => {
994
+ if (variables[varName] && variables[varName].props[prop]) {
995
+ return variables[varName].props[prop];
996
+ } else {
997
+ console.warn(`fscss[@obj] Value extraction failed for "@obj.${varName}.${prop}.value". Variable or property not found.`);
998
+ }
999
+ return match;
1000
+ });
1001
+
1002
+ // Handle single property rule (e.g., @fun.varname2.background)
1003
+ processedCode = processedCode.replace(/@obj\.([\w\-\_\—0-9]+)\.([\w\-\_\—0-9]+)\!?/g, (match, varName, prop) => {
1004
+ if (variables[varName] && variables[varName].props[prop]) {
1005
+ return `${prop}: ${variables[varName].props[prop]};`;
1006
+ } else {
1007
+ console.warn(`fscss[@obj] Single property rule failed for "@obj.${varName}.${prop}". Variable or property not found.`);
1008
+ }
1009
+ return match;
1010
+ });
1011
+
1012
+ // Handle full variable block (e.g., @fun.varname2)
1013
+ processedCode = processedCode.replace(/@obj\.([\w\-\_\—0-9]+)(?=[\s;}])\!?/g, (match, varName) => {
1014
+ if (variables[varName]) {
1015
+ return variables[varName].raw;
1016
+ } else {
1017
+ console.warn(`[@obj] Full variable block replacement failed for "@obj.${varName}". Variable not found.`);
1018
+ }
1019
+ return match;
1020
+ });
1021
+
1022
+ // Clean up code
1023
+ processedCode = processedCode.replace(funRegex, '');
1024
+ processedCode = processedCode.replace(/^\s*[\r\n]/gm, '');
1025
+ processedCode = processedCode.trim();
1026
+
1027
+ return processedCode;
1028
+ }
1029
+
1030
+
1031
+ // Extracts values using copy() and creates CSS custom properties
1032
+ function flattenNestedCSS(css, options = {}) {
1033
+ const {
1034
+ preserveComments = false,
1035
+ indent = ' ',
1036
+ validate = true,
1037
+ errorHandler = (msg) => console.warn(msg),
1038
+ } = options;
1039
+
1040
+ // Remove comments unless preserved
1041
+ if (!preserveComments) {
1042
+ css = css.replace(/\/\*[\s\S]*?\*\//g, '').trim();
1043
+ }
1044
+
1045
+ function isValidSelector(selector) {
1046
+ // Allow modern CSS features (:has(), > selector, etc.)
1047
+ return selector && selector.trim() !== '' &&
1048
+ !/[^a-zA-Z0-9\-_@*.\#:,\s>&~+()\[\]'"]|\/\//.test(selector);
1049
+ }
1050
+
1051
+ function isValidProperty(prop) {
1052
+ const [name, ...rest] = prop.split(':').map(s => s.trim());
1053
+ return !validate || /^(--|[\w-]+)$/.test(name);
1054
+ }
1055
+
1056
+ function parseBlock(css, start, parentSelector = '') {
1057
+ let output = '';
1058
+ let pos = start;
1059
+ const stack = [];
1060
+ let current = '';
1061
+ let inString = false;
1062
+ let quote = null;
1063
+ let depth = 0;
1064
+
1065
+ while (pos < css.length) {
1066
+ const char = css[pos];
1067
+
1068
+ if (char === '\\' && inString) {
1069
+ current += char;
1070
+ pos++;
1071
+ if (pos < css.length) {
1072
+ current += css[pos];
1073
+ }
1074
+ pos++;
1075
+ continue;
1076
+ }
1077
+
1078
+ if ((char === '"' || char === "'") && !inString) {
1079
+ inString = true;
1080
+ quote = char;
1081
+ current += char;
1082
+ } else if (char === quote && inString) {
1083
+ inString = false;
1084
+ quote = null;
1085
+ current += char;
1086
+ } else if (char === '{' && !inString) {
1087
+ if (depth === 0) {
1088
+ const selector = current.trim();
1089
+ current = '';
1090
+ stack.push({ selector, parent: parentSelector });
1091
+ } else {
1092
+ current += char;
1093
+ }
1094
+ depth++;
1095
+ } else if (char === '}' && !inString) {
1096
+ depth--;
1097
+ if (depth === 0) {
1098
+ const block = stack.pop();
1099
+ if (!block) continue;
1100
+
1101
+ let fullSelector = '';
1102
+ if (block.selector.includes('&')) {
1103
+ fullSelector = block.selector.replace(/&/g, block.parent);
1104
+ } else {
1105
+ fullSelector = block.parent ? `${block.parent} ${block.selector}` : block.selector;
1106
+ }
1107
+
1108
+ // Parse nested content
1109
+ const nested = parseNestedContent(current, fullSelector);
1110
+
1111
+ if (nested.properties.length > 0 || nested.keyframes.length > 0) {
1112
+ output += `${fullSelector} {\n`;
1113
+ if (nested.properties.length > 0) {
1114
+ output += indent + nested.properties.join(`;\n${indent}`) + ';\n';
1115
+ }
1116
+ output += nested.keyframes.join('\n');
1117
+ output += '}\n\n';
1118
+ }
1119
+
1120
+ output += nested.nestedBlocks;
1121
+ current = '';
1122
+ } else {
1123
+ current += char;
1124
+ }
1125
+ } else if (char === '@' && !inString && depth === 0) {
1126
+ // Handle at-rules at root level
1127
+ const atRuleEnd = findAtRuleEnd(css, pos);
1128
+ if (atRuleEnd === -1) break;
1129
+
1130
+ output += css.substring(pos, atRuleEnd).trim() + '\n\n';
1131
+ pos = atRuleEnd;
1132
+ continue;
1133
+ } else {
1134
+ current += char;
1135
+ }
1136
+
1137
+ pos++;
1138
+ }
1139
+
1140
+ return { output, pos };
1141
+ }
1142
+
1143
+ function findAtRuleEnd(css, start) {
1144
+ let depth = 0;
1145
+ let inString = false;
1146
+ let quote = null;
1147
+ let pos = start;
1148
+
1149
+ while (pos < css.length) {
1150
+ const char = css[pos];
1151
+
1152
+ if (char === '\\' && inString) {
1153
+ pos += 2;
1154
+ continue;
1155
+ }
1156
+
1157
+ if ((char === '"' || char === "'") && !inString) {
1158
+ inString = true;
1159
+ quote = char;
1160
+ } else if (char === quote && inString) {
1161
+ inString = false;
1162
+ quote = null;
1163
+ } else if (char === '{' && !inString) {
1164
+ depth++;
1165
+ } else if (char === '}' && !inString) {
1166
+ depth--;
1167
+ if (depth === 0) {
1168
+ return pos + 1;
1169
+ }
1170
+ }
1171
+
1172
+ pos++;
1173
+ }
1174
+
1175
+ return -1;
1176
+ }
1177
+
1178
+ function parseNestedContent(content, parentSelector) {
1179
+ const result = {
1180
+ properties: [],
1181
+ nestedBlocks: '',
1182
+ keyframes: []
1183
+ };
1184
+
1185
+ let current = '';
1186
+ let inString = false;
1187
+ let quote = null;
1188
+ let depth = 0;
1189
+ let pos = 0;
1190
+
1191
+ while (pos < content.length) {
1192
+ const char = content[pos];
1193
+
1194
+ if (char === '\\' && inString) {
1195
+ current += char;
1196
+ pos++;
1197
+ if (pos < content.length) {
1198
+ current += content[pos];
1199
+ }
1200
+ pos++;
1201
+ continue;
1202
+ }
1203
+
1204
+ if ((char === '"' || char === "'") && !inString) {
1205
+ inString = true;
1206
+ quote = char;
1207
+ current += char;
1208
+ } else if (char === quote && inString) {
1209
+ inString = false;
1210
+ quote = null;
1211
+ current += char;
1212
+ } else if (char === '{' && !inString) {
1213
+ depth++;
1214
+ current += char;
1215
+ } else if (char === '}' && !inString) {
1216
+ depth--;
1217
+ current += char;
1218
+ if (depth === 0) {
1219
+ // Found a complete nested block
1220
+ const block = parseBlock(current, 0, parentSelector).output;
1221
+ result.nestedBlocks += block;
1222
+ current = '';
1223
+ }
1224
+ } else if (char === ';' && !inString && depth === 0) {
1225
+ // Property handling
1226
+ const prop = current.trim();
1227
+ if (prop) {
1228
+ if (isValidProperty(prop)) {
1229
+ result.properties.push(prop);
1230
+ } else if (validate) {
1231
+ errorHandler(`Invalid property: ${prop}`);
1232
+ }
1233
+ }
1234
+ current = '';
1235
+ } else if (char === '@' && !inString && depth === 0) {
1236
+ // Handle keyframes inside blocks
1237
+ const atEnd = findAtRuleEnd(content, pos);
1238
+ if (atEnd === -1) break;
1239
+
1240
+ const atContent = content.substring(pos, atEnd);
1241
+ result.keyframes.push(atContent.trim());
1242
+ pos = atEnd;
1243
+ current = '';
1244
+ continue;
1245
+ } else {
1246
+ current += char;
1247
+ }
1248
+
1249
+ pos++;
1250
+ }
1251
+
1252
+ // Handle trailing property
1253
+ const lastProp = current.trim();
1254
+ if (lastProp && depth === 0) {
1255
+ if (isValidProperty(lastProp)) {
1256
+ result.properties.push(lastProp);
1257
+ } else if (validate) {
1258
+ errorHandler(`Invalid property: ${lastProp}`);
1259
+ }
1260
+ }
1261
+
1262
+ return result;
1263
+ }
1264
+
1265
+ const result = parseBlock(css, 0);
1266
+ return result.output;
1267
+ }
1268
+ function procP(text) {
1269
+ return text.replace(/%(\d+)\(([^[]+)\[\s*([^\]]+)\]\)/g, (match, number, properties, value) => {
1270
+ const propList = properties.split(',').map(p => p.trim());
1271
+ if (propList.length != number) {
1272
+ console.warn(`Number of properties ${propList.length} does not match %${number}`);
1273
+ return match;
1274
+ }
1275
+ return propList.map(prop => `${prop}${value}`).join("");
1276
+ });
1277
+ }
1278
+
1279
+ function transformCssValues(css) {
1280
+ const customProperties = new Set();
1281
+ const copyRegex = /(:\s*)(["']?)(.*?)(["']?)\s*copy\(([-]?\d+),\s*([^\;^\)^\(^,^ ]*)\)/g;
1282
+
1283
+ const transformedCss = css.replace(copyRegex, (match, prefix, quote1, value, quote2, lengthStr, variableName) => {
1284
+ const length = parseInt(lengthStr);
1285
+ const sanitizedVar = variableName.replace(/[^a-zA-Z0-9_-]/g, '');
1286
+ let extractedValue = '';
1287
+
1288
+ if (length >= 0) {
1289
+ extractedValue = value.substring(0, length);
1290
+ } else {
1291
+ extractedValue = value.substring(value.length + length);
1292
+ }
1293
+
1294
+ customProperties.add(`--${sanitizedVar}:${extractedValue};`);
1295
+ return `${prefix}${quote1}${value}${quote2}`;
1296
+ });
1297
+
1298
+ // Append custom properties to :root if any were created
1299
+ if (customProperties.size > 0) {
1300
+ const rootBlock = `:root{${Array.from(customProperties).join('\n')}\n}`;
1301
+ return transformedCss + `\n${rootBlock}`;
1302
+ }
1303
+ return transformedCss;
1304
+ }
1305
+
1306
+ // Repeats a string while handling quotes
1307
+ function repeatString(str, count) {
1308
+ return str.replace(/^['"]|['"]$/g, '').repeat(Math.max(0, parseInt(count)));
1309
+ }
1310
+
1311
+ // Processes recursive CSS patterns (re() function)
1312
+ function replaceRe(css) {
1313
+ // Enhanced regex to capture re() declarations with flexibility
1314
+ const reRegex = /(?:store|str|re)\(\s*([^:,]+)\s*[,:]\s*(?:"([^"]*)"|'([^']*)')\s*\)/gi;
1315
+ const variableMap = new Map();
1316
+
1317
+ // Step 1: Remove re() declarations and store variable-value mappings
1318
+ let cleanedCss = css.replace(reRegex, (match, variable, dqValue, sqValue) => {
1319
+ const value = dqValue || sqValue;
1320
+ variable = variable.trim();
1321
+ variableMap.set(variable, value);
1322
+ return ''; // Completely remove the re() call
1323
+ });
1324
+
1325
+ // If no variables found, return cleaned CSS
1326
+ if (variableMap.size === 0) return cleanedCss;
1327
+
1328
+ // Step 2: Replace variables throughout the CSS
1329
+ let changed;
1330
+ let iterations = 0;
1331
+ const maxIterations = 100;
1332
+ let current = cleanedCss;
1333
+
1334
+ do {
1335
+ changed = false;
1336
+ for (const [variable, value] of variableMap.entries()) {
1337
+ // Use word boundaries to avoid partial replacements
1338
+ const varRegex = new RegExp(`\\b${escapeRegExp(variable)}\\b`, 'g');
1339
+ const newCss = current.replace(varRegex, value);
1340
+
1341
+ if (newCss !== current) {
1342
+ changed = true;
1343
+ current = newCss;
1344
+ }
1345
+ }
1346
+ iterations++;
1347
+ } while (changed && iterations < maxIterations);
1348
+
1349
+ if (iterations >= maxIterations) {
1350
+ console.warn('Maximum iterations reached. Possible circular dependency.');
1351
+ }
1352
+
1353
+ return current;
1354
+ }
1355
+
1356
+ function escapeRegExp(string) {
1357
+ return string.replace(/[.*+?^${}|[\]\\]/g, '\\$&');
1358
+ }
1359
+ /* Variable fallback chain */
1360
+ function vfc(fscss){
1361
+ fscss = fscss.replace(
1362
+ /([\w-]+:\s*)(\$\/?[\w-]+!?)(\s*\|\|\s*([^\n\};]+))?/g,
1363
+ (match, pr, variable, fallbackPart, fallback) => {
1364
+
1365
+ // Invalid variable format
1366
+ if (!/^\$\/[\w-]+!?$/.test(variable)) {
1367
+ console.warn(`fscss[VFC]: Invalid variable escape syntax -> ${variable} at ${match}`);
1368
+ return match;
1369
+ }
1370
+
1371
+ // Required variable but has fallback
1372
+ if (variable.endsWith("!") && fallback) {
1373
+ console.warn(`fscss[VFC]: Required variable "${variable}" should not have fallback (${fallback})`);
1374
+ }
1375
+
1376
+ // Fallback starts with ||
1377
+ if (fallbackPart && !fallback?.trim()) {
1378
+ console.warn(`fscss[VFC]: Empty fallback in -> ${match}`);
1379
+ return match;
1380
+ }
1381
+
1382
+ // Invalid fallback variable syntax
1383
+ if (fallback?.includes("$/") && !/^\$\/[\w-]+!?$/.test(fallback.trim())) {
1384
+ console.warn(`fscss[VFC]: Invalid fallback variable syntax -> ${fallback}`);
1385
+ }
1386
+
1387
+ // Compile logic
1388
+ if (fallback) {
1389
+ return `${pr}${fallback.trim()};${pr}${variable}`;
1390
+ }
1391
+
1392
+ return `${pr}${variable}`;
1393
+ })
1394
+ return fscss;
1395
+ }
1396
+ // Applies all FSCSS transformations to CSS content
1397
+ function applyFscssTransformations(css) {
1398
+ // Handle mx/mxs padding shorthands
1399
+ css = css.replace(/(?:mxs|\$p)\((([^\,]*)\,)?(([^\,]*)\,)?(([^\,]*)\,)?(([^\,]*)\,)?(([^\,]*)\,)?(([^\,]*)\,\s*)?("([^"]*)"|'([^']*)')\)/gi, '$2:$14$15;$4:$14$15;$6:$14$15;$8:$14$15;$10:$14$15;$12:$14$15;')
1400
+ .replace(/(?:mx|\$m)\((([^\,]*)\,)?(([^\,]*)\,)?(([^\,]*)\,)?(([^\,]*)\,)?(([^\,]*)\,)?(([^\,]*)\,\s*)?("([^"]*)"|'([^']*)')\)/gi, '$2$14$15$4$14$15$6$14$15$8$14$15$10$14$15$12$14$15')
1401
+
1402
+ // Handle string repetition (rpt)
1403
+ .replace(/rpt\((\d+)\,\s*("([^"]*)"|'([^']*)')\)/gi, (match, count, quotedStr) => repeatString(quotedStr, count))
1404
+
1405
+ // Process CSS variable declarations and references
1406
+ .replace(/\$(([\_\-\d\w]+)\:(\"[^\"]*\"|\'[^\']*\'|[^\;]*)\;)/gi, ':root{--$1}')
1407
+ .replace(/\$([^\!\s]+)!/gi, 'var(--$1)')
1408
+ .replace(/\$([\w\-\_\d]+)/gi, 'var(--$1)')
1409
+
1410
+ // Handle vendor prefix expansion
1411
+ .replace(/\-\*\-(([^\:]+)\:(\"[^\"]*\"|\'[^\']*\'|[^\;]*)\;)/gi, '-webkit-$1-moz-$1-ms-$1-o-$1')
1412
+ // Process list-based shorthands (%i, %6-%1)
1413
+ .replace(/%i\((([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\]\[]*)\,)?(([^\,\]\[]*)\,)?(([^\,\[\]]*))?\s*\[([^\]\[]*)\]\)/gi, '$2$21$4$21$6$21$8$21$10$21$12$21$14$21$16$21$18$21$20$21')
1414
+ .replace(/%6\((([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\]\[]*)\,)?(([^\,\]\[]*)\,)?(([^\,\[\]]*))?\s*\[([^\]\[]*)\]\)/gi, '$2$13$4$13$6$13$8$13$10$13$12$13')
1415
+ .replace(/%5\((([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\]\[]*)\,)?(([^\,\]\[]*))?\s*\[([^\]\[]*)\]\)/gi, '$2$11$4$11$6$11$8$11$10$11')
1416
+ .replace(/%4\((([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\[\]]*))?\s*\[([^\]\[]*)\]\)/gi, '$2$9$4$9$6$9$8$9')
1417
+ .replace(/%3\((([^\,\[\]]*)\,)?(([^\,\[\]]*)\,)?(([^\,\[\]]*))?\s*\[([^\]\[]*)\]\)/gi, '$2$7$4$7$6$7')
1418
+ .replace(/%2\((([^\,\[\]]*)\,)?(([^\,\]\[]*))?\s*\[([^\]\[]*)\]\)/gi, '$2$5$4$5')
1419
+ .replace(/%1\((([^\,\]\[]*))?\s*\[([^\]\[]*)\]\)/gi, '$2$3');
1420
+ css = procP(css);
1421
+ css = css.replace(/\$\(\s*@keyframes\s*(\S+)\)/gi, '$1{animation-name:$1;}@keyframes $1')
1422
+ .replace(/\$\(\s*(\@[\w\-\*]*)\s*([^\{\}\,&]*)(\s*,\s*[^\{\}&]*)?&?(\[([^\{\}]*)\])?\s*\)/gi, '$2$3{animation:$2 $5;}$1 $2')
1423
+
1424
+ // Process property references
1425
+ .replace(/\$\(\s*--([^\{\}]*)\)/gi, '$1')
1426
+ .replace(/\$\(([^\:]*):\s*([^\)\:]*)\)/gi, '[$1=\'$2\']')
1427
+
1428
+ // Handle grouping syntax (g)
1429
+ .replace(/g\(([^"'\s]*)\,\s*(("([^"]*)"|'([^']*)')\,\s*)?("([^"]*)"|'([^']*)')\s*\)/gi, '$1 $4$5$1 $7$8')
1430
+ .replace(/\$\(([^\:]*):\s*([^\)\:]*)\)/gi, '[$1=\'$2\']')
1431
+ .replace(/\$\(([^\:^\)]*)\)/gi, '[$1]');
1432
+ /* || */
1433
+ return css;
1434
+ }
1435
+ async function impSel(text) {
1436
+ text = await initlibraries(text);
1437
+ const validImpExt = [".fscss", ".css", ".txt", ".scss", ".less", "xfscss"]
1438
+ const regex = /@import\(exec\(([^)]+)\)\s*\.\s*(?:pick|find)\(([^)]+)\)\)/g;
1439
+ const matches = [...text.matchAll(regex)];
1440
+
1441
+
1442
+ let result = text;
1443
+ let setFile = null;
1444
+
1445
+ for (const match of matches) {
1446
+ const [fullMatch, urlSrc, part] = match;
1447
+
1448
+ setFile = urlSrc;
1449
+
1450
+
1451
+ if (runnedSetS.has(setFile)) {
1452
+
1453
+ // Helper to escape special characters in the filename (like dots or dashes)
1454
+ const escapedFile = setFile.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1455
+
1456
+ // Simplified regex using \s* for zero-or-more whitespace
1457
+ const fregex = new RegExp("@import\\(exec\\(("+escapedFile+")\\)\\s*\\.\\s*(?:pick|find)\\(([^)]+)\\)\\)", 'g');
1458
+
1459
+
1460
+ result = result.replace(fregex, `/* Can't import ${setFile} multiple times */`);
1461
+
1462
+ console.warn(`[FSCSS Warning] Can't import ${setFile} multiple times at `);
1463
+ }
1464
+
1465
+ try {
1466
+ const impUrl = urlSrc.replace(/["']/g, "");
1467
+ const impExt = impUrl.slice(impUrl.lastIndexOf(".")).toLowerCase();
1468
+ if (impUrl.trim().startsWith("_init") && impUrl.includes(" ")) {
1469
+ console.warn(`fscss[@import] library not found for: ${impUrl}`);
1470
+ return;
1471
+ }
1472
+
1473
+ if (!validImpExt.includes(impExt)) {
1474
+ console.warn(`fscss[@import] invalid extension for: ${impUrl}`);
1475
+ return;
1476
+ }
1477
+
1478
+ const response = await fetch(impUrl);
1479
+ if (!response.ok) throw new Error(`fscss[@import] HTTP ${response.status} for ${urlSrc}`);
1480
+ const resText = await response.text();
1481
+ const extracted = extractOnlyBlock(resText, part.trim());
1482
+ result = result.replace(fullMatch, extracted);
1483
+ } catch (err) {
1484
+ console.error(`fscss[@import] Failed: ${urlSrc} `, err);
1485
+ result = result.replace(fullMatch, `/* Failed import: ${urlSrc} */`);
1486
+
1487
+ }
1488
+ }
1489
+
1490
+ if(!result.match(regex)) return result;
1491
+ runnedSetS.add(setFile);
1492
+ return impSel(result);
1493
+
1494
+ }
1495
+
1496
+ function extractOnlyBlock(cssText, blockName) {
1497
+ const regex = new RegExp(`${blockName}\\s*{[^}]*}`, "g");
1498
+ const match = cssText.match(regex);
1499
+ return match ? match.join("\n") : console.warn(`fscss[@import pick] No block matches: ${blockName} `);
1500
+ }
1501
+
1502
+ const runnedSetImp = new Set();
1503
+
1504
+ async function procImp(text) {
1505
+ text = await initlibraries(text);
1506
+ const regex = /\@import\((?:\s+)?exec\((?:\s+)?(?:"([^"]+)"|'([^']+)'|`([^`]+)`|([^\)]+)(?:\s+)?)\)(?:\s+)?\)/g;
1507
+
1508
+ const matches = [...text.matchAll(regex)];
1509
+
1510
+ let result = text;
1511
+ let setFile = null;
1512
+
1513
+
1514
+ for (const match of matches) {
1515
+ let [fullMatch, url1, url2, url3, url4] = match;
1516
+
1517
+ const impUrl = (url1 || url2 || url3 || url4).trim();
1518
+ setFile = impUrl;
1519
+
1520
+ if (runnedSetImp.has(setFile)) {
1521
+ // Helper to escape special characters in the filename (like dots or dashes)
1522
+ const escapedFile = setFile.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1523
+
1524
+ // Simplified regex using \s* for zero-or-more whitespace
1525
+ const fregex = new RegExp("\\@import\\((?:\\s+)?exec\\((?:\\s+)?(?:\"("+ escapedFile + ")\"|'("+ escapedFile + ")'|`("+ escapedFile + ")`|("+ escapedFile + ")(?:\\s+)?)\\)(?:\\s+)?\\)", 'g');
1526
+
1527
+
1528
+ result = result.replace(fregex, `/* Can't import ${setFile} multiple times */`);
1529
+
1530
+ console.warn(`[FSCSS Warning] Can't import ${setFile} multiple times at `);
1531
+ }
1532
+
1533
+
1534
+ try {
1535
+
1536
+ const response = await fetch(impUrl);
1537
+
1538
+ if (!response.ok) throw new Error(`fscss[@import] HTTP ${response.status} for ${impUrl}`);
1539
+
1540
+ const resText = await response.text();
1541
+ result = result.replace(fullMatch, resText);
1542
+
1543
+ } catch (error) {
1544
+ console.error(`fscss[@import] Failed: ${impUrl} `, error);
1545
+
1546
+ result = result.replace(fullMatch, `/* Failed import: ${impUrl} */`);
1547
+
1548
+ }
1549
+ }
1550
+
1551
+ if (!result.match(regex)) return result;
1552
+ runnedSetImp.add(setFile);
1553
+ return procImp(result);
1554
+ }
1555
+
1556
+ async function impFrom(text) {
1557
+ text = await initlibraries(text);
1558
+ const regex = /\@import\((?:\s+)?(?:exec)?\(([\w\d\.\@\—\-_*\#\$\s\,]+)\)(?:\s+)?from(?:\s+)?(?:"([^"]+)"|'([^']+)'|`([^`]+)`)(?:\s+)?\)/g;
1559
+
1560
+ const matches = [...text.matchAll(regex)];
1561
+
1562
+ let result = text;
1563
+ let setFile = null;
1564
+
1565
+
1566
+ for (const match of matches) {
1567
+ let [fullMatch, blocks, url1, url2, url3] = match;
1568
+
1569
+ blocks = blocks.trim();
1570
+
1571
+ const impUrl = (url1 || url2 || url3).trim();
1572
+ setFile = impUrl;
1573
+
1574
+ if (runnedSet.has(setFile)) {
1575
+ // Helper to escape special characters in the filename (like dots or dashes)
1576
+ const escapedFile = setFile.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1577
+
1578
+ // Simplified regex using \s* for zero-or-more whitespace
1579
+ const fregex = new RegExp("\\@import\\((?:\\s+)?(?:exec)?\\(([\\w\\d\\.\\@\\—\\-_*\\#\\$\\s\\,]+)\\)(?:\\s+)?from(?:\\s+)?(?:\"((?:\\s+)?" + escapedFile + "(?:\\s+)?)\"|'((?:\\s+)?" + escapedFile + "(?:\\s+)?)'|`((?:\\s+)?" + escapedFile + "(?:\\s+)?)`)(?:\\s+)?\\)", 'g');
1580
+
1581
+
1582
+ result = result.replace(fregex, `/* Can't import ${setFile} multiple times */`);
1583
+
1584
+ console.warn(`[FSCSS Warning] Can't import ${setFile} multiple times at `);
1585
+ }
1586
+
1587
+
1588
+ try {
1589
+
1590
+ const response = await fetch(impUrl);
1591
+
1592
+ if (!response.ok) throw new Error(`fscss[@import] HTTP ${response.status} for ${impUrl}`);
1593
+
1594
+ const resText = await response.text();
1595
+
1596
+ if (blocks === '*') {
1597
+ result = result.replace(fullMatch, resText);
1598
+ }
1599
+ if (blocks !== '*' && blocks.includes('*')) {
1600
+ console.warn(`[FSCSS Warning] syntax error at ${fullMatch}: unexpected *`);
1601
+ result = result.replace(fullMatch, `/* syntax error: unexpected * */`);
1602
+ }
1603
+ if (blocks !== '*' && !blocks.includes('*')) {
1604
+ const arblock = blocks.split(",").map(a => a.trim());
1605
+ const exblocks = findBlock(resText, arblock);
1606
+ result = result.replace(fullMatch, exblocks);
1607
+ }
1608
+
1609
+ } catch (error) {
1610
+ console.error(`fscss[@import] Failed: ${impUrl} `, error);
1611
+
1612
+ result = result.replace(fullMatch, `/* Failed import: ${impUrl} */`);
1613
+
1614
+ }
1615
+ }
1616
+
1617
+ if (!result.match(regex)) return result;
1618
+
1619
+ runnedSet.add(setFile);
1620
+ return impFrom(result);
1621
+ }
1622
+
1623
+ function findBlock(text, blocks = []) {
1624
+ if (!text || text === "" || typeof text !== "string") return console.warn("FSCSS >Invalid input");
1625
+ if (!blocks || blocks.length === 0) return console.warn("FSCSS >Invalid input");
1626
+ let resBlock = '';
1627
+
1628
+ blocks.forEach(key => {
1629
+ let blk = '';
1630
+ let keyname = key;
1631
+
1632
+ //Captures the source, the 'as' keyword, and
1633
+ const aliasRegex = /([^\s]+)(?:\s+as\s+([^\s]+))?/;
1634
+ const matchAs = key.trim().match(aliasRegex);
1635
+
1636
+ if (matchAs) {
1637
+ const [_, name, alias] = matchAs;
1638
+ keyname = name;
1639
+ if (alias) {
1640
+ blk = alias;
1641
+ } else if (key.includes(' as')) {
1642
+ // Handles the "func as " (missing alias) case
1643
+ console.warn(`[FSCSS Warning] Can't assign @${name} to invalid or empty value`);
1644
+ blk = name;
1645
+ } else {
1646
+ blk = name;
1647
+ }
1648
+ }
1649
+
1650
+ const regex = new RegExp('@define\\s+(' + keyname + ')\\s*\\(([^)]*)\\)\\s*\\$?\\{\\s*(?:"([^"]*)"|\'([^\']*)\'|`([^`]*)`|([^\\}^\\{]*?))\\s*\\}', "g");
1651
+
1652
+ const match = text.match(regex);
1653
+ if (!match) {
1654
+ return console.warn(`[FSCSS Warning] @${keyname} is undefined for import`);
1655
+ }
1656
+ const resRegex = new RegExp('(@define\\s+)(' + keyname + ')(\\s*\\(([^)]*)\\)\\s*\\$?\\{\\s*(?:"([^"]*)"|\'([^\']*)\'|`([^`]*)`|([^\\}^\\{]*?))\\s*\\})', 'g');
1657
+
1658
+ resBlock += (match.join('\n')).replace(resRegex, (m, g1, g2, g3) => {
1659
+ return `${g1}${blk}${g3}`;
1660
+ }) + '\n';
1661
+ })
1662
+ return resBlock.trim();
1663
+ }
1664
+
1665
+ async function processStyles() {
1666
+ const styleElements = document.querySelectorAll('style');
1667
+
1668
+ if (!styleElements.length) {
1669
+ console.warn('fscss[Obj]\n No <style> elements found.');
1670
+ return;
1671
+ }for (const element of styleElements) {
1672
+ let css = element.textContent;
1673
+ if(!css.includes("exec.obj.block(all)")){
1674
+ if(!css.includes("exec.obj.block(f import)")||!css.includes("exec.obj.block(f import pick)"))css = await impSel(css);
1675
+ if(!css.includes("exec.obj.block(f import)")||!css.includes("exec.obj.block(f import from)"))css = await impFrom(css);
1676
+ if(!css.includes("exec.obj.block(f import)"))css = await procImp(css);
1677
+ if(!css.includes("exec.obj.block(vfc)")) css = vfc(css);
1678
+ if(!css.includes("exec.obj.block(store:before)")||!css.includes("exec.obj.block(store)"))css = replaceRe(css);
1679
+ if(!css.includes("exec.obj.block(ext:before)")||!css.includes("exec.obj.block(ext)"))css = procExt(css);
1680
+ if(!css.includes("exec.obj.block(f var)"))css = procVar(css);
1681
+ if(!css.includes("exec.obj.block(fun)"))css = procFun(css);
1682
+ if(!css.includes("exec.obj.block(obj)"))css = procFunObj(css);
1683
+ if(!css.includes("exec.obj.block(length)"))css = procChe(css);
1684
+ if(!css.includes("exec.obj.block(count)"))css = procCnt(css);
1685
+ if(!css.includes("exec.obj.block(define)"))css = procDef(css);
1686
+ if(!css.includes("exec.obj.block(arr)"))css = procArr(css);
1687
+ if(!css.includes("exec.obj.block(event)"))css = procEv(css);
1688
+ if(!css.includes("exec.obj.block(random)"))css = procRan(css);
1689
+ if(!css.includes("exec.obj.block(copy)"))css = transformCssValues(css);
1690
+ if(!css.includes("exec.obj.block(store:after)")||!css.includes("exec.obj.block(store)"))css = replaceRe(css);
1691
+ if(!css.includes("exec.obj.block(num)"))css = procNum(css);
1692
+ if(!css.includes("exec.obj.block(ext:after)")||!css.includes("exec.obj.block(ext)"))css = procExt(css);
1693
+ if(!css.includes("exec.obj.block(t group)"))css = applyFscssTransformations(css);
1694
+ if(!css.includes("exec.obj.block(length)"))css = procChe(css);
1695
+ if(!css.includes("exec.obj.block(count)"))css = procCnt(css);
1696
+ if(!css.includes("exec.obj.block(debug)"))css = procExC(css);
1697
+ }
1698
+ css=css.replace(/exec\.obj\.block\([^\)\n]*\)\;?/g, "");
1699
+ element.innerHTML = css;
1700
+
1701
+ }
1702
+ }
1703
+ function processDrawElements() {
1704
+ document.querySelectorAll('.draw').forEach(element => {
1705
+ const originalColor = element.style.color || '#000';
1706
+ element.style.color = 'transparent';
1707
+ element.style.webkitTextStroke = `2px ${originalColor}`;
1708
+ });
1709
+ }
1710
+
1711
+ try {
1712
+ await processStyles();
1713
+ await processDrawElements(); // This can run after styles are processed
1714
+ } catch (error) {
1715
+ console.error('Error processing styles or draw elements:', error);
1716
+ }
1717
+ })()}
1718
+
1719
+ function applyFscssStyles() {const fscssLinks=document.querySelectorAll('[type*="fscss"]');
1720
+ fscssLinks.forEach(link => {fetch(link.href).then(
1721
+ response=>response.text()
1722
+
1723
+ ).then(css =>{
1724
+ const style=document.createElement('style');
1725
+ style.textContent = css;
1726
+ document.head.appendChild(style);xfscssProcessorWrap();}).catch(error => {
1727
+ console.error(`Failed to load FSCSS from ${link.href}`, error);});});}
1728
+
1729
+
1730
+ xfscssProcessorWrap();
1731
+ applyFscssStyles();
1732
+
1733
+