@three-blocks/devtools 1.0.0-alpha.176.g8ff8a72e6369
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/CHANGELOG.md +11 -0
- package/LICENSE +76 -0
- package/NOTICE +32 -0
- package/README.md +254 -0
- package/dist/browser/environment-bake.js +1 -0
- package/dist/browser/shader-capture.d.ts +45 -0
- package/dist/browser/shader-capture.js +3 -0
- package/dist/browser-smoke-76626IZQ.js +254 -0
- package/dist/chunk-26FK4CRS.js +6 -0
- package/dist/chunk-4EHPYBKA.cjs +1 -0
- package/dist/chunk-5L2VS3BN.js +2 -0
- package/dist/chunk-76WRV5MZ.js +7 -0
- package/dist/chunk-EI7MMDWY.js +1 -0
- package/dist/chunk-HOZDD6PW.js +2 -0
- package/dist/chunk-HRYYNBVC.js +3 -0
- package/dist/chunk-INDAJN42.js +94 -0
- package/dist/chunk-JMS5NTP7.js +3 -0
- package/dist/chunk-ME3X2KFY.js +14 -0
- package/dist/chunk-NE7SC2BX.js +2 -0
- package/dist/chunk-SCJNCGMF.js +17 -0
- package/dist/chunk-UDUICSME.js +1 -0
- package/dist/chunk-VGJ3V4QQ.js +78 -0
- package/dist/chunk-ZDNZCQUQ.js +2 -0
- package/dist/chunk-ZKK6E42X.js +1 -0
- package/dist/chunk-ZT6T2W4B.js +2 -0
- package/dist/cli.js +24 -0
- package/dist/environment-bake-5P4IAL4O.js +4 -0
- package/dist/index.d.ts +1183 -0
- package/dist/index.js +272 -0
- package/dist/shader-autowire-DCODBFMX.js +18 -0
- package/dist/shader-browser-65V22LLL.js +1 -0
- package/dist/shader-browser-JII6ZFCW.js +2 -0
- package/dist/shader-capture-server.d.ts +272 -0
- package/dist/shader-capture-server.js +19 -0
- package/dist/shader-config-4EXO5DKK.js +2 -0
- package/dist/shader-parity-QXJWR6OZ.js +1 -0
- package/dist/shader-parity-XPKQQK26.js +2 -0
- package/dist/shader-project-runner-GUR3LTYS.js +5 -0
- package/dist/shader-transform-CUkZn5Oa.d.ts +55 -0
- package/dist/shader-watch-QHTNTSZE.js +2 -0
- package/dist/shader-workflow-U4G565EB.js +2 -0
- package/dist/status-DV2BYZHR.js +2 -0
- package/dist/text-atlas-BHPSDU7C.js +2 -0
- package/dist/transform.cjs +1 -0
- package/dist/transform.d.ts +62 -0
- package/dist/transform.js +1 -0
- package/dist/webpack-loader.cjs +1 -0
- package/dist/webpack-loader.d.ts +17 -0
- package/dist/webpack-loader.js +1 -0
- package/fonts/OFL-1.1.txt +93 -0
- package/package.json +113 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import {c,d,b as b$1}from'./chunk-VGJ3V4QQ.js';export{a as DOCUMENTED_BROWSER_NOISE,k as createAttachedPlaywrightShaderDriver,i as createPlaywrightShaderDriver,j as createStaticPlaywrightShaderDriver,b as isDocumentedBrowserNoise,h as isRetryableShaderObservationNavigation,c as webgpuBrowserArgs,d as webgpuBrowserHeadless}from'./chunk-VGJ3V4QQ.js';import {a as a$1,l,d as d$1,f,j,e,i,g,m,h,w,r,s,o,k,c as c$1,F,v,C,u,t,B,L,I,K,p,J,b}from'./chunk-SCJNCGMF.js';export{o as SHADER_ARTIFACT_DIRECTORY,N as SHADER_CAPTURE_CLIENT_ID,y as SHADER_COMMITTED_TIMING_FILE,v as SHADER_DEVTOOLS_VERSION,x as SHADER_LOCAL_TIMING_FILE,p as SHADER_PARITY_DIRECTORY,z as SHADER_PARITY_EVIDENCE_FILE,w as SHADER_PROVIDER_TRANSFORM_VERSION,n as SHADER_TOOL_CONFIG_FILE,Q as applyShaderProviderTransform,S as assertShaderProviderTransform,R as createShaderProviderTransform,u as ensureShaderToolConfig,r as findShaderProjectRoot,t as inferShaderCaptureTarget,M as loadShaderCaptureRuntimeSource,s as loadShaderToolConfig,b as parseProjectMetadata,c as parseShaderReceipt,q as parseShaderToolConfig,H as readShaderCommittedTiming,E as readShaderLocalTiming,G as readShaderParityEvidence,F as readShaderTiming,D as serializeShaderManifest,A as shaderCoverage,C as stableStringify,B as validateShaderCapture,L as writeShaderArtifacts,I as writeShaderLocalTiming,J as writeShaderParityEvidence,K as writeShaderTimingTwins}from'./chunk-SCJNCGMF.js';export{b as compareShaderScreenshots,a as shaderScreenshotMetrics}from'./chunk-UDUICSME.js';import {a}from'./chunk-EI7MMDWY.js';import {rm,mkdir,writeFile,rename,realpath,readdir,readFile,lstat}from'fs/promises';import U from'path';import {createRequire}from'module';import {createHash,randomUUID}from'crypto';import pn,{platform,homedir}from'os';import {fileURLToPath}from'url';import*as at from'zlib';import at__default from'zlib';import {createDefaultContainer,VK_FORMAT_R8G8B8A8_UNORM,KHR_SUPERCOMPRESSION_ZSTD,KHR_SUPERCOMPRESSION_NONE,KHR_DF_FLAG_ALPHA_STRAIGHT,KHR_DF_TRANSFER_LINEAR,KHR_DF_PRIMARIES_BT709,KHR_DF_MODEL_RGBSDA,KHR_DF_VERSION,KHR_DF_KHR_DESCRIPTORTYPE_BASICFORMAT,KHR_DF_VENDORID_KHRONOS,KHR_DF_CHANNEL_RGBSDA_RED,KHR_DF_CHANNEL_RGBSDA_GREEN,KHR_DF_CHANNEL_RGBSDA_BLUE,KHR_DF_CHANNEL_RGBSDA_ALPHA,KHR_DF_SAMPLE_DATATYPE_LINEAR,write,read,VK_FORMAT_R16G16B16A16_SFLOAT}from'ktx-parse';import ws from'msdf-bmfont-xml';import Gr from'opentype.js';import {PNG}from'pngjs';import {THREE_WEBGPU_R185_COMPATIBILITY,SHADER_ADDRESS_SCHEMA_VERSION,SHADER_RECIPE_SCHEMA_VERSION,SHADER_HYDRATION_SCHEMA_VERSION}from'three-blocks/shaders';import {watch}from'fs';var Pr=4096,Bo=createRequire(import.meta.url),$r,H=new Proxy({},{get(e,t){return $r??=Bo("typescript"),Reflect.get($r,t)}});function ve(e){let t=e;for(;H.isParenthesizedExpression(t)||H.isAsExpression(t)||H.isSatisfiesExpression(t)||H.isNonNullExpression(t);)t=t.expression;return t}a(ve,"unwrap");function Po(e){if(H.isIdentifier(e)||H.isStringLiteral(e)||H.isNumericLiteral(e))return e.text}a(Po,"propertyName");function bt(e,t){let r=new Map;for(let n of e.properties){if(!H.isPropertyAssignment(n))throw new Error(`${t} may contain only static property assignments.`);let o=Po(n.name);if(o===void 0||r.has(o))throw new Error(`${t} contains a computed or duplicate property.`);r.set(o,n.initializer);}return r}a(bt,"properties");function St(e,t){if(e===void 0)throw new Error(`${t} is missing.`);let r=ve(e);if(!H.isObjectLiteralExpression(r))throw new Error(`${t} must be a static object literal.`);return r}a(St,"objectLiteral");function kt(e,t){if(e===void 0)throw new Error(`${t} is missing.`);let r=ve(e);if(!H.isStringLiteral(r)&&!H.isNoSubstitutionTemplateLiteral(r))throw new Error(`${t} must be a string literal.`);return r.text}a(kt,"stringLiteral");function xt(e,t){if(e===void 0)throw new Error(`${t} is missing.`);let r=ve(e);if(!H.isNumericLiteral(r))throw new Error(`${t} must be a numeric literal.`);return Number(r.text)}a(xt,"numericLiteral");function _r(e,t){if(e===void 0)throw new Error(`${t} is missing.`);let r=ve(e);if(!H.isArrayLiteralExpression(r))throw new Error(`${t} must be a static array literal.`);return r.elements}a(_r,"arrayLiteral");function $o(e,t){if(e===void 0)throw new Error(`${t} is missing.`);let r=ve(e);if(r.kind===H.SyntaxKind.NullKeyword)return null;if(!H.isNumericLiteral(r))throw new Error(`${t} must be null or a numeric literal.`);return Number(r.text)}a($o,"numericOrNullLiteral");function _o(e){return e.parseDiagnostics??[]}a(_o,"parseDiagnostics");function Rt(e,t,r,n){let o=H.createSourceFile(t,e,H.ScriptTarget.Latest,true,H.ScriptKind.TS),s=_o(o);if(s.length>0)throw new Error(`Shader manifest is not valid TypeScript: ${H.flattenDiagnosticMessageText(s[0]?.messageText??"parse error"," ")}`);let i=o.statements.filter(H.isExportAssignment).filter(f=>!f.isExportEquals);if(i.length!==1)throw new Error("Shader manifest must contain exactly one default export.");let a$1=bt(St(i[0]?.expression,"Shader manifest default export"),"Shader manifest"),c=a$1.get("version");if(c===void 0||!H.isNumericLiteral(ve(c))||Number(ve(c).getText(o))!==3)throw new Error("Shader manifest version must be the numeric literal 3.");if(kt(a$1.get("scene"),"Shader manifest scene")!==r)throw new Error(`Shader manifest scene does not match "${r}".`);if(n){if(kt(a$1.get("three"),"Shader manifest Three.js version")!==n.three||kt(a$1.get("threeBlocks"),"Shader manifest Three Blocks version")!==n.threeBlocks)throw new Error("Shader manifest runtime versions do not match its receipt.");let f=bt(St(a$1.get("runtime"),"Shader manifest runtime"),"Shader manifest runtime");if(kt(f.get("id"),"Shader manifest runtime id")!==n.compatibility||xt(f.get("address"),"Shader manifest address schema")!==n.address||xt(f.get("recipe"),"Shader manifest recipe schema")!==n.recipe||xt(f.get("hydration"),"Shader manifest hydration schema")!==n.hydration)throw new Error("Shader manifest runtime compatibility schemas do not match its receipt.")}let u=bt(St(a$1.get("entries"),"Shader manifest entries"),"Shader manifest entries");if(u.size===0||u.size>Pr)throw new Error(`Shader manifest must contain between 1 and ${Pr} entries.`);let p=_r(a$1.get("modules"),"Shader manifest modules").map((f,h)=>{let y=ve(f);if(!H.isStringLiteral(y)&&!H.isNoSubstitutionTemplateLiteral(y))throw new Error(`Shader manifest module ${h} must be a WGSL string literal.`);if(y.text.length===0)throw new Error(`Shader manifest module ${h} is empty.`);return y.text}),l=_r(a$1.get("states"),"Shader manifest states").map((f,h)=>{let y=bt(St(f,`Shader manifest state ${h}`),`Shader manifest state ${h}`),g=a((I,S)=>{let F=$o(y.get(I),`Shader manifest state ${h} ${I}`);if(F===null)return false;let _=p[F];if(_===void 0||!_.includes(S))throw new Error(`Shader manifest state ${h} ${I} does not reference a ${S} module.`);return true},"moduleAt"),R=g("vertex","@vertex"),k=g("fragment","@fragment"),w=g("compute","@compute");if(w&&(R||k))throw new Error(`Shader manifest state ${h} mixes render and compute stages.`);if(!w&&!R&&!k)throw new Error(`Shader manifest state ${h} contains no shader stage.`);return {vertex:R,fragment:k,compute:w}}),m={render:0,vertex:0,fragment:0,compute:0};for(let[f,h]of u){if(f.length===0||/[\u0000-\u001f\u007f]/.test(f))throw new Error("Shader manifest contains an invalid entry key.");let y=xt(h,`Shader manifest entry "${f}"`),g=l[y];if(g===void 0)throw new Error(`Shader manifest entry "${f}" references an absent state.`);(g.vertex||g.fragment)&&(m.render+=1),g.vertex&&(m.vertex+=1),g.fragment&&(m.fragment+=1),g.compute&&(m.compute+=1);}return m}a(Rt,"inspectPrecompiledManifest");var Mo=createRequire(import.meta.url),Ar,V=new Proxy({},{get(e,t){return Ar??=Mo("typescript"),Reflect.get(Ar,t)}}),Oo=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),Fo=new Set(["script","style","template"]),Cr=2e5,Io={amp:"&",apos:"'",copy:"\xA9",deg:"\xB0",gt:">",hellip:"\u2026",ldquo:"\u201C",lsquo:"\u2018",lt:"<",mdash:"\u2014",nbsp:"\xA0",ndash:"\u2013",quot:'"',rdquo:"\u201D",rsquo:"\u2019"};function Lo(e){return e.replace(/&(#x[0-9a-f]+|#[0-9]+|[a-z][a-z0-9]+);/giu,(t,r)=>{if(r.startsWith("#x")||r.startsWith("#X")){let n=Number.parseInt(r.slice(2),16);return nt(n)?String.fromCodePoint(n):t}if(r.startsWith("#")){let n=Number.parseInt(r.slice(1),10);return nt(n)?String.fromCodePoint(n):t}return Io[r.toLowerCase()]??t})}a(Lo,"decodeHtmlEntities");function nt(e){return Number.isSafeInteger(e)&&e>=0&&e<=1114111&&!(e>=55296&&e<=57343)}a(nt,"validCodePoint");function Or(e){return nt(e)&&e>=32&&!(e>=127&&e<=159)}a(Or,"renderableCodePoint");function jo(e){return /(?:^|\s)data-canvas-text(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+))?(?=\s|\/?>)/iu.test(e)}a(jo,"hasCanvasTextAttribute");function Gt(e){let t=[],r=[],n=e.match(/<!--[\s\S]*?-->|<![^>]*>|<[^>]*>|[^<]+/gu)??[];for(let o of n){if(!o.startsWith("<")){if(r.some(c=>c.synchronized)&&!r.some(c=>c.skipped)){let c=Lo(o);c.trim().length>0&&t.push(c);}continue}if(o.startsWith("<!--")||o.startsWith("<!")||o.startsWith("<?"))continue;let s=/^<\s*\//u.test(o),i=/^<\s*\/?\s*([a-z][a-z0-9:-]*)/iu.exec(o)?.[1]?.toLowerCase();if(!i)continue;if(s){let c=r.map(u=>u.tag).lastIndexOf(i);c>=0&&r.splice(c);continue}/\/\s*>$/u.test(o)||Oo.has(i)||r.push({tag:i,synchronized:jo(o),skipped:Fo.has(i)});}return t}a(Gt,"extractCanvasTextFromHtml");function No(e){let t=new Set,r=new Set;for(let n of e.statements){if(!V.isImportDeclaration(n)||!V.isStringLiteral(n.moduleSpecifier)||n.moduleSpecifier.text!=="three-blocks/text")continue;let o=n.importClause?.namedBindings;if(o&&V.isNamespaceImport(o)&&r.add(o.name.text),o&&V.isNamedImports(o))for(let s of o.elements)(s.propertyName?.text??s.name.text)==="defineTextContent"&&t.add(s.name.text);}return {named:t,namespaces:r}}a(No,"importedTextHelpers");function Do(e,t){return V.isIdentifier(e)?t.named.has(e.text):V.isPropertyAccessExpression(e)&&V.isIdentifier(e.expression)&&t.namespaces.has(e.expression.text)&&e.name.text==="defineTextContent"}a(Do,"isDefineTextContentCall");function Ho(e){let t=e;for(;V.isParenthesizedExpression(t)||V.isAsExpression(t)||V.isSatisfiesExpression(t)||V.isTypeAssertionExpression(t);)t=t.expression;return t}a(Ho,"unwrapExpression");function Wt(e,t,r){let n=Ho(e);if(V.isStringLiteral(n)||V.isNoSubstitutionTemplateLiteral(n)){t.push(n.text);return}if(V.isArrayLiteralExpression(n)){for(let i of n.elements){if(V.isSpreadElement(i))throw new Error(`${r}: defineTextContent() cannot use spread elements.`);Wt(i,t,r);}return}if(V.isObjectLiteralExpression(n)){for(let i of n.properties){if(!V.isPropertyAssignment(i))throw new Error(`${r}: defineTextContent() accepts only static property assignments.`);Wt(i.initializer,t,r);}return}let o=n.getStart(),s=n.getSourceFile().getLineAndCharacterOfPosition(o).line+1;throw new Error(`${r}:${s}: defineTextContent() contains dynamic text; declare a Unicode range or an explicit static string.`)}a(Wt,"collectStaticStrings");function zt(e,t="content.ts"){let r=V.createSourceFile(t,e,V.ScriptTarget.Latest,true,t.endsWith(".tsx")?V.ScriptKind.TSX:V.ScriptKind.TS),n=No(r),o=[];function s(i){if(V.isCallExpression(i)&&Do(i.expression,n)){if(i.arguments.length!==1||!i.arguments[0])throw new Error(`${t}: defineTextContent() requires exactly one static argument.`);Wt(i.arguments[0],o,t);return}V.forEachChild(i,s);}return a(s,"visit"),s(r),o}a(zt,"extractDefinedTextContent");function Vo(e){let t=[];if(e==="latin"){for(let r=32;r<=126;r++)t.push(r);for(let r of "\u2018\u2019\u201C\u201D\u2013\u2014\u2026\u2022\xB7\xAB\xBB\u2039\u203A\u20AC\xA3\xA5\xB0\xB1\xD7\xF7\xA9\xAE\u2122\xA0"){let n=r.codePointAt(0);n!==void 0&&t.push(n);}}else {for(let r=12353;r<=12438;r++)t.push(r);for(let r=12443;r<=12447;r++)t.push(r);for(let r=12448;r<=12543;r++)t.push(r);for(let r of "\u3000\u3001\u3002\u300C\u300D\u300E\u300F\uFF08\uFF09\u30FB\u30FC\u301C\u3008\u3009\u300A\u300B\u3010\u3011\uFF01\uFF1F\uFF1A\uFF1B\uFF10\uFF11\uFF12\uFF13\uFF14\uFF15\uFF16\uFF17\uFF18\uFF19\uFF05\uFF06"){let n=r.codePointAt(0);n!==void 0&&t.push(n);}}return t}a(Vo,"presetCodePoints");function Mr(e,t){for(let r of t.normalize("NFC")){let n=r.codePointAt(0);n!==void 0&&Or(n)&&e.add(n);}}a(Mr,"addCharacters");function Kt(e,t={}){let r=new Set;for(let a of e)Mr(r,a);t.additionalCharacters&&Mr(r,t.additionalCharacters);for(let a of t.presets??[])for(let c of Vo(a))r.add(c);let n=0;for(let a of t.ranges??[]){if(!nt(a.start)||!nt(a.end)||a.end<a.start)throw new RangeError("Text Unicode ranges must contain ordered Unicode scalar values.");if(n+=a.end-a.start+1,n>Cr)throw new RangeError(`Configured Unicode ranges exceed the ${Cr}-code-point safety limit.`);for(let c=a.start;c<=a.end;c++)Or(c)&&r.add(c);}r.add(32),r.add(63),r.add(65533);let o=[...r].sort((a,c)=>a-c),s=o.map(a=>String.fromCodePoint(a)).join(""),i=createHash("sha256").update(s.normalize("NFC")).digest("hex");return {codePoints:o,characters:s,hash:i}}a(Kt,"buildGlyphSet");var Wo=createRequire(import.meta.url),Fr,M=new Proxy({},{get(e,t){return Fr??=Wo("typescript"),Reflect.get(Fr,t)}});function Go(e){let t=e;for(;M.isParenthesizedExpression(t)||M.isAsExpression(t)||M.isSatisfiesExpression(t)||M.isTypeAssertionExpression(t);)t=t.expression;return t}a(Go,"unwrap");function zo(e,t){if(M.isIdentifier(e)||M.isStringLiteral(e)||M.isNumericLiteral(e))return e.text;throw new Error(`${t}: text configuration property names must be static.`)}a(zo,"propertyName");function vt(e,t){let r=Go(e);if(M.isStringLiteral(r)||M.isNoSubstitutionTemplateLiteral(r))return r.text;if(M.isNumericLiteral(r))return Number(r.text);if(r.kind===M.SyntaxKind.TrueKeyword)return true;if(r.kind===M.SyntaxKind.FalseKeyword)return false;if(r.kind===M.SyntaxKind.NullKeyword)return null;if(M.isPrefixUnaryExpression(r)&&(r.operator===M.SyntaxKind.MinusToken||r.operator===M.SyntaxKind.PlusToken)){let o=vt(r.operand,t);if(typeof o=="number")return r.operator===M.SyntaxKind.MinusToken?-o:o}if(M.isArrayLiteralExpression(r))return r.elements.map(o=>{if(M.isSpreadElement(o))throw new Error(`${t}: text configuration cannot use spread elements.`);return vt(o,t)});if(M.isObjectLiteralExpression(r)){let o=Object.create(null);for(let s of r.properties){if(!M.isPropertyAssignment(s))throw new Error(`${t}: text configuration accepts only static property assignments.`);let i=zo(s.name,t);if(Object.hasOwn(o,i))throw new Error(`${t}: duplicate text configuration property "${i}".`);o[i]=vt(s.initializer,t);}return o}let n=r.getSourceFile().getLineAndCharacterOfPosition(r.getStart()).line+1;throw new Error(`${t}:${n}: text configuration must be statically inspectable.`)}a(vt,"evaluateStatic");function Ko(e){let t=new Set,r=new Set;for(let n of e.statements){if(!M.isImportDeclaration(n)||!M.isStringLiteral(n.moduleSpecifier)||n.moduleSpecifier.text!=="three-blocks/text")continue;let o=n.importClause?.namedBindings;if(o&&M.isNamespaceImport(o)&&r.add(o.name.text),o&&M.isNamedImports(o))for(let s of o.elements)(s.propertyName?.text??s.name.text)==="defineText"&&t.add(s.name.text);}return {named:t,namespaces:r}}a(Ko,"helperNames");function qo(e,t){return M.isIdentifier(e)?t.named.has(e.text):M.isPropertyAccessExpression(e)&&M.isIdentifier(e.expression)&&t.namespaces.has(e.expression.text)&&e.name.text==="defineText"}a(qo,"isDefineTextCall");function he(e,t){if(typeof e!="string"||e.trim().length===0)throw new Error(`${t} must be a non-empty string.`);return e}a(he,"requiredString");function Et(e,t,r=false){if(!Array.isArray(e)||!r&&e.length===0)throw new Error(`${t} must be ${r?"an":"a non-empty"} array of strings.`);return e.map((n,o)=>he(n,`${t}[${o}]`))}a(Et,"stringArray");function Tt(e,t){if(e.includes("\\")||U.posix.isAbsolute(e)||U.posix.normalize(e)!==e||e===".."||e.startsWith("../")||/[\u0000-\u001f\u007f]/u.test(e))throw new Error(`${t} must be a safe project-relative path.`);return e}a(Tt,"safeProjectPath");function Xo(e,t){if(!a$1(e))throw new Error(`${t} must be an object.`);let r=Object.keys(e).sort();if(r.length===1&&r[0]==="builtin")return {builtin:he(e.builtin,`${t}.builtin`)};if(r.length===1&&r[0]==="path")return {path:Tt(he(e.path,`${t}.path`),`${t}.path`)};if(r.join(",")==="checksum,file,package")return {package:he(e.package,`${t}.package`),file:Tt(he(e.file,`${t}.file`),`${t}.file`),checksum:he(e.checksum,`${t}.checksum`)};throw new Error(`${t} must select exactly one supported source.`)}a(Xo,"parseFontSource");function qt(e,t){let r=he(e,t);if(r.includes("\\")||/[\u0000-\u001f\u007f]/u.test(r)||r.split("/").includes(".."))throw new Error(`${t} is unsafe.`);return r}a(qt,"deployedPath");function Jo(e){if(e===void 0)return {};if(!a$1(e))throw new Error("Text generation options must be an object.");let t=e.presets===void 0?void 0:Et(e.presets,"Text generation presets",true).map(c=>{if(c!=="latin"&&c!=="japanese-kana")throw new Error(`Unsupported text preset "${c}".`);return c}),r;if(e.ranges!==void 0){if(!Array.isArray(e.ranges))throw new Error("Text generation ranges must be an array.");r=e.ranges.map((c,u)=>{if(!a$1(c)||typeof c.start!="number"||typeof c.end!="number")throw new Error(`Text generation range ${u} is invalid.`);return {start:c.start,end:c.end}});}let n=a(c=>{let u=e[c];if(u!==void 0){if(typeof u!="number"||!Number.isFinite(u))throw new Error(`Text generation ${c} must be finite.`);return u}},"numeric"),o=n("size"),s=n("distanceRange"),i=n("padding"),a$2=n("maxTextureSize");return {...t===void 0?{}:{presets:t},...r===void 0?{}:{ranges:r},...e.additionalCharacters===void 0?{}:{additionalCharacters:he(e.additionalCharacters,"Text generation additionalCharacters")},...o===void 0?{}:{size:o},...s===void 0?{}:{distanceRange:s},...i===void 0?{}:{padding:i},...a$2===void 0?{}:{maxTextureSize:a$2}}}a(Jo,"parseGeneration");function Yo(e){if(!a$1(e)||e.schemaVersion!==void 0&&e.schemaVersion!==1)throw new Error("Text configuration must use schemaVersion 1.");let t=Et(e.content,"Text content inputs").map(o=>Tt(o,"Text content input"));if(!a$1(e.fonts)||Object.keys(e.fonts).length===0)throw new Error("Text fonts must be a non-empty object.");let r={},n=0;for(let[o,s]of Object.entries(e.fonts)){if(he(o,"Text font key"),!a$1(s))throw new Error(`Text font "${o}" must be an object.`);let i=s.default===true;i&&n++,r[o]={source:Xo(s.source,`Text font "${o}" source`),browser:qt(s.browser,`Text font "${o}" browser path`),atlas:qt(s.atlas,`Text font "${o}" atlas path`),metrics:qt(s.metrics,`Text font "${o}" metrics path`),families:Et(s.families,`Text font "${o}" families`),languages:s.languages===void 0?[]:Et(s.languages,`Text font "${o}" languages`,true),default:i};}if(Object.keys(r).length>1&&n!==1)throw new Error("Multiple text fonts require exactly one default route.");if(n>1)throw new Error("Text fonts can select only one default route.");return {schemaVersion:1,content:t,fonts:r,generation:Jo(e.generation)}}a(Yo,"validateConfiguration");function Ir(e,t="three-blocks.text.ts"){let r=M.createSourceFile(t,e,M.ScriptTarget.Latest,true,M.ScriptKind.TS),n=Ko(r),o=[];function s(i){if(M.isCallExpression(i)&&qo(i.expression,n)){if(i.arguments.length!==1||!i.arguments[0])throw new Error(`${t}: defineText() requires one static argument.`);o.push(vt(i.arguments[0],t));return}M.forEachChild(i,s);}if(a(s,"visit"),s(r),o.length!==1)throw new Error(`${t} must contain exactly one imported defineText() call.`);return Yo(o[0])}a(Ir,"parseTextConfiguration");function Xt(e,t){if(typeof e=="string")t.push(e);else if(Array.isArray(e))for(let r of e)Xt(r,t);else if(a$1(e))for(let r of Object.values(e))Xt(r,t);}a(Xt,"jsonStrings");async function Bt(e,t="three-blocks.text.ts"){let r=Tt(t,"Text configuration path"),n=await l(e,U.join(e,r),d$1.semanticInput,"Text configuration");return Ir(n.data.toString("utf8"),r)}a(Bt,"readTextConfiguration");async function Pt(e,t){let r=[],n={},o=0;for(let s of t.content){let i=await l(e,U.join(e,s),d$1.semanticInput,"Text content input");if(o+=i.data.byteLength,o>d$1.semanticTotal)throw new Error("Text content inputs exceed the total inspection size limit.");n[s]=f(i.data);let a=i.data.toString("utf8"),c=U.extname(s).toLowerCase();if(c===".html"||c===".htm")r.push(...Gt(a));else if([".ts",".tsx",".js",".jsx",".mts",".cts",".mjs",".cjs"].includes(c))r.push(...zt(a,s));else if(c===".json")Xt(JSON.parse(a),r);else if(c===".txt"||c===".md")r.push(a);else throw new Error(`Unsupported configured text content type: ${s}.`)}return {values:r,glyphs:Kt(r,t.generation),inputs:n}}a(Pt,"discoverTextContent");var rr=1,it="1.0.0",Ss=Object.freeze({"geist-sans":{id:"geist-sans",family:"Geist Sans",version:"1.600",license:"OFL-1.1",licenseFile:"OFL-1.1.txt",sourceFile:"geist-sans/Geist-Variable.ttf",sourceUrl:"https://raw.githubusercontent.com/vercel/geist-font/1.6.0/fonts/Geist/variable/Geist%5Bwght%5D.ttf",sourceBytes:168472,sourceChecksum:"995c579489b33cd28a6732d7aa7ca1b46c2faa832c18b4063933d7652c39932b",browserFile:"geist-sans/Geist-Variable.woff2",browserUrl:"https://raw.githubusercontent.com/vercel/geist-font/449415077ee4ffc191b4e7e557cd35e88b1b98fd/packages/next/dist/fonts/geist-sans/Geist-Variable.woff2",browserBytes:58512,browserChecksum:"46525b05bbf4527d263f8624ca7024c7d0dce3c64430267d30c31c6dd3821e4d"},"noto-sans-jp":{id:"noto-sans-jp",family:"Noto Sans JP",version:"2.004-H2",license:"OFL-1.1",licenseFile:"OFL-1.1.txt",sourceFile:"noto-sans-jp/NotoSansJP[wght].ttf",sourceUrl:"https://raw.githubusercontent.com/google/fonts/295d98a7a0c17c68f1341eaeea354e7960ea70d3/ofl/notosansjp/NotoSansJP%5Bwght%5D.ttf",sourceBytes:9589900,sourceChecksum:"c2f3b4d463500a2ddcd3849cded1fceeb9fd6d1c32e6cbecd568453ba50fc68f",browserFile:"noto-sans-jp/NotoSansJP[wght].woff2",browserUrl:"https://raw.githubusercontent.com/RenaudRohlinger/three-blocks-monorepo/364a50cc5f6f92735a110b50144e8d62404c9d87/packages/three-blocks-devtools/fonts/noto-sans-jp/NotoSansJP%5Bwght%5D.woff2",browserBytes:4350080,browserChecksum:"6fd94964d1990baa2a392cea7a036683d2b80b9dfd590cb3918e8dab98d8e188"}}),ks="THREE_BLOCKS_FONT_CACHE_DIR",xs=6e4,$t=new Map,Rs=fileURLToPath(new URL("../fonts/",import.meta.url));function se(e,t){if(typeof e!="number"||!Number.isFinite(e))throw new Error(`${t} must be finite.`);return e}a(se,"finiteNumber");function Ee(e,t){let r=se(e,t);if(!Number.isSafeInteger(r))throw new Error(`${t} must be an integer.`);return r}a(Ee,"integer");function vs(e){if(!a$1(e)||!a$1(e.info)||!a$1(e.common)||!Array.isArray(e.chars))throw new Error("MSDF generator returned invalid BMFont metadata.");let t=e.chars.map((o,s)=>{if(!a$1(o))throw new Error(`BMFont character ${s} is invalid.`);return {id:Ee(o.id,`BMFont character ${s}.id`),x:se(o.x,`BMFont character ${s}.x`),y:se(o.y,`BMFont character ${s}.y`),width:se(o.width,`BMFont character ${s}.width`),height:se(o.height,`BMFont character ${s}.height`),xoffset:se(o.xoffset,`BMFont character ${s}.xoffset`),yoffset:se(o.yoffset,`BMFont character ${s}.yoffset`),xadvance:se(o.xadvance,`BMFont character ${s}.xadvance`)}}),r=e.kernings===void 0?[]:e.kernings;if(!Array.isArray(r))throw new Error("BMFont kernings are invalid.");let n=r.map((o,s)=>{if(!a$1(o))throw new Error(`BMFont kerning ${s} is invalid.`);return {first:Ee(o.first,`BMFont kerning ${s}.first`),second:Ee(o.second,`BMFont kerning ${s}.second`),amount:se(o.amount,`BMFont kerning ${s}.amount`)}});return {info:{size:se(e.info.size,"BMFont info.size"),face:typeof e.info.face=="string"?e.info.face:"Font"},common:{base:se(e.common.base,"BMFont common.base"),scaleW:Ee(e.common.scaleW,"BMFont common.scaleW"),scaleH:Ee(e.common.scaleH,"BMFont common.scaleH")},chars:t,kernings:n}}a(vs,"parseBMFont");function zr(e){let t=e.generation.size??48,r=e.generation.distanceRange??8,n=e.generation.padding??2,o=e.generation.maxTextureSize??4096;if(!Number.isInteger(t)||t<8||t>256)throw new Error("Text generation size must be an integer from 8 to 256.");if(!Number.isInteger(r)||r<1||r>64)throw new Error("Text generation distanceRange must be an integer from 1 to 64.");if(!Number.isInteger(n)||n<0||n>32)throw new Error("Text generation padding must be an integer from 0 to 32.");if(!Number.isInteger(o)||o<64||o>8192||(o&o-1)!==0)throw new Error("Text generation maxTextureSize must be a power of two from 64 to 8192.");return {size:t,distanceRange:r,padding:n,maxTextureSize:o}}a(zr,"atlasOptions");function nr(e){let t=Ss[e];if(t===void 0)throw new Error(`Unknown built-in font ${JSON.stringify(e)}.`);return t}a(nr,"builtinFontMetadata");function Kr(e){let t=e.cacheDirectory??process.env[ks];return t?U.resolve(t):platform()==="darwin"?U.join(homedir(),"Library","Caches","three-blocks","fonts"):platform()==="win32"?U.join(process.env.LOCALAPPDATA?.trim()||U.join(homedir(),"AppData","Local"),"Three Blocks","Cache","fonts"):U.join(process.env.XDG_CACHE_HOME?.trim()||U.join(homedir(),".cache"),"three-blocks","fonts")}a(Kr,"fontCacheRoot");function jr(e,t){return t==="source"?{font:e,kind:t,file:e.sourceFile,url:e.sourceUrl,bytes:e.sourceBytes,checksum:e.sourceChecksum,...e.sourceArchive===void 0?{}:{archive:e.sourceArchive}}:{font:e,kind:t,file:e.browserFile,url:e.browserUrl,bytes:e.browserBytes,checksum:e.browserChecksum}}a(jr,"builtinAsset");function qr(e,t){let r=nr(e),n=t.mapBuiltinFont?.(r)??r;if(n.id!==r.id||n.version!==r.version||n.sourceBytes!==r.sourceBytes||n.sourceChecksum!==r.sourceChecksum||n.browserBytes!==r.browserBytes||n.browserChecksum!==r.browserChecksum)throw new Error(`Runtime metadata for built-in font ${JSON.stringify(e)} changed its pinned identity.`);return n}a(qr,"runtimeBuiltinFontMetadata");function Es(e,t){return U.join(Kr(t),e.font.id,e.font.version,e.checksum,U.basename(e.file))}a(Es,"builtinCachePath");async function Ts(e$1,t){try{let r=await j(e$1,d$1.texture,`${t.font.id} cached ${t.kind} font`);if(r.data.byteLength===t.bytes&&f(r.data)===t.checksum)return r.data;await rm(e$1,{force:!0});return}catch(r){if(e(r)==="ENOENT")return;throw r}}a(Ts,"readCachedFont");async function Bs(e$1){try{let t=await j(U.join(Rs,e$1.file),e$1.bytes,`${e$1.font.id} packaged ${e$1.kind} font`);return t.data.byteLength===e$1.bytes&&f(t.data)===e$1.checksum?t.data:void 0}catch(t){if(e(t)==="ENOENT")return;throw t}}a(Bs,"readPackagedFont");async function Ps(e,t){try{let r=await l(e.root,e.filePath,t.bytes,`${t.font.id} existing browser font output`);return r.data.byteLength!==t.bytes||f(r.data)!==t.checksum?void 0:r.data}catch{return}}a(Ps,"readBuiltinBrowserSeed");function $s(e,t,r){let n=Math.max(0,e.byteLength-65557),o=-1;for(let u=e.byteLength-22;u>=n;u--)if(e.readUInt32LE(u)===101010256){o=u;break}if(o<0)throw new Error("downloaded ZIP has no end-of-central-directory record");let s=e.readUInt16LE(o+10),i=e.readUInt32LE(o+12),a=e.readUInt32LE(o+16);if(a+i>o)throw new Error("downloaded ZIP central directory is out of bounds");let c=a;for(let u=0;u<s;u++){if(c+46>e.byteLength||e.readUInt32LE(c)!==33639248)throw new Error("downloaded ZIP central directory is invalid");let p=e.readUInt16LE(c+10),l=e.readUInt32LE(c+20),m=e.readUInt32LE(c+24),f=e.readUInt16LE(c+28),h=e.readUInt16LE(c+30),y=e.readUInt16LE(c+32),g=e.readUInt32LE(c+42),R=c+46+f+h+y;if(R>e.byteLength)throw new Error("downloaded ZIP entry metadata is out of bounds");let k=e.subarray(c+46,c+46+f).toString("utf8");if(c=R,k!==t)continue;if(m!==r)throw new Error(`ZIP entry has ${m} bytes; expected ${r}`);if(g+30>e.byteLength||e.readUInt32LE(g)!==67324752)throw new Error("downloaded ZIP local entry is invalid");let w=e.readUInt16LE(g+26),I=e.readUInt16LE(g+28),S=g+30+w+I;if(S+l>e.byteLength)throw new Error("downloaded ZIP entry data is out of bounds");let F=e.subarray(S,S+l);if(p===0)return Buffer.from(F);if(p===8)return at.inflateRawSync(F,{maxOutputLength:r});throw new Error(`ZIP entry uses unsupported compression method ${p}`)}throw new Error(`downloaded ZIP does not contain ${JSON.stringify(t)}`)}a($s,"zipEntry");async function _s(e,t){let r=new URL(e.url);if(r.protocol!=="https:")throw new Error(`Built-in font source must use HTTPS: ${e.url}.`);let n;try{n=await t(r,{signal:AbortSignal.timeout(xs)});}catch(h){throw new Error(`request failed: ${h instanceof Error?h.message:String(h)}`,{cause:h})}if(!n.ok)throw new Error(`server returned HTTP ${n.status} ${n.statusText}`.trim());let o=e.archive?.bytes??e.bytes,s=e.archive?.checksum??e.checksum,i=n.headers.get("content-length");if(i!==null){let h=Number(i);if(!Number.isSafeInteger(h)||h!==o)throw new Error(`server declared ${i} bytes; expected ${o}`)}if(n.body===null)throw new Error("server returned an empty response body");let a=n.body.getReader(),c=[],u=0;for(;;){let h=await a.read();if(h.done)break;if(u+=h.value.byteLength,u>o||u>d$1.texture)throw await a.cancel(),new Error(`download exceeded the expected ${o}-byte size`);c.push(Buffer.from(h.value.buffer,h.value.byteOffset,h.value.byteLength));}let p=Buffer.concat(c,u);if(p.byteLength!==o)throw new Error(`downloaded ${p.byteLength} bytes; expected ${o}`);let l=f(p);if(l!==s)throw new Error(`checksum mismatch: expected ${s}, received ${l}`);let m=e.archive===void 0?p:$s(p,e.archive.entry,e.bytes);if(m.byteLength!==e.bytes)throw new Error(`resolved ${m.byteLength} bytes; expected ${e.bytes}`);let f$1=f(m);if(f$1!==e.checksum)throw new Error(`resolved checksum mismatch: expected ${e.checksum}, received ${f$1}`);return m}a(_s,"downloadFont");async function Yt(e,t){await mkdir(U.dirname(e),{recursive:true});let r=`${e}.${process.pid}.${randomUUID()}.tmp`;try{await writeFile(r,t,{flag:"wx"}),await rename(r,e);}finally{await rm(r,{force:true});}}a(Yt,"writeCachedFont");async function Nr(e,t,r){let n=Es(e,t),o=$t.get(n);if(o)return o;let s=(async()=>{let i=await Ts(n,e);if(i)return i;if(t.fetch===void 0&&t.mapBuiltinFont===void 0){let a=await Bs(e);if(a!==void 0)return await Yt(n,a),a}if(r!==void 0){let a=await Ps(r,e);if(a!==void 0)return await Yt(n,a),a}try{let a=await _s(e,t.fetch??globalThis.fetch);return await Yt(n,a),a}catch(a){throw new Error(`Could not download the built-in ${e.font.id} ${e.kind} font from ${e.url}: ${a instanceof Error?a.message:String(a)}. Connect once to prewarm the checksum-keyed cache at ${JSON.stringify(Kr(t))}, or configure source.path/source.package for fully offline text generation.`,{cause:a})}})();$t.set(n,s);try{return await s}finally{$t.get(n)===s&&$t.delete(n);}}a(Nr,"cachedBuiltinAsset");async function Xr(e,t,r){let[n,o]=await Promise.allSettled([Nr(jr(e,"source"),t),Nr(jr(e,"browser"),t,r)]);if(n.status==="rejected")throw n.reason;if(o.status==="rejected")throw o.reason;return [n.value,o.value]}a(Xr,"cachedBuiltinPair");async function As(e,t={}){let r=qr(e,t);await Xr(r,t);}a(As,"prewarmBuiltinFont");async function Jr(e,t,r){let n=await j(e,d$1.texture,r),o=f(n.data);if(t!=="pending"&&o!==t)throw new Error(`${r} checksum mismatch: expected ${t}, received ${o}.`);return n.data}a(Jr,"checkedExternalFile");function Yr(e,t){if(!/^(?:@[a-z0-9._-]+\/)?[a-z0-9._-]+$/iu.test(t))throw new Error("Text font package name is unsafe.");return U.join(e,"node_modules",...t.split("/"))}a(Yr,"packageRoot");async function Cs(e,t){if("builtin"in t){let o=nr(t.builtin);return {sourceHash:o.sourceChecksum,browserHash:o.browserChecksum,description:`builtin:${o.id}@${o.version}`,license:o.license}}if("path"in t){let o=await l(e,U.join(e,t.path),d$1.texture,"Text source font");return {sourceHash:f(o.data),browserHash:f(o.data),description:t.path}}let r=U.join(Yr(e,t.package),t.file),n=await Jr(r,t.checksum,"Package text source font");return {sourceHash:f(n),browserHash:f(n),description:`${t.package}/${t.file}`}}a(Cs,"resolveFontIdentity");async function Ms(e,t,r,n){if("builtin"in t){let a=qr(t.builtin,r),[c,u]=await Xr(a,r,n===void 0?void 0:{root:e,filePath:n});return {source:c,sourceHash:a.sourceChecksum,browser:u,browserHash:a.browserChecksum,description:`builtin:${a.id}@${a.version}`,license:a.license}}if("path"in t){let a=await l(e,U.join(e,t.path),d$1.texture,"Text source font"),c=f(a.data);return {source:a.data,sourceHash:c,browser:a.data,browserHash:c,description:t.path}}let o=U.join(Yr(e,t.package),t.file),s=await Jr(o,t.checksum,"Package text source font"),i=f(s);return {source:s,sourceHash:i,browser:s,browserHash:i,description:`${t.package}/${t.file}`}}a(Ms,"resolveFont");function st(e,t){let r=t.replace(/^\/+/,""),n=U.resolve(e,"public",r),o=U.resolve(e,"public"),s=U.relative(o,n);if(s===""||s===".."||s.startsWith(`..${U.sep}`)||U.isAbsolute(s))throw new Error(`Deployed text path ${JSON.stringify(t)} escapes public/.`);return n}a(st,"deployedFile");function tr(e,t){return U.relative(e,t).split(U.sep).join("/")}a(tr,"portablePath");function Zr(e){return e.endsWith(".json")?`${e.slice(0,-5)}.meta.json`:`${e}.meta.json`}a(Zr,"metadataPath");function Qr(e){return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)}a(Qr,"bufferArray");function Os(e,t){return t.filter(r=>r===65533||e.charToGlyphIndex(String.fromCodePoint(r))!==0)}a(Os,"supportedCodePoints");function Fs(e,t,r,n){return new Promise((o,s)=>{ws(e,{filename:r,charset:t.map(i=>String.fromCodePoint(i)),outputType:"json",fieldType:"msdf",fontSize:n.size,distanceRange:n.distanceRange,texturePadding:n.padding,textureSize:[n.maxTextureSize,n.maxTextureSize],smartSize:true,pot:true},(i,a,c)=>{if(i)return s(i);if(a.length!==1||a[0]===void 0)return s(new Error(`Text glyphs require ${a.length} atlas pages; raise maxTextureSize or lower size.`));try{o({png:a[0].texture,data:vs(JSON.parse(c.data))});}catch(u){s(u);}});})}a(Fs,"generateBMFontData");function Is(e,t,r){let n=1/e.info.size,o=e.common.base,s=t.unitsPerEm,i=t.tables.hhea;return {name:t.names?.fontFamily?.en??e.info.face,atlas:{type:"msdf",distanceRange:r.distanceRange,size:e.info.size,width:e.common.scaleW,height:e.common.scaleH,yOrigin:"top"},metrics:{emSize:1,lineHeight:(i.ascender-i.descender+i.lineGap)/s,ascender:i.ascender/s,descender:i.descender/s,underlineY:(t.tables.post?.underlinePosition??-s*.1)/s,underlineThickness:(t.tables.post?.underlineThickness??s*.05)/s},glyphs:e.chars.slice().sort((a,c)=>a.id-c.id).map(a=>({unicode:a.id,advance:a.xadvance*n,...a.width>0&&a.height>0?{planeBounds:{left:a.xoffset*n,bottom:(o-a.yoffset-a.height)*n,right:(a.xoffset+a.width)*n,top:(o-a.yoffset)*n},atlasBounds:{left:a.x,top:a.y,right:a.x+a.width,bottom:a.y+a.height}}:{}})),kerning:e.kernings.filter(a=>a.amount!==0).sort((a,c)=>a.first-c.first||a.second-c.second).map(a=>({unicode1:a.first,unicode2:a.second,advance:a.amount*n}))}}a(Is,"convertMetrics");function en(){return at}a(en,"zstdFunctions");function Ls(e){let t=PNG.sync.read(e),r=new Uint8Array(t.data.buffer,t.data.byteOffset,t.data.byteLength),o=en().zstdCompressSync,s=o===void 0?"none":"zstd",i=at.constants.ZSTD_c_compressionLevel,a$1=o?.(r,i===void 0?{}:{params:{[i]:19}}),c=createDefaultContainer();c.vkFormat=VK_FORMAT_R8G8B8A8_UNORM,c.typeSize=1,c.pixelWidth=t.width,c.pixelHeight=t.height,c.supercompressionScheme=s==="zstd"?KHR_SUPERCOMPRESSION_ZSTD:KHR_SUPERCOMPRESSION_NONE,c.levels=[{levelData:a$1===void 0?r:new Uint8Array(a$1.buffer,a$1.byteOffset,a$1.byteLength),uncompressedByteLength:r.byteLength}];let u=a((l,m)=>({bitOffset:l*8,bitLength:7,channelType:m,samplePosition:[0,0,0,0],sampleLower:0,sampleUpper:255}),"sample");c.dataFormatDescriptor=[{vendorId:KHR_DF_VENDORID_KHRONOS,descriptorType:KHR_DF_KHR_DESCRIPTORTYPE_BASICFORMAT,versionNumber:KHR_DF_VERSION,colorModel:KHR_DF_MODEL_RGBSDA,colorPrimaries:KHR_DF_PRIMARIES_BT709,transferFunction:KHR_DF_TRANSFER_LINEAR,flags:KHR_DF_FLAG_ALPHA_STRAIGHT,texelBlockDimension:[0,0,0,0],bytesPlane:[0,0,0,0,0,0,0,0],samples:[u(0,KHR_DF_CHANNEL_RGBSDA_RED),u(1,KHR_DF_CHANNEL_RGBSDA_GREEN),u(2,KHR_DF_CHANNEL_RGBSDA_BLUE),u(3,KHR_DF_CHANNEL_RGBSDA_ALPHA|KHR_DF_SAMPLE_DATATYPE_LINEAR)]}],c.keyValue.KTXwriter=`three-blocks text ${it}`,c.keyValue.KTXorientation="rd";let p=write(c,{keepWriter:true});return tn(p,t.width,t.height),{bytes:p,width:t.width,height:t.height,compression:s}}a(Ls,"createKtx2");function tn(e,t,r){let n=read(e);if(n.vkFormat!==VK_FORMAT_R8G8B8A8_UNORM)throw new Error("Text atlas must use RGBA8 KTX2.");if(n.pixelWidth<=0||n.pixelHeight<=0||n.levels.length!==1||n.levels[0]===void 0)throw new Error("Text atlas KTX2 dimensions or levels are invalid.");if(t!==void 0&&n.pixelWidth!==t)throw new Error("Text atlas KTX2 width does not match metrics.");if(r!==void 0&&n.pixelHeight!==r)throw new Error("Text atlas KTX2 height does not match metrics.");if(n.keyValue.KTXorientation!=="rd")throw new Error("Text atlas KTX2 orientation must be rd.");let o=n.levels[0],s,i;if(n.supercompressionScheme===KHR_SUPERCOMPRESSION_ZSTD){let c=en().zstdDecompressSync;if(c===void 0)throw new Error("This Node.js runtime cannot validate Zstandard KTX2 text atlases.");s=c(o.levelData),i="zstd";}else if(n.supercompressionScheme===KHR_SUPERCOMPRESSION_NONE)s=o.levelData,i="none";else throw new Error("Text atlas uses an unsupported KTX2 supercompression scheme.");let a=n.pixelWidth*n.pixelHeight*4;if(s.byteLength!==a||o.uncompressedByteLength!==a)throw new Error("Text atlas KTX2 decoded byte length is invalid.");return {width:n.pixelWidth,height:n.pixelHeight,compression:i}}a(tn,"validateKtx2Bytes");function Dr(e){return `${JSON.stringify(e)}
|
|
2
|
+
`}a(Dr,"stableJson");function Zt(e,t,r){return {path:tr(e,t),sha256:f(r),bytes:r.byteLength}}a(Zt,"fileReceipt");function rn(e,t,r,n){return f(JSON.stringify({generator:it,fontKey:n,fontHash:e.sourceHash,glyphSetHash:t,options:r}))}a(rn,"createInputHash");async function js(e,t,r,n,o,s,i$1){if(o.length===0)throw new Error(`Text font ${JSON.stringify(t)} covers no required glyphs.`);let a=Gr.parse(Qr(n.source)),c=await Fs(n.source,o,t,i$1),u=Is(c.data,a,i$1),p=Buffer.from(Dr(u)),l=Ls(c.png);if(c.data.common.scaleW!==l.width||c.data.common.scaleH!==l.height)throw new Error(`Text font ${JSON.stringify(t)} metrics and texture dimensions differ.`);let m=st(e,r.browser),f=st(e,r.atlas),h=st(e,r.metrics),y=Zr(h),g={schemaVersion:rr,generatorVersion:it,font:{key:t,source:n.description,sourceHash:n.sourceHash,...n.license===void 0?{}:{license:n.license}},inputHash:rn(n,s,i$1,t),glyphSetHash:s,codePoints:o,options:i$1,texture:{format:"RGBA8",orientation:"rd",compression:l.compression,width:l.width,height:l.height},files:{browser:Zt(e,m,n.browser),atlas:Zt(e,f,l.bytes),metrics:Zt(e,h,p)}},R=Buffer.from(Dr(g));await i(m,n.browser),await i(f,l.bytes),await i(h,p),await i(y,R);let k=[m,f,h,y].map(w=>tr(e,w));return {font:t,receipt:g,metadataPath:tr(e,y),updatedFiles:k}}a(js,"generateRoute");async function Ns(e,t="three-blocks.text.ts",r={}){let n=await Bt(e,t),o=await Pt(e,n),s=zr(n),i=[];for(let[p,l]of Object.entries(n.fonts).sort((m,f)=>m[0].localeCompare(f[0]))){let m=await Ms(e,l.source,r,"builtin"in l.source?st(e,l.browser):void 0),f=Gr.parse(Qr(m.source));i.push({key:p,route:l,resolved:m,font:f,codePoints:Os(f,o.glyphs.codePoints)});}let a=new Set(i.flatMap(p=>p.codePoints)),c=o.glyphs.codePoints.filter(p=>!a.has(p));if(c.length>0)throw new Error(`Configured fonts do not cover ${c.length} required glyph(s): ${c.map(p=>String.fromCodePoint(p)).join(" ")}`);let u=[];for(let p of i)u.push(await js(e,p.key,p.route,p.resolved,p.codePoints,o.glyphs.hash,s));return {glyphs:o.glyphs.codePoints.length,glyphSetHash:o.glyphs.hash,atlases:u,updatedFiles:u.flatMap(p=>p.updatedFiles)}}a(Ns,"generateTextAtlases");function Qt(e,t){if(!a$1(e)||typeof e.path!="string"||typeof e.sha256!="string"||!/^[a-f0-9]{64}$/u.test(e.sha256)||!Number.isSafeInteger(e.bytes)||e.bytes<0)throw new Error(`${t} receipt is invalid.`);return e}a(Qt,"parseFileReceipt");function nn(e){if(!a$1(e)||e.schemaVersion!==rr||e.generatorVersion!==it||!a$1(e.font)||typeof e.font.key!="string"||typeof e.font.source!="string"||typeof e.font.sourceHash!="string"||!/^[a-f0-9]{64}$/u.test(e.font.sourceHash)||typeof e.inputHash!="string"||!/^[a-f0-9]{64}$/u.test(e.inputHash)||typeof e.glyphSetHash!="string"||!/^[a-f0-9]{64}$/u.test(e.glyphSetHash)||!Array.isArray(e.codePoints)||!e.codePoints.every(t=>Number.isSafeInteger(t))||!a$1(e.options)||!a$1(e.texture)||!a$1(e.files))throw new Error("Text atlas generation metadata is invalid.");if(e.texture.format!=="RGBA8"||e.texture.orientation!=="rd"||!["zstd","none"].includes(e.texture.compression))throw new Error("Text atlas texture metadata is invalid.");return Qt(e.files.browser,"Browser font"),Qt(e.files.atlas,"Text atlas"),Qt(e.files.metrics,"Text metrics"),e}a(nn,"parseTextAtlasReceipt");function Ds(e){if(!a$1(e)||!a$1(e.atlas)||!Array.isArray(e.glyphs))throw new Error("Text metrics are invalid.");let t=Ee(e.atlas.width,"Text metrics atlas.width"),r=Ee(e.atlas.height,"Text metrics atlas.height"),n=e.glyphs.map((o,s)=>{if(!a$1(o))throw new Error(`Text metrics glyph ${s} is invalid.`);return Ee(o.unicode,`Text metrics glyph ${s}.unicode`)});return {width:t,height:r,codePoints:n}}a(Ds,"metricsCoverage");async function er(e,t,r,n){let o=await l(e,U.join(e,t.path),r,n);if(o.data.byteLength!==t.bytes||f(o.data)!==t.sha256)throw new Error(`${n} checksum or byte length differs from generation metadata.`);return o.data}a(er,"verifyReceiptFile");async function _t(e,t="three-blocks.text.ts"){let r;try{r=await Bt(e,t);}catch(n){return {state:"invalid",reason:`Text configuration is invalid: ${n instanceof Error?n.message:String(n)}`,missing:[],atlases:[]}}try{let n=await Pt(e,r),o=zr(r),s=[],i=new Set;for(let[c,u]of Object.entries(r.fonts).sort((p,l)=>p[0].localeCompare(l[0]))){let p=await l(e,Zr(st(e,u.metrics)),d$1.metadata,"Text atlas generation metadata"),l$1=nn(JSON.parse(p.data.toString("utf8")));if(l$1.font.key!==c)throw new Error(`Text atlas metadata belongs to ${JSON.stringify(l$1.font.key)}, not ${JSON.stringify(c)}.`);let m=await Cs(e,u.source),f$1=rn(m,l$1.glyphSetHash,o,c);if(l$1.inputHash!==f$1)return {state:"invalid",reason:`Text atlas ${c} font source or generation options changed.`,missing:[],atlases:[...s,l$1]};let[h,y,g]=await Promise.all([er(e,l$1.files.browser,d$1.texture,"Browser font"),er(e,l$1.files.atlas,d$1.texture,"Text atlas"),er(e,l$1.files.metrics,d$1.metrics,"Text metrics")]);if(f(h)!==m.browserHash)throw new Error(`Browser font ${c} differs from its resolved source.`);let R=Ds(JSON.parse(g.toString("utf8"))),k=tn(y,R.width,R.height);if(k.width!==l$1.texture.width||k.height!==l$1.texture.height||k.compression!==l$1.texture.compression)throw new Error(`Text atlas ${c} texture metadata does not match KTX2.`);for(let w of R.codePoints)i.add(w);s.push(l$1);}let a=n.glyphs.codePoints.filter(c=>!i.has(c));return a.length>0?{state:"missing",reason:`${a.length} required glyph(s) are missing.`,missing:a,atlases:s}:{state:"ready",reason:`${n.glyphs.codePoints.length} required glyphs are covered by ${s.length} atlas(es).`,missing:[],atlases:s}}catch(n){return (typeof n=="object"&&n!==null&&"code"in n?n.code:void 0)==="ENOENT"?{state:"missing",reason:"Text atlas files or generation metadata are absent.",missing:[],atlases:[]}:{state:"invalid",reason:n instanceof Error?n.message:String(n),missing:[],atlases:[]}}}a(_t,"inspectTextAtlases");var sr=[".ts",".tsx",".mts",".cts",".js",".jsx",".mjs",".cjs",".wgsl",".glsl",".vert",".frag",".json",".css"],ar=new Set(sr),or=/^(?:three-blocks\.shaders\.json|(?:precompile|three-blocks\.shaders)\.config\.(?:cjs|cts|js|mjs|mts|ts))$/u,Vs=/(?:^|\/)scene\.(?:cjs|cts|js|jsx|mjs|mts|ts|tsx)$/u,Us=/\b(?:export\s+)?(?:async\s+)?function\s+createScene\b|\bcreateScene\s*=\s*(?:async\s*)?\(/u,Ws=/\b(?:[A-Za-z_$][\w$]*\.)*(?:shaders|shaderCache|sceneShaders)\s*\.\s*(?:material|pipeline|compute|container)\s*\(/u,Gs=/\b(import|export)(?!\s*\()\s*(type\b\s*)?(?:[^"'();]*?\bfrom\s*)?["']([^"']+)["']/gu,zs=/\bimport\s*\(\s*["']([^"']+)["']\s*\)/gu,Ks=/\b(?:import|export)(?!\s*\()\s*(?:[^"'();]*?\bfrom\s*)?["']([^"']+)["']|\bimport\s*\(\s*["']([^"']+)["']\s*\)/gu,qs=/^[0-9A-Za-z][0-9A-Za-z.+_-]{0,127}$/u,ir=4096,Xs="./shaders";function an(e,t){let r=U.relative(e,t).split(U.sep).join("/");if(r.length===0||/[\u0000-\u001f\u007f]/u.test(r))throw new Error("Semantic input has an unsafe relative path.");return r}a(an,"portableRelativePath");function dr(e,t){try{return new TextDecoder("utf-8",{fatal:!0}).decode(e)}catch{throw new Error(`Shader-relevant source ${JSON.stringify(t)} is not valid UTF-8.`)}}a(dr,"sourceText");function lr(e,t){let r="",n="code";for(let o=0;o<e.length;o++){let s=e[o]??"",i=e[o+1]??"";if(n==="code"){if(s==="/"&&i==="/"){r+=" ",n="line-comment",o++;continue}if(s==="/"&&i==="*"){r+=" ",n="block-comment",o++;continue}if(s==="'"||s==='"'||s==="`"){n=s==="'"?"single":s==='"'?"double":"template",r+=t?s:" ";continue}r+=s;continue}if(n==="line-comment"){s===`
|
|
3
|
+
`?(r+=`
|
|
4
|
+
`,n="code"):r+=" ";continue}if(n==="block-comment"){s==="*"&&i==="/"?(r+=" ",n="code",o++):r+=s===`
|
|
5
|
+
`?`
|
|
6
|
+
`:" ";continue}let a=n==="single"?"'":n==="double"?'"':"`";if(s==="\\"&&i.length>0){r+=t?`${s}${i}`:" ",o++;continue}r+=t?s:s===`
|
|
7
|
+
`?`
|
|
8
|
+
`:" ",s===a&&(n="code");}return r}a(lr,"lexicalSource");function Js(e){let t=new Set,r=lr(e,true);for(let n of r.matchAll(Gs))n[2]===void 0&&n[3]!==void 0&&t.add(n[3]);for(let n of r.matchAll(zs))n[1]!==void 0&&t.add(n[1]);return [...t].sort()}a(Js,"importSpecifiers");function Ys(e){let t=new Set;for(let r of lr(e,true).matchAll(Ks)){let n=r[1]??r[2];n!==void 0&&t.add(n);}return [...t].sort()}a(Ys,"runtimeSpecifiers");function dn(e){return (e.split(/[?#]/u,1)[0]??e).replaceAll("\\","/")}a(dn,"cleanSpecifier");function Zs(e,t,r){let n=dn(t),o;if(n.startsWith("./")||n.startsWith("../"))o=U.posix.normalize(U.posix.join(U.posix.dirname(e),n));else if(n.startsWith("@/"))o=`src/${n.slice(2)}`;else if(n.startsWith("/src/"))o=n.slice(1);else return;if(o===".three-blocks"||o.startsWith(".three-blocks/"))return;let s=U.posix.extname(o).toLowerCase(),i=new Set([o]);if(s.length===0||!ar.has(s)){for(let a of sr)i.add(`${o}${a}`);for(let a of sr)i.add(`${o}/index${a}`);}else if([".js",".mjs",".cjs",".jsx"].includes(s)){let a=o.slice(0,-s.length);for(let c of [".ts",".tsx",".mts",".cts"])i.add(`${a}${c}`);}return [...i].find(a=>r.has(a))}a(Zs,"resolveProjectImport");function Qs(e,t){let r=lr(t,false);return Vs.test(e)||Us.test(r)||Ws.test(r)}a(Qs,"isShaderRoot");async function Te(e,t){let r=await realpath(e);if(t!==void 0){let l$1={},m=0;for(let f$1 of t){let h=await l(r,U.join(r,f$1),d$1.semanticInput,"Declared shader semantic input");if(m+=h.data.byteLength,m>d$1.semanticTotal)throw new Error("Declared shader semantic inputs exceed the total inspection size limit.");l$1[f$1]=f(h.data);}return l$1}let n=new Map,o=U.join(r,"src");if(await g(o))for(let l$1 of await m(r,o,m=>ar.has(U.extname(m).toLowerCase()))){let m=await l(r,l$1,d$1.semanticInput,"Shader semantic input");n.set(an(r,l$1),m.data);}for(let l$1 of await readdir(r,{withFileTypes:true})){if(!l$1.isFile()||!or.test(l$1.name)&&!ar.has(U.extname(l$1.name).toLowerCase()))continue;let m=await l(r,U.join(r,l$1.name),d$1.semanticInput,or.test(l$1.name)?"Shader configuration input":"Shader semantic input");n.set(l$1.name,m.data);}if(n.size>ir)throw new Error(`Shader input discovery exceeds the ${ir}-file limit.`);let s=new Set,i=new Map;for(let[l,m]of n){if(!l.includes("/")&&or.test(l)&&s.add(l),!l.startsWith("src/"))continue;let f=dr(m,l);i.set(l,f),Qs(l,f)&&s.add(l);}if(s.size===0)throw new Error("No shader registration or scene source root was found.");let a=new Set,c=[...s].sort();for(;c.length>0;){let l=c.shift();if(l===void 0||a.has(l))continue;let m=n.get(l);if(m===void 0)continue;a.add(l);let f=i.get(l)??dr(m,l);for(let h of Js(f)){let y=Zs(l,h,n);y!==void 0&&!a.has(y)&&c.push(y);}c.sort();}let u=0,p={};for(let l of [...a].sort()){let m=n.get(l);if(m===void 0)throw new Error(`Shader input ${JSON.stringify(l)} disappeared during inspection.`);if(u+=m.byteLength,u>d$1.semanticTotal)throw new Error("Semantic shader inputs exceed the total inspection size limit.");p[l]=f(m);}return p}a(Te,"snapshotShaderInputs");function cr(e){if(typeof e=="string")return e;if(a$1(e))return cr(e.import)??cr(e.default)}a(cr,"conditionalImportTarget");async function on(e,t){let r=e;for(;;){let n=U.join(r,"node_modules",...t.split("/"),"package.json");if(await g(n)){let s=await j(n,d$1.packageJson,`${t} package.json`),i=JSON.parse(s.data.toString("utf8"));if(!a$1(i)||i.name!==t||typeof i.version!="string"||!qs.test(i.version))throw new Error(`Installed ${t} package metadata is invalid.`);return {root:U.dirname(s.path),manifest:i}}let o=U.dirname(r);if(o===r)break;r=o;}throw new Error(`Cannot verify the installed ${t} package.`)}a(on,"findInstalledPackage");async function ea(e,t){if(!a$1(t.exports))throw new Error("Installed three-blocks package has no public exports map.");let r=cr(t.exports[Xs]);if(r===void 0||!r.startsWith("./"))throw new Error("Installed three-blocks shader export has no import target.");let n=await realpath(e),o=[U.resolve(n,r)],s=new Map,i=0;for(;o.length>0;){let c=o.shift();if(c===void 0)break;let u=await j(c,d$1.semanticInput,"Three Blocks shader runtime module");if(!h(n,u.path)||u.path===n)throw new Error("Three Blocks shader runtime closure escapes its package.");let p=an(n,u.path);if(s.has(p))continue;if(i+=u.data.byteLength,i>d$1.semanticTotal)throw new Error("Three Blocks shader runtime closure exceeds the inspection limit.");s.set(p,f(u.data));let l=dr(u.data,p);for(let m of Ys(l)){let f=dn(m);if(!f.startsWith("./")&&!f.startsWith("../"))continue;let h$1=U.resolve(U.dirname(u.path),f);if(!h(n,h$1))throw new Error("Three Blocks shader runtime import escapes its package.");o.push(h$1);}if(o.sort(),s.size+o.length>ir)throw new Error("Three Blocks shader runtime closure exceeds the file limit.")}let a=[...s].sort((c,u)=>c[0].localeCompare(u[0])).map(([c,u])=>`${c}\0${u}`).join(`
|
|
9
|
+
`);return f(a)}a(ea,"shaderRuntimeClosure");async function ye(e){let[t,r]=await Promise.all([on(e,"three"),on(e,"three-blocks")]);return {three:String(t.manifest.version),threeBlocks:String(r.manifest.version),threeBlocksShaderClosure:await ea(r.root,r.manifest)}}a(ye,"readInstalledShaderRuntime");function ta(e,t){return e.render===t.render&&e.vertex===t.vertex&&e.fragment===t.fragment&&e.compute===t.compute}a(ta,"sameCoverage");function ra(e){let t=e.some(n=>n.state==="invalid")?"invalid":e.some(n=>n.state==="missing")?"missing":e.some(n=>n.state==="stale")?"stale":"fresh",r=e.filter(n=>n.state===t);return {state:t,reason:t==="fresh"?`${e.length} configured shader scene${e.length===1?" is":"s are"} fresh.`:r.map(n=>`${n.scene}: ${n.reason}`).join("; ")}}a(ra,"classifyMatrix");function na(e){let t=e.tool;if(!t)return "Shader receipt has no public tool compatibility metadata.";if(t.compatibility!==THREE_WEBGPU_R185_COMPATIBILITY)return "Shader receipt targets a different runtime compatibility contract.";if(t.transform!==w)return "Shader receipt uses a different provider transform version.";if(t.address!==SHADER_ADDRESS_SCHEMA_VERSION||t.recipe!==SHADER_RECIPE_SCHEMA_VERSION||t.hydration!==SHADER_HYDRATION_SCHEMA_VERSION)return "Shader receipt uses incompatible address, recipe, or hydration schemas."}a(na,"exactToolCompatibility");function oa(e,t){let r=Object.keys(t).filter(s=>Object.hasOwn(e,s)&&e[s]!==t[s]),n=Object.keys(t).filter(s=>!Object.hasOwn(e,s)),o=Object.keys(e).filter(s=>!Object.hasOwn(t,s));return {...r.length>0?{changedInputs:r}:{},...n.length>0?{addedInputs:n}:{},...o.length>0?{removedInputs:o}:{}}}a(oa,"inputChanges");async function Fe(e=process.cwd()){let t=await r(e),r$1=await s(t),n=U.join(t,o),o$1=a(()=>({schemaVersion:1,root:t,state:"missing",reason:`${o}/meta.json is absent.`,scenes:r$1.scenes.map(s=>({scene:s.key,state:"missing",reason:"No committed shader receipt."}))}),"missing");if(!await g(n)||!await g(U.join(n,"meta.json")))return o$1();try{let s=await k(t,n,"Shader artifact directory"),i=await l(s,U.join(s,"meta.json"),d$1.receipt,"Shader receipt"),a=c$1(JSON.parse(i.data.toString("utf8"))),c=await F(s,i.data),u=await ye(t),p=new Set(r$1.scenes.map(S=>S.key)),m=Object.keys(a.scenes).filter(S=>!p.has(S));if(m.length>0)throw new Error(`Shader receipt contains unconfigured scenes: ${m.join(", ")}.`);let f$1=na(a);if(f$1)throw new Error(f$1);if(!/^0\.185\./u.test(u.three))throw new Error(`Installed Three.js ${u.three} is outside the r185 capture contract.`);let h=a.runtime.three!==u.three||a.runtime.threeBlocks!==u.threeBlocks,y=a.runtime.threeBlocksShaderClosure!==u.threeBlocksShaderClosure,g=a.tool?.version!==v,R=U.join(t,r$1.publicDir??"public"),k$1=[];for(let S of r$1.scenes){let F=a.scenes[S.key];if(!F){k$1.push({scene:S.key,state:"missing",reason:"Scene is absent from the complete receipt matrix."});continue}let _=await l(s,U.join(s,F.artifact),d$1.manifest,"Shader manifest");if(f(_.data)!==F.artifactHash)throw new Error(`Shader artifact checksum differs for scene "${S.key}".`);if(F.asset!==void 0&&F.assetHash!==void 0){let ee=await l(R,U.join(R,F.asset),d$1.manifest,"Static shader manifest");if(f(ee.data)!==F.assetHash)throw new Error(`Static shader manifest checksum differs for scene "${S.key}".`)}if(F.bytes!==void 0&&F.bytes!==_.data.byteLength)throw new Error(`Shader artifact byte count differs for scene "${S.key}".`);let b=Rt(_.data.toString("utf8"),_.path,S.key,{three:a.runtime.three,threeBlocks:a.runtime.threeBlocks,compatibility:THREE_WEBGPU_R185_COMPATIBILITY,address:SHADER_ADDRESS_SCHEMA_VERSION,recipe:SHADER_RECIPE_SCHEMA_VERSION,hydration:SHADER_HYDRATION_SCHEMA_VERSION});if(!ta(b,F.coverage))throw new Error(`Shader coverage differs for scene "${S.key}".`);if(!r$1.allowLiveBuilds&&F.skipped&&F.skipped.render+F.skipped.compute>0)throw new Error(`Scene "${S.key}" contains skipped live builds but allowLiveBuilds is false.`);let L=await Te(t,S.inputs),B=oa(F.inputs,L),P=(B.changedInputs?.length??0)+(B.addedInputs?.length??0)+(B.removedInputs?.length??0),C=h||y||g||P>0,T=c?.scenes[S.key],$=T===void 0||c===void 0?void 0:{...T,schemaVersion:c.schemaVersion,measuredAt:c.measuredAt,source:c.source,...c.source==="committed-capture"?{adapter:c.adapter,platform:c.platform}:{}};k$1.push({scene:S.key,state:C?"stale":"fresh",reason:h?"Installed runtime versions differ from the receipt.":y?"Installed three-blocks/shaders runtime closure differs from the receipt.":g?`Receipt was generated by @three-blocks/devtools ${a.tool?.version??"unknown"}.`:P>0?`${P} semantic shader input${P===1?"":"s"} changed.`:"Manifest, runtime, schemas, transform, and semantic inputs match.",coverage:b,...!C&&$!==void 0&&$.builds===b.render+b.compute?{timing:$}:{},...B});}let w=ra(k$1),I=w.state==="fresh"&&c!==void 0&&k$1.every(S=>S.timing!==void 0)?c:void 0;return {schemaVersion:1,root:t,...w,scenes:k$1,runtime:u,receipt:a,...I===void 0?{}:{timing:I}}}catch(s){let i=s instanceof Error?s.message:String(s);return {schemaVersion:1,root:t,state:"invalid",reason:i,scenes:r$1.scenes.map(a=>({scene:a.key,state:"invalid",reason:i}))}}}a(Fe,"inspectShaderMatrix");var gn=".three-blocks/shaders/pending-capture";function da(e){return (e instanceof Error?`${e.name}: ${e.message}`:String(e)).includes("ShaderHydrationError:")}a(da,"isShaderHydrationFailure");async function ca(e,t,r){if(t.length===0)return;let n=U.join(e,o,"meta.json"),o$1=await readFile(n);if(f(o$1)!==f(r))throw new Error("Shader receipt changed before failed scenes could be marked for recapture.");let s=c$1(JSON.parse(o$1.toString("utf8"))),i$1=f(r),a=new Set(t),c=c$1({...s,scenes:Object.fromEntries(Object.entries(s.scenes).map(([u,p])=>[u,a.has(u)?{...p,inputs:{...p.inputs,[gn]:i$1}}:p]))});await i(n,`${C(c)}
|
|
10
|
+
`);}a(ca,"markShaderScenesForRecapture");function la(e,t){return C(e)===C(t)}a(la,"equalSnapshot");async function pr(e={}){let t$1=e.root?await realpath(e.root):await r(e.start),r$1=e.config===void 0?await u(t$1):void 0,n=e.config??r$1?.config??await s(t$1),o=n.scenes,s$1,i={},a$1;if(e.ifStale){let B=await Fe(t$1);if(B.state==="fresh")return {schemaVersion:1,root:t$1,skipped:true,reason:B.reason,scenes:[]};if(B.state!=="invalid"&&B.receipt!==void 0){o=n.scenes.filter(P=>B.scenes.find(C=>C.scene===P.key)?.state!=="fresh"),s$1=B.receipt;for(let P of B.scenes){if(P.state!=="fresh"||P.timing===void 0)continue;let{builds:C,liveBuildMs:T,precompiledBuildMs:$,avoidedBuildMs:ee,runs:W,spreadMs:de}=P.timing;i[P.scene]={builds:C,liveBuildMs:T,precompiledBuildMs:$,avoidedBuildMs:ee,runs:W,spreadMs:de},P.timing.source==="committed-capture"&&P.timing.adapter!==void 0&&P.timing.platform!==void 0&&(a$1={adapter:P.timing.adapter,platform:P.timing.platform});}}}let c=performance.now(),u$1=await ye(t$1),p=s$1!==void 0&&(s$1.runtime.three!==u$1.three||s$1.runtime.threeBlocks!==u$1.threeBlocks||s$1.runtime.threeBlocksShaderClosure!==u$1.threeBlocksShaderClosure||s$1.tool?.version!==v)?f(C({runtime:s$1.runtime,tool:s$1.tool})):void 0,l=a(async()=>new Map(await Promise.all(n.scenes.map(async B=>[B.key,await Te(t$1,B.inputs)]))),"snapshotInputs"),m=await l(),f$1=a(async()=>{let B=await l();for(let P of n.scenes){let C=m.get(P.key),T=B.get(P.key);if(C===void 0||T===void 0||!la(C,T))throw new Error(`Semantic shader inputs changed during capture for scene "${P.key}"; the current scene was not committed.`)}},"assertInputsUnchanged"),h=e.driver===void 0,y=e.driver===void 0&&e.driverKind===void 0&&e.serve===void 0&&e.url===void 0?await t(t$1):void 0,g=e.serve??y?.serve,R=e.driverKind??y?.driverKind??(g===void 0?"vite":"static");if(e.url!==void 0&&(e.serve!==void 0||e.driverKind!==void 0))throw new Error("--url cannot be combined with --driver or --serve.");if(R==="vite"&&g!==void 0)throw new Error("--serve requires the static shader driver.");if(R==="static"&&g===void 0&&e.driver===void 0)throw new Error("The static shader driver requires --serve <built-directory>.");let k=e.driver===void 0?await import('./shader-browser-65V22LLL.js'):void 0,w=e.driver??(e.url!==void 0?k.createAttachedPlaywrightShaderDriver({root:t$1,runtime:u$1,url:e.url,...e.headed!==void 0?{headed:e.headed}:{}}):R==="static"?k.createStaticPlaywrightShaderDriver({root:t$1,runtime:u$1,serve:g,...e.headed!==void 0?{headed:e.headed}:{}}):k.createPlaywrightShaderDriver({root:t$1,runtime:u$1,...e.headed!==void 0?{headed:e.headed}:{}})),I$1=new Map,S=[],F$1=s$1!==void 0&&n.scenes.every(B=>s$1?.scenes[B.key]!==void 0),_=s$1,b,L$1=e.attempts??2;if(!Number.isSafeInteger(L$1)||L$1<1||L$1>5)throw new Error("Shader capture attempts must be an integer in 1...5.");try{for(let[C,T]of o.entries()){e.onSceneStart?.(T.key,C,o.length);let $,ee,W=0;for(;W<L$1;W++)try{if($=B(await w.capture(T,n),{scene:T.key,runtime:u$1}),$.skipped.length>0&&!n.allowLiveBuilds)throw new Error(`Scene "${T.key}" contains ${$.skipped.length} unregistered live shader build${$.skipped.length===1?"":"s"} while allowLiveBuilds is false.`);break}catch(de){ee=de,$=void 0,W+1<L$1&&e.onSceneRetry?.(T.key,W+2,L$1,n.timeoutMs,de);}if(!$)throw new Error(`Shader capture "${T.key}" failed after ${L$1} attempts: ${ee instanceof Error?ee.message:String(ee)}`);if(I$1.set(T.key,$),S.push({scene:T.key,attempts:W+1,coverage:$.coverage,skipped:$.skipped.length,startupBuilds:$.stats.registeredBuilds,startupBuildMs:$.stats.buildMs,...$.timing===void 0?{}:{timing:$.timing}}),F$1&&_!==void 0){await f$1();let de=new Map(n.scenes.map(re=>{let ge=re.key===T.key?m.get(re.key):_?.scenes[re.key]?.inputs;if(ge===void 0)throw new Error(`Shader checkpoint is missing scene "${re.key}".`);return p!==void 0&&!I$1.has(re.key)&&(ge={...ge,[gn]:p}),[re.key,ge]}));b=await L({root:t$1,scenes:n.scenes,captures:new Map([[T.key,$]]),runtime:u$1,inputs:de,previousReceipt:_,publicDirectory:n.publicDir??"public"}),_=b.receipt;}}await f$1(),b??=await L({root:t$1,scenes:n.scenes,captures:I$1,runtime:u$1,inputs:m,...s$1===void 0?{}:{previousReceipt:s$1},publicDirectory:n.publicDir??"public"}),Object.keys(i).length>0&&(a$1===void 0?await I(t$1,i):await K(t$1,i,a$1));let B$1=await readFile(U.join(b.directory,"meta.json")),P=await F(b.directory,B$1);return {schemaVersion:1,root:t$1,skipped:!1,reason:`Wrote ${S.length} shader scene${S.length===1?"":"s"}.`,durationMs:performance.now()-c,scenes:S,measurement:{beforeBuilds:S.reduce((C,T)=>C+T.startupBuilds,0),afterBuilds:0,firstFrameDeltaMs:-S.reduce((C,T)=>C+T.startupBuildMs,0),source:"capture-build-phase"},...r$1===void 0?{}:{configuration:{created:r$1.created,file:r$1.file}},written:b,...P===void 0?{}:{timing:P}}}finally{h&&await w.close();}}a(pr,"captureShaders");var wn=1e4,ua=2e3;function ma(e){let t=Math.min(e.timeoutMs,wn),r=Math.min(ua,Math.floor(t/2)),n=Math.max(1,t-r);return {...e,timeoutMs:n,settleTimeoutMs:Math.min(e.settleTimeoutMs??n,n)}}a(ma,"browserObservationConfig");function fa(e){return ["workerReady","assetsReady",...e.requiresText?["textReady"]:[],"compileEnd","firstFrame"]}a(fa,"requiredReadiness");async function ur(e,t,r,n){let o=Math.min(n,wn),s;try{let i=new Promise((a,c)=>{s=setTimeout(()=>c(new Error(`Scene "${t.key}" ${r} observation returned no result within ${o}ms. Readiness could not be inspected; check ${JSON.stringify(t.url)} for an early page/console error or a missing capture readiness signal.`)),o);});return await Promise.race([e(),i])}finally{s!==void 0&&clearTimeout(s);}}a(ur,"boundedObservation");function hn(e){if(e.length===0)throw new Error("Cannot take the median of an empty shader timing capture.");let t=[...e].sort((s,i)=>s-i),r=Math.floor(t.length/2),n=t[r];if(n===void 0)throw new Error("Shader timing median is unavailable.");if(t.length%2===1)return n;let o=t[r-1];if(o===void 0)throw new Error("Shader timing median pair is unavailable.");return (o+n)/2}a(hn,"median");function mr(e,t,r){if(e.scene!==t.key||e.mode!==r)throw new Error(`Browser observation identity differs for scene "${t.key}".`);if(e.compatibility!==THREE_WEBGPU_R185_COMPATIBILITY||e.transform!==w)throw new Error(`Browser observation compatibility differs for scene "${t.key}".`);let n=fa(t).filter(o=>e.readiness[o]!==true);if(n.length>0)throw new Error(`Scene "${t.key}" ${r} observation is missing readiness bits: ${n.join(", ")}.`);if(e.errors.length>0)throw new Error(`Scene "${t.key}" ${r} browser errors:
|
|
11
|
+
- ${e.errors.join(`
|
|
12
|
+
- `)}`)}a(mr,"assertObservation");function pa(e,t,r,n){if(t.render>0&&(e.allowPipelineReuse?r.stats.registeredRenderBuilds===0:r.stats.registeredRenderBuilds<t.render))throw new Error(`Scene "${e.key}" live baseline built ${r.stats.registeredRenderBuilds}/${t.render} registered render pipelines${e.allowPipelineReuse?" on a pipeline-reuse route":""}.`);if(t.compute>0&&(e.allowPipelineReuse?r.stats.registeredComputeBuilds===0:r.stats.registeredComputeBuilds<t.compute))throw new Error(`Scene "${e.key}" live baseline built ${r.stats.registeredComputeBuilds}/${t.compute} registered compute kernels${e.allowPipelineReuse?" on a pipeline-reuse route":""}.`);bn(e,t,n);}a(pa,"assertZeroBuild");function bn(e,t,r){if(r.stats.registeredRenderBuilds!==0||r.stats.registeredComputeBuilds!==0){let n=r.stats.missedKeys??[];throw new Error(`Scene "${e.key}" injected path performed ${r.stats.registeredRenderBuilds} render and ${r.stats.registeredComputeBuilds} compute registered live builds.`+(n.length>0?` Missed keys: ${n.join(", ")}.`:""))}if(e.allowPipelineReuse){if(t.render>0&&r.stats.injectedRender===0)throw new Error(`Scene "${e.key}" injected no render entries.`);if(t.compute>0&&r.stats.injectedCompute===0)throw new Error(`Scene "${e.key}" injected no compute entries.`)}else {if(r.stats.injectedRender<t.render)throw new Error(`Scene "${e.key}" injected ${r.stats.injectedRender}/${t.render} render entries.`);if(r.stats.injectedCompute<t.compute)throw new Error(`Scene "${e.key}" injected ${r.stats.injectedCompute}/${t.compute} compute entries.`)}if(r.stats.missed!==0||r.stats.missedRender!==0||r.stats.missedCompute!==0)throw new Error(`Scene "${e.key}" injected path reported shader manifest misses.`)}a(bn,"assertPrecompiledZeroBuild");async function ha(e,t,r,n,o){let s=U.join(e,p);if(await g(s)){let a=await lstat(s);if(a.isSymbolicLink()||!a.isDirectory())throw new Error("Shader parity artifact directory is not a real directory.")}else await mkdir(s,{recursive:true});let i=[`${t}.live.png`,`${t}.precompiled.png`,`${t}.diff.png`];return await Promise.all([r,n,o].map(async(a,c)=>{let u=i[c];if(u===void 0)throw new Error("Parity artifact mapping failed.");let p=U.join(s,u);if(await g(p)){let l=await lstat(p);if(l.isSymbolicLink()||!l.isFile())throw new Error(`Shader parity target is not a regular file: ${u}.`)}await writeFile(p,a,{mode:384});})),i.map(a=>`${p}/${a}`)}a(ha,"writeParityFailure");async function ya(e={}){let t$1=e.root?await realpath(e.root):await r(e.start),r$1=await Fe(t$1);if(r$1.state!=="fresh")throw new Error(`Shader no-GPU validation is ${r$1.state}: ${r$1.reason}`);if(e.skipBrowser)return {schemaVersion:1,root:t$1,noGpu:r$1,browser:"skipped",scenes:[]};if(e.parityOnly===true&&e.commitTiming===true)throw new Error("Parity-only shader verification cannot commit timing.");let n=e.runs??5;if(!Number.isSafeInteger(n)||n<1||n>100)throw new Error("Shader timing runs must be an integer in 1...100.");let o$1=e.config??await s(t$1),s$1=ma(o$1),i=await readFile(U.join(t$1,o,"meta.json")),a$1=c$1(JSON.parse(i.toString("utf8")));if(r$1.receipt===void 0||C(a$1)!==C(r$1.receipt))throw new Error("Shader receipt changed after no-GPU validation; restart browser parity verification.");let c=r$1.runtime??await ye(t$1),u=e.driver===void 0,p=e.driver===void 0&&e.driverKind===void 0&&e.serve===void 0&&e.url===void 0?await t(t$1):void 0,l=e.serve??p?.serve,m=e.driverKind??p?.driverKind??(l===void 0?"vite":"static");if(e.url!==void 0&&(e.serve!==void 0||e.driverKind!==void 0))throw new Error("--url cannot be combined with --driver or --serve.");if(m==="vite"&&l!==void 0)throw new Error("--serve requires the static shader driver.");if(m==="static"&&l===void 0&&e.driver===void 0)throw new Error("The static shader driver requires --serve <built-directory>.");let f=e.driver===void 0?await import('./shader-browser-65V22LLL.js'):void 0,{compareShaderScreenshots:h}=await import('./shader-parity-QXJWR6OZ.js'),y=a(()=>e.url!==void 0?f.createAttachedPlaywrightShaderDriver({root:t$1,runtime:c,url:e.url,...e.headed!==void 0?{headed:e.headed}:{}}):m==="static"?f.createStaticPlaywrightShaderDriver({root:t$1,runtime:c,serve:l,...e.headed!==void 0?{headed:e.headed}:{}}):f.createPlaywrightShaderDriver({root:t$1,runtime:c,...e.headed!==void 0?{headed:e.headed}:{}}),"createDriver"),g=e.driver??y(),R=e.driver??y(),k=[],w={},I$1=[],S=new Set;try{for(let[_,b]of o$1.scenes.entries()){e.onSceneStart?.(b.key,_,o$1.scenes.length);let L=r$1.scenes.find(G=>G.scene===b.key);if(!L?.coverage)throw new Error(`Fresh receipt has no coverage for scene "${b.key}".`);let B=L.coverage,P=a(async G=>{let we=G?"live":"precompiled",me=G?"precompiled":"live",He=G?g:R,_e=G?R:g,ce=await ur(()=>He.observe(b,we,s$1),b,we,o$1.timeoutMs),K=await ur(()=>_e.observe(b,me,s$1,ce.frame),b,me,o$1.timeoutMs),be=ce.mode==="live"?ce:K,Se=ce.mode==="precompiled"?ce:K;mr(be,b,"live"),mr(Se,b,"precompiled"),pa(b,B,be,Se);let ne=h(be.screenshot,Se.screenshot,o$1.parity.channelTolerance,b.maxDiffRatio??o$1.parity.maxDiffRatio);if(!ne.matches){let jt=await ha(t$1,b.key,be.screenshot,Se.screenshot,ne.diff),Nt=ne.nonBlack?`${ne.differentPixels}/${ne.totalPixels} pixels differ (${(ne.diffRatio*100).toFixed(3)}%).`:`rendered output is black (live=${ne.baselineLuminance.toFixed(4)}, precompiled=${ne.precompiledLuminance.toFixed(4)}).`;throw new Error(`Shader parity failed for scene "${b.key}" at completed frames live=${be.frame}, precompiled=${Se.frame}: ${Nt} Artifacts: ${jt.join(", ")}`)}return {live:be,precompiled:Se,parity:ne}},"observePair"),C,T,$;if(e.parityOnly===!0)try{C=await P(!0);}catch(G){da(G)&&S.add(b.key),I$1.push({scene:b.key,error:G}),e.onSceneError?.(b.key,G);continue}else {await P(!0);let G=[];for(let K=0;K<n;K++)G.push(await P(K%2===0));let we=G[G.length-1];if(we===void 0)throw new Error(`Shader timing produced no runs for scene "${b.key}".`);if(C=we,T=await ur(()=>R.observePublished(b,s$1),b,"published",o$1.timeoutMs),mr(T,b,"precompiled"),bn(b,B,T),$=b.runtimeMotion?h(T.beforeScreenshot,T.screenshot,o$1.parity.channelTolerance,1):void 0,$&&$.diffRatio<1e-4)throw new Error(`Published scene "${b.key}" stopped animating during its normal 120-frame soak (changed ${$.differentPixels}/${$.totalPixels} canvas pixels).`);let me=hn(G.map(K=>K.live.stats.buildMs)),He=hn(G.map(K=>K.precompiled.stats.buildMs)),_e=Math.max(0,me-He),ce=G.map(K=>Math.max(0,K.live.stats.buildMs-K.precompiled.stats.buildMs));w[b.key]={builds:B.render+B.compute,liveBuildMs:me,precompiledBuildMs:He,avoidedBuildMs:_e,runs:n,spreadMs:Math.max(...ce.map(K=>Math.abs(K-_e)))};}let{diff:ee,...W}=C.parity,{screenshot:de,...re}=C.live,{screenshot:ge,...mt}=C.precompiled,Ze;if(T!==void 0){let{beforeScreenshot:G,screenshot:we,...me}=T;Ze=me;}k.push({scene:b.key,coverage:B,live:re,precompiled:mt,...Ze===void 0?{}:{published:Ze},parity:W,...$===void 0?{}:{runtimeMotion:{differentPixels:$.differentPixels,totalPixels:$.totalPixels,diffRatio:$.diffRatio}}}),await J(t$1,[b.key],i);}if(e.parityOnly===!0){if(await ca(t$1,[...S],i),I$1.length>0)throw new Error(`Shader parity failed for ${I$1.length}/${o$1.scenes.length} scene(s):
|
|
13
|
+
`+I$1.map(_=>{let b=_.error instanceof Error?_.error.message:String(_.error);return ` - ${_.scene}: ${b}`}).join(`
|
|
14
|
+
`));return {schemaVersion:1,root:t$1,noGpu:r$1,browser:"passed",scenes:k}}if(e.commitTiming===!0){let _={adapter:"WebGPU adapter",platform:`${pn.platform()}/${pn.arch()}`},b=await(g.timingEnvironment?.()??_),L=await K(t$1,w,b);return {schemaVersion:1,root:t$1,noGpu:r$1,browser:"passed",scenes:k,timing:L.local,committedTiming:L.committed}}let F=await I(t$1,w);return {schemaVersion:1,root:t$1,noGpu:r$1,browser:"passed",scenes:k,timing:F}}finally{u&&(await R.close(),await g.close());}}a(ya,"testShaders");function ga(e=process.env,t=process.stdout){if(e.NO_COLOR!==void 0)return 0;if(e.FORCE_COLOR!==void 0){let r=String(e.FORCE_COLOR);return r==="0"||r==="false"?0:r==="3"?24:r==="2"?8:4}return !t||!t.isTTY||e.TERM==="dumb"?0:/^(truecolor|24bit)$/i.test(e.COLORTERM??"")||e.WT_SESSION||e.TERM_PROGRAM==="iTerm.app"||e.TERM_PROGRAM==="vscode"?24:/-256(color)?$/i.test(e.TERM??"")?8:4}a(ga,"resolveColorDepth");function wa(e=process.env,t=process.platform){return t!=="win32"?true:!!(e.WT_SESSION||e.TERM_PROGRAM||e.ConEmuANSI||/-256(color)?$/i.test(e.TERM??""))}a(wa,"resolveUnicode");function ba(e=process.stdout){let t=e?.columns;return typeof t=="number"&&Number.isInteger(t)&&t>0?t:80}a(ba,"termWidth");var Sn={depth:ga(),unicode:wa(),fancy:!!process.stdout.isTTY&&process.env.TERM!=="dumb"},Ke={logo:{square:[30,84,200]},accent:[86,132,230],gold:[244,174,12],danger:[221,76,51],live:[212,255,71]};function Sa(e,t,r){if(Math.max(e,t,r)-Math.min(e,t,r)<12){let o=Math.round((e+t+r)/3);return o<8?16:o>238?231:232+Math.round((o-8)/10)}let n=a(o=>o<48?0:o<115?1:Math.min(5,Math.round((o-35)/40)),"level");return 16+36*n(e)+6*n(t)+n(r)}a(Sa,"ansi256");function qe(e,t,r){return r>=24?`38;2;${e[0]};${e[1]};${e[2]}`:r>=8?`38;5;${Sa(e[0],e[1],e[2])}`:String(t)}a(qe,"fgOpen");function ka(e=Sn.depth,t=Sn.unicode){let r=e>0?(n,o=39)=>s=>`\x1B[${n}m${String(s)}\x1B[${o}m`:()=>n=>String(n);return {depth:e,unicode:t,accent:r(qe(Ke.accent,94,e)),live:r(qe(Ke.live,92,e)),danger:r(qe(Ke.danger,91,e)),gold:r(qe(Ke.gold,33,e)),deep:r(qe(Ke.logo.square,34,e)),warn:r(qe(Ke.gold,33,e)),dim:r(2,22),bold:r(1,22)}}a(ka,"createTheme");function xa(e){let t=e.unicode;return {tick:e.live(t?"\u2713":"\u221A"),cross:e.danger(t?"\u2717":"x"),warn:e.warn(t?"\u25B2":"!"),info:e.accent(t?"\u203A":">"),pointer:e.accent(t?"\u276F":">"),dot:e.dim(t?"\xB7":"."),ring:e.dim(t?"\u25CB":"o"),bar:t?"\u2502":"|",ellipsis:t?"\u2026":"...",mark:t?`${e.gold("\u25B2")} ${e.danger("\u25CF")} ${e.deep("\u25A0")}`:null,spin:t?["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"]:["-","\\","|","/"]}}a(xa,"createSymbols");var A=ka(),O=xa(A),Ra=/\x1b\[[0-9;]*m/g;function va(e){return String(e).replace(Ra,"")}a(va,"stripAnsi");function Ea(e){return e===8203||e===8205||e>=768&&e<=879||e>=65024&&e<=65039?0:e>=4352&&e<=4447||e>=11904&&e<=42191||e>=44032&&e<=55203||e>=63744&&e<=64255||e>=65072&&e<=65103||e>=65280&&e<=65376||e>=65504&&e<=65510||e>=127744&&e<=129791||e>=131072&&e<=262141?2:1}a(Ea,"charWidth");function Ta(e){let t=0;for(let r of va(e))t+=Ea(r.codePointAt(0)??0);return t}a(Ta,"visibleWidth");function hr(e,t){let r=t-Ta(String(e));return r>0?String(e)+" ".repeat(r):String(e)}a(hr,"padEndAnsi");function Ie(e){return ["fresh","ready","precompiled","passed","captured","verified","first frame","compiled","worker ready","assets ready"].includes(e)?O.tick:["stale","live","generating","fallback","updating","skipped"].includes(e)?O.warn:["missing","starting","not-observed","unobserved"].includes(e)?O.ring:O.cross}a(Ie,"stateMark");var Ct=".three-blocks/runtime/status.json",lt=256*1024,At="three-blocks browser smoke",Ba=["three-blocks.json","three-blocks.shaders.json","three-blocks.text.ts"];function Bn(e){return "kind"in e&&e.kind==="adopted"}a(Bn,"isAdoptedProjectStatus");async function Mt(e,t,r,n){let o=await l(e,t,r,n);return JSON.parse(o.data.toString("utf8"))}a(Mt,"readJsonWithin");var Pa=["starting","worker ready","assets ready","compiled","first frame","updating","error"],$a=["ready","generating","fallback","missing","invalid"],_a=["WebGPU","WebGL"],Aa=["OffscreenCanvas","MainThread"],Ca=/^[0-9A-Za-z][0-9A-Za-z._-]{0,63}$/,xn=16,Rn=1e9;function ae(e,t,r,n=[]){if(!a$1(e))throw new Error(`${t} must be an object.`);let o=new Set([...r,...n]);for(let s of r)if(!Object.hasOwn(e,s))throw new Error(`${t}.${s} is required.`);for(let s of Object.keys(e))if(!o.has(s))throw new Error(`${t}.${s} is not supported by schema v1.`);return e}a(ae,"exactRecord");function ct(e,t,r){if(typeof e!="string"||!t.includes(e))throw new Error(`${r} has an unsupported value.`);return e}a(ct,"enumValue");function Z(e,t){if(typeof e!="boolean")throw new Error(`${t} must be a boolean.`);return e}a(Z,"booleanValue");function vn(e,t){return e===null?null:Z(e,t)}a(vn,"nullableBoolean");function Le(e,t){if(typeof e!="number"||!Number.isSafeInteger(e)||e<0||e>Rn)throw new Error(`${t} must be a non-negative integer no greater than ${Rn}.`);return e}a(Le,"boundedCounter");function Ma(e){if(typeof e!="string"||e.length>32)throw new Error("Runtime status receipt observedAt must be a bounded ISO timestamp.");let t=Date.parse(e);if(!Number.isFinite(t)||new Date(t).toISOString()!==e)throw new Error("Runtime status receipt observedAt must be an exact ISO timestamp.");return e}a(Ma,"observedTimestamp");function Oa(e){if(e===null)return null;if(typeof e!="string"||e.length===0||e.length>2048||/[\u0000-\u001f\u007f]/u.test(e))throw new Error("Runtime status receipt error must be null or one bounded display-safe line.");return e}a(Oa,"receiptError");function Fa(e){if(!Array.isArray(e)||e.length>xn)throw new Error(`Runtime status receipt assets.codecs must contain at most ${xn} entries.`);let t=e.map((r,n)=>{let o=ae(r,`Runtime status receipt assets.codecs[${n}]`,["name","available","decoded"]);if(typeof o.name!="string"||!Ca.test(o.name))throw new Error(`Runtime status receipt assets.codecs[${n}].name is invalid.`);let s=Z(o.available,`Runtime status receipt assets.codecs[${n}].available`),i=Z(o.decoded,`Runtime status receipt assets.codecs[${n}].decoded`);if(i&&!s)throw new Error(`Runtime status receipt codec ${JSON.stringify(o.name)} cannot be decoded when unavailable.`);return {name:o.name,available:s,decoded:i}});if(new Set(t.map(r=>r.name)).size!==t.length)throw new Error("Runtime status receipt assets.codecs must have unique names.");return t}a(Fa,"parseRuntimeCodecs");function Ia(e){if(e.assetsReady&&!e.workerReady)throw new Error("Runtime lifecycle assetsReady requires workerReady.");if(e.compiled&&!e.assetsReady)throw new Error("Runtime lifecycle compiled requires assetsReady.");if(e.firstFrame&&!e.compiled)throw new Error("Runtime lifecycle firstFrame requires compiled.");let t=e.state==="starting"?[false,false,false,false]:e.state==="worker ready"?[true,false,false,false]:e.state==="assets ready"?[true,true,false,false]:e.state==="compiled"?[true,true,true,false]:e.state==="first frame"||e.state==="updating"?[true,true,true,true]:null;if(t!==null&&![e.workerReady,e.assetsReady,e.compiled,e.firstFrame].every((r,n)=>r===t[n]))throw new Error(`Runtime lifecycle flags do not match state ${JSON.stringify(e.state)}.`)}a(Ia,"validateLifecycle");function Pn(e){let t=ae(e,"Runtime status receipt",["schemaVersion","observedAt","worker","assets","hmr","stats","lifecycle","shaders","error"],["text"]);if(t.schemaVersion!==1)throw new Error("Runtime status receipt must use schemaVersion 1.");let r=ae(t.worker,"Runtime status receipt worker",["backend","renderer","protocolVersion"]);if(r.protocolVersion!==1)throw new Error("Runtime status receipt worker.protocolVersion must be 1.");let n=ae(t.assets,"Runtime status receipt assets",["codecs","resources"]),o=ae(t.hmr,"Runtime status receipt hmr",["capabilities","outcome"]),s=ae(o.capabilities,"Runtime status receipt hmr.capabilities",["scene","component","assetManifest","workerRestart"]),i=ae(o.outcome,"Runtime status receipt hmr.outcome",["attempted","succeeded","rollbackPreserved","workerRestarted"]),a=Z(i.attempted,"Runtime status receipt hmr.outcome.attempted"),c=vn(i.succeeded,"Runtime status receipt hmr.outcome.succeeded"),u=vn(i.rollbackPreserved,"Runtime status receipt hmr.outcome.rollbackPreserved"),p=Z(i.workerRestarted,"Runtime status receipt hmr.outcome.workerRestarted");if(a?c===null||u===null:c!==null||u!==null||p)throw new Error("Runtime status receipt HMR outcome fields are inconsistent with attempted.");let l={scene:Z(s.scene,"Runtime status receipt hmr.capabilities.scene"),component:Z(s.component,"Runtime status receipt hmr.capabilities.component"),assetManifest:Z(s.assetManifest,"Runtime status receipt hmr.capabilities.assetManifest"),workerRestart:Z(s.workerRestart,"Runtime status receipt hmr.capabilities.workerRestart")};if(a&&!l.scene)throw new Error("Runtime status receipt cannot attempt HMR without the scene capability.");if(p&&!l.workerRestart)throw new Error("Runtime status receipt cannot restart a worker without the workerRestart capability.");let m=ae(t.stats,"Runtime status receipt stats",["snapshots","textures","workerProfiler","mainPanels"]),f=ae(t.lifecycle,"Runtime status receipt lifecycle",["state","workerReady","assetsReady","compiled","firstFrame"]),h={state:ct(f.state,Pa,"Runtime status receipt lifecycle.state"),workerReady:Z(f.workerReady,"Runtime status receipt lifecycle.workerReady"),assetsReady:Z(f.assetsReady,"Runtime status receipt lifecycle.assetsReady"),compiled:Z(f.compiled,"Runtime status receipt lifecycle.compiled"),firstFrame:Z(f.firstFrame,"Runtime status receipt lifecycle.firstFrame")};Ia(h);let y=ae(t.shaders,"Runtime status receipt shaders",["mode","pipelines"]),g=ct(y.mode,["precompiled","live"],"Runtime status receipt shaders.mode"),R=Le(y.pipelines,"Runtime status receipt shaders.pipelines");if(g==="precompiled"&&R===0)throw new Error("A precompiled runtime receipt must observe at least one shader pipeline.");let k;if(t.text!==void 0){let I=ae(t.text,"Runtime status receipt text",["state","atlases","glyphs","requiredGlyphs"]);if(k={state:ct(I.state,$a,"Runtime status receipt text.state"),atlases:Le(I.atlases,"Runtime status receipt text.atlases"),glyphs:Le(I.glyphs,"Runtime status receipt text.glyphs"),requiredGlyphs:Le(I.requiredGlyphs,"Runtime status receipt text.requiredGlyphs")},k.state==="ready"&&(k.atlases===0||k.requiredGlyphs===0||k.glyphs<k.requiredGlyphs))throw new Error("A ready text receipt must cover a non-empty required glyph set with at least one atlas.")}let w=Oa(t.error);if(h.state==="error"?w===null:w!==null)throw new Error("Runtime status receipt error must be present only when lifecycle.state is error.");return {schemaVersion:1,observedAt:Ma(t.observedAt),worker:{backend:ct(r.backend,Aa,"Runtime status receipt worker.backend"),renderer:ct(r.renderer,_a,"Runtime status receipt worker.renderer"),protocolVersion:1},assets:{codecs:Fa(n.codecs),resources:Le(n.resources,"Runtime status receipt assets.resources")},hmr:{capabilities:l,outcome:{attempted:a,succeeded:c,rollbackPreserved:u,workerRestarted:p}},stats:{snapshots:Le(m.snapshots,"Runtime status receipt stats.snapshots"),textures:Le(m.textures,"Runtime status receipt stats.textures"),workerProfiler:Z(m.workerProfiler,"Runtime status receipt stats.workerProfiler"),mainPanels:Z(m.mainPanels,"Runtime status receipt stats.mainPanels")},lifecycle:h,shaders:{mode:g,pipelines:R},...k===void 0?{}:{text:k},error:w}}a(Pn,"parseRuntimeStatusReceipt");function La(e,t){return e.render===t.render&&e.vertex===t.vertex&&e.fragment===t.fragment&&e.compute===t.compute}a(La,"sameCoverage");async function yr(e=process.cwd()){let t=U.resolve(e);for(;;){if((await Promise.all(Ba.map(n=>g(U.join(t,n))))).some(Boolean))return realpath(t);let r=U.dirname(t);if(r===t)return realpath(U.resolve(e));t=r;}}a(yr,"findProjectRoot");async function ja(e,t){let r=t.template,n=U.join(e,".three-blocks","shaders"),o=U.join(n,"meta.json");if(!await g(n)||!await g(o))return {state:"missing",scene:r,reason:t.artifacts?.shaders==="pending"?"The selected template has no verified shader capture yet.":".three-blocks/shaders/meta.json is absent."};try{let s=await k(e,n,"Shader artifact directory"),i=c$1(await Mt(s,o,d$1.receipt,"Shader receipt")),a=i.scenes[r];if(a===void 0)return {state:"invalid",scene:r,reason:`Shader receipt has no "${r}" scene.`};let c=await l(s,U.join(s,a.artifact),d$1.manifest,"Shader manifest");if(f(c.data)!==a.artifactHash)return {state:"invalid",scene:r,reason:"The selected shader manifest checksum does not match its receipt."};let u=Rt(c.data.toString("utf8"),c.path,r);if(!La(u,a.coverage))return {state:"invalid",scene:r,reason:"Shader receipt coverage does not match the manifest entries.",coverage:u};let{three:p,threeBlocks:l$1,threeBlocksShaderClosure:m}=await ye(e);if(i.runtime.three!==p||t.runtime.three!==p||i.runtime.threeBlocks!==l$1||t.runtime.threeBlocks!==l$1)return {state:"stale",scene:r,reason:`Installed runtime versions (${p}, ${l$1}) do not match the metadata and shader receipt.`,coverage:u};if(i.runtime.threeBlocksShaderClosure!==m)return {state:"stale",scene:r,reason:"The installed three-blocks/shaders runtime closure differs from the capture receipt.",coverage:u};let f$1=await Te(e),h=Object.keys(f$1),y=Object.keys(a.inputs),g=h.filter(w=>!Object.hasOwn(a.inputs,w)),R=y.filter(w=>!Object.hasOwn(f$1,w)),k$1=h.filter(w=>Object.hasOwn(a.inputs,w)&&a.inputs[w]!==f$1[w]);return g.length>0||R.length>0||k$1.length>0?{state:"stale",scene:r,reason:`${g.length} added, ${R.length} removed, and ${k$1.length} changed semantic shader inputs.`,coverage:u,...k$1.length>0?{changedInputs:k$1}:{},...g.length>0?{addedInputs:g}:{},...R.length>0?{removedInputs:R}:{}}:{state:"fresh",scene:r,reason:"Manifest, installed shader runtime closure, and the shader-relevant source snapshot match.",coverage:u}}catch(s){return {state:"invalid",scene:r,reason:s instanceof Error?s.message:String(s)}}}a(ja,"inspectShaders");async function Na(e,t){if(t.artifacts?.text==="pending")return {state:"missing",reason:"The template has no verified text artifacts yet.",atlases:[]};let r=await _t(e);return {state:r.state,reason:r.reason,atlases:r.atlases.map(n=>({name:n.font.key,glyphs:n.codePoints.length,width:n.texture.width,height:n.texture.height}))}}a(Na,"inspectText");function Da(e,t){if(e.lifecycle.assetsReady&&e.assets.codecs.some(r=>!r.available))throw new Error("Runtime status receipt claims assets ready while a configured codec is unavailable.");if(t.features.text!==(e.text!==void 0))throw new Error("Runtime status receipt text observation does not match three-blocks.json.")}a(Da,"validateRuntimeReceiptForProject");async function Ha(e,t){let r=U.join(e,...Ct.split("/"));if(!await g(r))return {kind:"absent",receipt:null,reason:"No browser observation receipt is available."};try{let n=await k(e,U.dirname(r),"Runtime status receipt directory"),o=Pn(await Mt(n,U.join(n,U.basename(r)),lt,"Runtime status receipt"));return Da(o,t),{kind:"valid",receipt:o,reason:o.error??`Browser observation captured at ${o.observedAt}.`}}catch(n){return {kind:"invalid",receipt:null,reason:`Runtime status receipt is invalid: ${n instanceof Error?n.message:String(n)}`}}}a(Ha,"inspectRuntimeReceipt");function Va(){return {scene:false,component:false,assetManifest:false,workerRestart:false}}a(Va,"emptyCapabilities");function Ua(){return {attempted:false,succeeded:null,rollbackPreserved:null,workerRestarted:false}}a(Ua,"emptyOutcome");function Wa(){return []}a(Wa,"configuredCodecs");function Ga(e,t,r){if(t.state!=="fresh")return "three-blocks shaders capture";if(r!==void 0&&r.state!=="ready")return "three-blocks text generate";let n=e.receipt;return e.kind!=="valid"||n===null||n.lifecycle.state==="error"?At:n.text!==void 0&&n.text.state!=="ready"?"three-blocks text generate":At}a(Ga,"recoveryCommand");async function $n(e=process.cwd()){let t=await yr(e),r=b(await Mt(t,U.join(t,"three-blocks.json"),d$1.metadata,"Project metadata")),n=await ja(t,r),o=r.features.text?await Na(t,r):void 0,s=await Ha(t,r),i=s.receipt,a=s.kind==="invalid",c=a||i?.lifecycle.state==="error",u=i===null?{state:a?"error":"starting",backend:null,renderer:null,protocolVersion:1}:{state:c?"error":i.lifecycle.workerReady?"worker ready":"starting",backend:i.worker.backend,renderer:i.worker.renderer,protocolVersion:i.worker.protocolVersion},p=i===null?{state:a?"error":"starting",codecs:Wa(),resources:0}:{state:c?"error":i.lifecycle.assetsReady?"assets ready":"starting",codecs:i.assets.codecs,resources:i.assets.resources},l=i===null?{state:a?"error":"starting",capabilities:Va(),outcome:Ua()}:{state:c||i.hmr.outcome.attempted&&(i.hmr.outcome.succeeded!==true||i.hmr.outcome.rollbackPreserved!==true)?"error":i.hmr.outcome.attempted?"first frame":"starting",capabilities:i.hmr.capabilities,outcome:i.hmr.outcome},m=i===null?{state:a?"error":"starting",snapshots:0,textures:0,workerProfiler:false,mainPanels:false}:{state:c?"error":i.stats.snapshots>0&&i.stats.workerProfiler&&i.stats.mainPanels?"first frame":"starting",...i.stats},f=i===null?{state:a?"error":"starting",mode:null,pipelines:0,artifactState:n.state}:{state:c?"error":i.lifecycle.compiled?n.state==="fresh"?i.shaders.mode:n.state:i.lifecycle.state,mode:i.shaders.mode,pipelines:i.shaders.pipelines,artifactState:n.state},h=o===void 0?void 0:i?.text===void 0?{state:a?"error":"starting",atlases:0,glyphs:0,requiredGlyphs:0}:{state:c?"error":o.state==="ready"?i.text.state:o.state,atlases:i.text.atlases,glyphs:i.text.glyphs,requiredGlyphs:i.text.requiredGlyphs};return {schemaVersion:1,root:t,metadata:r,configuration:{worker:u,assets:p,hmr:l,optimization:f,stats:m,...h===void 0?{}:{text:h}},runtime:{state:a?"error":i?.lifecycle.state??"starting",observed:i!==null,observedAt:i?.observedAt??null,reason:s.reason,recovery:Ga(s,n,o),observation:i},shaders:n,...o?{text:o}:{}}}a($n,"inspectProject");async function En(e){let[t,r]=await Promise.all([g(U.join(e,"three-blocks.shaders.json")),g(U.join(e,"three-blocks.text.ts"))]),[n,o]=await Promise.all([t?Fe(e):Promise.resolve(void 0),r?_t(e):Promise.resolve(void 0)]);return {schemaVersion:1,root:e,kind:"adopted",markers:{shaders:t,text:r},...n===void 0?{}:{shaders:n},...o===void 0?{}:{text:o}}}a(En,"inspectAdoptedProject");async function za(e=process.cwd()){let t=await yr(e),r=U.join(t,"three-blocks.json");if(await g(r)){try{b(await Mt(t,r,d$1.metadata,"Project metadata"));}catch{return En(t)}return $n(t)}return En(t)}a(za,"inspectThreeBlocksStatus");function Ka(e){return Bn(e)?(e.markers.shaders||e.markers.text)&&(e.shaders===void 0||e.shaders.state==="fresh")&&(e.text===void 0||e.text.state==="ready"):e.shaders.state==="fresh"&&(e.text===void 0||e.text.state==="ready")&&e.runtime.state!=="error"}a(Ka,"threeBlocksStatusIsFresh");function qa(e){return e==="ktx2"?"KTX2":e==="draco"?"Draco":e==="meshopt"?"Meshopt":e}a(qa,"codecName");function Xa(e,t=Date.now()){let r=t-Date.parse(e);if(!Number.isFinite(r)||r<0)return e;let n=Math.round(r/1e3);if(n<60)return "just now";let o=Math.round(n/60);if(o<60)return `${o} minute${o===1?"":"s"} ago`;let s=Math.round(o/60);return s<48?`${s} hour${s===1?"":"s"} ago`:`${Math.round(s/24)} days ago`}a(Xa,"relativeTime");function le(e,t,r){return `${e} ${hr(t,12)} ${r}`}a(le,"row");function Be(e,t){return ` ${hr(A.dim(e),12)} ${A.dim(t)}`}a(Be,"subRow");function Tn(e){return e<100?e.toFixed(1):Math.round(e).toString()}a(Tn,"milliseconds");function Ja(e){return e?`${e.render} render \xB7 ${e.compute} compute`:"no coverage"}a(Ja,"coverageText");function _n(e){let t=[le(Ie(e.state),"shaders",`${e.state==="fresh"?"fresh":A.warn(e.state)} ${O.dot} ${A.dim(e.reason)}`)];for(let r of e.scenes){let n=r.timing,o=n?.source==="committed-capture"?`Committed capture \xB7 recorded on ${n.adapter??"unknown adapter"}`:"Latest local capture",s=n===void 0?"":`n=${n.runs}`,i=n===void 0?"":`\u2248${Tn(n.avoidedBuildMs)} ms \xB1 ${Tn(n.spreadMs)} TSL build time saved`,a=n===void 0?r.state==="fresh"?` ${O.dot} ${A.dim("Build timing not recorded for this capture \xB7 run three-blocks shaders test")}`:"":` ${O.dot} ${A.dim(`${i} \xB7 ${s} \xB7 ${o}`)}`;t.push(le(Ie(r.state),r.scene,`${r.state} ${O.dot} ${Ja(r.coverage)}${a}`)),n!==void 0&&n.spreadMs>n.avoidedBuildMs*.4&&t.push(Be("measure",A.warn("noisy measurement \u2014 close other GPU apps and re-run")));let c=[...r.changedInputs??[],...r.addedInputs??[],...r.removedInputs??[]];c.length>0&&t.push(Be("changed",c.join(", ")));}return e.state!=="fresh"&&t.push(`${O.info} ${A.accent("three-blocks shaders capture")}`),t.join(`
|
|
15
|
+
`)}a(_n,"formatShaderMatrixStatus");function Ya(e){let t=e.scene,r=e.coverage,n=r?`${r.render} render \xB7 ${r.compute} compute`:"no coverage";if(e.state==="fresh")return [le(Ie("fresh"),t,`fresh ${O.dot} ${n} ${O.dot} ${A.dim("precompiled at runtime")}`)];let o=[le(Ie(e.state),t,`${e.state==="missing"?A.dim("missing"):A.warn(e.state)} ${O.dot} ${A.dim(e.reason)}`)],s=[...e.changedInputs??[],...e.addedInputs??[],...e.removedInputs??[]];return s.length>0&&o.push(Be("changed",s.join(", "))),o}a(Ya,"shaderRow");function An(e,t=Date.now()){let r=O.mark?`${O.mark} `:"",n=e.metadata.runtime,o=[`${r}${A.bold("three-blocks")} ${A.dim("status")}`,Be("project",e.root),"",A.bold("Project"),le(O.tick,e.metadata.template,`three ${n.three} ${O.dot} three-blocks ${n.threeBlocks}`),"",A.bold("Shaders"),...Ya(e.shaders)];if(e.text){let a=e.text,c=a.atlases.reduce((u,p)=>u+p.glyphs,0);o.push("",A.bold("Text"),le(Ie(a.state),"coverage",a.state==="ready"?`ready ${O.dot} ${c} glyphs ${O.dot} ${a.atlases.length} atlas${a.atlases.length===1?"":"es"}`:`${A.warn(a.state)} ${O.dot} ${A.dim(a.reason)}`),...a.atlases.map(u=>Be("atlas",`${u.name} \xB7 ${u.glyphs} glyphs \xB7 ${u.width}\xD7${u.height}`)));}let s=e.runtime.observation;if(o.push("",A.bold("Browser check")),s!==null&&e.runtime.state!=="error"){let a=s.assets.codecs.map(c=>`${qa(c.name)}${c.decoded?"":c.available?" (idle)":" (unavailable)"}`).join(" \xB7 ");o.push(le(O.tick,"verified",`${Xa(s.observedAt,t)} ${O.dot} ${s.worker.renderer} worker ${O.dot} ${s.lifecycle.state} ${O.dot} ${s.shaders.pipelines} pipeline${s.shaders.pipelines===1?"":"s"} ${s.shaders.mode}`),Be("codecs",a||"none configured")),s.hmr.outcome.attempted&&o.push(Be("hmr",s.hmr.outcome.succeeded?`update succeeded${s.hmr.outcome.workerRestarted?" \xB7 worker restarted":""}`:"update failed"));}else e.runtime.state==="error"?o.push(le(O.cross,"runtime",A.danger(e.runtime.reason))):o.push(le(O.ring,"unverified",A.dim(`no browser run recorded \u2014 ${At}`)));return e.shaders.state==="fresh"&&(e.text===void 0||e.text.state==="ready")&&e.runtime.state!=="error"||o.push("",A.bold("Next"),`${O.info} ${A.accent(e.runtime.recovery)}`),o.join(`
|
|
16
|
+
`)}a(An,"formatStatus");function Za(e,t=Date.now()){if(!Bn(e))return An(e,t);let r=O.mark?`${O.mark} `:"",n=e.markers.shaders||e.markers.text,o=[`${r}${A.bold("three-blocks")} ${A.dim("status")}`,Be("project",e.root)];if(!n)return o.push("",`${O.dot} ${A.dim("no Three Blocks project markers found")}`,` ${A.dim("shaders:")} add three-blocks.shaders.json \u2014 /docs/tools/devtools`,` ${A.dim("starter:")} npx three-blocks starter`),o.join(`
|
|
17
|
+
`);if(e.shaders!==void 0&&o.push("",A.bold("Shaders"),_n(e.shaders)),e.text!==void 0){let s=e.text.atlases.reduce((i,a)=>i+a.codePoints.length,0);o.push("",A.bold("Text"),le(Ie(e.text.state),"coverage",e.text.state==="ready"?`ready ${O.dot} ${s} glyphs ${O.dot} ${e.text.atlases.length} atlas${e.text.atlases.length===1?"":"es"}`:`${A.warn(e.text.state)} ${O.dot} ${A.dim(e.text.reason)}`));}return o.join(`
|
|
18
|
+
`)}a(Za,"formatThreeBlocksStatus");var xr="virtual:three-blocks-devtools/browser-smoke",Cn=`\0${xr}`,si=`/@id/__x00__${xr}`,In=9e4;async function Ln(){try{let[e,t]=await Promise.all([import('playwright'),import('vite')]);return {chromium:e.chromium,vite:t}}catch(e){throw new Error('Browser smoke and preview require the optional "playwright" and "vite" packages. Install both in the project and run `npx playwright install chromium`.',{cause:e})}}a(Ln,"loadBrowserSmokeTools");function Pe(e,t,r,n,o){let s=e??o;if(!Number.isSafeInteger(s)||s<r||s>n)throw new Error(`${t} must be an integer in ${r}...${n}.`);return s}a(Pe,"boundedInteger");function jn(e,t,r,n,o){let s=e??o;if(!Number.isFinite(s)||s<r||s>n)throw new Error(`${t} must be a finite number in ${r}...${n}.`);return s}a(jn,"boundedRatio");function Nn(e){let t=e??"/";if(t.length===0||t.length>2048||/[\u0000-\u001f\u007f]/u.test(t))throw new Error("Browser smoke route must be a bounded project URL.");let r=new URL(t,"http://three-blocks.invalid/");if(r.origin!=="http://three-blocks.invalid"||r.hash.length>0)throw new Error("Browser smoke route must stay within the project and have no fragment.");return `${r.pathname}${r.search}`}a(Nn,"safeRoute");function Xe(e,t){return e[t]===true}a(Xe,"booleanField");function ue(e,t){if(!a$1(e)||!a$1(e.value))return {source:"missing",backend:"unknown",worker:false,workerReady:false,assetsReady:false,compileEnd:false,textEnabled:t,textReady:!t,firstFrame:false};let r=e.value,n=e.source==="public";if(n&&r.protocolVersion!==1)return {source:"public",backend:"unknown",worker:false,workerReady:false,assetsReady:false,compileEnd:false,textEnabled:t,textReady:!t,firstFrame:false};let o=a$1(r.readiness)?r.readiness:r,s=r.worker,i=n&&a$1(s)?s.offscreenCanvas===true&&s.visible===true:s===true;return {source:n?"public":"legacy",backend:n&&a$1(s)?s.offscreenCanvas===true?"OffscreenCanvas":"MainThread":s===true?"OffscreenCanvas":"unknown",worker:i,workerReady:Xe(o,"workerReady"),assetsReady:Xe(o,"assetsReady")||Xe(o,"loadEnd"),compileEnd:Xe(o,"compileEnd"),textEnabled:t,textReady:!t||Xe(o,"textReady"),firstFrame:Xe(o,"firstFrame")}}a(ue,"parseBrowserSmokeLifecycle");function Ot(e){let t=PNG.sync.read(e),r=Math.floor(t.width*.25),n=Math.floor(t.width*.75),o=Math.floor(t.height*.25),s=Math.floor(t.height*.75),i=0,a=0;for(let c=o;c<s;c+=2)for(let u=r;u<n;u+=2){let p=(c*t.width+u)*4,l=t.data[p],m=t.data[p+1],f=t.data[p+2];l===void 0||m===void 0||f===void 0||(i+=Math.max(l,m,f),a+=1);}return a===0?0:i/a}a(Ot,"screenshotLuminance");function ai(){return `
|
|
19
|
+
import * as THREE from 'three/webgpu';
|
|
20
|
+
import { createAssetLoaderRegistry, createAssetManager, createThreeAssetAdapters, defineAssets } from 'three-blocks/assets';
|
|
21
|
+
import { SceneHotReloader } from 'three-blocks/hmr';
|
|
22
|
+
import { createShaderCache } from 'three-blocks/shaders';
|
|
23
|
+
import { createStatsWorker } from 'three-blocks/stats';
|
|
24
|
+
import { threeBlocksBuildReceipt, threeBlocksConfig, loadThreeBlocksMeshoptDecoder } from 'three-blocks/vite/config';
|
|
25
|
+
|
|
26
|
+
const root = globalThis;
|
|
27
|
+
const hmr = root.__threeBlocksSmokeProbe ??= { before: 0, after: 0 };
|
|
28
|
+
if ( import.meta.hot ) {
|
|
29
|
+
import.meta.hot.on( 'vite:beforeUpdate', () => { hmr.before += 1; } );
|
|
30
|
+
import.meta.hot.on( 'vite:afterUpdate', () => { hmr.after += 1; } );
|
|
31
|
+
import.meta.hot.accept();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function externalCodec( name, config, pathKey ) {
|
|
35
|
+
if ( config === false ) return { name, state: 'disabled', routes: [], decoded: false, evidence: 'delivery', blocker: null, error: null };
|
|
36
|
+
const routes = [];
|
|
37
|
+
try {
|
|
38
|
+
for ( const file of config.files ) {
|
|
39
|
+
const route = config[ pathKey ] + file;
|
|
40
|
+
const response = await fetch( new URL( route, location.origin ), { cache: 'no-store' } );
|
|
41
|
+
const body = await response.arrayBuffer();
|
|
42
|
+
if ( ! response.ok ) throw new Error( route + ' returned HTTP ' + response.status );
|
|
43
|
+
if ( body.byteLength === 0 ) throw new Error( route + ' returned an empty body' );
|
|
44
|
+
routes.push( { route: new URL( route, location.origin ).pathname, bytes: body.byteLength, contentType: response.headers.get( 'content-type' ) ?? '' } );
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
name,
|
|
48
|
+
state: 'ready',
|
|
49
|
+
routes,
|
|
50
|
+
decoded: false,
|
|
51
|
+
evidence: 'delivery',
|
|
52
|
+
blocker: null,
|
|
53
|
+
error: null,
|
|
54
|
+
};
|
|
55
|
+
} catch ( error ) {
|
|
56
|
+
return { name, state: 'error', routes, decoded: false, evidence: 'delivery', blocker: null, error: error instanceof Error ? error.message : String( error ) };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function meshoptCodec() {
|
|
61
|
+
if ( threeBlocksConfig.codecs.meshopt === false ) return { name: 'meshopt', state: 'disabled', routes: [], decoded: false, evidence: 'decoder-ready', blocker: null, error: null };
|
|
62
|
+
try {
|
|
63
|
+
const decoder = await loadThreeBlocksMeshoptDecoder();
|
|
64
|
+
await decoder.ready;
|
|
65
|
+
if ( decoder.supported !== true ) throw new Error( 'Meshopt decoder reports supported=false' );
|
|
66
|
+
return {
|
|
67
|
+
name: 'meshopt',
|
|
68
|
+
state: 'ready',
|
|
69
|
+
routes: [],
|
|
70
|
+
decoded: false,
|
|
71
|
+
evidence: 'decoder-ready',
|
|
72
|
+
blocker: null,
|
|
73
|
+
error: null,
|
|
74
|
+
};
|
|
75
|
+
} catch ( error ) {
|
|
76
|
+
return { name: 'meshopt', state: 'error', routes: [], decoded: false, evidence: 'decoder-ready', blocker: null, error: error instanceof Error ? error.message : String( error ) };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async function decodeCodecFixtures() {
|
|
81
|
+
const fixtureRoot = '/__three-blocks-codec-fixtures';
|
|
82
|
+
const available = await fetch( fixtureRoot + '/Box.gltf', { cache: 'no-store' } ).then( async response => {
|
|
83
|
+
if ( ! response.ok ) return false;
|
|
84
|
+
try {
|
|
85
|
+
const value = JSON.parse( await response.text() );
|
|
86
|
+
return Array.isArray( value?.extensionsUsed ) && value.extensionsUsed.includes( 'KHR_draco_mesh_compression' );
|
|
87
|
+
} catch {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}, () => false );
|
|
91
|
+
if ( ! available ) return null;
|
|
92
|
+
const canvas = document.createElement( 'canvas' );
|
|
93
|
+
canvas.width = 4;
|
|
94
|
+
canvas.height = 4;
|
|
95
|
+
const renderer = new THREE.WebGPURenderer( { canvas, antialias: false } );
|
|
96
|
+
let runtime;
|
|
97
|
+
let manager;
|
|
98
|
+
try {
|
|
99
|
+
await renderer.init();
|
|
100
|
+
runtime = createThreeAssetAdapters( {
|
|
101
|
+
renderer,
|
|
102
|
+
codecs: threeBlocksConfig.codecs,
|
|
103
|
+
loadMeshopt: loadThreeBlocksMeshoptDecoder,
|
|
104
|
+
} );
|
|
105
|
+
manager = createAssetManager( runtime.registry );
|
|
106
|
+
const load = async ( name, definition, validate ) => {
|
|
107
|
+
try {
|
|
108
|
+
const lease = await manager.lease( defineAssets( { fixture: definition } ) );
|
|
109
|
+
try {
|
|
110
|
+
if ( ! validate( lease.assets.fixture ) ) throw new Error( name + ' returned the wrong decoded object.' );
|
|
111
|
+
return { ok: true, error: null };
|
|
112
|
+
} finally {
|
|
113
|
+
lease.release();
|
|
114
|
+
}
|
|
115
|
+
} catch ( error ) {
|
|
116
|
+
return { ok: false, error: error instanceof Error ? error.message : String( error ) };
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
return {
|
|
120
|
+
draco: await load( 'Draco', { type: 'gltf', url: fixtureRoot + '/Box.gltf' }, value => value?.scene?.isObject3D === true ),
|
|
121
|
+
meshopt: await load( 'Meshopt', { type: 'gltf', url: fixtureRoot + '/Meshopt.gltf' }, value => value?.scene?.isObject3D === true ),
|
|
122
|
+
ktx2: await load( 'KTX2', { type: 'ktx2', url: fixtureRoot + '/geist.msdf.ktx2' }, value => value?.isTexture === true ),
|
|
123
|
+
};
|
|
124
|
+
} finally {
|
|
125
|
+
await manager?.shutdown();
|
|
126
|
+
await runtime?.dispose();
|
|
127
|
+
renderer.dispose();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async function proveHotRuntime() {
|
|
132
|
+
const sharedAsset = { id: 'shared-browser-smoke-asset' };
|
|
133
|
+
let disposedAssets = 0;
|
|
134
|
+
const registry = createAssetLoaderRegistry( {
|
|
135
|
+
json: {
|
|
136
|
+
type: 'json',
|
|
137
|
+
load: async () => sharedAsset,
|
|
138
|
+
dispose: () => { disposedAssets += 1; },
|
|
139
|
+
},
|
|
140
|
+
} );
|
|
141
|
+
const manager = createAssetManager( registry );
|
|
142
|
+
const manifest = { shared: { type: 'json', url: '/__three-blocks-smoke-shared.json' } };
|
|
143
|
+
const createScene = async ( name ) => {
|
|
144
|
+
const scope = manager.createScope();
|
|
145
|
+
const assets = await scope.load( manifest );
|
|
146
|
+
return {
|
|
147
|
+
name,
|
|
148
|
+
asset: assets.shared,
|
|
149
|
+
hot: { state: 0 },
|
|
150
|
+
dispose() { scope.dispose(); },
|
|
151
|
+
};
|
|
152
|
+
};
|
|
153
|
+
const first = await createScene( 'first' );
|
|
154
|
+
first.hot.state = 37;
|
|
155
|
+
let now = 0;
|
|
156
|
+
const pushed = [];
|
|
157
|
+
const profiler = {
|
|
158
|
+
init() {}, begin() {}, end() {}, update() {}, dispose() {},
|
|
159
|
+
getData: () => ( { fps: 60, cpu: 1, gpu: 2, gpuCompute: 3 } ),
|
|
160
|
+
};
|
|
161
|
+
const stats = createStatsWorker( {
|
|
162
|
+
sampleRate: 4,
|
|
163
|
+
now: () => now,
|
|
164
|
+
publish: ( value ) => pushed.push( value ),
|
|
165
|
+
createProfiler: async () => profiler,
|
|
166
|
+
} );
|
|
167
|
+
await stats.init( {} );
|
|
168
|
+
stats.beginFrame();
|
|
169
|
+
stats.endFrame();
|
|
170
|
+
const stableStats = stats;
|
|
171
|
+
const reloader = new SceneHotReloader( first, {
|
|
172
|
+
context: { manager, stats },
|
|
173
|
+
compile: ( candidate ) => {
|
|
174
|
+
if ( candidate.name === 'failed' ) throw new Error( 'intentional browser-smoke compile failure' );
|
|
175
|
+
},
|
|
176
|
+
} );
|
|
177
|
+
const replaced = await reloader.replace( () => createScene( 'second' ) );
|
|
178
|
+
now = 300;
|
|
179
|
+
stats.beginFrame();
|
|
180
|
+
stats.endFrame();
|
|
181
|
+
const cacheAfterCommit = manager.cacheSnapshot();
|
|
182
|
+
const committed = reloader.current;
|
|
183
|
+
let rollbackPhase = null;
|
|
184
|
+
try {
|
|
185
|
+
await reloader.replace( () => createScene( 'failed' ) );
|
|
186
|
+
} catch ( error ) {
|
|
187
|
+
rollbackPhase = error && typeof error === 'object' ? error.phase : null;
|
|
188
|
+
}
|
|
189
|
+
const cacheAfterRollback = manager.cacheSnapshot();
|
|
190
|
+
const shaderCache = createShaderCache( 'browser-smoke' );
|
|
191
|
+
const firstMaterial = {};
|
|
192
|
+
const firstRegistration = shaderCache.forScene( 'browser-smoke' ).material( 'browser-smoke/material', firstMaterial );
|
|
193
|
+
const nextMaterial = {};
|
|
194
|
+
const nextRegistration = shaderCache.forScene( 'browser-smoke', { replaceExisting: true } )
|
|
195
|
+
.material( 'browser-smoke/material', nextMaterial );
|
|
196
|
+
firstRegistration.dispose();
|
|
197
|
+
const invalidation = shaderCache.invalidationFor( 'browser-smoke/material', 'browser-smoke' );
|
|
198
|
+
const shaderReplacementActive = shaderCache.registration( 'browser-smoke/material', 'browser-smoke' )?.target === nextMaterial;
|
|
199
|
+
nextRegistration.dispose();
|
|
200
|
+
const result = {
|
|
201
|
+
sceneIdentityReplaced: replaced.previous === first && replaced.current === committed && committed !== first,
|
|
202
|
+
stateRestored: committed.hot.state === 37,
|
|
203
|
+
assetIdentityPreserved: first.asset === committed.asset && committed.asset === sharedAsset,
|
|
204
|
+
assetReferencesPreserved: cacheAfterCommit.length === 1 && cacheAfterCommit[ 0 ]?.references === 1 && disposedAssets === 0,
|
|
205
|
+
statsIdentityPreserved: stats === stableStats,
|
|
206
|
+
statsSequenceAdvanced: pushed.length === 2 && pushed[ 0 ]?.sequence === 0 && pushed[ 1 ]?.sequence === 1,
|
|
207
|
+
shaderInvalidated: shaderReplacementActive && invalidation?.key === 'browser-smoke/material' && /replaced during HMR/.test( invalidation.reason ),
|
|
208
|
+
rollbackPreserved: rollbackPhase === 'compile' && reloader.current === committed && cacheAfterRollback.length === 1 && cacheAfterRollback[ 0 ]?.references === 1,
|
|
209
|
+
};
|
|
210
|
+
committed.dispose();
|
|
211
|
+
stats.dispose();
|
|
212
|
+
await manager.shutdown();
|
|
213
|
+
return result;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export async function probe() {
|
|
217
|
+
const codecs = [
|
|
218
|
+
await externalCodec( 'draco', threeBlocksConfig.codecs.draco, 'decoderPath' ),
|
|
219
|
+
await externalCodec( 'ktx2', threeBlocksConfig.codecs.ktx2, 'transcoderPath' ),
|
|
220
|
+
await meshoptCodec(),
|
|
221
|
+
];
|
|
222
|
+
const decoded = await decodeCodecFixtures();
|
|
223
|
+
if ( decoded ) {
|
|
224
|
+
for ( const codec of codecs ) {
|
|
225
|
+
const result = decoded[ codec.name ];
|
|
226
|
+
if ( result?.ok ) {
|
|
227
|
+
codec.decoded = true;
|
|
228
|
+
codec.evidence = 'asset-manager-decoded';
|
|
229
|
+
codec.blocker = null;
|
|
230
|
+
} else if ( result ) {
|
|
231
|
+
codec.state = 'error';
|
|
232
|
+
codec.error = result.error;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return {
|
|
237
|
+
textEnabled: threeBlocksConfig.text.enabled,
|
|
238
|
+
receipt: threeBlocksBuildReceipt,
|
|
239
|
+
hmrEvidence: await proveHotRuntime(),
|
|
240
|
+
codecs,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
`}a(ai,"browserProbeSource");function ii(){return {name:"three-blocks:browser-smoke-probe",enforce:"post",resolveId(e){return e===xr?Cn:void 0},load(e){return e===Cn?ai():void 0}}}a(ii,"browserProbePlugin");function Dn(e){let t={console:[],page:[]};return e.on("console",r=>{r.type()!=="error"||b$1(r.text())||t.console.push(r.text());}),e.on("pageerror",r=>{b$1(r.message)||t.page.push(r.message);}),t}a(Dn,"collectPageErrors");async function Ne(e){return e.evaluate(()=>{let t=globalThis,r=t.__threeBlocksSmoke;if(r!==void 0)return {source:"public",value:r};let n=t.__threeBlocksBrowserTools;if(n&&typeof n=="object"){let o=Reflect.get(n,"smoke");if(o!==void 0)return {source:"public",value:o}}return {source:t.__threeBlocks===void 0?"missing":"legacy",value:t.__threeBlocks??null}})}a(Ne,"readBridge");async function di(e){return e.evaluate(()=>{let t=globalThis,r=t.document.querySelector("[data-tb-fatal-code]"),n=r?.getAttribute("data-tb-fatal-code")??"",o=(r?.title||r?.textContent||"")?.replace(/^three-blocks — error:\s*/u,"").replace(/^Uncaught(?:\s+Error)?:\s*/u,"").trim()??"";return {fatalVisible:r!==null&&/^[a-z][a-z0-9-]{0,63}$/u.test(n)&&t.getComputedStyle(r).display!=="none"&&t.getComputedStyle(r).visibility!=="hidden",code:n.length>0?n:null,detail:o.length>0?o:null}})}a(di,"readCompatibilityFailure");async function Mn(e){return e.evaluate(()=>{let t=globalThis,r=t.__threeBlocksTextFallbackProbe?.states,n=Array.isArray(r)?r.filter(a=>typeof a=="string").slice(0,32):[],o=n.indexOf("fallback"),s=n.lastIndexOf("ready"),i=[...t.document.querySelectorAll("[data-canvas-text]")];return {states:n,fallbackObserved:o>=0,recovered:o>=0&&s>o,visibleElements:i.filter(a=>a.getAttribute("data-canvas-text-fallback")!=="false").length,totalElements:i.length}})}a(Mn,"readTextFallbackEvidence");async function Ft(e){return e.evaluate(()=>{let t=globalThis,r=t.__threeBlocksSmoke?.diagnostics?.shaderMode;return {snapshots:Math.max(0,Number(t.__threeBlocksSmoke?.stats?.snapshots)||0),textures:Math.max(0,Number(t.__threeBlocksSmoke?.stats?.textures)||0),shaderMode:r==="precompiled"||r==="live"?r:null,mainPanels:t.document.querySelector("[data-three-blocks-stats-mode]")!==null}})}a(Ft,"readBrowserRuntimeObservation");async function ci(e,t){let r=Buffer.from(`${JSON.stringify(t,null,2)}
|
|
244
|
+
`,"utf8");if(r.byteLength>lt)throw new Error(`Runtime status receipt exceeds ${lt} bytes.`);let n=U.join(e,...Ct.split("/")),o=U.dirname(n);await mkdir(o,{recursive:true});let s=await realpath(o),i=U.relative(e,s);if(i.startsWith("..")||U.isAbsolute(i))throw new Error("Runtime status receipt directory escapes the project root.");let a=U.join(s,`.status.${process.pid}.${randomUUID()}.tmp`);try{await writeFile(a,r,{flag:"wx",mode:384}),await rename(a,n);}finally{await rm(a,{force:true});}}a(ci,"writeRuntimeStatusReceipt");async function It(e,t,r){await e.waitForFunction(n=>{let o=globalThis,s=o.__threeBlocksSmoke,i=s!==void 0;if(s===void 0){let l=o.__threeBlocksBrowserTools;l&&typeof l=="object"&&(s=Reflect.get(l,"smoke")),i=s!==void 0;}if(s===void 0&&(s=o.__threeBlocks),!s||typeof s!="object")return false;let a=s;if(i&&a.protocolVersion!==1)return false;let c=a.readiness&&typeof a.readiness=="object"?a.readiness:a,u=a.worker;return (i&&u&&typeof u=="object"?Reflect.get(u,"offscreenCanvas")===true&&Reflect.get(u,"visible")===true:u===true)&&c.workerReady===true&&(c.assetsReady===true||c.loadEnd===true)&&c.compileEnd===true&&c.firstFrame===true&&(!n||c.textReady===true)},t,{timeout:r});}a(It,"waitForLifecycle");async function On(e,t){await e.waitForFunction(()=>{let n=[...globalThis.document.querySelectorAll("[data-canvas-text]")];return n.length>0&&n.every(o=>o.getAttribute("data-canvas-text-fallback")==="true")},void 0,{timeout:Math.min(t,3e4)});}a(On,"waitForTextFallback");async function wr(e,t,r){await t();let n=250,o=performance.now()+Math.min(r,5e3),s=performance.now(),i=a(()=>{s=performance.now();},"navigated");e.on("framenavigated",i);try{for(;performance.now()-s<n;){if(performance.now()>=o)throw new Error("Timed out waiting for startup navigation to settle.");await e.waitForTimeout(25);}}finally{e.off("framenavigated",i);}await t();}a(wr,"waitForStableReadiness");async function Fn(e,t){return await e(),t()}a(Fn,"readAfterInitialReadiness");function li(e,t,r){if(!a$1(e)||typeof e.route!="string"||!e.route.startsWith("/")||e.route.length>2048||!Number.isSafeInteger(e.bytes)||Number(e.bytes)<=0||typeof e.contentType!="string"||e.contentType.length>256)throw new Error(`Browser codec ${t} route ${r} is invalid.`);let n=e.route.endsWith(".wasm")?"application/wasm":"javascript";if(!e.contentType.includes(n))throw new Error(`Browser codec route ${e.route} returned unexpected content-type ${JSON.stringify(e.contentType)}.`);return {route:e.route,bytes:Number(e.bytes),contentType:e.contentType}}a(li,"parseCodecRoute");function je(e,t,r){if(typeof e!="string"||!t.includes(e))throw new Error(`${r} is invalid.`);return e}a(je,"literal");function gr(e,t){if(!Number.isSafeInteger(e)||Number(e)<0)throw new Error(`${t} is invalid.`);return Number(e)}a(gr,"nonnegativeInteger");function ui(e){if(!a$1(e)||e.schemaVersion!==2||!a$1(e.renderer)||!a$1(e.assets)||!a$1(e.shaders)||!a$1(e.stats)||typeof e.output!="string"||e.output.length===0||e.output.length>2048||typeof e.threeVersion!="string"||e.threeVersion.length===0||e.threeVersion.length>128)throw new Error("Browser build receipt is invalid.");if(e.renderer.owner!=="worker"||e.renderer.api!=="WebGPU"||e.renderer.fallback!=="WebGL")throw new Error("Browser build receipt does not declare the worker-owned WebGPU/WebGL renderer contract.");let t=e.text;if(t!==void 0&&(!a$1(t)||!["ready","generating","fallback","missing","invalid"].includes(String(t.state))))throw new Error("Browser build receipt text state is invalid.");return {schemaVersion:2,renderer:{owner:"worker",api:"WebGPU",fallback:"WebGL"},assets:{draco:je(e.assets.draco,["ready","disabled"],"Browser build receipt Draco state"),ktx2:je(e.assets.ktx2,["ready","disabled"],"Browser build receipt KTX2 state"),meshopt:je(e.assets.meshopt,["lazy","disabled"],"Browser build receipt Meshopt state")},shaders:{state:je(e.shaders.state,["fresh","stale","invalid","missing"],"Browser build receipt shader state"),mode:je(e.shaders.mode,["precompiled","live"],"Browser build receipt shader mode"),pipelines:gr(e.shaders.pipelines,"Browser build receipt shader pipeline count")},...t===void 0?{}:{text:{state:je(t.state,["ready","generating","fallback","missing","invalid"],"Browser build receipt text state"),atlases:gr(t.atlases,"Browser build receipt text atlas count"),glyphs:gr(t.glyphs,"Browser build receipt text glyph count")}},stats:{enabled:e.stats.enabled===true,production:e.stats.production===true},output:e.output,threeVersion:e.threeVersion}}a(ui,"parseBuildReceipt");var br=Object.freeze({sceneIdentityReplaced:false,stateRestored:false,assetIdentityPreserved:false,assetReferencesPreserved:false,statsIdentityPreserved:false,statsSequenceAdvanced:false,shaderInvalidated:false,rollbackPreserved:false}),ut=Object.freeze({requested:false,appIdentityStable:false,contentIdentityStable:false,canvasReplaced:false,workerIdentityChanged:false,generationAdvanced:false,restartCountAdvanced:false,stateReplayed:false,readinessRestored:false,shaderModeStable:false,statsSnapshotsAdvanced:false,statsTextureTransferred:false,statsTextureStopped:false,error:null}),mi=Object.freeze(["three-blocks/assets","three-blocks/hmr","three-blocks/runtime","three-blocks/shaders","three-blocks/stats","three-blocks/text","three-blocks/worker"]);function fi(e){if(!a$1(e))throw new Error("Browser HMR evidence is invalid.");let t={...br};for(let r of Object.keys(t)){if(e[r]!==true)throw new Error(`Browser HMR evidence ${r} did not pass.`);t[r]=true;}return t}a(fi,"parseHmrEvidence");function pi(e){if(!a$1(e)||typeof e.textEnabled!="boolean"||!Array.isArray(e.codecs)||e.codecs.length!==3)throw new Error("Browser codec probe returned an invalid payload.");let t=["draco","ktx2","meshopt"],r=e.codecs.map((n,o)=>{let s=t[o];if(s===void 0||!a$1(n)||n.name!==s||!["ready","disabled","error"].includes(String(n.state))||!Array.isArray(n.routes)||n.error!==null&&typeof n.error!="string")throw new Error(`Browser codec probe entry ${o} is invalid.`);let i=n.state,a=n.routes.map((u,p)=>li(u,s,p)),c=je(n.evidence,["delivery","decoder-ready","text-atlas-decoded","asset-manager-decoded"],`Browser codec ${s} evidence`);if(typeof n.decoded!="boolean"||n.blocker!==null&&typeof n.blocker!="string")throw new Error(`Browser codec ${s} decode evidence is invalid.`);if(i==="ready"&&s!=="meshopt"&&a.length===0)throw new Error(`Browser codec ${s} exposed no routes.`);if(i==="error"&&(typeof n.error!="string"||n.error.length===0||n.error.length>8192))throw new Error(`Browser codec ${s} has an invalid error.`);return {name:s,state:i,routes:a,decoded:n.decoded,evidence:c,blocker:typeof n.blocker=="string"?n.blocker:null,error:typeof n.error=="string"?n.error:null}});return {textEnabled:e.textEnabled,codecs:r,receipt:ui(e.receipt),hmrEvidence:fi(e.hmrEvidence)}}a(pi,"parseCodecProbe");async function hi(e){let t=await e.evaluate(async r=>{let n=await import(r);if(typeof n.probe!="function")throw new Error("Browser smoke probe module has no probe() export.");return await n.probe()},si);return pi(t)}a(hi,"probeCodecs");function yi(e){return e instanceof Error&&/execution context was destroyed|most likely because of a navigation/iu.test(e.message)}a(yi,"isNavigationRace");async function gi(e,t,r){for(let n=0;n<3;n++)try{return await hi(e)}catch(o){if(!yi(o)||n===2)throw o;await wr(e,t,r);}throw new Error("Browser codec probe did not complete.")}a(gi,"probeCodecsAfterNavigation");async function Sr(e){return e.evaluate(()=>{let t=globalThis,r=0;for(let n of t.document.querySelectorAll("canvas")){if(n.width<=0||n.height<=0)continue;let o=null;try{o=n.getContext("2d");}catch{continue}if(o)try{let s=o.getImageData(0,0,n.width,n.height).data,i=0,a=0;for(let c=0;c+2<s.length;c+=4)i+=Math.max(s[c]??0,s[c+1]??0,s[c+2]??0),a+=1;a>0&&(r=Math.max(r,i/a));}catch{}}return r})}a(Sr,"panelLuminance");function wi(e){return e.split(U.sep).join("/")}a(wi,"portablePath");async function bi(e){return e.evaluate(()=>{let r=globalThis.__threeBlocksSmokeProbe;if(!r||typeof r!="object")return 0;let n=Reflect.get(r,"after");return typeof n=="number"&&Number.isSafeInteger(n)?n:0})}a(bi,"hmrEventCount");async function Si(e,t,r,n,o,s,i){if(n===void 0)return {requested:false,module:null,dispatched:false,acknowledged:false,lifecycleStable:true,sourceUnchanged:true,evidenceSource:"public-runtime-browser-probe",evidence:i,restart:ut,error:null};let a=wi(n),c=false,u=false,p=false,l$1=false;try{let m=await l(r,U.join(r,n),d$1.semanticInput,"HMR scene module"),f$1=f(m.data),h=e.moduleGraph.getModulesByFile(m.path);if(!h||h.size===0)throw new Error(`HMR scene module ${JSON.stringify(a)} is not in Vite's module graph.`);let y=await bi(t);e.watcher.emit("change",m.path),c=!0,await t.waitForFunction(R=>{let w=globalThis.__threeBlocksSmokeProbe;return !!(w&&typeof w=="object"&&Number(Reflect.get(w,"after"))>R)},y,{timeout:Math.min(o,3e4)}),u=!0,await It(t,s,Math.min(o,3e4)),p=!0;let g=await l(r,m.path,d$1.semanticInput,"HMR scene module");if(l$1=f(g.data)===f$1,!l$1)throw new Error("HMR scene source changed during the smoke run.");return {requested:!0,module:a,dispatched:c,acknowledged:u,lifecycleStable:p,sourceUnchanged:l$1,evidenceSource:"public-runtime-browser-probe",evidence:i,restart:ut,error:null}}catch(m){return {requested:true,module:a,dispatched:c,acknowledged:u,lifecycleStable:p,sourceUnchanged:l$1,evidenceSource:"public-runtime-browser-probe",evidence:i,restart:ut,error:m instanceof Error?m.message:String(m)}}}a(Si,"exerciseHmr");async function ki(e,t,r,n){let o="stats-baseline";try{let s=await e.evaluate(()=>{let l=globalThis;return new URL(l.location.href).searchParams.get("tbStats")==="1"});s&&(o="stats-query-boot",await e.waitForFunction(()=>globalThis.__threeBlocksSmoke?.stats?.panelVisible===!0,void 0,{timeout:Math.min(t,3e4)}));let i=await e.evaluate(()=>{let l=globalThis;return {panelVisible:l.__threeBlocksSmoke?.stats?.panelVisible,textures:Number(l.__threeBlocksSmoke?.stats?.textures)||0,panelAttached:l.document.querySelector("[data-three-blocks-stats-mode]")!==null}});if(!s&&(i.panelVisible!==!1||i.textures!==0||i.panelAttached))throw new Error("Generated stats panel is not default-off before browser-smoke activation.");o="stats-enable",await e.evaluate(async()=>{let m=globalThis.__threeBlocksSmoke?.stats;if(!m||typeof m.setPanelVisible!="function"||typeof m.setPanelMode!="function")throw new Error("Generated stats panel controls are unavailable.");if(await Reflect.apply(m.setPanelVisible,m,[!0])!==!0)throw new Error("Generated stats panel could not be enabled.");if(await Reflect.apply(m.setPanelMode,m,["expanded"])!==!0)throw new Error("Generated stats panel could not be expanded.")}),o="stats-expanded",await e.waitForFunction(()=>{let l=globalThis;return l.__threeBlocksSmoke?.stats?.panelVisible===!0&&l.document.querySelector('[data-three-blocks-stats-mode="expanded"]')!==null},void 0,{timeout:Math.min(t,3e4)}),o="stats-initial-texture",await e.waitForFunction(l=>Number(globalThis.__threeBlocksSmoke?.stats?.textures)>l,i.textures,{timeout:Math.min(t,3e4)}),o="snapshot";let a=await e.evaluate(()=>{let l=globalThis,m=l.__threeBlocksSmoke,f=l.document.querySelector("#app"),h=l.document.querySelector("#scene"),y=l.document.querySelector("main")??f;if(!m||typeof m.restartWorker!="function"||!f||!h||!y||typeof m.diagnostics?.workerId!="string")throw new Error("Generated worker restart diagnostics are unavailable.");return l.__threeBlocksWorkerRestartProbe={app:f,content:y,canvas:h},{workerId:m.diagnostics.workerId,generation:m.worker.generation,restartCount:m.restart.count,snapshots:m.stats.snapshots,textures:m.stats.textures}});o="restart-call",await e.evaluate(async()=>{let l=globalThis,m=l.__threeBlocksSmoke?.restartWorker;if(typeof m!="function")throw new Error("Generated restartWorker() is unavailable.");await Reflect.apply(m,l.__threeBlocksSmoke,["browser smoke worker restart"]);}),o="restart-readiness",await e.waitForFunction(l=>{let f=globalThis.__threeBlocksSmoke,h=f?.readiness;return typeof f?.diagnostics?.workerId=="string"&&f.diagnostics.workerId!==l.workerId&&Number(f.worker?.generation)>l.generation&&f.restart?.stateReplayed===!0&&h?.workerReady===!0&&h.assetsReady===!0&&h.compileEnd===!0&&h.firstFrame===!0&&(!l.textEnabled||h.textReady===!0)},{workerId:a.workerId,generation:a.generation,textEnabled:r},{timeout:Math.min(t,45e3)}),o="stats-snapshot",await e.waitForFunction(l=>Number(globalThis.__threeBlocksSmoke?.stats?.snapshots)>l,a.snapshots,{timeout:Math.min(t,3e4)}),o="stats-texture",await e.waitForFunction(l=>Number(globalThis.__threeBlocksSmoke?.stats?.textures)>l,a.textures,{timeout:Math.min(t,3e4)});let c=await e.evaluate(l=>{let m=globalThis,f=m.__threeBlocksSmoke,h=m.__threeBlocksWorkerRestartProbe,y=f?.readiness;if(!f||!h||!y)throw new Error("Generated restart evidence disappeared.");return {requested:!0,appIdentityStable:h.app===m.document.querySelector("#app"),contentIdentityStable:h.content===(m.document.querySelector("main")??m.document.querySelector("#app")),canvasReplaced:f.restart.canvasReplaced&&h.canvas!==m.document.querySelector("#scene"),workerIdentityChanged:typeof f.diagnostics?.workerId=="string"&&f.diagnostics.workerId!==l.workerId,generationAdvanced:f.worker.generation===l.generation+1,restartCountAdvanced:f.restart.count===l.restartCount+1,stateReplayed:f.restart.stateReplayed&&f.restart.lastReason==="browser smoke worker restart",readinessRestored:y.workerReady===!0&&y.assetsReady===!0&&y.compileEnd===!0&&y.firstFrame===!0&&(!l.textEnabled||y.textReady===!0),shaderModeStable:f.diagnostics?.shaderMode===l.expectedShaderMode,statsSnapshotsAdvanced:f.stats.snapshots>l.snapshots,statsTextureTransferred:f.stats.textures>l.textures,statsTextureStopped:!1,error:null}},{...a,textEnabled:r,expectedShaderMode:n});o="stats-disable",await e.evaluate(async()=>{let m=globalThis.__threeBlocksSmoke?.stats;if(!m||typeof m.setPanelVisible!="function")throw new Error("Generated stats visibility control disappeared before disable.");if(await Reflect.apply(m.setPanelVisible,m,[!1])!==!0)throw new Error("Generated stats panel could not be disabled.")}),await e.waitForFunction(()=>globalThis.__threeBlocksSmoke?.stats?.panelVisible===!1,void 0,{timeout:Math.min(t,3e4)}),await e.waitForTimeout(750);let u=await e.evaluate(()=>Number(globalThis.__threeBlocksSmoke?.stats?.textures)||0);await e.waitForTimeout(1100);let p=await e.evaluate(()=>Number(globalThis.__threeBlocksSmoke?.stats?.textures)||0);if(p!==u)throw new Error(`Stats textures advanced after disable (${u} -> ${p}).`);return {...c,statsTextureStopped:!0}}catch(s){return {...ut,requested:true,error:`${o}: ${s instanceof Error?s.message:String(s)}`}}}a(ki,"exerciseWorkerRestart");function Je(e){return [...new Set(e)].sort((t,r)=>t.localeCompare(r))}a(Je,"sortedUnique");function xi(e,t,r){let n=Je(e),o=Je(t),s=r?Je([...n,...o].filter(a=>/MSDF atlases are missing code points:/iu.test(a))):[],i=new Set(s);return {console:n.filter(a=>!i.has(a)),page:o.filter(a=>!i.has(a)),resolved:s}}a(xi,"classifyRecoveredTextErrors");function Ri(e){return e.replace(/\u001b\[[0-?]*[ -/]*[@-~]/gu,"")}a(Ri,"stripTerminalControl");function vi(e,t,r){let n=e.config.base.startsWith("/")?e.config.base:"/";return new URL(r.replace(/^\/+/,""),`${t}${n.endsWith("/")?n:`${n}/`}`).href}a(vi,"projectUrl");async function Ei(e){let{chromium:t,vite:{createLogger:r,createServer:n}}=await Ln();if(e.forceWebgl===true&&e.unsupportedWorker===true)throw new Error("Browser smoke forceWebgl and unsupportedWorker modes are mutually exclusive.");if(e.unsupportedWorker===true&&e.expectTextGenerationFailure===true)throw new Error("Browser smoke unsupportedWorker and expectTextGenerationFailure modes are mutually exclusive.");let o=await realpath(e.root),s=Nn(e.route),i=Pe(e.timeoutMs,"Browser smoke timeoutMs",1e3,15*6e4,In),a$1=Pe(e.settleMs,"Browser smoke settleMs",0,1e4,1e3),c$1={width:Pe(e.viewport?.width,"Browser smoke viewport width",64,8192,1024),height:Pe(e.viewport?.height,"Browser smoke viewport height",64,8192,640)},u=jn(e.minimumLuminance,"Browser smoke minimumLuminance",0,255,2),p,l,m,f,h=false,y=ue(void 0,false),g=[],R=null,k=br,w={requested:e.hmrModule!==void 0,module:e.hmrModule??null,dispatched:false,acknowledged:false,lifecycleStable:e.hmrModule===void 0,sourceUnchanged:e.hmrModule===void 0,evidenceSource:"public-runtime-browser-probe",evidence:br,restart:ut,error:e.hmrModule===void 0?null:"HMR was not reached."},I=false,S=false,F={fatalVisible:false,code:null,detail:null},_={states:[],fallbackObserved:false,recovered:false,visibleElements:0,totalElements:0},b={snapshots:0,textures:0,shaderMode:null,mainPanels:false},L=[],B=0,P=0,C={console:[],page:[]},T,$=process.env.PATH;process.env.PATH=[U.join(o,"node_modules",".bin"),$].filter(Boolean).join(U.delimiter);try{let z=r("silent");z.warn=Ae=>{L.push(Ri(Ae));},p=await n({root:o,logLevel:"silent",customLogger:z,plugins:[ii()],optimizeDeps:{force:!0,include:[...mi]},server:{host:"127.0.0.1",port:0,strictPort:!1}}),await p.listen();let J=p.httpServer?.address();if(!J||typeof J=="string")throw new Error("Vite did not expose an ephemeral TCP address.");let Y=`http://127.0.0.1:${J.port}`;l=await t.launch({headless:d(e.headed===!0),args:[...c()]}),m=await l.newContext({viewport:c$1}),await m.addInitScript({content:`
|
|
245
|
+
(() => {
|
|
246
|
+
const key = '__three-blocks-text-fallback-states-v1';
|
|
247
|
+
let states = [];
|
|
248
|
+
try { states = JSON.parse( sessionStorage.getItem( key ) || '[]' ); } catch {}
|
|
249
|
+
const probe = globalThis.__threeBlocksTextFallbackProbe = { states };
|
|
250
|
+
const record = value => {
|
|
251
|
+
if ( typeof value !== 'string' || value.length === 0 || probe.states.at( -1 ) === value || probe.states.length >= 32 ) return;
|
|
252
|
+
probe.states.push( value );
|
|
253
|
+
try { sessionStorage.setItem( key, JSON.stringify( probe.states ) ); } catch {}
|
|
254
|
+
};
|
|
255
|
+
const inspect = node => {
|
|
256
|
+
if ( node && node.nodeType === 1 ) record( node.getAttribute( 'data-three-blocks-text-state' ) );
|
|
257
|
+
};
|
|
258
|
+
new MutationObserver( records => {
|
|
259
|
+
for ( const mutation of records ) {
|
|
260
|
+
inspect( mutation.target );
|
|
261
|
+
for ( const node of mutation.addedNodes || [] ) {
|
|
262
|
+
inspect( node );
|
|
263
|
+
if ( node.querySelectorAll ) for ( const child of node.querySelectorAll( '[data-three-blocks-text-state]' ) ) inspect( child );
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
} ).observe( document, { subtree: true, childList: true, attributes: true, attributeFilter: [ 'data-three-blocks-text-state' ] } );
|
|
267
|
+
})();
|
|
268
|
+
`}),e.forceWebgl===!0&&await m.addInitScript(()=>{Object.defineProperty(Navigator.prototype,"gpu",{configurable:!0,value:void 0});}),e.unsupportedWorker===!0&&await m.addInitScript(()=>{Object.defineProperty(globalThis,"Worker",{configurable:!0,value:void 0});}),f=await m.newPage();let oe=f;if(T=Dn(f),f.on("console",Ae=>{/WebGPU is not available, running under WebGL2 backend/iu.test(Ae.text())&&(S=!0);}),await f.goto(vi(p,Y,s),{waitUntil:"domcontentloaded",timeout:i}),e.unsupportedWorker===!0)I=await Fn(async()=>{await wr(oe,a(async()=>{await oe.waitForFunction(()=>globalThis.document.querySelector("#three-blocks-dev-overlay")?.shadowRoot?.querySelector(".dot")?.dataset.tone==="error",void 0,{timeout:Math.min(i,15e3)});},"waitForFailure"),i);},()=>oe.evaluate(()=>"gpu"in navigator&&navigator.gpu!==void 0)),F=await di(f),y=ue(await Ne(f),!1);else {let Ae=a(()=>e.expectTextGenerationFailure===!0?On(oe,i):It(oe,!1,i),"initialReadiness");I=await Fn(()=>wr(oe,Ae,i),()=>oe.evaluate(()=>"gpu"in navigator&&navigator.gpu!==void 0));let te=await gi(f,Ae,i);if(h=te.textEnabled,g=te.codecs,R=te.receipt,k=te.hmrEvidence,e.expectTextGenerationFailure===!0){if(!te.textEnabled)throw new Error("Expected text-generation failure mode requires a text-enabled project.");await On(f,i);let ke=performance.now()+Math.min(i,3e4);for(;!L.some(ro=>/automatic atlas generation failed/iu.test(ro));){if(performance.now()>=ke)throw new Error("Timed out waiting for the automatic text-generation failure warning.");await f.waitForTimeout(50);}y=ue(await Ne(f),!0);}else if(await It(f,te.textEnabled,i),y=ue(await Ne(f),te.textEnabled),te.textEnabled&&y.textReady&&(g=g.map(ke=>ke.name==="ktx2"?{...ke,decoded:!0,evidence:"text-atlas-decoded",blocker:null}:ke)),w=await Si(p,f,o,e.hmrModule,i,te.textEnabled,k),e.hmrModule!==void 0){let ke=await ki(f,i,te.textEnabled,te.receipt.shaders.mode);w={...w,restart:ke},y=ue(await Ne(f),te.textEnabled);}}a$1>0&&await f.waitForTimeout(a$1),_=await Mn(f),b=await Ft(f);let to=await f.screenshot({type:"png"});B=Ot(to),P=await Sr(f);}catch(z){if(f!==void 0)try{y=ue(await Ne(f),h),_=await Mn(f),b=await Ft(f);let J=await f.screenshot({type:"png"});B=Ot(J),P=await Sr(f);}catch(J){C.page.push(`Failure diagnostics could not be captured: ${J instanceof Error?J.message:String(J)}`);}C.page.push(z instanceof Error?z.message:String(z));}finally{T!==void 0&&(C.console.push(...T.console),C.page.push(...T.page)),await m?.close().catch(Y=>{C.page.push(`Browser context cleanup failed: ${Y instanceof Error?Y.message:String(Y)}`);}),await l?.close().catch(Y=>{C.page.push(`Browser cleanup failed: ${Y instanceof Error?Y.message:String(Y)}`);});let z=p?.httpServer,J=z?Reflect.get(z,"closeAllConnections"):void 0;z&&typeof J=="function"&&Reflect.apply(J,z,[]),await p?.close().catch(Y=>{C.page.push(`Vite cleanup failed: ${Y instanceof Error?Y.message:String(Y)}`);}),$===void 0?delete process.env.PATH:process.env.PATH=$;}let ee=Number(B.toFixed(2)),W=Number(P.toFixed(2)),de=B<=u&&P<=u,re=xi(C.console,C.page,_.recovered),ge=re.console,mt=re.page,Ze=re.resolved,G=y.worker&&y.workerReady&&y.assetsReady&&y.compileEnd&&y.textReady&&y.firstFrame,we=g.length===3&&g.every(z=>z.state!=="error"),me=Object.values(w.evidence).every(Boolean),He=!w.restart.requested||w.restart.error===null&&[w.restart.appIdentityStable,w.restart.contentIdentityStable,w.restart.canvasReplaced,w.restart.workerIdentityChanged,w.restart.generationAdvanced,w.restart.restartCountAdvanced,w.restart.stateReplayed,w.restart.readinessRestored,w.restart.shaderModeStable,w.restart.statsSnapshotsAdvanced,w.restart.statsTextureTransferred,w.restart.statsTextureStopped].every(Boolean),_e=!w.requested||w.dispatched&&w.acknowledged&&w.lifecycleStable&&w.sourceUnchanged&&me&&He&&w.error===null,ce=L.filter(z=>/automatic atlas generation failed/iu.test(z)),K=ce.reduce((z,J)=>z+(J.match(/three-blocks text generate/gu)?.length??0),0),be=e.expectTextGenerationFailure===true&&h&&_.fallbackObserved&&!_.recovered&&_.totalElements>0&&_.visibleElements===_.totalElements&&ce.length===1&&K===1,Se=e.unsupportedWorker===true&&F.fatalVisible&&F.code==="render-worker-unavailable"&&!y.workerReady&&!y.compileEnd&&!y.firstFrame,ne=e.unsupportedWorker===true?"unsupported-worker":e.forceWebgl===true?"WebGL-fallback":"WebGPU-first",jt=e.unsupportedWorker===true?"none":G?e.forceWebgl===true||!I?"WebGL":"WebGPU":"unknown",Nt=y.workerReady&&y.compileEnd&&y.firstFrame,j={schemaVersion:1,command:"browser smoke",passed:e.unsupportedWorker===true?Se:e.expectTextGenerationFailure===true?be:G&&we&&_e&&!de&&ge.length===0&&mt.length===0,scene:s,lifecycle:y,renderer:{requested:ne,active:jt,navigatorGpu:I,workerOwned:Nt,fallbackDiagnostic:S},compatibility:{...F,silentMainThreadRenderer:e.unsupportedWorker===true&&(y.compileEnd||y.firstFrame)},receipt:R,textFallback:_,warnings:Je(L),rendering:{luminance:ee,panelLuminance:W,threshold:u,blackFrame:de},codecs:g,hmr:w,errors:{console:ge,page:mt,resolved:Ze}};if(j.passed&&e.unsupportedWorker!==true&&e.expectTextGenerationFailure!==true){if(j.receipt===null||j.lifecycle.backend==="unknown"||j.renderer.active!=="WebGPU"&&j.renderer.active!=="WebGL")throw new Error("A successful browser smoke cannot write runtime status without an observed backend and renderer/build receipt.");let z=j.hmr.requested,J=z?_e:null,Y={schemaVersion:1,observedAt:new Date().toISOString(),worker:{backend:j.lifecycle.backend,renderer:j.renderer.active,protocolVersion:1},assets:{codecs:j.codecs.map(oe=>({name:oe.name,available:oe.state==="ready",decoded:oe.decoded})),resources:0},hmr:{capabilities:{scene:true,component:true,assetManifest:true,workerRestart:true},outcome:{attempted:z,succeeded:J,rollbackPreserved:z?j.hmr.evidence.rollbackPreserved:null,workerRestarted:j.hmr.restart.requested&&j.hmr.restart.workerIdentityChanged}},stats:{snapshots:b.snapshots,textures:b.textures,workerProfiler:b.snapshots>0,mainPanels:b.mainPanels},lifecycle:{state:"first frame",workerReady:j.lifecycle.workerReady,assetsReady:j.lifecycle.assetsReady,compiled:j.lifecycle.compileEnd,firstFrame:j.lifecycle.firstFrame},shaders:{mode:b.shaderMode??j.receipt.shaders.mode,pipelines:j.receipt.shaders.pipelines},...j.receipt.text===void 0?{}:{text:{state:j.receipt.text.state,atlases:j.receipt.text.atlases,glyphs:j.receipt.text.glyphs,requiredGlyphs:j.receipt.text.glyphs}},error:null};await ci(o,Y);}return j}a(Ei,"runBrowserSmoke");function Ti(e){let t=e.lifecycle,r=[`${e.passed?"\u2713":"\u2717"} Browser ${e.scene} \xB7 worker ${t.worker&&t.workerReady?"ready":"failed"} \xB7 assets ${t.assetsReady?"ready":"failed"} \xB7 compile ${t.compileEnd?"ready":"failed"}`,` Renderer ${e.renderer.active} \xB7 ${e.renderer.workerOwned?"worker-owned":e.renderer.requested}`,` Frame ${e.rendering.luminance.toFixed(2)} \xB7 panel ${e.rendering.panelLuminance.toFixed(2)}${e.rendering.blackFrame?" \xB7 black":""}`,` Codecs ${e.codecs.map(n=>`${n.name} ${n.state}${n.decoded?" decoded":""}`).join(" \xB7 ")||"not observed"}`];e.compatibility.fatalVisible&&r.push(` Compatibility ${e.compatibility.detail??"fatal compatibility screen visible"}`),e.textFallback.states.length>0&&r.push(` Text ${e.textFallback.states.join(" \u2192 ")}`),e.hmr.requested&&r.push(` HMR ${e.hmr.acknowledged&&e.hmr.sourceUnchanged&&Object.values(e.hmr.evidence).every(Boolean)?"ready":"failed"} \xB7 ${e.hmr.module??"unknown module"}`),e.hmr.restart.requested&&r.push(` Restart ${e.hmr.restart.error===null&&e.hmr.restart.workerIdentityChanged&&e.hmr.restart.stateReplayed?"ready":"failed"} \xB7 worker/state/stats`);for(let n of e.warnings)r.push(` Warning ${n}`);for(let n of e.errors.console)r.push(` Console ${n}`);for(let n of e.errors.page)r.push(` Page ${n}`);for(let n of e.errors.resolved)r.push(` Recovered ${n}`);e.hmr.error&&r.push(` HMR error ${e.hmr.error}`),e.hmr.restart.error&&r.push(` Restart error ${e.hmr.restart.error}`);for(let n of e.codecs)n.error&&r.push(` ${n.name} error ${n.error}`);return r.join(`
|
|
269
|
+
`)}a(Ti,"formatBrowserSmokeReport");async function Bi(e){let{chromium:t,vite:{build:r,preview:n}}=await Ln(),o=await realpath(e.root),s=(e.routes===void 0||e.routes.length===0?["/"]:e.routes).map(Nn),i=Pe(e.timeoutMs,"Browser preview timeoutMs",1e3,15*6e4,In),a=Pe(e.settleMs,"Browser preview settleMs",0,1e4,500),c$1={width:Pe(e.viewport?.width,"Browser preview viewport width",64,8192,1024),height:Pe(e.viewport?.height,"Browser preview viewport height",64,8192,640)},u=jn(e.minimumLuminance,"Browser preview minimumLuminance",0,255,2),p=e.expectShaders??"precompiled",l=e.text===true,m=[],f,h,y=process.env.PATH;process.env.PATH=[U.join(o,"node_modules",".bin"),y].filter(Boolean).join(U.delimiter);try{await r({root:o,logLevel:"warn",...e.buildMode===void 0?{}:{mode:e.buildMode}}),f=await n({root:o,logLevel:"warn",preview:{host:"127.0.0.1",port:0,strictPort:!1,open:!1}});let g=f.httpServer?.address();if(!g||typeof g=="string")throw new Error("Vite preview did not expose an ephemeral TCP address.");let R=f.config.base.startsWith("/")?f.config.base:"/",k=`http://127.0.0.1:${g.port}${R.endsWith("/")?R:`${R}/`}`;h=await t.launch({headless:d(e.headed===!0),args:[...c()]});for(let w of s){let I=await h.newContext({viewport:c$1}),S=await I.newPage(),F=Dn(S),_=[],b=ue(void 0,l),L=null,B=0,P=0;try{await S.goto(new URL(w.replace(/^\/+/,""),k).href,{waitUntil:"domcontentloaded",timeout:i}),await It(S,l,i),a>0&&await S.waitForTimeout(a),b=ue(await Ne(S),l),L=(await Ft(S)).shaderMode;let W=await S.screenshot({type:"png"});B=Ot(W),P=await Sr(S);}catch(W){try{b=ue(await Ne(S),l),L=(await Ft(S)).shaderMode;}catch{}_.push(W instanceof Error?W.message:String(W));}finally{await I.close().catch(W=>{_.push(`Browser context cleanup failed: ${W instanceof Error?W.message:String(W)}`);});}let C=Je(F.console),T=Je([...F.page,..._]),$=b.worker&&b.workerReady&&b.assetsReady&&b.compileEnd&&b.textReady&&b.firstFrame,ee=B<=u&&P<=u;m.push({route:w,passed:$&&!ee&&L===p&&C.length===0&&T.length===0,lifecycle:b,shaderMode:L,rendering:{luminance:Number(B.toFixed(2)),panelLuminance:Number(P.toFixed(2)),threshold:u,blackFrame:ee},errors:{console:C,page:T}});}}finally{await h?.close().catch(()=>{});let g=f?.httpServer,R=g?Reflect.get(g,"closeAllConnections"):void 0;g&&typeof R=="function"&&Reflect.apply(R,g,[]),await f?.close().catch(()=>{}),y===void 0?delete process.env.PATH:process.env.PATH=y;}return {schemaVersion:1,command:"browser preview",passed:m.length>0&&m.every(g=>g.passed),buildMode:e.buildMode??null,expectShaders:p,routes:m}}a(Bi,"runBrowserPreview");function Pi(e){let t=[`${e.passed?"\u2713":"\u2717"} Preview production build${e.buildMode===null?"":` \xB7 --mode ${e.buildMode}`} \xB7 expects shaders ${e.expectShaders}`];for(let r of e.routes){let n=r.lifecycle;t.push(` ${r.passed?"\u2713":"\u2717"} ${r.route} \xB7 worker ${n.worker&&n.workerReady?"ready":"failed"} \xB7 compile ${n.compileEnd?"ready":"failed"} \xB7 shaders ${r.shaderMode??"unobserved"} \xB7 frame ${r.rendering.luminance.toFixed(2)}${r.rendering.blackFrame?" \xB7 black":""}`);for(let o of r.errors.console)t.push(` Console ${o}`);for(let o of r.errors.page)t.push(` Page ${o}`);}return t.join(`
|
|
270
|
+
`)}a(Pi,"formatBrowserPreviewReport");var Yn="/__three-blocks/devtools/environment-bake",Fi="/__three-blocks/devtools/environment-bake/upload",Er="virtual:three-blocks-devtools/environment-bake.ts",Un=`\0${Er}`,Ii=`/@id/__x00__${Er}`,Li="src/assets/environment/room-environment.pmrem.ktx2",Rr=128*1024*1024,ji=1;async function Ni(){try{let[e,t]=await Promise.all([import('playwright'),import('vite')]);return {chromium:e.chromium,createServer:t.createServer}}catch(e){throw new Error('Environment baking requires the optional "playwright" and "vite" packages. Install both in the project and run `npx playwright install chromium`.',{cause:e})}}a(Ni,"loadEnvironmentBakeBrowserTools");function Zn(e,t,r,n,o){let s=e??o;if(!Number.isSafeInteger(s)||s<r||s>n)throw new Error(`${t} must be an integer in ${r}...${n}.`);return s}a(Zn,"boundedInteger");function Tr(e){let t=Zn(e,"Environment cube size",16,1024,256);if((t&t-1)!==0)throw new Error("Environment cube size must be a power of two.");return t}a(Tr,"validateEnvironmentCubeSize");function Di(){return at__default}a(Di,"zstdFunctions");function Hi(e){if(!/^[0-9A-Za-z][0-9A-Za-z.+_-]{0,63}$/u.test(e))throw new Error("Browser reported an invalid Three.js revision.");return e}a(Hi,"boundedThreeRevision");function Vi(e){if(e.vkFormat!==VK_FORMAT_R16G16B16A16_SFLOAT)throw new Error("RoomEnvironment bake must be RGBA16F KTX2.");if(e.typeSize!==2)throw new Error("RoomEnvironment RGBA16F KTX2 must use a two-byte component type.");if(e.supercompressionScheme!==KHR_SUPERCOMPRESSION_NONE)throw new Error("Browser RoomEnvironment KTX2 must be uncompressed before deterministic encoding.");if(!Number.isSafeInteger(e.pixelWidth)||e.pixelWidth<=0||e.pixelWidth>8192||!Number.isSafeInteger(e.pixelHeight)||e.pixelHeight<=0||e.pixelHeight>8192||e.pixelDepth!==0||e.layerCount!==0||e.faceCount!==1||e.levels.length!==1||e.levels[0]===void 0)throw new Error("RoomEnvironment KTX2 has invalid CubeUV dimensions or topology.");let t=e.pixelWidth*e.pixelHeight*8;if(!Number.isSafeInteger(t)||t>Rr)throw new Error("RoomEnvironment KTX2 decoded payload exceeds the safety limit.");let r=e.levels[0],n=t+e.pixelHeight*256;if(r.levelData.byteLength<t||r.levelData.byteLength>n||r.levelData.byteLength%8!==0||r.uncompressedByteLength!==r.levelData.byteLength)throw new Error(`RoomEnvironment KTX2 level byte count ${r.levelData.byteLength} is outside the bounded RGBA16F CubeUV layout.`);return e.levels.map(o=>new Uint8Array(o.levelData))}a(Vi,"validateRawContainer");function Ui(e,t){return e.byteLength===t.byteLength&&Buffer.from(e).equals(Buffer.from(t))}a(Ui,"sameBytes");function Qn(e,t){let r=Tr(t.cubeSize),n=Hi(t.threeRevision);if(e.byteLength===0||e.byteLength>d$1.texture)throw new Error("RoomEnvironment KTX2 input exceeds the bounded texture size.");let o=read(e),s=Vi(o),i=t.compression??"zstd",a=Di(),c=at__default.constants.ZSTD_c_compressionLevel;if(i==="zstd"&&(a.zstdCompressSync===void 0||a.zstdDecompressSync===void 0||c===void 0))throw new Error("This Node.js runtime does not provide deterministic Zstandard support; use --no-zstd explicitly to opt out.");if(o.supercompressionScheme=i==="zstd"?KHR_SUPERCOMPRESSION_ZSTD:KHR_SUPERCOMPRESSION_NONE,o.levelCount=s.length,o.levels=s.map(m=>{let f=i==="zstd"?a.zstdCompressSync?.(m,{params:{[c]:19}}):void 0;return {levelData:f===void 0?m:new Uint8Array(f.buffer,f.byteOffset,f.byteLength),uncompressedByteLength:m.byteLength}}),i==="zstd")for(let m of o.dataFormatDescriptor)m.bytesPlane=[0,0,0,0,0,0,0,0];o.keyValue={KTXorientation:"rd",KTXwriter:`three-blocks RoomEnvironment \xB7 three r${n}`};let u=write(o,{keepWriter:true});if(u.byteLength===0||u.byteLength>d$1.texture)throw new Error("Encoded RoomEnvironment KTX2 exceeds the bounded texture size.");let p=read(u);if(p.vkFormat!==VK_FORMAT_R16G16B16A16_SFLOAT||p.pixelWidth!==o.pixelWidth||p.pixelHeight!==o.pixelHeight||p.supercompressionScheme!==o.supercompressionScheme||p.keyValue.KTXorientation!=="rd"||p.levels.length!==s.length)throw new Error("RoomEnvironment KTX2 header failed round-trip validation.");for(let m=0;m<p.levels.length;m+=1){let f=p.levels[m],h=s[m];if(f===void 0||h===void 0)throw new Error(`RoomEnvironment KTX2 level ${m} is missing after round-trip.`);let y=i==="zstd"?a.zstdDecompressSync?.(f.levelData):f.levelData;if(y===void 0||f.uncompressedByteLength!==h.byteLength||!Ui(y,h))throw new Error(`RoomEnvironment KTX2 level ${m} failed byte-for-byte round-trip validation.`)}let l=s.reduce((m,f)=>m+f.byteLength,0);return {bytes:u,metadata:{compression:i,cubeSize:r,format:"RGBA16F CubeUVReflectionMapping",height:p.pixelHeight,rawBytes:l,sha256:f(u),three:n,version:ji,width:p.pixelWidth}}}a(Qn,"encodeRoomEnvironmentKtx2");var vr=class{static{a(this,"BakeInbox");}promise;#n=a(()=>{},"#resolve");#e=a(()=>{},"#reject");#t=false;constructor(){this.promise=new Promise((t,r)=>{this.#n=t,this.#e=r;});}receive(t){return this.#t?false:(this.#t=true,this.#n(t),true)}reject(t){this.#t||(this.#t=true,this.#e(t));}};function Wi(e){if(e.url!==void 0)try{return new URL(e.url,"http://three-blocks.invalid").pathname}catch{return}}a(Wi,"requestPath");function De(e,t,r=""){e.statusCode=t,e.setHeader("Content-Type",r.startsWith("<!")?"text/html; charset=utf-8":"text/plain; charset=utf-8"),e.setHeader("Cache-Control","no-store"),e.end(r);}a(De,"respond");function Gi(e,t){return {name:"three-blocks:environment-bake",enforce:"post",resolveId(r){return r===Er?Un:void 0},load(r){return r===Un?t:void 0},configureServer(r){r.middlewares.use((n,o,s)=>{let i=Wi(n);if(i===Yn&&(n.method==="GET"||n.method==="HEAD")){let m=n.method==="HEAD"?"":`<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Three Blocks environment bake</title></head><body><canvas id="three-blocks-environment-baker" width="1" height="1"></canvas><script type="module" src="${Ii}"></script></body></html>`;De(o,200,m);return}if(i!==Fi)return s();if(n.method!=="POST"){De(o,405,"POST required");return}let a=n.headers["content-type"];if(typeof a!="string"||!a.toLowerCase().startsWith("image/ktx2")){De(o,415,"image/ktx2 required");return}let c=Number(n.headers["content-length"]??0);if(Number.isFinite(c)&&c>Rr){De(o,413,"Bake payload exceeds 128 MiB");return}let u=[],p=0,l=false;n.on("data",m=>{p+=m.byteLength,p>Rr?l=true:u.push(m);}),n.on("error",m=>e.reject(m)),n.on("end",()=>{if(l){De(o,413,"Bake payload exceeds 128 MiB"),e.reject(new Error("RoomEnvironment bake upload exceeded 128 MiB."));return}let m=n.headers["x-three-revision"];if(typeof m!="string"){De(o,400,"x-three-revision required"),e.reject(new Error("RoomEnvironment upload omitted the Three.js revision."));return}let f=e.receive({bytes:new Uint8Array(Buffer.concat(u)),threeRevision:m});De(o,f?204:409,f?"":"Bake upload already received");});});}}}a(Gi,"bakePlugin");async function zi(){let e=U.dirname(fileURLToPath(import.meta.url)),t=[U.join(e,"browser","environment-bake.js"),U.join(e,"browser","environment-bake.ts")];for(let r of t)if(await g(r))return (await j(r,d$1.semanticInput,"Environment bake browser entry")).data.toString("utf8");throw new Error("The separately built environment bake browser entry is missing.")}a(zi,"browserEntrySource");function Ki(e){return new Promise((t,r)=>{e.on("pageerror",n=>{b$1(n.message)||r(n);}),e.on("console",n=>{n.type()==="error"&&!b$1(n.text())&&r(new Error(n.text()));});})}a(Ki,"pageFailure");async function qi(e,t){await e.waitForFunction(()=>globalThis.__THREE_BLOCKS_ROOM_ENVIRONMENT_BAKE__!==void 0,void 0,{timeout:Math.min(t,3e4)});let r=await e.evaluate(()=>globalThis.__THREE_BLOCKS_ROOM_ENVIRONMENT_BAKE__);if(!r||typeof r!="object"||Reflect.get(r,"ok")!==true){let n=r&&typeof r=="object"?Reflect.get(r,"error"):void 0;throw new Error(typeof n=="string"?n:"Browser RoomEnvironment bake did not report success.")}}a(qi,"readBrowserBakeResult");var eo=a(async e=>{let{chromium:t,createServer:r}=await Ni(),n=new vr,o,s,i,a,c$1=false;try{let u=await zi();o=await r({root:e.root,configFile:!1,logLevel:"silent",optimizeDeps:{noDiscovery:!0},plugins:[Gi(n,u)],server:{host:"127.0.0.1",port:0,strictPort:!1}}),await o.listen();let p=o.httpServer?.address();if(!p||typeof p=="string")throw new Error("Environment bake Vite server has no ephemeral TCP address.");s=await t.launch({headless:d(e.headed),args:[...c()]}),i=await s.newContext({viewport:{width:320,height:240}});let l=await i.newPage(),m=Ki(l),f=new Promise((y,g)=>{a=setTimeout(()=>g(new Error(`RoomEnvironment bake timed out after ${e.timeoutMs}ms.`)),e.timeoutMs),a.unref();});await l.goto(`http://127.0.0.1:${p.port}${Yn}?size=${e.size}`,{waitUntil:"domcontentloaded",timeout:Math.min(e.timeoutMs,3e4)});let h=await Promise.race([n.promise,m,f]);return await qi(l,e.timeoutMs),h}catch(u){throw c$1=true,n.reject(u instanceof Error?u:new Error(String(u))),await n.promise.catch(()=>{}),u}finally{a&&clearTimeout(a);let u=[];if(await i?.close().catch(p=>u.push(`context: ${p instanceof Error?p.message:String(p)}`)),await s?.close().catch(p=>u.push(`browser: ${p instanceof Error?p.message:String(p)}`)),await o?.close().catch(p=>u.push(`Vite: ${p instanceof Error?p.message:String(p)}`)),!c$1&&u.length>0)throw new Error(`RoomEnvironment cleanup failed (${u.join("; ")}).`)}},"captureRoomEnvironment");function Xi(e,t){let r=t??Li;if(U.isAbsolute(r)||r.length===0||r.length>2048||/[\u0000-\u001f\u007f]/u.test(r)||!r.endsWith(".ktx2"))throw new Error("Environment output must be a bounded project-relative .ktx2 path.");let n=U.resolve(e,r);if(!h(e,n)||n===e)throw new Error("Environment output escapes the project root.");return {asset:n,metadata:`${n.slice(0,-5)}.json`}}a(Xi,"outputPaths");async function Ji(e,t){let r=U.relative(e,t);if(r==="")return;let n=e;for(let s of r.split(U.sep)){n=U.join(n,s),await g(n)||await mkdir(n);let i=await lstat(n);if(i.isSymbolicLink()||!i.isDirectory())throw new Error(`Environment output parent is not a real directory: ${n}.`)}let o=await realpath(t);if(!h(e,o))throw new Error("Environment output parent resolves outside the project root.")}a(Ji,"ensureSafeParent");async function Wn(e){if(!await g(e))return;let t=await lstat(e);if(t.isSymbolicLink()||!t.isFile())throw new Error(`Environment output target must be a regular file: ${e}.`)}a(Wn,"validateOutputTarget");async function Yi(e,t,r,n){await Promise.all([Wn(e),Wn(r)]);let o=`${process.pid}-${randomUUID()}`,s=U.join(U.dirname(e),`.${U.basename(e)}.${o}.tmp`),i=U.join(U.dirname(r),`.${U.basename(r)}.${o}.tmp`),a=`${s}.backup`,c=`${i}.backup`,u=false,p=false,l=false,m=false;try{await Promise.all([writeFile(s,t,{flag:"wx"}),writeFile(i,n,{encoding:"utf8",flag:"wx"})]),await g(e)&&(await rename(e,a),u=!0),await g(r)&&(await rename(r,c),p=!0),await rename(s,e),l=!0,await rename(i,r),m=!0,await Promise.all([rm(a,{force:!0}),rm(c,{force:!0})]);}catch(f){throw m&&await rm(r,{force:true}),l&&await rm(e,{force:true}),p&&await rename(c,r),u&&await rename(a,e),f}finally{await Promise.all([rm(s,{force:true}),rm(i,{force:true}),rm(a,{force:true}),rm(c,{force:true})]);}}a(Yi,"writeAtomicPair");function Gn(e,t){return U.relative(e,t).split(U.sep).join("/")}a(Gn,"portableRelative");async function Zi(e){let t=await realpath(e.root),r=Tr(e.size??256),n=Zn(e.timeoutMs,"Environment bake timeoutMs",1e3,15*6e4,24e4),o=Xi(t,e.output);await Ji(t,U.dirname(o.asset));let i=await(e.capture??eo)({root:t,size:r,timeoutMs:n,headed:e.headed===true}),a=Qn(i.bytes,{cubeSize:r,threeRevision:i.threeRevision,compression:e.compression??"zstd"}),c=`${JSON.stringify(a.metadata,null,2)}
|
|
271
|
+
`;await Yi(o.asset,a.bytes,o.metadata,c);let u=await readFile(o.asset);if(f(u)!==a.metadata.sha256)throw new Error("Committed RoomEnvironment checksum does not match metadata.");return {schemaVersion:1,command:"environment bake",output:Gn(t,o.asset),metadataOutput:Gn(t,o.metadata),bytes:a.bytes.byteLength,metadata:a.metadata}}a(Zi,"bakeRoomEnvironment");function Qi(e){if(e<1e3)return `${e} B`;let t=e/1e3;return `${t>=100?Math.round(t):t.toFixed(1)} kB`}a(Qi,"formatBytes");function ed(e){return [`\u2713 Environment ${e.metadata.width}\xD7${e.metadata.height} \xB7 CubeUV ${e.metadata.cubeSize}px \xB7 RGBA16F ${e.metadata.compression}`,` Output ${e.output} \xB7 ${Qi(e.bytes)}`,` Checksum ${e.metadata.sha256}`].join(`
|
|
272
|
+
`)}a(ed,"formatEnvironmentBakeReport");var Lt=class{static{a(this,"ShaderWatchQueue");}#n;#e;#t;#r;#o;#s=false;#a=false;constructor(t){if(this.#n=t.capture,this.#e=t.debounceMs??200,this.#t=t.onError??(()=>{}),!Number.isSafeInteger(this.#e)||this.#e<0||this.#e>6e4)throw new Error("Shader watch debounce must be an integer in 0...60000ms.")}notify(){this.#a||(this.#s=true,!this.#o&&(this.#r&&clearTimeout(this.#r),this.#r=setTimeout(()=>{this.#r=void 0,this.#i();},this.#e)));}#i(){this.#a||this.#o||!this.#s||(this.#s=false,this.#o=this.#n().catch(t=>{this.#t(t instanceof Error?t:new Error(String(t)));}).finally(()=>{this.#o=void 0,this.#s&&!this.#a&&this.notify();}));}async close(){this.#a=true,this.#s=false,this.#r&&clearTimeout(this.#r),this.#r=void 0,await this.#o;}};function nd(e){let t=e.split(U.sep).join("/");return t===""||t.startsWith("node_modules/")||t.startsWith(".git/")||t.startsWith("dist/")||t===".three-blocks"||t.startsWith(".three-blocks/")}a(nd,"ignored");async function od(e={}){let t=e.root??await r(e.start),r$1,n=new Promise(c=>{r$1=c;}),o=new Lt({...e.debounceMs!==void 0?{debounceMs:e.debounceMs}:{},...e.onError?{onError:e.onError}:{},capture:a(async()=>{let c=await pr({root:t,...e.config?{config:e.config}:{},...e.driver?{driver:e.driver}:{},...e.driverKind?{driverKind:e.driverKind}:{},...e.serve?{serve:e.serve}:{},...e.url?{url:e.url}:{},...e.headed!==void 0?{headed:e.headed}:{},...e.attempts!==void 0?{attempts:e.attempts}:{}});e.onResult?.(c);},"capture")}),s,i=false,a$1=a(async()=>{i||(i=true,s?.close(),await o.close(),r$1?.());},"close");return s=watch(t,{recursive:true},(c,u)=>{nd(u??"")||o.notify();}),s.on("error",c=>e.onError?.(c)),e.signal&&(e.signal.aborted?await a$1():e.signal.addEventListener("abort",()=>{a$1();},{once:true})),e.initial!==false&&o.notify(),{root:t,done:n,close:a$1}}a(od,"watchShaders");export{lt as RUNTIME_STATUS_RECEIPT_MAX_BYTES,Ct as RUNTIME_STATUS_RECEIPT_PATH,At as RUNTIME_STATUS_RECOVERY,Lt as ShaderWatchQueue,it as TEXT_ATLAS_GENERATOR_VERSION,rr as TEXT_ATLAS_SCHEMA_VERSION,Zi as bakeRoomEnvironment,Kt as buildGlyphSet,nr as builtinFontMetadata,eo as captureRoomEnvironment,pr as captureShaders,Pt as discoverTextContent,Qn as encodeRoomEnvironmentKtx2,Gt as extractCanvasTextFromHtml,zt as extractDefinedTextContent,yr as findProjectRoot,Pi as formatBrowserPreviewReport,Ti as formatBrowserSmokeReport,ed as formatEnvironmentBakeReport,_n as formatShaderMatrixStatus,An as formatStatus,Za as formatThreeBlocksStatus,Ns as generateTextAtlases,$n as inspectProject,Fe as inspectShaderMatrix,_t as inspectTextAtlases,za as inspectThreeBlocksStatus,ue as parseBrowserSmokeLifecycle,Pn as parseRuntimeStatusReceipt,nn as parseTextAtlasReceipt,Ir as parseTextConfiguration,As as prewarmBuiltinFont,ye as readInstalledShaderRuntime,Bt as readTextConfiguration,Bi as runBrowserPreview,Ei as runBrowserSmoke,Ot as screenshotLuminance,Te as snapshotShaderInputs,ya as testShaders,Ka as threeBlocksStatusIsFresh,Tr as validateEnvironmentCubeSize,od as watchShaders};
|