@three-blocks/devtools 5.0.0 → 6.0.0-alpha.333.gf29db3a0524e
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 +17 -0
- package/dist/browser/shader-capture.js +1 -1
- package/dist/{browser-smoke-WWMWRM6S.js → browser-smoke-NTM7XYO6.js} +1 -1
- package/dist/{chunk-6RGA2IVT.js → chunk-IM4TPX74.js} +1 -1
- package/dist/chunk-X5OFYHIY.js +3 -0
- package/dist/cli.js +6 -6
- package/dist/index.d.ts +11 -0
- package/dist/index.js +27 -27
- package/dist/{status-EK3BIJ2K.js → status-6GFLRFEZ.js} +1 -1
- package/dist/{text-atlas-WRYJT3E7.js → text-atlas-UORTLOQJ.js} +1 -1
- package/package.json +9 -4
- package/dist/chunk-JHBQB7WC.js +0 -3
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {a as a$1}from'./chunk-65VEJRRT.js';import {j as j$1,a as a$2,c,h,b,f}from'./chunk-5L2VS3BN.js';import {a}from'./chunk-HOZDD6PW.js';import {createHash,randomUUID}from'crypto';import {rm,mkdir,writeFile,rename}from'fs/promises';import {platform,homedir}from'os';import y from'path';import {fileURLToPath}from'url';import*as G 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}from'ktx-parse';import It from'msdf-bmfont-xml';import se from'opentype.js';import {PNG}from'pngjs';import {createRequire}from'module';var Je=createRequire(import.meta.url),he,g=new Proxy({},{get(e,t){return he??=Je("typescript"),Reflect.get(he,t)}}),qe=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),Xe=new Set(["script","style","template"]),ge=2e5,Ze={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 Ye(e){return e.replace(/&(#x[0-9a-f]+|#[0-9]+|[a-z][a-z0-9]+);/giu,(t,n)=>{if(n.startsWith("#x")||n.startsWith("#X")){let r=Number.parseInt(n.slice(2),16);return H(r)?String.fromCodePoint(r):t}if(n.startsWith("#")){let r=Number.parseInt(n.slice(1),10);return H(r)?String.fromCodePoint(r):t}return Ze[n.toLowerCase()]??t})}a(Ye,"decodeHtmlEntities");function H(e){return Number.isSafeInteger(e)&&e>=0&&e<=1114111&&!(e>=55296&&e<=57343)}a(H,"validCodePoint");function we(e){return H(e)&&e>=32&&!(e>=127&&e<=159)}a(we,"renderableCodePoint");function Qe(e){return /(?:^|\s)data-canvas-text(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+))?(?=\s|\/?>)/iu.test(e)}a(Qe,"hasCanvasTextAttribute");function xe(e){let t=[],n=[],r=e.match(/<!--[\s\S]*?-->|<![^>]*>|<[^>]*>|[^<]+/gu)??[];for(let o of r){if(!o.startsWith("<")){if(n.some(s=>s.synchronized)&&!n.some(s=>s.skipped)){let s=Ye(o);s.trim().length>0&&t.push(s);}continue}if(o.startsWith("<!--")||o.startsWith("<!")||o.startsWith("<?"))continue;let i=/^<\s*\//u.test(o),a=/^<\s*\/?\s*([a-z][a-z0-9:-]*)/iu.exec(o)?.[1]?.toLowerCase();if(!a)continue;if(i){let s=n.map(u=>u.tag).lastIndexOf(a);s>=0&&n.splice(s);continue}/\/\s*>$/u.test(o)||qe.has(a)||n.push({tag:a,synchronized:Qe(o),skipped:Xe.has(a)});}return t}a(xe,"extractCanvasTextFromHtml");function et(e){let t=new Set,n=new Set;for(let r of e.statements){if(!g.isImportDeclaration(r)||!g.isStringLiteral(r.moduleSpecifier)||r.moduleSpecifier.text!=="three-blocks/text")continue;let o=r.importClause?.namedBindings;if(o&&g.isNamespaceImport(o)&&n.add(o.name.text),o&&g.isNamedImports(o))for(let i of o.elements)(i.propertyName?.text??i.name.text)==="defineTextContent"&&t.add(i.name.text);}return {named:t,namespaces:n}}a(et,"importedTextHelpers");function tt(e,t){return g.isIdentifier(e)?t.named.has(e.text):g.isPropertyAccessExpression(e)&&g.isIdentifier(e.expression)&&t.namespaces.has(e.expression.text)&&e.name.text==="defineTextContent"}a(tt,"isDefineTextContentCall");function nt(e){let t=e;for(;g.isParenthesizedExpression(t)||g.isAsExpression(t)||g.isSatisfiesExpression(t)||g.isTypeAssertionExpression(t);)t=t.expression;return t}a(nt,"unwrapExpression");function Q(e,t,n){let r=nt(e);if(g.isStringLiteral(r)||g.isNoSubstitutionTemplateLiteral(r)){t.push(r.text);return}if(g.isArrayLiteralExpression(r)){for(let a of r.elements){if(g.isSpreadElement(a))throw new Error(`${n}: defineTextContent() cannot use spread elements.`);Q(a,t,n);}return}if(g.isObjectLiteralExpression(r)){for(let a of r.properties){if(!g.isPropertyAssignment(a))throw new Error(`${n}: defineTextContent() accepts only static property assignments.`);Q(a.initializer,t,n);}return}let o=r.getStart(),i=r.getSourceFile().getLineAndCharacterOfPosition(o).line+1;throw new Error(`${n}:${i}: defineTextContent() contains dynamic text; declare a Unicode range or an explicit static string.`)}a(Q,"collectStaticStrings");function be(e,t="content.ts"){let n=g.createSourceFile(t,e,g.ScriptTarget.Latest,true,t.endsWith(".tsx")?g.ScriptKind.TSX:g.ScriptKind.TS),r=et(n),o=[];function i(a){if(g.isCallExpression(a)&&tt(a.expression,r)){if(a.arguments.length!==1||!a.arguments[0])throw new Error(`${t}: defineTextContent() requires exactly one static argument.`);Q(a.arguments[0],o,t);return}g.forEachChild(a,i);}return a(i,"visit"),i(n),o}a(be,"extractDefinedTextContent");function rt(e){let t=[];if(e==="latin"){for(let n=32;n<=126;n++)t.push(n);for(let n 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 r=n.codePointAt(0);r!==void 0&&t.push(r);}}else {for(let n=12353;n<=12438;n++)t.push(n);for(let n=12443;n<=12447;n++)t.push(n);for(let n=12448;n<=12543;n++)t.push(n);for(let n 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 r=n.codePointAt(0);r!==void 0&&t.push(r);}}return t}a(rt,"presetCodePoints");function ye(e,t){for(let n of t.normalize("NFC")){let r=n.codePointAt(0);r!==void 0&&we(r)&&e.add(r);}}a(ye,"addCharacters");function Te(e,t={}){let n=new Set;for(let c of e)ye(n,c);t.additionalCharacters&&ye(n,t.additionalCharacters);for(let c of t.presets??[])for(let s of rt(c))n.add(s);let r=0;for(let c of t.ranges??[]){if(!H(c.start)||!H(c.end)||c.end<c.start)throw new RangeError("Text Unicode ranges must contain ordered Unicode scalar values.");if(r+=c.end-c.start+1,r>ge)throw new RangeError(`Configured Unicode ranges exceed the ${ge}-code-point safety limit.`);for(let s=c.start;s<=c.end;s++)we(s)&&n.add(s);}n.add(32),n.add(63),n.add(65533);let o=[...n].sort((c,s)=>c-s),i=o.map(c=>String.fromCodePoint(c)).join(""),a=createHash("sha256").update(i.normalize("NFC")).digest("hex");return {codePoints:o,characters:i,hash:a}}a(Te,"buildGlyphSet");var it=createRequire(import.meta.url),Ee,p=new Proxy({},{get(e,t){return Ee??=it("typescript"),Reflect.get(Ee,t)}});function st(e){let t=e;for(;p.isParenthesizedExpression(t)||p.isAsExpression(t)||p.isSatisfiesExpression(t)||p.isTypeAssertionExpression(t);)t=t.expression;return t}a(st,"unwrap");function at(e,t){if(p.isIdentifier(e)||p.isStringLiteral(e)||p.isNumericLiteral(e))return e.text;throw new Error(`${t}: text configuration property names must be static.`)}a(at,"propertyName");function V(e,t){let n=st(e);if(p.isStringLiteral(n)||p.isNoSubstitutionTemplateLiteral(n))return n.text;if(p.isNumericLiteral(n))return Number(n.text);if(n.kind===p.SyntaxKind.TrueKeyword)return true;if(n.kind===p.SyntaxKind.FalseKeyword)return false;if(n.kind===p.SyntaxKind.NullKeyword)return null;if(p.isPrefixUnaryExpression(n)&&(n.operator===p.SyntaxKind.MinusToken||n.operator===p.SyntaxKind.PlusToken)){let o=V(n.operand,t);if(typeof o=="number")return n.operator===p.SyntaxKind.MinusToken?-o:o}if(p.isArrayLiteralExpression(n))return n.elements.map(o=>{if(p.isSpreadElement(o))throw new Error(`${t}: text configuration cannot use spread elements.`);return V(o,t)});if(p.isObjectLiteralExpression(n)){let o=Object.create(null);for(let i of n.properties){if(!p.isPropertyAssignment(i))throw new Error(`${t}: text configuration accepts only static property assignments.`);let a=at(i.name,t);if(Object.hasOwn(o,a))throw new Error(`${t}: duplicate text configuration property "${a}".`);o[a]=V(i.initializer,t);}return o}let r=n.getSourceFile().getLineAndCharacterOfPosition(n.getStart()).line+1;throw new Error(`${t}:${r}: text configuration must be statically inspectable.`)}a(V,"evaluateStatic");function ct(e){let t=new Set,n=new Set;for(let r of e.statements){if(!p.isImportDeclaration(r)||!p.isStringLiteral(r.moduleSpecifier)||r.moduleSpecifier.text!=="three-blocks/text")continue;let o=r.importClause?.namedBindings;if(o&&p.isNamespaceImport(o)&&n.add(o.name.text),o&&p.isNamedImports(o))for(let i of o.elements)(i.propertyName?.text??i.name.text)==="defineText"&&t.add(i.name.text);}return {named:t,namespaces:n}}a(ct,"helperNames");function dt(e,t){return p.isIdentifier(e)?t.named.has(e.text):p.isPropertyAccessExpression(e)&&p.isIdentifier(e.expression)&&t.namespaces.has(e.expression.text)&&e.name.text==="defineText"}a(dt,"isDefineTextCall");function $(e,t){if(typeof e!="string"||e.trim().length===0)throw new Error(`${t} must be a non-empty string.`);return e}a($,"requiredString");function J(e,t,n=false){if(!Array.isArray(e)||!n&&e.length===0)throw new Error(`${t} must be ${n?"an":"a non-empty"} array of strings.`);return e.map((r,o)=>$(r,`${t}[${o}]`))}a(J,"stringArray");function q(e,t){if(e.includes("\\")||y.posix.isAbsolute(e)||y.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(q,"safeProjectPath");function lt(e,t){if(!a$1(e))throw new Error(`${t} must be an object.`);let n=Object.keys(e).sort();if(n.length===1&&n[0]==="builtin")return {builtin:$(e.builtin,`${t}.builtin`)};if(n.length===1&&n[0]==="path")return {path:q($(e.path,`${t}.path`),`${t}.path`)};if(n.join(",")==="checksum,file,package")return {package:$(e.package,`${t}.package`),file:q($(e.file,`${t}.file`),`${t}.file`),checksum:$(e.checksum,`${t}.checksum`)};throw new Error(`${t} must select exactly one supported source.`)}a(lt,"parseFontSource");function M(e,t){let n=$(e,t);if(n.includes("\\")||/[\u0000-\u001f\u007f]/u.test(n)||n.split("/").includes(".."))throw new Error(`${t} is unsafe.`);return n}a(M,"deployedPath");function ut(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:J(e.presets,"Text generation presets",true).map(s=>{if(s!=="latin"&&s!=="japanese-kana")throw new Error(`Unsupported text preset "${s}".`);return s}),n;if(e.ranges!==void 0){if(!Array.isArray(e.ranges))throw new Error("Text generation ranges must be an array.");n=e.ranges.map((s,u)=>{if(!a$1(s)||typeof s.start!="number"||typeof s.end!="number")throw new Error(`Text generation range ${u} is invalid.`);return {start:s.start,end:s.end}});}let r=a(s=>{let u=e[s];if(u!==void 0){if(typeof u!="number"||!Number.isFinite(u))throw new Error(`Text generation ${s} must be finite.`);return u}},"numeric"),o=r("size"),i=r("distanceRange"),a$2=r("padding"),c=r("maxTextureSize");return {...t===void 0?{}:{presets:t},...n===void 0?{}:{ranges:n},...e.additionalCharacters===void 0?{}:{additionalCharacters:$(e.additionalCharacters,"Text generation additionalCharacters")},...o===void 0?{}:{size:o},...i===void 0?{}:{distanceRange:i},...a$2===void 0?{}:{padding:a$2},...c===void 0?{}:{maxTextureSize:c}}}a(ut,"parseGeneration");function ft(e){if(!a$1(e)||e.schemaVersion!==void 0&&e.schemaVersion!==1)throw new Error("Text configuration must use schemaVersion 1.");let t=J(e.content,"Text content inputs").map(o=>q(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 n={},r=0;for(let[o,i]of Object.entries(e.fonts)){if($(o,"Text font key"),!a$1(i))throw new Error(`Text font "${o}" must be an object.`);let a=i.default===true;a&&r++;let c={};if(i.weights!==void 0){if(!a$1(i.weights))throw new Error(`Text font "${o}" weights must be an object.`);for(let[s,u]of Object.entries(i.weights)){let l=Number(s);if(!Number.isInteger(l)||l<1||l>1e3)throw new Error(`Text font "${o}" weight "${s}" must be an integer CSS weight between 1 and 1000.`);if(!a$1(u))throw new Error(`Text font "${o}" weight ${s} must be an object.`);c[String(l)]={atlas:M(u.atlas,`Text font "${o}" weight ${s} atlas path`),metrics:M(u.metrics,`Text font "${o}" weight ${s} metrics path`)};}}n[o]={source:lt(i.source,`Text font "${o}" source`),browser:M(i.browser,`Text font "${o}" browser path`),atlas:M(i.atlas,`Text font "${o}" atlas path`),metrics:M(i.metrics,`Text font "${o}" metrics path`),weights:c,families:J(i.families,`Text font "${o}" families`),languages:i.languages===void 0?[]:J(i.languages,`Text font "${o}" languages`,true),default:a};}if(Object.keys(n).length>1&&r!==1)throw new Error("Multiple text fonts require exactly one default route.");if(r>1)throw new Error("Text fonts can select only one default route.");return {schemaVersion:1,content:t,fonts:n,generation:ut(e.generation)}}a(ft,"validateConfiguration");function pt(e,t="three-blocks.text.ts"){let n=p.createSourceFile(t,e,p.ScriptTarget.Latest,true,p.ScriptKind.TS),r=ct(n),o=[];function i(a){if(p.isCallExpression(a)&&dt(a.expression,r)){if(a.arguments.length!==1||!a.arguments[0])throw new Error(`${t}: defineText() requires one static argument.`);o.push(V(a.arguments[0],t));return}p.forEachChild(a,i);}if(a(i,"visit"),i(n),o.length!==1)throw new Error(`${t} must contain exactly one imported defineText() call.`);return ft(o[0])}a(pt,"parseTextConfiguration");function ee(e,t){if(typeof e=="string")t.push(e);else if(Array.isArray(e))for(let n of e)ee(n,t);else if(a$1(e))for(let n of Object.values(e))ee(n,t);}a(ee,"jsonStrings");async function te(e,t="three-blocks.text.ts"){let n=q(t,"Text configuration path"),r=await j$1(e,y.join(e,n),a$2.semanticInput,"Text configuration");return pt(r.data.toString("utf8"),n)}a(te,"readTextConfiguration");async function ne(e,t){let n=[],r={},o=0;for(let i of t.content){let a=await j$1(e,y.join(e,i),a$2.semanticInput,"Text content input");if(o+=a.data.byteLength,o>a$2.semanticTotal)throw new Error("Text content inputs exceed the total inspection size limit.");r[i]=c(a.data);let c$1=a.data.toString("utf8"),s=y.extname(i).toLowerCase();if(s===".html"||s===".htm")n.push(...xe(c$1));else if([".ts",".tsx",".js",".jsx",".mts",".cts",".mjs",".cjs"].includes(s))n.push(...be(c$1,i));else if(s===".json")ee(JSON.parse(c$1),n);else if(s===".txt"||s===".md")n.push(c$1);else throw new Error(`Unsupported configured text content type: ${i}.`)}return {values:n,glyphs:Te(n,t.generation),inputs:r}}a(ne,"discoverTextContent");var Ie=1,Z="1.0.0",_t=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/1.6.0/fonts/Geist/webfonts/Geist%5Bwght%5D.woff2",browserBytes:69356,browserChecksum:"fd0de7b7c4329443c2fa2fadae90d57af9fa7857a814568f5a529537541a5538"},"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"}}),Ht="THREE_BLOCKS_FONT_CACHE_DIR",Mt=6e4,X=new Map,Dt=fileURLToPath(new URL("../fonts/",import.meta.url));function A(e,t){if(typeof e!="number"||!Number.isFinite(e))throw new Error(`${t} must be finite.`);return e}a(A,"finiteNumber");function P(e,t){let n=A(e,t);if(!Number.isSafeInteger(n))throw new Error(`${t} must be an integer.`);return n}a(P,"integer");function zt(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,i)=>{if(!a$1(o))throw new Error(`BMFont character ${i} is invalid.`);return {id:P(o.id,`BMFont character ${i}.id`),x:A(o.x,`BMFont character ${i}.x`),y:A(o.y,`BMFont character ${i}.y`),width:A(o.width,`BMFont character ${i}.width`),height:A(o.height,`BMFont character ${i}.height`),xoffset:A(o.xoffset,`BMFont character ${i}.xoffset`),yoffset:A(o.yoffset,`BMFont character ${i}.yoffset`),xadvance:A(o.xadvance,`BMFont character ${i}.xadvance`)}}),n=e.kernings===void 0?[]:e.kernings;if(!Array.isArray(n))throw new Error("BMFont kernings are invalid.");let r=n.map((o,i)=>{if(!a$1(o))throw new Error(`BMFont kerning ${i} is invalid.`);return {first:P(o.first,`BMFont kerning ${i}.first`),second:P(o.second,`BMFont kerning ${i}.second`),amount:A(o.amount,`BMFont kerning ${i}.amount`)}});return {info:{size:A(e.info.size,"BMFont info.size"),face:typeof e.info.face=="string"?e.info.face:"Font"},common:{base:A(e.common.base,"BMFont common.base"),scaleW:P(e.common.scaleW,"BMFont common.scaleW"),scaleH:P(e.common.scaleH,"BMFont common.scaleH")},chars:t,kernings:r}}a(zt,"parseBMFont");function Ne(e){let t=e.generation.size??48,n=e.generation.distanceRange??8,r=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(n)||n<1||n>64)throw new Error("Text generation distanceRange must be an integer from 1 to 64.");if(!Number.isInteger(r)||r<0||r>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:n,padding:r,maxTextureSize:o}}a(Ne,"atlasOptions");function _e(e){let t=_t[e];if(t===void 0)throw new Error(`Unknown built-in font ${JSON.stringify(e)}.`);return t}a(_e,"builtinFontMetadata");function He(e){let t=e.cacheDirectory??process.env[Ht];return t?y.resolve(t):platform()==="darwin"?y.join(homedir(),"Library","Caches","three-blocks","fonts"):platform()==="win32"?y.join(process.env.LOCALAPPDATA?.trim()||y.join(homedir(),"AppData","Local"),"Three Blocks","Cache","fonts"):y.join(process.env.XDG_CACHE_HOME?.trim()||y.join(homedir(),".cache"),"three-blocks","fonts")}a(He,"fontCacheRoot");function Fe(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(Fe,"builtinAsset");function Me(e,t){let n=_e(e),r=t.mapBuiltinFont?.(n)??n;if(r.id!==n.id||r.version!==n.version||r.sourceBytes!==n.sourceBytes||r.sourceChecksum!==n.sourceChecksum||r.browserBytes!==n.browserBytes||r.browserChecksum!==n.browserChecksum)throw new Error(`Runtime metadata for built-in font ${JSON.stringify(e)} changed its pinned identity.`);return r}a(Me,"runtimeBuiltinFontMetadata");function Ut(e,t){return y.join(He(t),e.font.id,e.font.version,e.checksum,y.basename(e.file))}a(Ut,"builtinCachePath");async function jt(e,t){try{let n=await h(e,a$2.texture,`${t.font.id} cached ${t.kind} font`);if(n.data.byteLength===t.bytes&&c(n.data)===t.checksum)return n.data;await rm(e,{force:!0});return}catch(n){if(b(n)==="ENOENT")return;throw n}}a(jt,"readCachedFont");async function Gt(e){try{let t=await h(y.join(Dt,e.file),e.bytes,`${e.font.id} packaged ${e.kind} font`);return t.data.byteLength===e.bytes&&c(t.data)===e.checksum?t.data:void 0}catch(t){if(b(t)==="ENOENT")return;throw t}}a(Gt,"readPackagedFont");async function Kt(e,t){try{let n=await j$1(e.root,e.filePath,t.bytes,`${t.font.id} existing browser font output`);return n.data.byteLength!==t.bytes||c(n.data)!==t.checksum?void 0:n.data}catch{return}}a(Kt,"readBuiltinBrowserSeed");function vt(e,t,n){let r=Math.max(0,e.byteLength-65557),o=-1;for(let u=e.byteLength-22;u>=r;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 i=e.readUInt16LE(o+10),a=e.readUInt32LE(o+12),c=e.readUInt32LE(o+16);if(c+a>o)throw new Error("downloaded ZIP central directory is out of bounds");let s=c;for(let u=0;u<i;u++){if(s+46>e.byteLength||e.readUInt32LE(s)!==33639248)throw new Error("downloaded ZIP central directory is invalid");let l=e.readUInt16LE(s+10),f=e.readUInt32LE(s+20),h=e.readUInt32LE(s+24),T=e.readUInt16LE(s+28),w=e.readUInt16LE(s+30),C=e.readUInt16LE(s+32),S=e.readUInt32LE(s+42),F=s+46+T+w+C;if(F>e.byteLength)throw new Error("downloaded ZIP entry metadata is out of bounds");let k=e.subarray(s+46,s+46+T).toString("utf8");if(s=F,k!==t)continue;if(h!==n)throw new Error(`ZIP entry has ${h} bytes; expected ${n}`);if(S+30>e.byteLength||e.readUInt32LE(S)!==67324752)throw new Error("downloaded ZIP local entry is invalid");let R=e.readUInt16LE(S+26),O=e.readUInt16LE(S+28),L=S+30+R+O;if(L+f>e.byteLength)throw new Error("downloaded ZIP entry data is out of bounds");let x=e.subarray(L,L+f);if(l===0)return Buffer.from(x);if(l===8)return G.inflateRawSync(x,{maxOutputLength:n});throw new Error(`ZIP entry uses unsupported compression method ${l}`)}throw new Error(`downloaded ZIP does not contain ${JSON.stringify(t)}`)}a(vt,"zipEntry");async function Wt(e,t){let n=new URL(e.url);if(n.protocol!=="https:")throw new Error(`Built-in font source must use HTTPS: ${e.url}.`);let r;try{r=await t(n,{signal:AbortSignal.timeout(Mt)});}catch(w){throw new Error(`request failed: ${w instanceof Error?w.message:String(w)}`,{cause:w})}if(!r.ok)throw new Error(`server returned HTTP ${r.status} ${r.statusText}`.trim());let o=e.archive?.bytes??e.bytes,i=e.archive?.checksum??e.checksum,a=r.headers.get("content-length");if(a!==null){let w=Number(a);if(!Number.isSafeInteger(w)||w!==o)throw new Error(`server declared ${a} bytes; expected ${o}`)}if(r.body===null)throw new Error("server returned an empty response body");let c$1=r.body.getReader(),s=[],u=0;for(;;){let w=await c$1.read();if(w.done)break;if(u+=w.value.byteLength,u>o||u>a$2.texture)throw await c$1.cancel(),new Error(`download exceeded the expected ${o}-byte size`);s.push(Buffer.from(w.value.buffer,w.value.byteOffset,w.value.byteLength));}let l=Buffer.concat(s,u);if(l.byteLength!==o)throw new Error(`downloaded ${l.byteLength} bytes; expected ${o}`);let f=c(l);if(f!==i)throw new Error(`checksum mismatch: expected ${i}, received ${f}`);let h=e.archive===void 0?l:vt(l,e.archive.entry,e.bytes);if(h.byteLength!==e.bytes)throw new Error(`resolved ${h.byteLength} bytes; expected ${e.bytes}`);let T=c(h);if(T!==e.checksum)throw new Error(`resolved checksum mismatch: expected ${e.checksum}, received ${T}`);return h}a(Wt,"downloadFont");async function oe(e,t){await mkdir(y.dirname(e),{recursive:true});let n=`${e}.${process.pid}.${randomUUID()}.tmp`;try{await writeFile(n,t,{flag:"wx"}),await rename(n,e);}finally{await rm(n,{force:true});}}a(oe,"writeCachedFont");async function Re(e,t,n){let r=Ut(e,t),o=X.get(r);if(o)return o;let i=(async()=>{let a=await jt(r,e);if(a)return a;if(t.fetch===void 0&&t.mapBuiltinFont===void 0){let c=await Gt(e);if(c!==void 0)return await oe(r,c),c}if(n!==void 0){let c=await Kt(n,e);if(c!==void 0)return await oe(r,c),c}try{let c=await Wt(e,t.fetch??globalThis.fetch);return await oe(r,c),c}catch(c){throw new Error(`Could not download the built-in ${e.font.id} ${e.kind} font from ${e.url}: ${c instanceof Error?c.message:String(c)}. Connect once to prewarm the checksum-keyed cache at ${JSON.stringify(He(t))}, or configure source.path/source.package for fully offline text generation.`,{cause:c})}})();X.set(r,i);try{return await i}finally{X.get(r)===i&&X.delete(r);}}a(Re,"cachedBuiltinAsset");async function De(e,t,n){let[r,o]=await Promise.allSettled([Re(Fe(e,"source"),t),Re(Fe(e,"browser"),t,n)]);if(r.status==="rejected")throw r.reason;if(o.status==="rejected")throw o.reason;return [r.value,o.value]}a(De,"cachedBuiltinPair");async function Fn(e,t={}){let n=Me(e,t);await De(n,t);}a(Fn,"prewarmBuiltinFont");async function ze(e,t,n){let r=await h(e,a$2.texture,n),o=c(r.data);if(t!=="pending"&&o!==t)throw new Error(`${n} checksum mismatch: expected ${t}, received ${o}.`);return r.data}a(ze,"checkedExternalFile");function Ue(e,t){if(!/^(?:@[a-z0-9._-]+\/)?[a-z0-9._-]+$/iu.test(t))throw new Error("Text font package name is unsafe.");return y.join(e,"node_modules",...t.split("/"))}a(Ue,"packageRoot");async function Vt(e,t){if("builtin"in t){let o=_e(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 j$1(e,y.join(e,t.path),a$2.texture,"Text source font");return {sourceHash:c(o.data),browserHash:c(o.data),description:t.path}}let n=y.join(Ue(e,t.package),t.file),r=await ze(n,t.checksum,"Package text source font");return {sourceHash:c(r),browserHash:c(r),description:`${t.package}/${t.file}`}}a(Vt,"resolveFontIdentity");async function Jt(e,t,n,r){if("builtin"in t){let c=Me(t.builtin,n),[s,u]=await De(c,n,r===void 0?void 0:{root:e,filePath:r});return {source:s,sourceHash:c.sourceChecksum,browser:u,browserHash:c.browserChecksum,description:`builtin:${c.id}@${c.version}`,license:c.license}}if("path"in t){let c$1=await j$1(e,y.join(e,t.path),a$2.texture,"Text source font"),s=c(c$1.data);return {source:c$1.data,sourceHash:s,browser:c$1.data,browserHash:s,description:t.path}}let o=y.join(Ue(e,t.package),t.file),i=await ze(o,t.checksum,"Package text source font"),a=c(i);return {source:i,sourceHash:a,browser:i,browserHash:a,description:`${t.package}/${t.file}`}}a(Jt,"resolveFont");function N(e,t){let n=t.replace(/^\/+/,""),r=y.resolve(e,"public",n),o=y.resolve(e,"public"),i=y.relative(o,r);if(i===""||i===".."||i.startsWith(`..${y.sep}`)||y.isAbsolute(i))throw new Error(`Deployed text path ${JSON.stringify(t)} escapes public/.`);return r}a(N,"deployedFile");function ae(e,t){return y.relative(e,t).split(y.sep).join("/")}a(ae,"portablePath");function je(e){return e.endsWith(".json")?`${e.slice(0,-5)}.meta.json`:`${e}.meta.json`}a(je,"metadataPath");function ce(e){return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)}a(ce,"bufferArray");function qt(e,t){return t.filter(n=>n===65533||e.charToGlyphIndex(String.fromCodePoint(n))!==0)}a(qt,"supportedCodePoints");function Ae(e,t,n,r){return new Promise((o,i)=>{It(e,{filename:n,charset:t.map(a=>String.fromCodePoint(a)),outputType:"json",fieldType:"msdf",fontSize:r.size,distanceRange:r.distanceRange,texturePadding:r.padding,textureSize:[r.maxTextureSize,r.maxTextureSize],smartSize:true,pot:true},(a,c,s)=>{if(a)return i(a);if(c.length!==1||c[0]===void 0)return i(new Error(`Text glyphs require ${c.length} atlas pages; raise maxTextureSize or lower size.`));try{o({png:c[0].texture,data:zt(JSON.parse(s.data))});}catch(u){i(u);}});})}a(Ae,"generateBMFontData");function ke(e,t,n,r){let o=1/e.info.size,i=e.common.base,a$1=t.unitsPerEm,c=t.tables.hhea,s=a(l=>{let f=t.charToGlyph(String.fromCodePoint(l))?.advanceWidth;return typeof f=="number"&&Number.isFinite(f)?f/a$1:void 0},"exactAdvance"),u=a((l,f)=>{try{let h=t.getKerningValue(t.charToGlyph(String.fromCodePoint(l)),t.charToGlyph(String.fromCodePoint(f)));return Number.isFinite(h)&&h!==0?h/a$1:void 0}catch{return}},"exactKerning");return {name:t.names?.fontFamily?.en??e.info.face,atlas:{type:"msdf",distanceRange:n.distanceRange,size:e.info.size,width:e.common.scaleW,height:e.common.scaleH,yOrigin:"top",...r===void 0?{}:{wght:r}},metrics:{emSize:1,lineHeight:(c.ascender-c.descender+c.lineGap)/a$1,ascender:c.ascender/a$1,descender:c.descender/a$1,underlineY:(t.tables.post?.underlinePosition??-a$1*.1)/a$1,underlineThickness:(t.tables.post?.underlineThickness??a$1*.05)/a$1},glyphs:e.chars.slice().sort((l,f)=>l.id-f.id).map(l=>({unicode:l.id,advance:s(l.id)??l.xadvance*o,...l.width>0&&l.height>0?{planeBounds:{left:l.xoffset*o,bottom:(i-l.yoffset-l.height)*o,right:(l.xoffset+l.width)*o,top:(i-l.yoffset)*o},atlasBounds:{left:l.x,top:l.y,right:l.x+l.width,bottom:l.y+l.height}}:{}})),kerning:e.kernings.filter(l=>l.amount!==0).sort((l,f)=>l.first-f.first||l.second-f.second).map(l=>({unicode1:l.first,unicode2:l.second,advance:u(l.first,l.second)??l.amount*o}))}}a(ke,"convertMetrics");function Ge(){return G}a(Ge,"zstdFunctions");function Be(e){let t=PNG.sync.read(e),n=new Uint8Array(t.data.buffer,t.data.byteOffset,t.data.byteLength),o=Ge().zstdCompressSync,i=o===void 0?"none":"zstd",a$1=G.constants.ZSTD_c_compressionLevel,c=o?.(n,a$1===void 0?{}:{params:{[a$1]:19}}),s=createDefaultContainer();s.vkFormat=VK_FORMAT_R8G8B8A8_UNORM,s.typeSize=1,s.pixelWidth=t.width,s.pixelHeight=t.height,s.supercompressionScheme=i==="zstd"?KHR_SUPERCOMPRESSION_ZSTD:KHR_SUPERCOMPRESSION_NONE,s.levels=[{levelData:c===void 0?n:new Uint8Array(c.buffer,c.byteOffset,c.byteLength),uncompressedByteLength:n.byteLength}];let u=a((f,h)=>({bitOffset:f*8,bitLength:7,channelType:h,samplePosition:[0,0,0,0],sampleLower:0,sampleUpper:255}),"sample");s.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)]}],s.keyValue.KTXwriter=`three-blocks text ${Z}`,s.keyValue.KTXorientation="rd";let l=write(s,{keepWriter:true});return de(l,t.width,t.height),{bytes:l,width:t.width,height:t.height,compression:i}}a(Be,"createKtx2");function de(e,t,n){let r=read(e);if(r.vkFormat!==VK_FORMAT_R8G8B8A8_UNORM)throw new Error("Text atlas must use RGBA8 KTX2.");if(r.pixelWidth<=0||r.pixelHeight<=0||r.levels.length!==1||r.levels[0]===void 0)throw new Error("Text atlas KTX2 dimensions or levels are invalid.");if(t!==void 0&&r.pixelWidth!==t)throw new Error("Text atlas KTX2 width does not match metrics.");if(n!==void 0&&r.pixelHeight!==n)throw new Error("Text atlas KTX2 height does not match metrics.");if(r.keyValue.KTXorientation!=="rd")throw new Error("Text atlas KTX2 orientation must be rd.");let o=r.levels[0],i,a;if(r.supercompressionScheme===KHR_SUPERCOMPRESSION_ZSTD){let s=Ge().zstdDecompressSync;if(s===void 0)throw new Error("This Node.js runtime cannot validate Zstandard KTX2 text atlases.");i=s(o.levelData),a="zstd";}else if(r.supercompressionScheme===KHR_SUPERCOMPRESSION_NONE)i=o.levelData,a="none";else throw new Error("Text atlas uses an unsupported KTX2 supercompression scheme.");let c=r.pixelWidth*r.pixelHeight*4;if(i.byteLength!==c||o.uncompressedByteLength!==c)throw new Error("Text atlas KTX2 decoded byte length is invalid.");return {width:r.pixelWidth,height:r.pixelHeight,compression:a}}a(de,"validateKtx2Bytes");function ie(e){return `${JSON.stringify(e)}
|
|
3
|
+
`}a(ie,"stableJson");function z(e,t,n){return {path:ae(e,t),sha256:c(n),bytes:n.byteLength}}a(z,"fileReceipt");function le(e){return Object.keys(e.weights).map(Number).sort((t,n)=>t-n)}a(le,"routeWeights");function Ke(e,t,n,r,o){return c(JSON.stringify({generator:Z,fontKey:r,fontHash:e.sourceHash,glyphSetHash:t,options:n,...o.length>0?{weights:o}:{}}))}a(Ke,"createInputHash");async function Xt(e,t,n){let{default:r}=await import('subset-font'),o=t.map(i=>String.fromCodePoint(i)).join("");return r(e,o,{targetFormat:"sfnt",variationAxes:{wght:n}})}a(Xt,"instanceFontWeight");async function Zt(e,t,n,r,o,i,a){if(o.length===0)throw new Error(`Text font ${JSON.stringify(t)} covers no required glyphs.`);let c=se.parse(ce(r.source)),s=await Ae(r.source,o,t,a),u=ke(s.data,c,a),l=Buffer.from(ie(u)),f$1=Be(s.png);if(s.data.common.scaleW!==f$1.width||s.data.common.scaleH!==f$1.height)throw new Error(`Text font ${JSON.stringify(t)} metrics and texture dimensions differ.`);let h=le(n);if(h.length>0&&!c.tables.fvar?.axes?.some(x=>x.tag==="wght"))throw new Error(`Text font ${JSON.stringify(t)} declares weights but its source has no variable wght axis.`);let T=[],w={};for(let x of h){let I=n.weights[String(x)],ue=await Xt(r.source,o,x),ve=se.parse(ce(ue)),K=await Ae(ue,o,`${t}-w${x}`,a),fe=Buffer.from(ie(ke(K.data,ve,a,x))),v=Be(K.png);if(K.data.common.scaleW!==v.width||K.data.common.scaleH!==v.height)throw new Error(`Text font ${JSON.stringify(t)} weight ${x} metrics and texture dimensions differ.`);let pe=N(e,I.atlas),me=N(e,I.metrics);T.push({file:pe,data:v.bytes},{file:me,data:fe}),w[String(x)]={atlas:z(e,pe,v.bytes),metrics:z(e,me,fe)};}let C=N(e,n.browser),S=N(e,n.atlas),F=N(e,n.metrics),k=je(F),R={schemaVersion:Ie,generatorVersion:Z,font:{key:t,source:r.description,sourceHash:r.sourceHash,...r.license===void 0?{}:{license:r.license}},inputHash:Ke(r,i,a,t,h),glyphSetHash:i,codePoints:o,options:a,texture:{format:"RGBA8",orientation:"rd",compression:f$1.compression,width:f$1.width,height:f$1.height},files:{browser:z(e,C,r.browser),atlas:z(e,S,f$1.bytes),metrics:z(e,F,l),...h.length>0?{weights:w}:{}}},O=Buffer.from(ie(R));await f(C,r.browser),await f(S,f$1.bytes),await f(F,l);for(let{file:x,data:I}of T)await f(x,I);await f(k,O);let L=[C,S,F,...T.map(x=>x.file),k].map(x=>ae(e,x));return {font:t,receipt:R,metadataPath:ae(e,k),updatedFiles:L}}a(Zt,"generateRoute");async function Rn(e,t="three-blocks.text.ts",n={}){let r=await te(e,t),o=await ne(e,r),i=Ne(r),a=[];for(let[l,f]of Object.entries(r.fonts).sort((h,T)=>h[0].localeCompare(T[0]))){let h=await Jt(e,f.source,n,"builtin"in f.source?N(e,f.browser):void 0),T=se.parse(ce(h.source));a.push({key:l,route:f,resolved:h,font:T,codePoints:qt(T,o.glyphs.codePoints)});}let c=new Set(a.flatMap(l=>l.codePoints)),s=o.glyphs.codePoints.filter(l=>!c.has(l));if(s.length>0)throw new Error(`Configured fonts do not cover ${s.length} required glyph(s): ${s.map(l=>String.fromCodePoint(l)).join(" ")}`);let u=[];for(let l of a)u.push(await Zt(e,l.key,l.route,l.resolved,l.codePoints,o.glyphs.hash,i));return {glyphs:o.glyphs.codePoints.length,glyphSetHash:o.glyphs.hash,atlases:u,updatedFiles:u.flatMap(l=>l.updatedFiles)}}a(Rn,"generateTextAtlases");function U(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(U,"parseFileReceipt");function Yt(e){if(!a$1(e)||e.schemaVersion!==Ie||e.generatorVersion!==Z||!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.");if(U(e.files.browser,"Browser font"),U(e.files.atlas,"Text atlas"),U(e.files.metrics,"Text metrics"),e.files.weights!==void 0){if(!a$1(e.files.weights))throw new Error("Text atlas weight receipts are invalid.");for(let[t,n]of Object.entries(e.files.weights)){let r=Number(t);if(!Number.isInteger(r)||r<1||r>1e3||!a$1(n))throw new Error(`Text atlas weight receipt "${t}" is invalid.`);U(n.atlas,`Text atlas weight ${t}`),U(n.metrics,`Text metrics weight ${t}`);}}return e}a(Yt,"parseTextAtlasReceipt");function $e(e){if(!a$1(e)||!a$1(e.atlas)||!Array.isArray(e.glyphs))throw new Error("Text metrics are invalid.");let t=P(e.atlas.width,"Text metrics atlas.width"),n=P(e.atlas.height,"Text metrics atlas.height"),r=e.glyphs.map((o,i)=>{if(!a$1(o))throw new Error(`Text metrics glyph ${i} is invalid.`);return P(o.unicode,`Text metrics glyph ${i}.unicode`)});return {width:t,height:n,codePoints:r}}a($e,"metricsCoverage");async function j(e,t,n,r){let o=await j$1(e,y.join(e,t.path),n,r);if(o.data.byteLength!==t.bytes||c(o.data)!==t.sha256)throw new Error(`${r} checksum or byte length differs from generation metadata.`);return o.data}a(j,"verifyReceiptFile");async function An(e,t="three-blocks.text.ts"){let n;try{n=await te(e,t);}catch(r){return {state:"invalid",reason:`Text configuration is invalid: ${r instanceof Error?r.message:String(r)}`,missing:[],atlases:[]}}try{let r=await ne(e,n),o=Ne(n),i=[],a=new Set;for(let[s,u]of Object.entries(n.fonts).sort((l,f)=>l[0].localeCompare(f[0]))){let l=await j$1(e,je(N(e,u.metrics)),a$2.metadata,"Text atlas generation metadata"),f=Yt(JSON.parse(l.data.toString("utf8")));if(f.font.key!==s)throw new Error(`Text atlas metadata belongs to ${JSON.stringify(f.font.key)}, not ${JSON.stringify(s)}.`);let h=await Vt(e,u.source),T=Ke(h,f.glyphSetHash,o,s,le(u));if(f.inputHash!==T)return {state:"invalid",reason:`Text atlas ${s} font source, weights, or generation options changed.`,missing:[],atlases:[...i,f]};let[w,C,S]=await Promise.all([j(e,f.files.browser,a$2.texture,"Browser font"),j(e,f.files.atlas,a$2.texture,"Text atlas"),j(e,f.files.metrics,a$2.metrics,"Text metrics")]);if(c(w)!==h.browserHash)throw new Error(`Browser font ${s} differs from its resolved source.`);let F=$e(JSON.parse(S.toString("utf8"))),k=de(C,F.width,F.height);if(k.width!==f.texture.width||k.height!==f.texture.height||k.compression!==f.texture.compression)throw new Error(`Text atlas ${s} texture metadata does not match KTX2.`);for(let R of le(u)){let O=f.files.weights?.[String(R)];if(O===void 0)throw new Error(`Text atlas ${s} weight ${R} has no generation receipt.`);let[L,x]=await Promise.all([j(e,O.atlas,a$2.texture,`Text atlas weight ${R}`),j(e,O.metrics,a$2.metrics,`Text metrics weight ${R}`)]),I=$e(JSON.parse(x.toString("utf8")));de(L,I.width,I.height);}for(let R of F.codePoints)a.add(R);i.push(f);}let c$1=r.glyphs.codePoints.filter(s=>!a.has(s));return c$1.length>0?{state:"missing",reason:`${c$1.length} required glyph(s) are missing.`,missing:c$1,atlases:i}:{state:"ready",reason:`${r.glyphs.codePoints.length} required glyphs are covered by ${i.length} atlas(es).`,missing:[],atlases:i}}catch(r){return (typeof r=="object"&&r!==null&&"code"in r?r.code:void 0)==="ENOENT"?{state:"missing",reason:"Text atlas files or generation metadata are absent.",missing:[],atlases:[]}:{state:"invalid",reason:r instanceof Error?r.message:String(r),missing:[],atlases:[]}}}a(An,"inspectTextAtlases");export{Ie as a,Z as b,_e as c,Fn as d,Rn as e,Yt as f,An as g};
|
package/dist/cli.js
CHANGED
|
@@ -5,12 +5,12 @@ ${e}
|
|
|
5
5
|
`:t),n.includes("--yes"))return true;if(!s.stdin.isTTY||!s.stderr.isTTY)throw new Error("Adapter wiring needs consent. Review the diff above, then rerun with --yes; no files were changed.");let{createInterface:o}=await import('readline/promises'),r=o({input:s.stdin,output:s.stderr});try{let c=await r.question("Apply this patch? (y/N) ");return /^y(?:es)?$/iu.test(c.trim())}finally{r.close();}}a(he,"approveAdapterPatch");function C(e){return h?{update(){},stop(){}}:h$1(e)}a(C,"wait");function me(){let e$1=a(b$1=>b.accent(b$1),"c"),t=a(b$1=>b.dim(b$1),"d"),o=c.mark?`${c.mark} `:"",r=[["Inspect",[[`${e$1("status")}`,`project report: shaders, text, browser evidence ${t("\u2014 no browser, no GPU")}`],[`${e$1("shaders")}`,"verify shader freshness and exit 1 with the exact recovery command"],[`${e$1("shaders status")} ${t("[--check]")}`,`per-scene shader freshness ${t("(--check exits 1 when not fresh)")}`],[`${e$1("text status")}`,"text atlas coverage"],[`${e$1("assets status")}`,"optimized-asset receipt freshness"]]],["Produce",[[`${e$1("shaders capture")} ${t("[--if-stale] [--commit-timing] [--no-assets]")}`,"capture shaders plus a local timing estimate, then optimize public GLB/.hdr assets; during development use the overlay Capture button"],[`${e$1("shaders watch")} ${t("[--debounce <ms>]")}`,"recapture automatically while you work"],[`${e$1("text generate")} ${t("[--config <path>]")}`,"regenerate MSDF text atlases"],[`${e$1("environment bake")} ${t("[--size 256]")}`,"bake the PMREM room environment to KTX2"],[`${e$1("assets optimize")} ${t("<file|dir\u2026> [--out <dir>] [--quality high]")}`,"meshopt + slot-aware KTX2 for GLB / image / .hdr inputs"]]],["Verify",[[`${e$1("shaders test")}`,"median timing + zero-build + compute + pixel parity gate"],[`${e$1("shaders test --parity-only")}`,"one correctness pair per scene; no timing or published-page soak"],[`${e$1("browser smoke")} ${t("[--route /] [--hmr <module>]")}`,"boot the dev app, verify worker lifecycle + HMR"],[`${e$1("browser preview")} ${t("[--route /]...")}`,"build + serve production, verify precompiled hydration"]]]],c$1=["",`${o}${b.bold("three-blocks devtools")} ${b.dim(`v${a$1}`)}`,b.dim("WebGPU shader precompilation and verification for Three Blocks projects."),"",`${b.bold("Usage")}`,` ${e$1("three-blocks-devtools")} ${t("[command] [options] [--json]")}`];for(let[b$1,a]of r)c$1.push("",b.bold(b$1),...e(a,{indent:2,maxWidth:a$2.width-2}));c$1.push("",b.bold("Options"),...e([[t("--json"),"stable machine-readable report on stdout"],[t("--reporter <plain|json>"),"select the stable terminal or CI reporter"],[t("--root <path>"),"project root (defaults to the nearest three-blocks project)"],[t("--backend <webgpu|webgl|both>"),"select shader backend lanes (default: config, then both)"],[t("--headed"),"show the automation browser window"],[t("--runs <n>"),"shader timing captures after warmup (default 5)"],[t("--parity-only"),"skip timing warmup/repeats and the published-page soak"],[t("--commit-timing"),"also write shareable hardware-labelled build timing"],[t("--skip-browser"),"check shader schema and freshness without browser parity"],[t("--driver <vite|static>"),"capture through Vite or an already-built static app"],[t("--serve <path>"),"built application directory for --driver static"],[t("--url <url>"),"attach to an already-running transformed application"],[t("--yes"),"apply a previewed framework adapter patch non-interactively"],[t("--out <dir>"),"assets optimize: output directory (default: beside each input)"],[t("--max-dim <px>"),"assets optimize: LDR texture cap (default 2048)"],[t("--quality <default|high>"),"assets optimize: high = UASTC color + higher encoder effort"],[t("--preset <color|normal|data>"),"assets optimize: override the standalone-image preset"],[t("--force"),"assets optimize: re-encode even when cached"]],{indent:2,maxWidth:a$2.width-2}),"",b.dim("During development, use the in-page overlay Capture button for one-click recapture."),b.dim("`shaders capture` remains the explicit isolated-browser fallback for batch and CI."),""),f(c$1.join(`
|
|
6
6
|
`));}a(me,"help");function we(e){return e?`${e.render} render \xB7 ${e.compute} compute`:"no coverage"}a(we,"coverageText");function ie(e){return e<100?e.toFixed(1):Math.round(e).toString()}a(ie,"milliseconds");function L(e,t,o){return `${e} ${d(t,12)} ${o}`}a(L,"row");function ce(e$1){if(e$1.skipped)return L(c.tick,"shaders",`fresh ${c.dot} capture skipped ${b.dim(`(--if-stale) \xB7 ${e$1.reason}`)}`);let t=Math.max(0,Math.round((e$1.durationMs??0)/1e3)),o=e$1.scenes.length,r=[L(c.tick,"shaders",`captured in ${t} s ${c.dot} wrote ${o} shader scene${o===1?"":"s"}`)];e$1.configuration?.created===true&&r.push(b.dim(` created ${e$1.configuration.file} with the default "/" capture route`));for(let b$1 of e$1.scenes)r.push(L(c.tick,b$1.scene,`${we(b$1.coverage)} ${c.dot} ${b.dim(`${b$1.attempts} attempt${b$1.attempts===1?"":"s"}`)}`));let c$1=e$1.scenes.flatMap(b=>{let a$1=b.timing;if(a$1?.launch===void 0||a$1.firstRequest===void 0||a$1.readiness===void 0||a$1.lastBuild===void 0||a$1.settled===void 0||a$1.posted===void 0)return [];let m=a((R,l)=>`${ie(Math.max(0,l-R))} ms`,"elapsed");return [[b.scene,`launch\u2192request ${m(a$1.launch,a$1.firstRequest)} ${c.dot} ready ${m(a$1.firstRequest,a$1.readiness)} ${c.dot} last build ${m(a$1.readiness,a$1.lastBuild)} ${c.dot} settle ${m(a$1.lastBuild,a$1.settled)} ${c.dot} post ${m(a$1.settled,a$1.posted)}`]]});return c$1.length>0&&r.push("",b.bold("Capture stages"),...e(c$1,{indent:2,maxWidth:a$2.width-2})),e$1.measurement!==void 0&&r.push(` TSL builds at startup: ${e$1.measurement.beforeBuilds} \u2192 ${e$1.measurement.afterBuilds} ${c.dot} \u2248${ie(Math.abs(e$1.measurement.firstFrameDeltaMs))} ms TSL work avoided (single-capture estimate)`),r.push(b.dim(" a running dev server reloads on its own; otherwise refresh the page")),r.join(`
|
|
7
7
|
`)}a(ce,"formatShaderCapture");function ge(e){let t=[L(c.tick,"shaders",`no-GPU ${e.noGpu.state} ${c.dot} browser ${e.browser}`)];for(let o of e.scenes){let r=e.timing?.scenes[o.scene],c$1=r===void 0?`${o.coverage.render+o.coverage.compute} TSL build${o.coverage.render+o.coverage.compute===1?"":"s"} skipped`:`${r.builds} TSL build${r.builds===1?"":"s"} skipped ${c.dot} \u2248${ie(r.avoidedBuildMs)} ms \xB1 ${ie(r.spreadMs)} TSL work avoided ${c.dot} median of ${r.runs} ${c.dot} Latest local capture`,b$1=r!==void 0&&r.spreadMs>r.avoidedBuildMs*.4?` ${c.dot} ${b.warn("noisy measurement \u2014 close other GPU apps and re-run")}`:"";t.push(L(c.tick,o.scene,`${c$1} ${c.dot} ${o.coverage.compute} compute ${c.dot} ${(o.parity.diffRatio*100).toFixed(3)}% pixel diff${b$1}`));}return t.join(`
|
|
8
|
-
`)}a(ge,"formatShaderTest");async function $e(){if(ue!==void 0)throw new Error(ue);if(v==="help"||v==="--help"||n.includes("--help"))return me();if(v==="version"||n.includes("--version")){f(h?JSON.stringify({version:a$1}):a$1);return}if(v==="browser"){let{formatBrowserPreviewReport:a,formatBrowserSmokeReport:m,runBrowserPreview:R,runBrowserSmoke:l}=await import('./browser-smoke-
|
|
8
|
+
`)}a(ge,"formatShaderTest");async function $e(){if(ue!==void 0)throw new Error(ue);if(v==="help"||v==="--help"||n.includes("--help"))return me();if(v==="version"||n.includes("--version")){f(h?JSON.stringify({version:a$1}):a$1);return}if(v==="browser"){let{formatBrowserPreviewReport:a,formatBrowserSmokeReport:m,runBrowserPreview:R,runBrowserSmoke:l}=await import('./browser-smoke-NTM7XYO6.js'),{findProjectRoot:y}=await import('./status-6GFLRFEZ.js');if(O==="preview"){let T=$("--root")??await y(),M=fe("--route"),F=$("--build-mode"),A=$("--expect-shaders")??"precompiled";if(A!=="precompiled"&&A!=="live")throw new Error('--expect-shaders must be "precompiled" or "live".');let _=k("--width"),X=k("--height"),P=k("--timeout"),V=k("--settle"),K=k("--min-luminance"),Y=C("building and verifying the production bundle"),z;try{z=await R({root:T,...M.length===0?{}:{routes:M},...F===void 0?{}:{buildMode:F},expectShaders:A,text:n.includes("--text"),...P===void 0?{}:{timeoutMs:P},...V===void 0?{}:{settleMs:V},...K===void 0?{}:{minimumLuminance:K},..._===void 0&&X===void 0?{}:{viewport:{width:_??1024,height:X??640}},headed:n.includes("--headed")});}finally{Y.stop();}s.stdout.write(`${h?JSON.stringify(z,null,2):a(z)}
|
|
9
9
|
`),z.passed||(s.exitCode=1);return}if(O!=="smoke")throw new Error(`Unsupported browser command "${O??""}".`);let w=$("--root")??await y(),p=k("--width"),E=k("--height"),S=$("--route"),N=k("--timeout"),G=k("--settle"),I=k("--min-luminance"),j=$("--hmr");if(n.includes("--webgl")&&n.includes("--unsupported-worker"))throw new Error("--webgl and --unsupported-worker are mutually exclusive.");let B=C(`smoking ${S??"/"} in a real browser`),g;try{g=await l({root:w,...S===void 0?{}:{route:S},...N===void 0?{}:{timeoutMs:N},...G===void 0?{}:{settleMs:G},...I===void 0?{}:{minimumLuminance:I},...j===void 0?{}:{hmrModule:j},forceWebgl:n.includes("--webgl"),unsupportedWorker:n.includes("--unsupported-worker"),expectTextGenerationFailure:n.includes("--expect-text-generation-failure"),...p===void 0&&E===void 0?{}:{viewport:{width:p??1024,height:E??640}},headed:n.includes("--headed")});}finally{B.stop();}s.stdout.write(`${h?JSON.stringify(g,null,2):m(g)}
|
|
10
|
-
`),g.passed||(s.exitCode=1);return}if(v==="assets"||v==="optimize"){let a$1=v==="optimize"?"optimize":O??"status",m=se.slice(v==="optimize"?1:2),{findProjectRoot:R}=await import('./status-
|
|
10
|
+
`),g.passed||(s.exitCode=1);return}if(v==="assets"||v==="optimize"){let a$1=v==="optimize"?"optimize":O??"status",m=se.slice(v==="optimize"?1:2),{findProjectRoot:R}=await import('./status-6GFLRFEZ.js'),l=$("--root")??await R().catch(()=>s.cwd());if(a$1==="status"){let{formatAssetStatusReport:B,inspectAssets:g}=await import('./asset-optimize-KY2NOFIQ.js'),T=await g(l);s.stdout.write(`${h?JSON.stringify(T,null,2):B(T)}
|
|
11
11
|
`),n.includes("--check")&&T.state==="stale"&&(s.exitCode=1);return}if(a$1!=="optimize")throw new Error(`Unsupported assets command "${a$1}".`);if(m.length===0)throw new Error("assets optimize needs at least one file or directory (.glb, .png, .jpg, .webp, .hdr).");let y=$("--quality");if(y!==void 0&&y!=="default"&&y!=="high")throw new Error('--quality must be "default" or "high".');let w=$("--preset");if(w!==void 0&&w!=="color"&&w!=="normal"&&w!=="data")throw new Error('--preset must be "color", "normal", or "data".');let p=$("--out"),E=k("--max-dim"),S=k("--hdr-max-dim"),{formatAssetOptimizeReport:N,optimizeAssets:G}=await import('./asset-optimize-KY2NOFIQ.js'),I=C("optimizing assets"),j;try{j=await G({root:l,inputs:m,...p===void 0?{}:{outDir:p},...E===void 0?{}:{maxDimension:E},...S===void 0?{}:{hdrMaxDimension:S},...y===void 0?{}:{quality:y},...w===void 0?{}:{preset:w},force:n.includes("--force"),onProgress:a(B=>I.update(`optimizing ${b.accent(B)}`),"onProgress")});}finally{I.stop();}s.stdout.write(`${h?JSON.stringify(j,null,2):N(j)}
|
|
12
|
-
`),j.failed.length>0&&(s.exitCode=1);return}if(v==="environment"){if(O!=="bake")throw new Error(`Unsupported environment command "${O??""}".`);let{bakeRoomEnvironment:a,formatEnvironmentBakeReport:m}=await import('./environment-bake-BGMGFAVK.js'),{findProjectRoot:R}=await import('./status-
|
|
13
|
-
`);return}if(v==="shaders"){let{findShaderProjectRoot:a$1}=await import('./shader-config-EOFU5D3Y.js'),m=O??"status";if(!["status","capture","test","watch"].includes(m))throw new Error(`Unsupported shader command "${m}".`);let R=$("--root"),l=await a$1(R),y=$("--driver");if(y!==void 0&&y!=="vite"&&y!=="static")throw new Error('--driver must be "vite" or "static".');let w=y,p=$("--serve"),E=$("--url"),S=$("--backend");if(S!==void 0&&S!=="webgpu"&&S!=="webgl"&&S!=="both")throw new Error('--backend must be "webgpu", "webgl", or "both".');let N=S;if(m==="status"){let{inspectShaderMatrix:g}=await import('./shader-workflow-BYF3IJOU.js'),{formatShaderMatrixStatus:T}=await import('./status-
|
|
12
|
+
`),j.failed.length>0&&(s.exitCode=1);return}if(v==="environment"){if(O!=="bake")throw new Error(`Unsupported environment command "${O??""}".`);let{bakeRoomEnvironment:a,formatEnvironmentBakeReport:m}=await import('./environment-bake-BGMGFAVK.js'),{findProjectRoot:R}=await import('./status-6GFLRFEZ.js'),l=$("--root")??await R(),y=k("--size"),w=$("--output"),p=k("--timeout"),E=C("baking the room environment on the GPU"),S;try{S=await a({root:l,...y===void 0?{}:{size:y},...w===void 0?{}:{output:w},...p===void 0?{}:{timeoutMs:p},compression:n.includes("--no-zstd")?"none":"zstd",headed:n.includes("--headed")});}finally{E.stop();}s.stdout.write(`${h?JSON.stringify(S,null,2):m(S)}
|
|
13
|
+
`);return}if(v==="shaders"){let{findShaderProjectRoot:a$1}=await import('./shader-config-EOFU5D3Y.js'),m=O??"status";if(!["status","capture","test","watch"].includes(m))throw new Error(`Unsupported shader command "${m}".`);let R=$("--root"),l=await a$1(R),y=$("--driver");if(y!==void 0&&y!=="vite"&&y!=="static")throw new Error('--driver must be "vite" or "static".');let w=y,p=$("--serve"),E=$("--url"),S=$("--backend");if(S!==void 0&&S!=="webgpu"&&S!=="webgl"&&S!=="both")throw new Error('--backend must be "webgpu", "webgl", or "both".');let N=S;if(m==="status"){let{inspectShaderMatrix:g}=await import('./shader-workflow-BYF3IJOU.js'),{formatShaderMatrixStatus:T}=await import('./status-6GFLRFEZ.js'),M=await g(l,void 0,N);s.stdout.write(`${h?JSON.stringify(M,null,2):T(M)}
|
|
14
14
|
`),(n.includes("--check")||O===void 0)&&M.state!=="fresh"&&(s.exitCode=1);return}if(m==="capture"){let{captureShaders:g}=await import('./shader-workflow-BYF3IJOU.js'),{applyShaderAutoWire:T,hasRegisterDevtoolsCall:M,inspectShaderAutoWire:F}=await import('./shader-autowire-SPE5DM2X.js'),{buildShaderCaptureProject:A,startNextShaderCaptureServer:_}=await import('./shader-project-runner-S2AID2RJ.js'),{inferShaderCaptureTarget:X}=await import('./shader-config-EOFU5D3Y.js'),P=w,V=p,K=E,Y,z,Q;try{if(P===void 0&&V===void 0&&K===void 0){let d=await F(l);if(!d.configured&&d.plan!==void 0){if(!await he(d.plan.diff))throw new Error("Adapter wiring was declined; no files were changed.");await T(d.plan);}else if(!d.configured&&d.bundler!=="vite"&&d.bundler!=="unknown")throw new Error(`${d.reason} No files were changed.`);if(d.bundler==="next")z=C("starting the project-local Next.js capture server"),Y=await _(l),K=Y.url,z.update("capturing shader scenes");else if(d.bundler==="webpack"||d.bundler==="esbuild"||d.bundler==="rollup"){z=C(`building the ${d.bundler} capture target`),await A(l);let x=await X(l);if(x.driverKind!=="static"||x.serve===void 0)throw new Error(`${d.bundler} build completed but no dist/, build/, or out/index.html was found; pass --driver static --serve <directory>.`);P="static",V=x.serve,z.update("capturing shader scenes");}}z??=C("capturing shader scenes"),Q=await g({root:l,headed:n.includes("--headed"),ifStale:n.includes("--if-stale"),commitTiming:n.includes("--commit-timing"),...N===void 0?{}:{backend:N},...P===void 0?{}:{driverKind:P},...V===void 0?{}:{serve:V},...K===void 0?{}:{url:K},onSceneStart:a((d,x,W)=>z?.update(`capturing ${b.accent(d)} ${b.dim(`(${x+1}/${W})`)}`),"onSceneStart"),onSceneRetry:a((d,x,W,q,D)=>{let Z=D instanceof Error&&/timed out/iu.test(D.message),ee=`capture attempt ${x}/${W} for "${d}" after ${Z?`timeout (${Math.round(q/1e3)} s burned)`:`failure (${D instanceof Error?D.message:String(D)})`}`;s.stderr.write(h?`${JSON.stringify({type:"shader-capture-retry",scene:d,attempt:x,total:W,timeoutMs:q,message:ee})}
|
|
15
15
|
`:`${ee}
|
|
16
16
|
`);},"onSceneRetry")});}finally{z?.stop(),await Y?.close();}let J;if(!n.includes("--no-assets"))try{let{discoverPublicAssets:d,optimizeAssets:x}=await import('./asset-optimize-KY2NOFIQ.js'),{loadShaderToolConfig:W}=await import('./shader-config-EOFU5D3Y.js'),q=(await W(l)).publicDir??"public",D=await d(l,q);if(D.length>0){let Z=C("optimizing project assets");try{J=await x({root:l,inputs:D,onProgress:a(ee=>Z.update(`optimizing ${b.accent(ee)}`),"onProgress")});}finally{Z.stop();}}}catch(d){let x=`Asset optimization skipped: ${d instanceof Error?d.message:String(d)}`;s.stderr.write(h?`${JSON.stringify({type:"asset-optimize-error",message:x})}
|
|
@@ -23,8 +23,8 @@ ${e}
|
|
|
23
23
|
`);}return}if(m==="test"){let g=$("--mode");if(g!==void 0&&g!=="strict")throw new Error('--mode currently supports only "strict".');let{testShaders:T}=await import('./shader-workflow-BYF3IJOU.js'),M=C("verifying precompiled shaders against the live baseline"),F=k("--runs"),A;try{A=await T({root:l,headed:n.includes("--headed"),skipBrowser:n.includes("--skip-browser"),...w===void 0?{}:{driverKind:w},...p===void 0?{}:{serve:p},...E===void 0?{}:{url:E},...F===void 0?{}:{runs:F},parityOnly:n.includes("--parity-only"),commitTiming:n.includes("--commit-timing"),...N===void 0?{}:{backend:N},onSceneStart:a((_,X,P)=>M.update(`verifying ${b.accent(_)} ${b.dim(`(${X+1}/${P})`)}`),"onSceneStart")});}finally{M.stop();}s.stdout.write(`${h?JSON.stringify(A,null,2):ge(A)}
|
|
24
24
|
`);return}let G=k("--debounce"),{watchShaders:I}=await import('./shader-watch-TLPGG53E.js'),j=new AbortController;s.once("SIGINT",()=>j.abort()),s.once("SIGTERM",()=>j.abort());let B=await I({root:l,headed:n.includes("--headed"),...w===void 0?{}:{driverKind:w},...p===void 0?{}:{serve:p},...E===void 0?{}:{url:E},...G===void 0?{}:{debounceMs:G},signal:j.signal,onResult(g){s.stdout.write(`${h?JSON.stringify(g):ce(g)}
|
|
25
25
|
`);},onError(g){s.stderr.write(`${h?JSON.stringify({error:g.message}):`${c.cross} ${b.danger(g.message)}`}
|
|
26
|
-
`);}});h||f(L(c.ring,"watching",b.dim(B.root))),await B.done;return}if(v==="text"&&O&&O!=="status"){if(O!=="generate")throw new Error(`Unsupported text command "${O}".`);let{generateTextAtlases:a}=await import('./text-atlas-
|
|
27
|
-
`);else {f(L(c.tick,"text",`${p.glyphs} glyphs ${c.dot} ${p.atlases.length} atlas${p.atlases.length===1?"":"es"} regenerated`));for(let E of p.updatedFiles)f(` ${d(b.dim("updated"),12)} ${b.dim(E)}`);}return}if(!["status","text"].includes(v))throw new Error(`Unknown command "${v}".`);let{formatThreeBlocksStatus:e,inspectThreeBlocksStatus:t,threeBlocksStatusIsFresh:o}=await import('./status-
|
|
26
|
+
`);}});h||f(L(c.ring,"watching",b.dim(B.root))),await B.done;return}if(v==="text"&&O&&O!=="status"){if(O!=="generate")throw new Error(`Unsupported text command "${O}".`);let{generateTextAtlases:a}=await import('./text-atlas-UORTLOQJ.js'),{findProjectRoot:m}=await import('./status-6GFLRFEZ.js'),R=n.indexOf("--config"),l=R===-1?"three-blocks.text.ts":n[R+1];if(l===void 0||l.startsWith("--"))throw new Error("--config requires a project-relative path.");let y=await m(),w=C("generating MSDF text atlases"),p;try{p=await a(y,l);}finally{w.stop();}if(h)s.stdout.write(`${JSON.stringify(p,null,2)}
|
|
27
|
+
`);else {f(L(c.tick,"text",`${p.glyphs} glyphs ${c.dot} ${p.atlases.length} atlas${p.atlases.length===1?"":"es"} regenerated`));for(let E of p.updatedFiles)f(` ${d(b.dim("updated"),12)} ${b.dim(E)}`);}return}if(!["status","text"].includes(v))throw new Error(`Unknown command "${v}".`);let{formatThreeBlocksStatus:e,inspectThreeBlocksStatus:t,threeBlocksStatusIsFresh:o}=await import('./status-6GFLRFEZ.js'),r=await t(),c$1=(r.text);if(v==="text"&&!c$1)throw new Error("This project does not enable the text feature.");let b$1=v==="text"?c$1:r;s.stdout.write(`${h?JSON.stringify(b$1,null,2):v==="status"?e(r):JSON.stringify(b$1,null,2)}
|
|
28
28
|
`),v==="status"&&n.includes("--check")&&!o(r)&&(s.exitCode=1);}a($e,"main");$e().catch(e=>{let t=e instanceof Error?e.message:String(e);h?s.stderr.write(`${JSON.stringify({error:t})}
|
|
29
29
|
`):s.stderr.write(`${c.cross} ${b.danger(t)}
|
|
30
30
|
`),s.exitCode=1;});
|
package/dist/index.d.ts
CHANGED
|
@@ -141,6 +141,11 @@ interface TextAtlasGenerationReceipt {
|
|
|
141
141
|
readonly browser: TextAtlasFileReceipt;
|
|
142
142
|
readonly atlas: TextAtlasFileReceipt;
|
|
143
143
|
readonly metrics: TextAtlasFileReceipt;
|
|
144
|
+
/** Per-weight atlas instances keyed by CSS weight, present when the route declares weights. */
|
|
145
|
+
readonly weights?: Readonly<Record<string, {
|
|
146
|
+
readonly atlas: TextAtlasFileReceipt;
|
|
147
|
+
readonly metrics: TextAtlasFileReceipt;
|
|
148
|
+
}>>;
|
|
144
149
|
};
|
|
145
150
|
}
|
|
146
151
|
interface GeneratedTextAtlas {
|
|
@@ -877,11 +882,17 @@ interface ToolTextFontSourcePackage {
|
|
|
877
882
|
readonly checksum: string;
|
|
878
883
|
}
|
|
879
884
|
type ToolTextFontSource = ToolTextFontSourceBuiltin | ToolTextFontSourcePath | ToolTextFontSourcePackage;
|
|
885
|
+
interface ToolTextFontWeightVariant {
|
|
886
|
+
readonly atlas: string;
|
|
887
|
+
readonly metrics: string;
|
|
888
|
+
}
|
|
880
889
|
interface ToolTextFontRoute {
|
|
881
890
|
readonly source: ToolTextFontSource;
|
|
882
891
|
readonly browser: string;
|
|
883
892
|
readonly atlas: string;
|
|
884
893
|
readonly metrics: string;
|
|
894
|
+
/** Atlas instances baked at other CSS weights; the base atlas/metrics pair represents 400. */
|
|
895
|
+
readonly weights: Readonly<Record<string, ToolTextFontWeightVariant>>;
|
|
885
896
|
readonly families: readonly string[];
|
|
886
897
|
readonly languages: readonly string[];
|
|
887
898
|
readonly default: boolean;
|