three-text 0.2.0 → 0.2.2

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/dist/index.min.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * three-text v0.2.0
2
+ * three-text v0.2.2
3
3
  * Copyright (C) 2025 Countertype LLC
4
4
  *
5
5
  * This program is free software: you can redistribute it and/or modify
@@ -11,4 +11,4 @@
11
11
  *
12
12
  * This software includes third-party code - see LICENSE_THIRD_PARTY for details.
13
13
  */
14
- const t=!("undefined"==typeof window||!window.THREE_TEXT_LOG)||"undefined"!=typeof globalThis&&"true"===globalThis.process?.env?.THREE_TEXT_LOG;const e=new class{warn(t,...e){console.warn(t,...e)}error(t,...e){console.error(t,...e)}log(e,...n){t&&console.log(e,...n)}};const n=new class{constructor(){this.metrics=[],this.activeTimers=new Map}start(e,n){if(!t)return;const i=performance.now();this.activeTimers.set(e,i),this.metrics.push({name:e,startTime:i,metadata:n})}end(n){if(!t)return null;const i=performance.now(),s=this.activeTimers.get(n);if(void 0===s)return e.warn(`Performance timer "${n}" was not started`),null;const r=i-s;this.activeTimers.delete(n);for(let t=this.metrics.length-1;t>=0;t--){const e=this.metrics[t];if(e.name===n&&!e.endTime){e.endTime=i,e.duration=r;break}}return console.log(`${n}: ${r.toFixed(2)}ms`),r}getSummary(){if(!t)return{};const e={};for(const t of this.metrics){if(!t.duration)continue;const n=e[t.name];n?(n.count++,n.totalDuration+=t.duration,n.avgDuration=n.totalDuration/n.count,n.lastDuration=t.duration):e[t.name]={count:1,avgDuration:t.duration,totalDuration:t.duration,lastDuration:t.duration}}return e}printSummary(){if(!t)return;const e=this.getSummary();console.table(e),console.log("Operations:",Object.keys(e).sort().join(", "))}printBaseline(){if(!t)return;const e=this.getSummary();Object.entries(e).forEach(([t,e])=>{console.log(`BASELINE ${t}: ${e.avgDuration.toFixed(2)}ms avg (${e.count} calls)`)})}clear(){t&&(this.metrics.length=0,this.activeTimers.clear())}time(e,n,i){if(!t)return n();this.start(e,i);try{return n()}finally{this.end(e)}}async timeAsync(e,n,i){if(!t)return n();this.start(e,i);try{return await n()}finally{this.end(e)}}},i=200,s=100,r=0,o=1/3;var a,h;!function(t){t[t.BOX=0]="BOX",t[t.GLUE=1]="GLUE",t[t.PENALTY=2]="PENALTY",t[t.DISCRETIONARY=3]="DISCRETIONARY"}(a||(a={})),function(t){t[t.TIGHT=0]="TIGHT",t[t.NORMAL=1]="NORMAL",t[t.LOOSE=2]="LOOSE",t[t.VERY_LOOSE=3]="VERY_LOOSE"}(h||(h={}));class l{constructor(){this.nodesByKey=new Map,this.activeList=[],this.allNodes=new Set}getKey(t,e){return t<<2|e}insert(t){const e=this.getKey(t.position,t.fitness),n=this.nodesByKey.get(e);n&&t.totalDemerits<n.totalDemerits?(n.totalDemerits=t.totalDemerits,n.previous=t.previous,n.totalWidth=t.totalWidth):n||(this.nodesByKey.set(e,t),this.allNodes.add(t),t.activeListIndex=this.activeList.length,this.activeList.push(t))}findExisting(t,e){return this.nodesByKey.get(this.getKey(t,e))}getAllActive(){return this.activeList}deactivateNode(t){if(t.active&&void 0!==t.activeListIndex){t.active=!1;const e=t.activeListIndex,n=this.activeList.length-1;if(e!==n){const t=this.activeList[n];this.activeList[e]=t,t.activeListIndex=e}this.activeList.pop(),t.activeListIndex=void 0}}size(){return this.allNodes.size}}const c=50,d=50,u=1e4,f=10,g=1e4,p=-1/0,y=2,m=4,x=1e4;class _{static badness(t,e){if(0===t)return 0;if(e<=0)return x;let n;return n=t<=7230584?Math.floor(297*t/e):e>=1663497?Math.floor(t/Math.floor(e/297)):t,n>1290?x:Math.floor((n*n*n+131072)/262144)}static findHyphenationPoints(t,e="en-us",n,i=y,s=m){let r;if(!n||!n[e])return[];if(r=n[e],!r)return[];const o=`.${t.toLowerCase()}.`,a=new Array(o.length).fill(0);for(let t=0;t<o.length;t++){let e=r;for(let n=t;n<o.length;n++){const i=o[n];if(!e.children||!e.children[i])break;if(e=e.children[i],e.patterns)for(let n=0;n<e.patterns.length;n++){const i=t+n;i<a.length&&(a[i]=Math.max(a[i],e.patterns[n]))}}}const h=[];for(let t=2;t<o.length-2;t++)a[t]%2==1&&h.push(t-1);return h.filter(e=>e>=i&&t.length-e>=s)}static itemizeText(t,e,n=!1,i="en-us",s,r=y,o=m,h){const l=[];return l.push(...this.itemizeParagraph(t,e,n,i,s,r,o,h)),l.push({type:a.GLUE,width:0,stretch:1/0,shrink:0,text:"",originIndex:t.length}),l.push({type:a.PENALTY,width:0,penalty:-1/0,text:"",originIndex:t.length}),l}static itemizeParagraph(t,e,n,i,s,r,h,l){const u=[],f=t.match(/\S+|\s+/g)||[];let g=0;for(let t=0;t<f.length;t++){const p=f[t],y=g;if(/\s+/.test(p)){const t=e(p);u.push({type:a.GLUE,width:t,stretch:.5*t,shrink:t*o,text:p,originIndex:y}),g+=p.length}else{const t=p.split(/(-)/);let o=y;for(let f=0;f<t.length;f++){const g=t[f];if(g)if("-"===g)u.push({type:a.DISCRETIONARY,width:e("-"),preBreak:"-",postBreak:"",noBreak:"-",preBreakWidth:e("-"),penalty:l?.exHyphenPenalty??d,flagged:!0,text:"-",originIndex:o}),o+=1;else{if(g.includes("­")){const t=g.split("­");let n=0;for(let i=0;i<t.length;i++){const s=t[i];s.length>0&&(u.push({type:a.BOX,width:e(s),text:s,originIndex:o+n}),n+=s.length),i<t.length-1&&(u.push({type:a.DISCRETIONARY,width:0,preBreak:"-",postBreak:"",noBreak:"",preBreakWidth:e("-"),penalty:l?.hyphenPenalty??c,flagged:!0,text:"",originIndex:o+n}),n+=1)}}else if(n&&g.length>=r+h){const t=_.findHyphenationPoints(g,i,s,r,h);if(t.length>0){let n=0;for(const i of t){const t=g.substring(n,i);u.push({type:a.BOX,width:e(t),text:t,originIndex:o+n}),u.push({type:a.DISCRETIONARY,width:0,preBreak:"-",postBreak:"",noBreak:"",preBreakWidth:e("-"),penalty:l?.hyphenPenalty??c,flagged:!0,text:"",originIndex:o+i}),n=i}const i=g.substring(n);u.push({type:a.BOX,width:e(i),text:i,originIndex:o+n})}else u.push({type:a.BOX,width:e(g),text:g,originIndex:o})}else u.push({type:a.BOX,width:e(g),text:g,originIndex:o});o+=g.length}}g+=p.length}}return u}static hasSingleWordLines(t,e,n){let i=0;for(let s=0;s<e.length-1;s++){const r=e[s];let o=0,h=0;for(let e=i;e<r;e++)t[e].type===a.GLUE&&o++,t[e].type!==a.PENALTY&&(h+=t[e].width);if(0===o&&h>0){if(h/n<.5)return!0}i=r+1}return!1}static breakText(t){n.start("LineBreak.breakText",{textLength:t.text.length,width:t.width,align:t.align||"left",hyphenate:t.hyphenate||!1});const{text:o,width:h,align:l="left",direction:p="ltr",hyphenate:x=!1,language:v="en-us",respectExistingBreaks:b=!0,measureText:w,hyphenationPatterns:E,unitsPerEm:O,tolerance:L=i,pretolerance:S=s,emergencyStretch:P=r,autoEmergencyStretch:T,lefthyphenmin:F=y,righthyphenmin:I=m,linepenalty:C=f,adjdemerits:U=g,hyphenpenalty:A=c,exhyphenpenalty:B=d,doublehyphendemerits:R=u,looseness:z=0,disableSingleWordDetection:D=!1}=t;if(b&&o.includes("\n")){const e=o.split("\n"),i=[];let s=0;for(const n of e){if(0===n.length)i.push({text:"",originalStart:s,originalEnd:s,xOffset:0,isLastLine:!0,naturalWidth:0,endedWithHyphen:!1});else{const e=_.breakText({...t,text:n,respectExistingBreaks:!1});e.forEach(t=>{t.originalStart+=s,t.originalEnd+=s}),i.push(...e)}s+=n.length+1}return n.end("LineBreak.breakText"),i}let k=x;!k||E&&E[v]||(e.warn(`Hyphenation patterns for ${v} not available`),k=!1);let M=P;void 0!==T&&h?M=h*T:!k&&P===r&&h&&(M=.1*h);const G={linePenalty:C,adjDemerits:U,doubleHyphenDemerits:R,hyphenPenalty:A,exHyphenPenalty:B,currentAlign:l,unitsPerEm:O};if(!h||h===1/0){const t=w(o);return n.end("LineBreak.breakText"),[{text:o,originalStart:0,originalEnd:o.length-1,xOffset:0,isLastLine:!0,naturalWidth:t,endedWithHyphen:!1}]}const N=_.itemizeText(o,w,k,v,E,F,I,G);if(0===N.length)return[];let H=0,q=M,W=null;const V=!D;for(;H<5;){let t=k?N.filter(t=>t.type!==a.DISCRETIONARY||t.penalty!==(G?.hyphenPenalty??c)):N,e=_.findBreakpoints(t,h,S,z,!1,0,G);if(0===e.length&&k&&(t=N,e=_.findBreakpoints(t,h,L,z,!1,0,G)),0===e.length&&(t=N,e=_.findBreakpoints(t,h,10001,z,!0,q,G)),0===e.length&&(e=_.findBreakpoints(t,h,1/0,z,!0,q,G)),e.length>0){const n=_.computeCumulativeWidths(t);if(W=_.createLines(o,t,e,h,l,p,n,G),V&&e.length>1&&_.hasSingleWordLines(t,e,h)){q+=.1*h,H++;continue}break}break}if(n.end("LineBreak.breakText"),W&&W.length>0)return W;const j=w(o);return[{text:o,originalStart:0,originalEnd:o.length-1,xOffset:0,adjustmentRatio:0,isLastLine:!0,naturalWidth:j,endedWithHyphen:!1}]}static findBreakpoints(t,e,n=1/0,i=0,s=!1,r=0,o){const c=_.computeCumulativeWidths(t),d=new l;d.insert({position:0,line:0,fitness:h.NORMAL,totalDemerits:0,totalWidth:0,previous:null,active:!0});for(let i=0;i<t.length;i++){const s=t[i];s.type===a.PENALTY&&s.penalty<1/0&&_.considerBreak(t,d,i,e,n,r,c,o),s.type===a.DISCRETIONARY&&s.penalty<1/0&&_.considerBreak(t,d,i,e,n,r,c,o),s.type===a.GLUE&&i>0&&t[i-1].type===a.BOX&&_.considerBreak(t,d,i,e,n,r,c,o),_.deactivateNodes(d,i,e,c.minWidths)}const u=[];let f=null;if(0===i){const t=d.getAllActive();let e=1/0;for(const n of t)n.active&&n.totalDemerits<e&&(e=n.totalDemerits,f=n)}else{const t=d.getAllActive();let e=0,n=1/0;for(const i of t)i.active&&i.totalDemerits<n&&(n=i.totalDemerits,e=i.line);let r=0,o=1/0;for(const n of t){if(!n.active)continue;const t=n.line-e;t<r&&i<=t||t>r&&i>=t?(f=n,r=t,o=n.totalDemerits):t===r&&n.totalDemerits<o&&(f=n,o=n.totalDemerits)}if(!s&&r!==i&&f)return[]}if(!f)return[];for(;f&&f.position>0;)u.unshift(f.position),f=f.previous;return u}static considerBreak(t,e,n,i,s=1/0,r=0,o,h){const l=(t[n].type===a.PENALTY?t[n].penalty:0)<=-1/0,c=e.getAllActive();for(let d=0;d<c.length;d++){const u=c[d];if(!u.active)continue;const f=_.computeAdjustmentRatio(t,u.position,n,u.line,i,o,h),{ratio:g,adjustment:y,stretch:m,shrink:x,totalWidth:v}=f;let b;if(y>0){const t=m+r;b=t<=0?10001:_.badness(y,t)}else b=y<0?x<=0||-y>x?10001:_.badness(-y,x):0;if(!l&&g<-1)continue;const w=_.computeFitnessClass(b,y>0);if(!l&&b>s)continue;let E=0,O=0;let L=(h?.linePenalty??0)+b,S=Math.abs(L)>=1e4?1e8:L*L;const P=t[n].type===a.PENALTY||t[n].type===a.DISCRETIONARY?t[n].penalty:0;0!==P&&(P>0?S+=P*P:P>p&&(S-=P*P));const T=t[n].type===a.PENALTY&&t[n].flagged||t[n].type===a.DISCRETIONARY&&t[n].flagged,F=u.position>0&&(t[u.position].type===a.PENALTY&&t[u.position].flagged||t[u.position].type===a.DISCRETIONARY&&t[u.position].flagged);T&&F&&(E=h?.doubleHyphenDemerits??0,S+=E),Math.abs(w-u.fitness)>1&&(O=h?.adjDemerits??0,S+=O),l&&(S=0);const I=u.totalDemerits+S;let C=e.findExisting(n,w);C?I<C.totalDemerits&&(C.totalDemerits=I,C.previous=u,C.totalWidth=v):e.insert({position:n,line:u.line+1,fitness:w,totalDemerits:I,totalWidth:v,previous:u,active:!0})}}static computeAdjustmentRatio(t,e,n,i,s,r,o){let h=0,l=0,c=0;if(r){h=r.widths[n]-r.widths[e],l=r.stretches[n]-r.stretches[e],c=r.shrinks[n]-r.shrinks[e];for(let i=e;i<n;i++){const e=t[i];e.type===a.PENALTY&&(h-=e.width)}}else for(let i=e;i<n;i++){const e=t[i];e.type!==a.PENALTY&&(h+=e.width,e.type===a.GLUE&&(l+=e.stretch,c+=e.shrink))}n<t.length&&(t[n].type===a.PENALTY||t[n].type===a.DISCRETIONARY)&&(h+=t[n].type===a.PENALTY?t[n].width:t[n].preBreakWidth);const d=s-h;let u;return u=d>0&&l>0?d/l:d<0&&c>0?d/c:0===d?0:d>0?3:-1,{ratio:u,adjustment:d,stretch:l,shrink:c,totalWidth:h}}static computeFitnessClass(t,e){return e?t<=12?h.NORMAL:t<=99?h.LOOSE:h.VERY_LOOSE:t<=12?h.NORMAL:h.TIGHT}static computeCumulativeWidths(t){const e=t.length+1,n=new Array(e),i=new Array(e),s=new Array(e),r=new Array(e);n[0]=0,i[0]=0,s[0]=0,r[0]=0;for(let e=0;e<t.length;e++){const o=t[e];if(n[e+1]=n[e]+o.width,o.type===a.PENALTY)r[e+1]=r[e];else if(o.type===a.GLUE){const t=o;i[e+1]=i[e]+t.stretch,s[e+1]=s[e]+t.shrink,r[e+1]=r[e]+Math.max(0,t.width-t.shrink)}else i[e+1]=i[e],s[e+1]=s[e],r[e+1]=r[e]+o.width}return{widths:n,stretches:i,shrinks:s,minWidths:r}}static deactivateNodes(t,e,n,i){const s=t.getAllActive();for(let r=s.length-1;r>=0;r--){const o=s[r];if(!o.active)continue;i[e]-i[o.position]>n&&t.deactivateNode(o)}}static createLines(t,e,n,i,s,r,o,h){if(0===n.length)return[{text:t,originalStart:0,originalEnd:t.length-1,xOffset:0}];const l=[];let c=0;for(let t=0;t<n.length;t++){const d=n[t],u=!(n[n.length-1]+1<e.length-1)&&t===n.length-1,f=[];let g=-1,p=-1,y=0;for(let t=c;t<d;t++){const n=e[t];if((n.type!==a.PENALTY||n.text)&&(n.type!==a.DISCRETIONARY||n.noBreak)){if(void 0!==n.originIndex){(-1===g||n.originIndex<g)&&(g=n.originIndex);const t=n.text?n.text.length:0,e=n.originIndex+t-1;e>p&&(p=e)}if(n.text)f.push(n.text);else if(n.type===a.DISCRETIONARY){const t=n;t.noBreak&&f.push(t.noBreak)}y+=n.width}}const m=e[d];let x=!1;if(d<e.length)if(m.type===a.PENALTY&&m.flagged)f.push("-"),y+=m.width,x=!0,void 0!==m.originIndex&&(p=m.originIndex-1);else if(m.type===a.DISCRETIONARY){const t=m;t.preBreak&&(f.push(t.preBreak),y+=t.preBreakWidth,x=t.flagged||!1,void 0!==m.originIndex&&(p=m.originIndex-1))}const v=f.join("");let b=0,w=0,E=s;if("justify"===s&&u&&(E="rtl"===r?"right":"left"),"center"===E)b=(i-y)/2;else if("right"===E)b=i-y;else if("justify"===E&&!u){w=_.computeAdjustmentRatio(e,c,d,t,i,o,h).ratio}l.push({text:v,originalStart:g,originalEnd:p,xOffset:b,adjustmentRatio:w,isLastLine:!1,naturalWidth:y,endedWithHyphen:x}),c=d+1}if(c<e.length-1){const t=[];let n=-1,o=-1,h=0;for(let i=c;i<e.length-1;i++){const s=e[i];s.type!==a.PENALTY&&(void 0!==s.originIndex&&((-1===n||s.originIndex<n)&&(n=s.originIndex),s.originIndex>o&&(o=s.originIndex)),s.text&&t.push(s.text),h+=s.width)}const d=t.join("");let u=0,f=s;"justify"===s&&(f="rtl"===r?"right":"left"),"center"===f?u=(i-h)/2:"right"===f&&(u=i-h),l.push({text:d,originalStart:n,originalEnd:o,xOffset:u,adjustmentRatio:0,isLastLine:!0,naturalWidth:h,endedWithHyphen:!1}),l.length>1&&(l[l.length-2].isLastLine=!1),l[l.length-1].isLastLine=!0}else l.length>0&&(l[l.length-1].isLastLine=!0);return l}}class v{static measureTextWidth(t,e,n=0){const i=t.hb.createBuffer();i.addText(e),i.guessSegmentProperties(),t.hb.shape(t.font,i);const s=i.json(t.font),r=n*t.upem;let o=0;return s.forEach((t,n)=>{o+=t.ax;const i=n===s.length-1,a=" "===e||" "===e||/^\s+$/.test(e);0===r||i&&!a||(o+=r)}),i.destroy(),o}}class b{constructor(t){this.loadedFont=t}computeLines(t){const{text:e,width:n,align:i,direction:s,hyphenate:r,language:o,respectExistingBreaks:a,tolerance:h,pretolerance:l,emergencyStretch:c,autoEmergencyStretch:d,hyphenationPatterns:u,lefthyphenmin:f,righthyphenmin:g,linepenalty:p,adjdemerits:y,hyphenpenalty:m,exhyphenpenalty:x,doublehyphendemerits:b,looseness:w,disableSingleWordDetection:E,letterSpacing:O}=t;let L;if(n)L=_.breakText({text:e,width:n,align:i,direction:s,hyphenate:r,language:o,respectExistingBreaks:a,tolerance:h,pretolerance:l,emergencyStretch:c,autoEmergencyStretch:d,hyphenationPatterns:u,lefthyphenmin:f,righthyphenmin:g,linepenalty:p,adjdemerits:y,hyphenpenalty:m,exhyphenpenalty:x,doublehyphendemerits:b,looseness:w,disableSingleWordDetection:E,unitsPerEm:this.loadedFont.upem,measureText:t=>v.measureTextWidth(this.loadedFont,t,O)});else{const t=e.split("\n");L=[];let n=0;for(const e of t)L.push({text:e,originalStart:n,originalEnd:n+e.length-1,xOffset:0}),n+=e.length+1}return{lines:L}}applyAlignment(t,e){const{width:n,align:i,planeBounds:s}=e;let r=0;const o={min:{...s.min},max:{...s.max}};if(n&&("center"===i||"right"===i)){const e=s.max.x-s.min.x;if("center"===i?r=(n-e)/2-s.min.x:"right"===i&&(r=n-s.max.x),0!==r){for(let e=0;e<t.length;e+=3)t[e]+=r;o.min.x+=r,o.max.x+=r}}return{offset:r,adjustedBounds:o}}}const w=1330926671,E=1953784678,O=2001684038;class L{static extractMetadata(t){if(!t||t.byteLength<12)throw new Error("Invalid font buffer: too small to be a valid font file");const e=new DataView(t),n=e.getUint32(0);if(![65536,w,E].includes(n))throw new Error(`Invalid font format. Expected TrueType or OpenType, got signature: 0x${n.toString(16)}`);const i=new Uint8Array(t),s=e.getUint16(4);let r=!1,o=0,a=0,h=0,l=0,c=0,d=0;for(let t=0;t<s;t++){const n=(new TextDecoder).decode(i.slice(12+16*t,12+16*t+4));("CFF "===n||"CFF2"===n)&&(r=!0),"head"===n&&(o=e.getUint32(12+16*t+8)),"hhea"===n&&(a=e.getUint32(12+16*t+8)),"OS/2"===n&&(h=e.getUint32(12+16*t+8)),"fvar"===n&&(d=e.getUint32(12+16*t+8)),"STAT"===n&&(l=e.getUint32(12+16*t+8)),"name"===n&&(c=e.getUint32(12+16*t+8))}const u=o?e.getUint16(o+18):1e3;let f=null;a&&(f={ascender:e.getInt16(a+4),descender:e.getInt16(a+6),lineGap:e.getInt16(a+8)});let g=null;h&&(g={typoAscender:e.getInt16(h+68),typoDescender:e.getInt16(h+70),typoLineGap:e.getInt16(h+72),winAscent:e.getUint16(h+74),winDescent:e.getUint16(h+76)});let p=null;return d&&l&&c&&(p=this.extractAxisNames(e,l,c)),{isCFF:r,unitsPerEm:u,hheaAscender:f?.ascender||null,hheaDescender:f?.descender||null,hheaLineGap:f?.lineGap||null,typoAscender:g?.typoAscender||null,typoDescender:g?.typoDescender||null,typoLineGap:g?.typoLineGap||null,winAscent:g?.winAscent||null,winDescent:g?.winDescent||null,axisNames:p}}static extractAxisNames(t,e,n){try{if(t.getUint16(e)<1)return null;const i=t.getUint16(e+4),s=t.getUint16(e+6),r=t.getUint32(e+8),o={};for(let a=0;a<s;a++){const s=e+r+a*i,h=String.fromCharCode(t.getUint8(s),t.getUint8(s+1),t.getUint8(s+2),t.getUint8(s+3)),l=t.getUint16(s+4),c=this.getNameFromNameTable(t,n,l);c&&(o[h]=c)}return Object.keys(o).length>0?o:null}catch(t){return null}}static getNameFromNameTable(t,e,n){try{const i=t.getUint16(e+2),s=t.getUint16(e+4);for(let r=0;r<i;r++){const i=e+6+12*r,o=t.getUint16(i),a=t.getUint16(i+2),h=t.getUint16(i+4),l=t.getUint16(i+6),c=t.getUint16(i+8),d=t.getUint16(i+10);if(l===n&&(0===o||3===o&&1033===h)){const n=e+s+d,i=new Uint8Array(t.buffer,n,c);if(0===o||3===o&&1===a){let t="";for(let e=0;e<i.length;e+=2)t+=String.fromCharCode(i[e]<<8|i[e+1]);return t}return new TextDecoder("ascii").decode(i)}}return null}catch(t){return null}}static getVerticalMetrics(t){return null!==t.typoAscender&&null!==t.typoDescender?{ascender:t.typoAscender,descender:t.typoDescender,lineGap:0}:null!==t.hheaAscender&&null!==t.hheaDescender?{ascender:t.hheaAscender,descender:t.hheaDescender,lineGap:0}:null!==t.winAscent&&null!==t.winDescent?{ascender:t.winAscent,descender:-t.winDescent,lineGap:0}:{ascender:Math.round(.8*t.unitsPerEm),descender:-Math.round(.2*t.unitsPerEm),lineGap:0}}static getFontMetrics(t){const e=L.getVerticalMetrics(t);return{ascender:e.ascender,descender:e.descender,lineGap:e.lineGap,unitsPerEm:t.unitsPerEm,naturalLineHeight:e.ascender-e.descender}}}class S{static detectFormat(t){if(t.byteLength<4)return"ttf/otf";const e=new DataView(t).getUint32(0);return e===O?"woff":2001684018===e?"woff2":"ttf/otf"}static async decompressWoff(t){const n=new DataView(t),i=new Uint8Array(t);if(n.getUint32(0)!==O)throw new Error("Not a valid WOFF font");const s=n.getUint32(4),r=n.getUint16(12),o=n.getUint32(16);if("undefined"==typeof DecompressionStream)throw new Error("WOFF fonts require DecompressionStream API (Chrome 80+, Firefox 113+, Safari 16.4+). Please use TTF/OTF fonts or upgrade your browser.");const a=new Uint8Array(o),h=new DataView(a.buffer);h.setUint32(0,s),h.setUint16(4,r);const l=2**Math.floor(Math.log2(r))*16;h.setUint16(6,l),h.setUint16(8,Math.floor(Math.log2(r))),h.setUint16(10,16*r-l);let c=12+16*r;const d=[];for(let t=0;t<r;t++){const e=44+20*t;d.push({tag:n.getUint32(e),offset:n.getUint32(e+4),length:n.getUint32(e+8),origLength:n.getUint32(e+12),checksum:n.getUint32(e+16)})}d.sort((t,e)=>t.tag-e.tag);for(let t=0;t<r;t++){const e=d[t],n=12+16*t;if(h.setUint32(n,e.tag),h.setUint32(n+4,e.checksum),h.setUint32(n+8,c),h.setUint32(n+12,e.origLength),e.length===e.origLength)a.set(i.subarray(e.offset,e.offset+e.length),c);else{const t=i.subarray(e.offset,e.offset+e.length),n=await S.decompressZlib(t);if(n.byteLength!==e.origLength)throw new Error(`Decompression failed: expected ${e.origLength} bytes, got ${n.byteLength}`);a.set(new Uint8Array(n),c)}c+=e.origLength;c+=(4-e.origLength%4)%4}return e.log("WOFF font decompressed successfully"),a.buffer.slice(0,c)}static async decompressZlib(t){const e=new ReadableStream({start(e){e.enqueue(t),e.close()}}).pipeThrough(new DecompressionStream("deflate"));return new Response(e).arrayBuffer()}}class P{constructor(t){this.getHarfBuzzInstance=t}async loadFont(t,i){if(n.start("FontLoader.loadFont",{bufferSize:t.byteLength}),!t||t.byteLength<12)throw new Error("Invalid font buffer: too small to be a valid font file");const s=S.detectFormat(t);if("woff"===s)e.log("WOFF font detected, decompressing..."),t=await S.decompressWoff(t);else if("woff2"===s)throw new Error("WOFF2 fonts are not yet supported. Please use WOFF or TTF/OTF format.");const r=new DataView(t).getUint32(0);if(![65536,w,E].includes(r))throw new Error(`Invalid font format. Expected TrueType or OpenType, got signature: 0x${r.toString(16)}`);const{hb:o,module:a}=await this.getHarfBuzzInstance();try{const e=o.createBlob(new Uint8Array(t)),n=o.createFace(e,0),s=o.createFont(n);i&&s.setVariations(i);const r=n.getAxisInfos(),h=Object.keys(r).length>0,l=L.extractMetadata(t);let c;if(h&&r){c={};for(const[t,e]of Object.entries(r))c[t]={...e,name:l.axisNames?.[t]||null}}return{hb:o,fontBlob:e,face:n,font:s,module:a,upem:l.unitsPerEm,metrics:l,fontVariations:i,isVariable:h,variationAxes:c}}catch(t){throw e.error("Failed to load font:",t),t}finally{n.end("FontLoader.loadFont")}}static destroyFont(t){try{t.font&&"function"==typeof t.font.destroy&&t.font.destroy(),t.face&&"function"==typeof t.face.destroy&&t.face.destroy(),t.fontBlob&&"function"==typeof t.fontBlob.destroy&&t.fontBlob.destroy()}catch(t){e.error("Error destroying font resources:",t)}}}async function T(t,e){try{if(e){return(await import(`${e}${t}.js`)).default}if("string"==typeof import.meta?.url){const e=new URL(".",import.meta.url).href,n=new URL(`./patterns/${t}.js`,e).href;return(await import(n)).default}return(await import(`./patterns/${t}.js`)).default}catch(e){throw new Error(`Failed to load hyphenation patterns for ${t}. Consider using static imports: import pattern from 'three-text/patterns/${t}'; Text.registerPattern('${t}', pattern);`)}}class F{constructor(t=0,e=0){this.x=t,this.y=e}set(t,e){return this.x=t,this.y=e,this}clone(){return new F(this.x,this.y)}copy(t){return this.x=t.x,this.y=t.y,this}add(t){return this.x+=t.x,this.y+=t.y,this}sub(t){return this.x-=t.x,this.y-=t.y,this}multiply(t){return this.x*=t,this.y*=t,this}divide(t){return this.x/=t,this.y/=t,this}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}lengthSq(){return this.x*this.x+this.y*this.y}normalize(){const t=this.length();return t>0&&this.divide(t),this}dot(t){return this.x*t.x+this.y*t.y}distanceTo(t){const e=this.x-t.x,n=this.y-t.y;return Math.sqrt(e*e+n*n)}distanceToSquared(t){const e=this.x-t.x,n=this.y-t.y;return e*e+n*n}equals(t){return this.x===t.x&&this.y===t.y}angle(){return Math.atan2(this.y,this.x)}}class I{constructor(t=0,e=0,n=0){this.x=t,this.y=e,this.z=n}set(t,e,n){return this.x=t,this.y=e,this.z=n,this}clone(){return new I(this.x,this.y,this.z)}copy(t){return this.x=t.x,this.y=t.y,this.z=t.z,this}add(t){return this.x+=t.x,this.y+=t.y,this.z+=t.z,this}sub(t){return this.x-=t.x,this.y-=t.y,this.z-=t.z,this}multiply(t){return this.x*=t,this.y*=t,this.z*=t,this}divide(t){return this.x/=t,this.y/=t,this.z/=t,this}length(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)}lengthSq(){return this.x*this.x+this.y*this.y+this.z*this.z}normalize(){const t=this.length();return t>0&&this.divide(t),this}dot(t){return this.x*t.x+this.y*t.y+this.z*t.z}cross(t){const e=this.y*t.z-this.z*t.y,n=this.z*t.x-this.x*t.z,i=this.x*t.y-this.y*t.x;return this.x=e,this.y=n,this.z=i,this}distanceTo(t){const e=this.x-t.x,n=this.y-t.y,i=this.z-t.z;return Math.sqrt(e*e+n*n+i*i)}distanceToSquared(t){const e=this.x-t.x,n=this.y-t.y,i=this.z-t.z;return e*e+n*n+i*i}equals(t){return this.x===t.x&&this.y===t.y&&this.z===t.z}}class C{constructor(t=new I(1/0,1/0,1/0),e=new I(-1/0,-1/0,-1/0)){this.min=t,this.max=e}set(t,e){return this.min.copy(t),this.max.copy(e),this}setFromPoints(t){this.makeEmpty();for(let e=0;e<t.length;e++)this.expandByPoint(t[e]);return this}makeEmpty(){return this.min.x=this.min.y=this.min.z=1/0,this.max.x=this.max.y=this.max.z=-1/0,this}isEmpty(){return this.max.x<this.min.x||this.max.y<this.min.y||this.max.z<this.min.z}expandByPoint(t){return this.min.x=Math.min(this.min.x,t.x),this.min.y=Math.min(this.min.y,t.y),this.min.z=Math.min(this.min.z,t.z),this.max.x=Math.max(this.max.x,t.x),this.max.y=Math.max(this.max.y,t.y),this.max.z=Math.max(this.max.z,t.z),this}expandByScalar(t){return this.min.x-=t,this.min.y-=t,this.min.z-=t,this.max.x+=t,this.max.y+=t,this.max.z+=t,this}containsPoint(t){return t.x>=this.min.x&&t.x<=this.max.x&&t.y>=this.min.y&&t.y<=this.max.y&&t.z>=this.min.z&&t.z<=this.max.z}containsBox(t){return this.min.x<=t.min.x&&t.max.x<=this.max.x&&this.min.y<=t.min.y&&t.max.y<=this.max.y&&this.min.z<=t.min.z&&t.max.z<=this.max.z}intersectsBox(t){return t.max.x>=this.min.x&&t.min.x<=this.max.x&&t.max.y>=this.min.y&&t.min.y<=this.max.y&&t.max.z>=this.min.z&&t.min.z<=this.max.z}getCenter(t=new I){return this.isEmpty()?t.set(0,0,0):t.set(.5*(this.min.x+this.max.x),.5*(this.min.y+this.max.y),.5*(this.min.z+this.max.z))}getSize(t=new I){return this.isEmpty()?t.set(0,0,0):t.set(this.max.x-this.min.x,this.max.y-this.min.y,this.max.z-this.min.z)}clone(){return new C(this.min.clone(),this.max.clone())}copy(t){return this.min.copy(t.min),this.max.copy(t.max),this}union(t){return this.min.x=Math.min(this.min.x,t.min.x),this.min.y=Math.min(this.min.y,t.min.y),this.min.z=Math.min(this.min.z,t.min.z),this.max.x=Math.max(this.max.x,t.max.x),this.max.y=Math.max(this.max.y,t.max.y),this.max.z=Math.max(this.max.z,t.max.z),this}equals(t){return t.min.equals(this.min)&&t.max.equals(this.max)}}var U,A;function B(t,e){if(!t)throw e||"Assertion Failed!"}!function(t){t[t.ODD=0]="ODD",t[t.NONZERO=1]="NONZERO",t[t.POSITIVE=2]="POSITIVE",t[t.NEGATIVE=3]="NEGATIVE",t[t.ABS_GEQ_TWO=4]="ABS_GEQ_TWO"}(U||(U={})),function(t){t[t.POLYGONS=0]="POLYGONS",t[t.CONNECTED_POLYGONS=1]="CONNECTED_POLYGONS",t[t.BOUNDARY_CONTOURS=2]="BOUNDARY_CONTOURS"}(A||(A={}));var R=function(){function t(){}return t.vertEq=function(t,e){return t.s===e.s&&t.t===e.t},t.vertLeq=function(t,e){return t.s<e.s||t.s===e.s&&t.t<=e.t},t.transLeq=function(t,e){return t.t<e.t||t.t===e.t&&t.s<=e.s},t.edgeGoesLeft=function(e){return t.vertLeq(e.Dst,e.Org)},t.edgeGoesRight=function(e){return t.vertLeq(e.Org,e.Dst)},t.vertL1dist=function(t,e){return Math.abs(t.s-e.s)+Math.abs(t.t-e.t)},t.edgeEval=function(e,n,i){B(t.vertLeq(e,n)&&t.vertLeq(n,i));var s=n.s-e.s,r=i.s-n.s;return s+r>0?s<r?n.t-e.t+(e.t-i.t)*(s/(s+r)):n.t-i.t+(i.t-e.t)*(r/(s+r)):0},t.edgeSign=function(e,n,i){B(t.vertLeq(e,n)&&t.vertLeq(n,i));var s=n.s-e.s,r=i.s-n.s;return s+r>0?(n.t-i.t)*s+(n.t-e.t)*r:0},t.transEval=function(e,n,i){B(t.transLeq(e,n)&&t.transLeq(n,i));var s=n.t-e.t,r=i.t-n.t;return s+r>0?s<r?n.s-e.s+(e.s-i.s)*(s/(s+r)):n.s-i.s+(i.s-e.s)*(r/(s+r)):0},t.transSign=function(e,n,i){B(t.transLeq(e,n)&&t.transLeq(n,i));var s=n.t-e.t,r=i.t-n.t;return s+r>0?(n.s-i.s)*s+(n.s-e.s)*r:0},t.vertCCW=function(t,e,n){return t.s*(e.t-n.t)+e.s*(n.t-t.t)+n.s*(t.t-e.t)>=0},t.interpolate=function(t,e,n,i){return(t=t<0?0:t)<=(n=n<0?0:n)?0===n?(e+i)/2:e+t/(t+n)*(i-e):i+n/(t+n)*(e-i)},t.intersect=function(e,n,i,s,r){var o,a,h;t.vertLeq(e,n)||(h=e,e=n,n=h),t.vertLeq(i,s)||(h=i,i=s,s=h),t.vertLeq(e,i)||(h=e,e=i,i=h,h=n,n=s,s=h),t.vertLeq(i,n)?t.vertLeq(n,s)?((o=t.edgeEval(e,i,n))+(a=t.edgeEval(i,n,s))<0&&(o=-o,a=-a),r.s=t.interpolate(o,i.s,a,n.s)):((o=t.edgeSign(e,i,n))+(a=-t.edgeSign(e,s,n))<0&&(o=-o,a=-a),r.s=t.interpolate(o,i.s,a,s.s)):r.s=(i.s+n.s)/2,t.transLeq(e,n)||(h=e,e=n,n=h),t.transLeq(i,s)||(h=i,i=s,s=h),t.transLeq(e,i)||(h=e,e=i,i=h,h=n,n=s,s=h),t.transLeq(i,n)?t.transLeq(n,s)?((o=t.transEval(e,i,n))+(a=t.transEval(i,n,s))<0&&(o=-o,a=-a),r.t=t.interpolate(o,i.t,a,n.t)):((o=t.transSign(e,i,n))+(a=-t.transSign(e,s,n))<0&&(o=-o,a=-a),r.t=t.interpolate(o,i.t,a,s.t)):r.t=(i.t+n.t)/2},t}(),z=function(){this.next=null,this.prev=null,this.anEdge=null,this.trail=null,this.n=0,this.marked=!1,this.inside=!1},D=function(){function t(t){this.side=t,this.next=null,this.Org=null,this.Sym=null,this.Onext=null,this.Lnext=null,this.Lface=null,this.activeRegion=null,this.winding=0}return Object.defineProperty(t.prototype,"Rface",{get:function(){return this.Sym.Lface},set:function(t){this.Sym.Lface=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"Dst",{get:function(){return this.Sym.Org},set:function(t){this.Sym.Org=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"Oprev",{get:function(){return this.Sym.Lnext},set:function(t){this.Sym.Lnext=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"Lprev",{get:function(){return this.Onext.Sym},set:function(t){this.Onext.Sym=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"Dprev",{get:function(){return this.Lnext.Sym},set:function(t){this.Lnext.Sym=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"Rprev",{get:function(){return this.Sym.Onext},set:function(t){this.Sym.Onext=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"Dnext",{get:function(){return this.Sym.Onext.Sym},set:function(t){this.Sym.Onext.Sym=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"Rnext",{get:function(){return this.Sym.Lnext.Sym},set:function(t){this.Sym.Lnext.Sym=t},enumerable:!0,configurable:!0}),t}(),k=function(){this.next=null,this.prev=null,this.anEdge=null,this.coords=[0,0,0],this.s=0,this.t=0,this.pqHandle=0,this.n=0,this.idx=0},M=function(){function t(){var t=new k,e=new z,n=new D(0),i=new D(1);t.next=t.prev=t,t.anEdge=null,e.next=e.prev=e,n.next=n,n.Sym=i,i.next=i,i.Sym=n,this.vHead=t,this.fHead=e,this.eHead=n,this.eHeadSym=i}return t.prototype.makeEdge_=function(t){var e=new D(0),n=new D(1);t.Sym.side<t.side&&(t=t.Sym);var i=t.Sym.next;return n.next=i,i.Sym.next=e,e.next=t,t.Sym.next=n,e.Sym=n,e.Onext=e,e.Lnext=n,e.Org=null,e.Lface=null,e.winding=0,e.activeRegion=null,n.Sym=e,n.Onext=n,n.Lnext=e,n.Org=null,n.Lface=null,n.winding=0,n.activeRegion=null,e},t.prototype.splice_=function(t,e){var n=t.Onext,i=e.Onext;n.Sym.Lnext=e,i.Sym.Lnext=t,t.Onext=i,e.Onext=n},t.prototype.makeVertex_=function(t,e,n){var i=t;B(i,"Vertex can't be null!");var s=n.prev;i.prev=s,s.next=i,i.next=n,n.prev=i,i.anEdge=e;var r=e;do{r.Org=i,r=r.Onext}while(r!==e)},t.prototype.makeFace_=function(t,e,n){var i=t;B(i,"Face can't be null");var s=n.prev;i.prev=s,s.next=i,i.next=n,n.prev=i,i.anEdge=e,i.trail=null,i.marked=!1,i.inside=n.inside;var r=e;do{r.Lface=i,r=r.Lnext}while(r!==e)},t.prototype.killEdge_=function(t){t.Sym.side<t.side&&(t=t.Sym);var e=t.next,n=t.Sym.next;e.Sym.next=n,n.Sym.next=e},t.prototype.killVertex_=function(t,e){var n=t.anEdge,i=n;do{i.Org=e,i=i.Onext}while(i!==n);var s=t.prev,r=t.next;r.prev=s,s.next=r},t.prototype.killFace_=function(t,e){var n=t.anEdge,i=n;do{i.Lface=e,i=i.Lnext}while(i!==n);var s=t.prev,r=t.next;r.prev=s,s.next=r},t.prototype.makeEdge=function(){var t=new k,e=new k,n=new z,i=this.makeEdge_(this.eHead);return this.makeVertex_(t,i,this.vHead),this.makeVertex_(e,i.Sym,this.vHead),this.makeFace_(n,i,this.fHead),i},t.prototype.splice=function(t,e){var n=!1,i=!1;if(t!==e){if(e.Org!==t.Org&&(i=!0,this.killVertex_(e.Org,t.Org)),e.Lface!==t.Lface&&(n=!0,this.killFace_(e.Lface,t.Lface)),this.splice_(e,t),!i){var s=new k;this.makeVertex_(s,e,t.Org),t.Org.anEdge=t}if(!n){var r=new z;this.makeFace_(r,e,t.Lface),t.Lface.anEdge=t}}},t.prototype.delete=function(t){var e=t.Sym,n=!1;if(t.Lface!==t.Rface&&(n=!0,this.killFace_(t.Lface,t.Rface)),t.Onext===t)this.killVertex_(t.Org,null);else if(t.Rface.anEdge=t.Oprev,t.Org.anEdge=t.Onext,this.splice_(t,t.Oprev),!n){var i=new z;this.makeFace_(i,t,t.Lface)}e.Onext===e?(this.killVertex_(e.Org,null),this.killFace_(e.Lface,null)):(t.Lface.anEdge=e.Oprev,e.Org.anEdge=e.Onext,this.splice_(e,e.Oprev)),this.killEdge_(t)},t.prototype.addEdgeVertex=function(t){var e=this.makeEdge_(t),n=e.Sym;this.splice_(e,t.Lnext),e.Org=t.Dst;var i=new k;return this.makeVertex_(i,n,e.Org),e.Lface=n.Lface=t.Lface,e},t.prototype.splitEdge=function(t){var e=this.addEdgeVertex(t).Sym;return this.splice_(t.Sym,t.Sym.Oprev),this.splice_(t.Sym,e),t.Dst=e.Org,e.Dst.anEdge=e.Sym,e.Rface=t.Rface,e.winding=t.winding,e.Sym.winding=t.Sym.winding,e},t.prototype.connect=function(t,e){var n=!1,i=this.makeEdge_(t),s=i.Sym;if(e.Lface!==t.Lface&&(n=!0,this.killFace_(e.Lface,t.Lface)),this.splice_(i,t.Lnext),this.splice_(s,e),i.Org=t.Dst,s.Org=e.Org,i.Lface=s.Lface=t.Lface,t.Lface.anEdge=s,!n){var r=new z;this.makeFace_(r,i,t.Lface)}return i},t.prototype.zapFace=function(t){var e,n,i,s,r,o=t.anEdge;n=o.Lnext;do{n=(e=n).Lnext,e.Lface=null,null===e.Rface&&(e.Onext===e?this.killVertex_(e.Org,null):(e.Org.anEdge=e.Onext,this.splice_(e,e.Oprev)),(i=e.Sym).Onext===i?this.killVertex_(i.Org,null):(i.Org.anEdge=i.Onext,this.splice_(i,i.Oprev)),this.killEdge_(e))}while(e!=o);s=t.prev,(r=t.next).prev=s,s.next=r},t.prototype.countFaceVerts_=function(t){var e=t.anEdge,n=0;do{n++,e=e.Lnext}while(e!==t.anEdge);return n},t.prototype.mergeConvexFaces=function(t){var e,n,i,s,r;for(e=this.fHead.next;e!==this.fHead;e=e.next)if(e.inside)for(r=(n=e.anEdge).Org;i=n.Lnext,(s=n.Sym)&&s.Lface&&s.Lface.inside&&this.countFaceVerts_(e)+this.countFaceVerts_(s.Lface)-2<=t&&R.vertCCW(n.Lprev.Org,n.Org,s.Lnext.Lnext.Org)&&R.vertCCW(s.Lprev.Org,s.Org,n.Lnext.Lnext.Org)&&(i=s.Lnext,this.delete(s),n=null,s=null),!n||n.Lnext.Org!==r;)n=i;return!0},t.prototype.check=function(){var t,e,n,i,s,r,o=this.fHead,a=this.vHead,h=this.eHead;for(e=o,e=o;(t=e.next)!==o;e=t){B(t.prev===e),s=t.anEdge;do{B(s.Sym!==s),B(s.Sym.Sym===s),B(s.Lnext.Onext.Sym===s),B(s.Onext.Sym.Lnext===s),B(s.Lface===t),s=s.Lnext}while(s!==t.anEdge)}for(B(t.prev===e&&null===t.anEdge),i=a,i=a;(n=i.next)!==a;i=n){B(n.prev===i),s=n.anEdge;do{B(s.Sym!==s),B(s.Sym.Sym===s),B(s.Lnext.Onext.Sym===s),B(s.Onext.Sym.Lnext===s),B(s.Org===n),s=s.Onext}while(s!==n.anEdge)}for(B(n.prev===i&&null===n.anEdge),r=h,r=h;(s=r.next)!==h;r=s)B(s.Sym.next===r.Sym),B(s.Sym!==s),B(s.Sym.Sym===s),B(null!==s.Org),B(null!==s.Dst),B(s.Lnext.Onext.Sym===s),B(s.Onext.Sym.Lnext===s);B(s.Sym.next===r.Sym&&s.Sym===this.eHeadSym&&s.Sym.Sym===s&&null===s.Org&&null===s.Dst&&null===s.Lface&&null===s.Rface)},t}(),G=function(){this.handle=null},N=function(){this.key=null,this.node=0},H=function(){function t(t,e){this.leq=e,this.max=0,this.nodes=[],this.handles=[],this.initialized=!1,this.freeList=0,this.size=0,this.max=t,this.nodes=[],this.handles=[];for(var n=0;n<t+1;n++)this.nodes[n]=new G,this.handles[n]=new N;this.initialized=!1,this.nodes[1].handle=1,this.handles[1].key=null}return t.prototype.floatDown_=function(t){var e,n,i,s=this.nodes,r=this.handles;for(e=s[t].handle;;){if((i=t<<1)<this.size&&this.leq(r[s[i+1].handle].key,r[s[i].handle].key)&&++i,B(i<=this.max),n=s[i].handle,i>this.size||this.leq(r[e].key,r[n].key)){s[t].handle=e,r[e].node=t;break}s[t].handle=n,r[n].node=t,t=i}},t.prototype.floatUp_=function(t){var e,n,i,s=this.nodes,r=this.handles;for(e=s[t].handle;;){if(n=s[i=t>>1].handle,0===i||this.leq(r[n].key,r[e].key)){s[t].handle=e,r[e].node=t;break}s[t].handle=n,r[n].node=t,t=i}},t.prototype.init=function(){for(var t=this.size;t>=1;--t)this.floatDown_(t);this.initialized=!0},t.prototype.min=function(){return this.handles[this.nodes[1].handle].key},t.prototype.insert=function(t){var e,n;if(2*(e=++this.size)>this.max){var i,s;for(this.max*=2,s=this.nodes.length,this.nodes.length=this.max+1,i=s;i<this.nodes.length;i++)this.nodes[i]=new G;for(s=this.handles.length,this.handles.length=this.max+1,i=s;i<this.handles.length;i++)this.handles[i]=new N}return 0===this.freeList?n=e:(n=this.freeList,this.freeList=this.handles[n].node),this.nodes[e].handle=n,this.handles[n].node=e,this.handles[n].key=t,this.initialized&&this.floatUp_(e),n},t.prototype.extractMin=function(){var t=this.nodes,e=this.handles,n=t[1].handle,i=e[n].key;return this.size>0&&(t[1].handle=t[this.size].handle,e[t[1].handle].node=1,e[n].key=null,e[n].node=this.freeList,this.freeList=n,--this.size,this.size>0&&this.floatDown_(1)),i},t.prototype.delete=function(t){var e,n=this.nodes,i=this.handles;B(t>=1&&t<=this.max&&null!==i[t].key),n[e=i[t].node].handle=n[this.size].handle,i[n[e].handle].node=e,--this.size,e<=this.size&&(e<=1||this.leq(i[n[e>>1].handle].key,i[n[e].handle].key)?this.floatDown_(e):this.floatUp_(e)),i[t].key=null,i[t].node=this.freeList,this.freeList=t},t}(),q=function(){this.eUp=null,this.nodeUp=null,this.windingNumber=0,this.inside=!1,this.sentinel=!1,this.dirty=!1,this.fixUpperEdge=!1},W=function(){this.key=null,this.next=null,this.prev=null},V=function(){function t(t,e){this.frame=t,this.leq=e,this.head=new W,this.head.next=this.head,this.head.prev=this.head}return t.prototype.min=function(){return this.head.next},t.prototype.max=function(){return this.head.prev},t.prototype.insert=function(t){return this.insertBefore(this.head,t)},t.prototype.search=function(t){var e=this.head;do{e=e.next}while(null!==e.key&&!this.leq(this.frame,t,e.key));return e},t.prototype.insertBefore=function(t,e){do{t=t.prev}while(null!==t.key&&!this.leq(this.frame,t.key,e));var n=new W;return n.key=e,n.next=t.next,t.next.prev=n,n.prev=t,t.next=n,n},t.prototype.delete=function(t){t.next.prev=t.prev,t.prev.next=t.next},t}(),j=function(){function t(){}return t.regionBelow=function(t){return t.nodeUp.prev.key},t.regionAbove=function(t){return t.nodeUp.next.key},t.debugEvent=function(t){},t.addWinding=function(t,e){t.winding+=e.winding,t.Sym.winding+=e.Sym.winding},t.edgeLeq=function(t,e,n){var i=t.event,s=e.eUp,r=n.eUp;return s.Dst===i?r.Dst===i?R.vertLeq(s.Org,r.Org)?R.edgeSign(r.Dst,s.Org,r.Org)<=0:R.edgeSign(s.Dst,r.Org,s.Org)>=0:R.edgeSign(r.Dst,i,r.Org)<=0:r.Dst===i?R.edgeSign(s.Dst,i,s.Org)>=0:R.edgeEval(s.Dst,i,s.Org)>=R.edgeEval(r.Dst,i,r.Org)},t.deleteRegion=function(t,e){e.fixUpperEdge&&B(0===e.eUp.winding),e.eUp.activeRegion=null,t.dict.delete(e.nodeUp)},t.fixUpperEdge=function(t,e,n){B(e.fixUpperEdge),t.mesh.delete(e.eUp),e.fixUpperEdge=!1,e.eUp=n,n.activeRegion=e},t.topLeftRegion=function(e,n){var i,s=n.eUp.Org;do{n=t.regionAbove(n)}while(n.eUp.Org===s);if(n.fixUpperEdge){if(null===(i=e.mesh.connect(t.regionBelow(n).eUp.Sym,n.eUp.Lnext)))return null;t.fixUpperEdge(e,n,i),n=t.regionAbove(n)}return n},t.topRightRegion=function(e){var n=e.eUp.Dst;do{e=t.regionAbove(e)}while(e.eUp.Dst===n);return e},t.addRegionBelow=function(t,e,n){var i=new q;return i.eUp=n,i.nodeUp=t.dict.insertBefore(e.nodeUp,i),i.fixUpperEdge=!1,i.sentinel=!1,i.dirty=!1,n.activeRegion=i,i},t.isWindingInside=function(t,e){switch(t.windingRule){case U.ODD:return!!(1&e);case U.NONZERO:return 0!==e;case U.POSITIVE:return e>0;case U.NEGATIVE:return e<0;case U.ABS_GEQ_TWO:return e>=2||e<=-2}throw new Error("Invalid winding rulle")},t.computeWinding=function(e,n){n.windingNumber=t.regionAbove(n).windingNumber+n.eUp.winding,n.inside=t.isWindingInside(e,n.windingNumber)},t.finishRegion=function(e,n){var i=n.eUp,s=i.Lface;s.inside=n.inside,s.anEdge=i,t.deleteRegion(e,n)},t.finishLeftRegions=function(e,n,i){for(var s,r=null,o=n,a=n.eUp;o!==i;){if(o.fixUpperEdge=!1,(s=(r=t.regionBelow(o)).eUp).Org!=a.Org){if(!r.fixUpperEdge){t.finishRegion(e,o);break}s=e.mesh.connect(a.Lprev,s.Sym),t.fixUpperEdge(e,r,s)}a.Onext!==s&&(e.mesh.splice(s.Oprev,s),e.mesh.splice(a,s)),t.finishRegion(e,o),a=r.eUp,o=r}return a},t.addRightEdges=function(e,n,i,s,r,o){var a,h,l,c,d=!0;l=i;do{B(R.vertLeq(l.Org,l.Dst)),t.addRegionBelow(e,n,l.Sym),l=l.Onext}while(l!==s);for(null===r&&(r=t.regionBelow(n).eUp.Rprev),h=n,c=r;(l=(a=t.regionBelow(h)).eUp.Sym).Org===c.Org;)l.Onext!==c&&(e.mesh.splice(l.Oprev,l),e.mesh.splice(c.Oprev,l)),a.windingNumber=h.windingNumber-l.winding,a.inside=t.isWindingInside(e,a.windingNumber),h.dirty=!0,!d&&t.checkForRightSplice(e,h)&&(t.addWinding(l,c),t.deleteRegion(e,h),e.mesh.delete(c)),d=!1,h=a,c=l;h.dirty=!0,B(h.windingNumber-l.winding===a.windingNumber),o&&t.walkDirtyRegions(e,h)},t.spliceMergeVertices=function(t,e,n){t.mesh.splice(e,n)},t.vertexWeights=function(t,e,n){var i=R.vertL1dist(e,t),s=R.vertL1dist(n,t),r=.5*s/(i+s),o=.5*i/(i+s);t.coords[0]+=r*e.coords[0]+o*n.coords[0],t.coords[1]+=r*e.coords[1]+o*n.coords[1],t.coords[2]+=r*e.coords[2]+o*n.coords[2]},t.getIntersectData=function(e,n,i,s,r,o){n.coords[0]=n.coords[1]=n.coords[2]=0,n.idx=-1,t.vertexWeights(n,i,s),t.vertexWeights(n,r,o)},t.checkForRightSplice=function(e,n){var i=t.regionBelow(n),s=n.eUp,r=i.eUp;if(R.vertLeq(s.Org,r.Org)){if(R.edgeSign(r.Dst,s.Org,r.Org)>0)return!1;R.vertEq(s.Org,r.Org)?s.Org!==r.Org&&(e.pq.delete(s.Org.pqHandle),t.spliceMergeVertices(e,r.Oprev,s)):(e.mesh.splitEdge(r.Sym),e.mesh.splice(s,r.Oprev),n.dirty=i.dirty=!0)}else{if(R.edgeSign(s.Dst,r.Org,s.Org)<0)return!1;t.regionAbove(n).dirty=n.dirty=!0,e.mesh.splitEdge(s.Sym),e.mesh.splice(r.Oprev,s)}return!0},t.checkForLeftSplice=function(e,n){var i,s=t.regionBelow(n),r=n.eUp,o=s.eUp;if(B(!R.vertEq(r.Dst,o.Dst)),R.vertLeq(r.Dst,o.Dst)){if(R.edgeSign(r.Dst,o.Dst,r.Org)<0)return!1;t.regionAbove(n).dirty=n.dirty=!0,i=e.mesh.splitEdge(r),e.mesh.splice(o.Sym,i),i.Lface.inside=n.inside}else{if(R.edgeSign(o.Dst,r.Dst,o.Org)>0)return!1;n.dirty=s.dirty=!0,i=e.mesh.splitEdge(o),e.mesh.splice(r.Lnext,o.Sym),i.Rface.inside=n.inside}return!0},t.checkForIntersect=function(e,n){var i,s,r=t.regionBelow(n),o=n.eUp,a=r.eUp,h=o.Org,l=a.Org,c=o.Dst,d=a.Dst,u=new k;if(B(!R.vertEq(d,c)),B(R.edgeSign(c,e.event,h)<=0),B(R.edgeSign(d,e.event,l)>=0),B(h!==e.event&&l!==e.event),B(!n.fixUpperEdge&&!r.fixUpperEdge),h===l)return!1;if(Math.min(h.t,c.t)>Math.max(l.t,d.t))return!1;if(R.vertLeq(h,l)){if(R.edgeSign(d,h,l)>0)return!1}else if(R.edgeSign(c,l,h)<0)return!1;return t.debugEvent(e),R.intersect(c,h,d,l,u),B(Math.min(h.t,c.t)<=u.t),B(u.t<=Math.max(l.t,d.t)),B(Math.min(d.s,c.s)<=u.s),B(u.s<=Math.max(l.s,h.s)),R.vertLeq(u,e.event)&&(u.s=e.event.s,u.t=e.event.t),i=R.vertLeq(h,l)?h:l,R.vertLeq(i,u)&&(u.s=i.s,u.t=i.t),R.vertEq(u,h)||R.vertEq(u,l)?(t.checkForRightSplice(e,n),!1):!R.vertEq(c,e.event)&&R.edgeSign(c,e.event,u)>=0||!R.vertEq(d,e.event)&&R.edgeSign(d,e.event,u)<=0?d===e.event?(e.mesh.splitEdge(o.Sym),e.mesh.splice(a.Sym,o),n=t.topLeftRegion(e,n),o=t.regionBelow(n).eUp,t.finishLeftRegions(e,t.regionBelow(n),r),t.addRightEdges(e,n,o.Oprev,o,o,!0),!0):c===e.event?(e.mesh.splitEdge(a.Sym),e.mesh.splice(o.Lnext,a.Oprev),r=n,n=t.topRightRegion(n),s=t.regionBelow(n).eUp.Rprev,r.eUp=a.Oprev,a=t.finishLeftRegions(e,r,null),t.addRightEdges(e,n,a.Onext,o.Rprev,s,!0),!0):(R.edgeSign(c,e.event,u)>=0&&(t.regionAbove(n).dirty=n.dirty=!0,e.mesh.splitEdge(o.Sym),o.Org.s=e.event.s,o.Org.t=e.event.t),R.edgeSign(d,e.event,u)<=0&&(n.dirty=r.dirty=!0,e.mesh.splitEdge(a.Sym),a.Org.s=e.event.s,a.Org.t=e.event.t),!1):(e.mesh.splitEdge(o.Sym),e.mesh.splitEdge(a.Sym),e.mesh.splice(a.Oprev,o),o.Org.s=u.s,o.Org.t=u.t,o.Org.pqHandle=e.pq.insert(o.Org),t.getIntersectData(e,o.Org,h,c,l,d),t.regionAbove(n).dirty=n.dirty=r.dirty=!0,!1)},t.walkDirtyRegions=function(e,n){for(var i,s,r=t.regionBelow(n);;){for(;r.dirty;)n=r,r=t.regionBelow(r);if(!n.dirty&&(r=n,null===(n=t.regionAbove(n))||!n.dirty))return;if(n.dirty=!1,i=n.eUp,s=r.eUp,i.Dst!==s.Dst&&t.checkForLeftSplice(e,n)&&(r.fixUpperEdge?(t.deleteRegion(e,r),e.mesh.delete(s),s=(r=t.regionBelow(n)).eUp):n.fixUpperEdge&&(t.deleteRegion(e,n),e.mesh.delete(i),i=(n=t.regionAbove(r)).eUp)),i.Org!==s.Org)if(i.Dst===s.Dst||n.fixUpperEdge||r.fixUpperEdge||i.Dst!==e.event&&s.Dst!==e.event)t.checkForRightSplice(e,n);else if(t.checkForIntersect(e,n))return;i.Org===s.Org&&i.Dst===s.Dst&&(t.addWinding(s,i),t.deleteRegion(e,n),e.mesh.delete(i),n=t.regionAbove(r))}},t.connectRightVertex=function(e,n,i){var s,r=i.Onext,o=t.regionBelow(n),a=n.eUp,h=o.eUp,l=!1;a.Dst!==h.Dst&&t.checkForIntersect(e,n),R.vertEq(a.Org,e.event)&&(e.mesh.splice(r.Oprev,a),n=t.topLeftRegion(e,n),r=t.regionBelow(n).eUp,t.finishLeftRegions(e,t.regionBelow(n),o),l=!0),R.vertEq(h.Org,e.event)&&(e.mesh.splice(i,h.Oprev),i=t.finishLeftRegions(e,o,null),l=!0),l?t.addRightEdges(e,n,i.Onext,r,r,!0):(s=R.vertLeq(h.Org,a.Org)?h.Oprev:a,s=e.mesh.connect(i.Lprev,s),t.addRightEdges(e,n,s,s.Onext,s.Onext,!1),s.Sym.activeRegion.fixUpperEdge=!0,t.walkDirtyRegions(e,n))},t.connectLeftDegenerate=function(e,n,i){var s,r,o,a,h;return s=n.eUp,R.vertEq(s.Org,i)?(B(!1),void t.spliceMergeVertices(e,s,i.anEdge)):R.vertEq(s.Dst,i)?(B(!1),n=t.topRightRegion(n),r=a=(o=(h=t.regionBelow(n)).eUp.Sym).Onext,h.fixUpperEdge&&(B(r!==o),t.deleteRegion(e,h),e.mesh.delete(o),o=r.Oprev),e.mesh.splice(i.anEdge,o),R.edgeGoesLeft(r)||(r=null),void t.addRightEdges(e,n,o.Onext,a,r,!0)):(e.mesh.splitEdge(s.Sym),n.fixUpperEdge&&(e.mesh.delete(s.Onext),n.fixUpperEdge=!1),e.mesh.splice(i.anEdge,s),void t.sweepEvent(e,i))},t.connectLeftVertex=function(e,n){var i,s,r,o,a,h,l=new q;if(l.eUp=n.anEdge.Sym,i=e.dict.search(l).key,s=t.regionBelow(i))if(o=i.eUp,a=s.eUp,0!==R.edgeSign(o.Dst,n,o.Org))if(r=R.vertLeq(a.Dst,o.Dst)?i:s,i.inside||r.fixUpperEdge){if(r===i)h=e.mesh.connect(n.anEdge.Sym,o.Lnext);else h=e.mesh.connect(a.Dnext,n.anEdge).Sym;r.fixUpperEdge?t.fixUpperEdge(e,r,h):t.computeWinding(e,t.addRegionBelow(e,i,h)),t.sweepEvent(e,n)}else t.addRightEdges(e,i,n.anEdge,n.anEdge,null,!0);else t.connectLeftDegenerate(e,i,n)},t.sweepEvent=function(e,n){e.event=n,t.debugEvent(e);for(var i=n.anEdge;null===i.activeRegion;)if((i=i.Onext)===n.anEdge)return void t.connectLeftVertex(e,n);var s=t.topLeftRegion(e,i.activeRegion);B(null!==s);var r=t.regionBelow(s),o=r.eUp,a=t.finishLeftRegions(e,r,null);a.Onext===o?t.connectRightVertex(e,s,a):t.addRightEdges(e,s,a.Onext,o,o,!0)},t.addSentinel=function(t,e,n,i){var s=new q,r=t.mesh.makeEdge();r.Org.s=n,r.Org.t=i,r.Dst.s=e,r.Dst.t=i,t.event=r.Dst,s.eUp=r,s.windingNumber=0,s.inside=!1,s.fixUpperEdge=!1,s.sentinel=!0,s.dirty=!1,s.nodeUp=t.dict.insert(s)},t.initEdgeDict=function(e){e.dict=new V(e,t.edgeLeq);var n=e.bmax[0]-e.bmin[0],i=e.bmax[1]-e.bmin[1],s=e.bmin[0]-n,r=e.bmax[0]+n,o=e.bmin[1]-i,a=e.bmax[1]+i;t.addSentinel(e,s,r,o),t.addSentinel(e,s,r,a)},t.doneEdgeDict=function(e){for(var n,i=0;null!==(n=e.dict.min().key);)n.sentinel||(B(n.fixUpperEdge),B(1===++i)),B(0===n.windingNumber),t.deleteRegion(e,n)},t.removeDegenerateEdges=function(e){var n,i,s,r=e.mesh.eHead;for(n=r.next;n!==r;n=i)i=n.next,s=n.Lnext,R.vertEq(n.Org,n.Dst)&&n.Lnext.Lnext!==n&&(t.spliceMergeVertices(e,s,n),e.mesh.delete(n),s=(n=s).Lnext),s.Lnext===n&&(s!==n&&(s!==i&&s!==i.Sym||(i=i.next),e.mesh.delete(s)),n!==i&&n!==i.Sym||(i=i.next),e.mesh.delete(n))},t.initPriorityQ=function(t){var e,n,i,s=0;for(n=(i=t.mesh.vHead).next;n!==i;n=n.next)s++;for(s+=8,e=t.pq=new H(s,R.vertLeq),n=(i=t.mesh.vHead).next;n!==i;n=n.next)n.pqHandle=e.insert(n);return n===i&&(e.init(),!0)},t.donePriorityQ=function(t){t.pq=null},t.removeDegenerateFaces=function(e,n){var i,s,r;for(i=n.fHead.next;i!==n.fHead;i=s)s=i.next,B((r=i.anEdge).Lnext!==r),r.Lnext.Lnext===r&&(t.addWinding(r.Onext,r),e.mesh.delete(r));return!0},t.computeInterior=function(e,n){var i,s;if(void 0===n&&(n=!0),t.removeDegenerateEdges(e),!t.initPriorityQ(e))return!1;for(t.initEdgeDict(e);null!==(i=e.pq.extractMin());){for(;null!==(s=e.pq.min())&&R.vertEq(s,i);)s=e.pq.extractMin(),t.spliceMergeVertices(e,i.anEdge,s.anEdge);t.sweepEvent(e,i)}return e.event=e.dict.min().key.eUp.Org,t.debugEvent(e),t.doneEdgeDict(e),t.donePriorityQ(e),!!t.removeDegenerateFaces(e,e.mesh)&&(n&&e.mesh.check(),!0)},t}(),$=function(){function t(){this.mesh=new M,this.normal=[0,0,0],this.sUnit=[0,0,0],this.tUnit=[0,0,0],this.bmin=[0,0],this.bmax=[0,0],this.windingRule=U.ODD,this.dict=null,this.pq=null,this.event=null,this.vertexIndexCounter=0,this.vertices=[],this.vertexIndices=[],this.vertexCount=0,this.elements=[],this.elementCount=0}return t.prototype.dot_=function(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]},t.prototype.normalize_=function(t){var e=t[0]*t[0]+t[1]*t[1]+t[2]*t[2];if(!e)throw"Zero-size vector!";e=Math.sqrt(e),t[0]/=e,t[1]/=e,t[2]/=e},t.prototype.longAxis_=function(t){var e=0;return Math.abs(t[1])>Math.abs(t[0])&&(e=1),Math.abs(t[2])>Math.abs(t[e])&&(e=2),e},t.prototype.computeNormal_=function(t){var e,n,i,s,r,o,a=[0,0,0],h=[0,0,0],l=[0,0,0],c=[0,0,0],d=[0,0,0],u=[null,null,null],f=[null,null,null],g=this.mesh.vHead;e=g.next;for(var p=0;p<3;++p)s=e.coords[p],h[p]=s,f[p]=e,a[p]=s,u[p]=e;for(e=g.next;e!==g;e=e.next)for(var y=0;y<3;++y)(s=e.coords[y])<h[y]&&(h[y]=s,f[y]=e),s>a[y]&&(a[y]=s,u[y]=e);var m=0;if(a[1]-h[1]>a[0]-h[0]&&(m=1),a[2]-h[2]>a[m]-h[m]&&(m=2),h[m]>=a[m])return t[0]=0,t[1]=0,void(t[2]=1);for(o=0,n=f[m],i=u[m],l[0]=n.coords[0]-i.coords[0],l[1]=n.coords[1]-i.coords[1],l[2]=n.coords[2]-i.coords[2],e=g.next;e!==g;e=e.next)c[0]=e.coords[0]-i.coords[0],c[1]=e.coords[1]-i.coords[1],c[2]=e.coords[2]-i.coords[2],d[0]=l[1]*c[2]-l[2]*c[1],d[1]=l[2]*c[0]-l[0]*c[2],d[2]=l[0]*c[1]-l[1]*c[0],(r=d[0]*d[0]+d[1]*d[1]+d[2]*d[2])>o&&(o=r,t[0]=d[0],t[1]=d[1],t[2]=d[2]);o<=0&&(t[0]=t[1]=t[2]=0,t[this.longAxis_(l)]=1)},t.prototype.checkOrientation_=function(){for(var t,e,n=this.mesh.fHead,i=this.mesh.vHead,s=0,r=n.next;r!==n;r=r.next)if(!((e=r.anEdge).winding<=0))do{s+=(e.Org.s-e.Dst.s)*(e.Org.t+e.Dst.t),e=e.Lnext}while(e!==r.anEdge);if(s<0){for(t=i.next;t!==i;t=t.next)t.t=-t.t;this.tUnit[0]=-this.tUnit[0],this.tUnit[1]=-this.tUnit[1],this.tUnit[2]=-this.tUnit[2]}},t.prototype.projectPolygon_=function(){var t,e,n=this.mesh.vHead,i=[0,0,0],s=!1;i[0]=this.normal[0],i[1]=this.normal[1],i[2]=this.normal[2],i[0]||i[1]||i[2]||(this.computeNormal_(i),s=!0),t=this.sUnit,e=this.tUnit;var r=this.longAxis_(i);t[r]=0,t[(r+1)%3]=1,t[(r+2)%3]=0,e[r]=0,e[(r+1)%3]=0,e[(r+2)%3]=i[r]>0?1:-1;for(var o=n.next;o!==n;o=o.next)o.s=this.dot_(o.coords,t),o.t=this.dot_(o.coords,e);s&&this.checkOrientation_();for(var a=!0,h=n.next;h!==n;h=h.next)a?(this.bmin[0]=this.bmax[0]=h.s,this.bmin[1]=this.bmax[1]=h.t,a=!1):(h.s<this.bmin[0]&&(this.bmin[0]=h.s),h.s>this.bmax[0]&&(this.bmax[0]=h.s),h.t<this.bmin[1]&&(this.bmin[1]=h.t),h.t>this.bmax[1]&&(this.bmax[1]=h.t))},t.prototype.addWinding_=function(t,e){t.winding+=e.winding,t.Sym.winding+=e.Sym.winding},t.prototype.tessellateMonoRegion_=function(t,e){var n,i;if((n=e.anEdge).Lnext===n||n.Lnext.Lnext===n)throw"Mono region invalid";for(;R.vertLeq(n.Dst,n.Org);n=n.Lprev);for(;R.vertLeq(n.Org,n.Dst);n=n.Lnext);i=n.Lprev;for(;n.Lnext!==i;)if(R.vertLeq(n.Dst,i.Org)){for(;i.Lnext!==n&&(R.edgeGoesLeft(i.Lnext)||R.edgeSign(i.Org,i.Dst,i.Lnext.Dst)<=0);)i=t.connect(i.Lnext,i).Sym;i=i.Lprev}else{for(;i.Lnext!==n&&(R.edgeGoesRight(n.Lprev)||R.edgeSign(n.Dst,n.Org,n.Lprev.Org)>=0);)n=t.connect(n,n.Lprev).Sym;n=n.Lnext}if(i.Lnext===n)throw"Mono region invalid";for(;i.Lnext.Lnext!==n;)i=t.connect(i.Lnext,i).Sym;return!0},t.prototype.tessellateInterior_=function(t){for(var e,n=t.fHead.next;n!==t.fHead;n=e)if(e=n.next,n.inside&&!this.tessellateMonoRegion_(t,n))return!1;return!0},t.prototype.discardExterior_=function(t){for(var e,n=t.fHead.next;n!==t.fHead;n=e)e=n.next,n.inside||t.zapFace(n)},t.prototype.setWindingNumber_=function(t,e,n){for(var i,s=t.eHead.next;s!==t.eHead;s=i)i=s.next,s.Rface.inside!==s.Lface.inside?s.winding=s.Lface.inside?e:-e:n?t.delete(s):s.winding=0},t.prototype.getNeighbourFace_=function(t){return t.Rface&&t.Rface.inside?t.Rface.n:-1},t.prototype.outputPolymesh_=function(t,e,n,i){var s,r,o=0,a=0;n>3&&t.mergeConvexFaces(n);for(var h=t.vHead.next;h!==t.vHead;h=h.next)h.n=-1;for(var l=t.fHead.next;l!==t.fHead;l=l.next)if(l.n=-1,l.inside){s=l.anEdge,r=0;do{-1===(h=s.Org).n&&(h.n=a,a++),r++,s=s.Lnext}while(s!==l.anEdge);if(r>n)throw"Face vertex greater that support polygon";l.n=o,++o}this.elementCount=o,e===A.CONNECTED_POLYGONS&&(o*=2),this.elements=[],this.elements.length=o*n,this.vertexCount=a,this.vertices=[],this.vertices.length=a*i,this.vertexIndices=[],this.vertexIndices.length=a;for(h=t.vHead.next;h!==t.vHead;h=h.next)if(-1!==h.n){var c=h.n*i;this.vertices[c+0]=h.coords[0],this.vertices[c+1]=h.coords[1],i>2&&(this.vertices[c+2]=h.coords[2]),this.vertexIndices[h.n]=h.idx}var d=0;for(l=t.fHead.next;l!==t.fHead;l=l.next)if(l.inside){s=l.anEdge,r=0;do{h=s.Org;this.elements[d++]=h.n,r++,s=s.Lnext}while(s!==l.anEdge);for(var u=r;u<n;++u)this.elements[d++]=-1;if(e===A.CONNECTED_POLYGONS){s=l.anEdge;do{this.elements[d++]=this.getNeighbourFace_(s),s=s.Lnext}while(s!==l.anEdge);for(var f=r;f<n;++f)this.elements[d++]=-1}}},t.prototype.outputContours_=function(t,e){var n,i,s=0,r=0;this.vertexCount=0,this.elementCount=0;for(var o=t.fHead.next;o!==t.fHead;o=o.next)if(o.inside){i=n=o.anEdge;do{this.vertexCount++,n=n.Lnext}while(n!==i);this.elementCount++}this.elements=[],this.elements.length=2*this.elementCount,this.vertices=[],this.vertices.length=this.vertexCount*e,this.vertexIndices=[],this.vertexIndices.length=this.vertexCount;var a=0,h=0,l=0;s=0;for(o=t.fHead.next;o!==t.fHead;o=o.next)if(o.inside){r=0,i=n=o.anEdge;do{this.vertices[a++]=n.Org.coords[0],this.vertices[a++]=n.Org.coords[1],e>2&&(this.vertices[a++]=n.Org.coords[2]),this.vertexIndices[h++]=n.Org.idx,r++,n=n.Lnext}while(n!==i);this.elements[l++]=s,this.elements[l++]=r,s+=r}},t.prototype.addContour=function(t,e){null===this.mesh&&(this.mesh=new M),t<2&&(t=2),t>3&&(t=3);for(var n=null,i=0;i<e.length;i+=t)null===n?(n=this.mesh.makeEdge(),this.mesh.splice(n,n.Sym)):(this.mesh.splitEdge(n),n=n.Lnext),n.Org.coords[0]=e[i+0],n.Org.coords[1]=e[i+1],n.Org.coords[2]=t>2?e[i+2]:0,n.Org.idx=this.vertexIndexCounter++,n.winding=1,n.Sym.winding=-1},t.prototype.tesselate=function(t,e,n,i,s,r){if(void 0===t&&(t=U.ODD),void 0===e&&(e=A.POLYGONS),void 0===r&&(r=!0),this.vertices=[],this.elements=[],this.vertexIndices=[],this.vertexIndexCounter=0,s&&(this.normal[0]=s[0],this.normal[1]=s[1],this.normal[2]=s[2]),this.windingRule=t,i<2&&(i=2),i>3&&(i=3),!this.mesh)return!1;this.projectPolygon_(),j.computeInterior(this,r);var o=this.mesh;return e===A.BOUNDARY_CONTOURS?this.setWindingNumber_(o,1,!0):this.tessellateInterior_(o),r&&o.check(),e===A.BOUNDARY_CONTOURS?this.outputContours_(o,i):this.outputPolymesh_(o,e,n,i),!0},t}();U.ODD,U.NONZERO,U.POSITIVE,U.NEGATIVE,U.ABS_GEQ_TWO,A.POLYGONS,A.CONNECTED_POLYGONS,A.BOUNDARY_CONTOURS;class Y{process(t,n=!0,i=!1){if(0===t.length)return{triangles:{vertices:[],indices:[]},contours:[]};const s=t.filter(t=>t.points.length>=3);return 0===s.length?{triangles:{vertices:[],indices:[]},contours:[]}:(e.log(`Tessellator: removeOverlaps=${n}, processing ${s.length} paths`),this.tessellate(s,n,i))}tessellate(t,n,i){const s=i||n?t:t.map(t=>this.reverseWinding(t));let r=this.pathsToContours(s);if(n){e.log("Two-pass: boundary extraction then triangulation");const t=this.performTessellation(r,A.BOUNDARY_CONTOURS);if(!t)return e.warn("Tess2 returned empty result from boundary pass"),{triangles:{vertices:[],indices:[]},contours:[]};r=this.boundaryToContours(t),e.log(`Boundary pass created ${r.length} contours. Starting triangulation pass.`)}else e.log("Single-pass triangulation for "+(i?"CFF":"TTF"));const o=this.performTessellation(r,A.POLYGONS);if(!o){const t=n?"Tess2 returned empty result from triangulation pass":"Tess2 returned empty result from single-pass triangulation";return e.warn(t),{triangles:{vertices:[],indices:[]},contours:r}}return{triangles:{vertices:Array.from(o.vertices),indices:Array.from(o.elements)},contours:r}}pathsToContours(t){return t.map(t=>{const e=[];for(const n of t.points)e.push(n.x,n.y);return e})}performTessellation(t,e){const n=function(t){var e=t.windingRule,n=void 0===e?U.ODD:e,i=t.elementType,s=void 0===i?A.POLYGONS:i,r=t.polySize,o=void 0===r?3:r,a=t.vertexSize,h=void 0===a?2:a,l=t.normal,c=void 0===l?[0,0,1]:l,d=t.contours,u=void 0===d?[]:d,f=t.strict,g=void 0===f||f,p=t.debug,y=void 0!==p&&p;if(!u&&g)throw new Error("Contours can't be empty");if(u){for(var m=new $,x=0;x<u.length;x++)m.addContour(h||2,u[x]);return m.tesselate(n,s,o,h,c,g),{vertices:m.vertices,vertexIndices:m.vertexIndices,vertexCount:m.vertexCount,elements:m.elements,elementCount:m.elementCount,mesh:y?m.mesh:void 0}}}({contours:t,windingRule:U.NONZERO,elementType:e,polySize:3,vertexSize:2,strict:!1});return n?.vertices&&n?.elements?n:null}boundaryToContours(t){const e=[];for(let n=0;n<t.elements.length;n+=2){const i=t.elements[n],s=t.elements[n+1],r=[];for(let e=0;e<s;e++){const n=2*(i+e);r.push(t.vertices[n],t.vertices[n+1])}r.length>2&&(r[0]===r[r.length-2]&&r[1]===r[r.length-1]||r.push(r[0],r[1])),e.push(r)}return e}reverseWinding(t){return{...t,points:[...t.points].reverse()}}}class Q{constructor(){}extrude(t,e=0,n){const i=[],s=[],r=[];if(0===e)this.addFlatFaces(t.triangles,i,s,r);else{this.addFrontAndBackFaces(t.triangles,i,s,r,e,n);for(const n of t.contours)this.addSideWalls(n,i,s,r,e)}return{vertices:i,normals:s,indices:r}}addFlatFaces(t,e,n,i){const s=e.length/3,r=t.vertices,o=t.indices;for(let t=0;t<r.length;t+=2)e.push(r[t],r[t+1],0),n.push(0,0,1);for(let t=0;t<o.length;t++)i.push(s+o[t])}addFrontAndBackFaces(t,e,n,i,s,r){const o=e.length/3,a=t.vertices,h=t.indices;for(let t=0;t<a.length;t+=2)e.push(a[t],a[t+1],0),n.push(0,0,-1);const l=25e-6*r,c=s<=l?l:s;for(let t=0;t<a.length;t+=2)e.push(a[t],a[t+1],c),n.push(0,0,1);const d=a.length/2;for(let t=0;t<h.length;t++)i.push(o+h[t]);for(let t=h.length-1;t>=0;t--)i.push(o+h[t]+d)}addSideWalls(t,e,n,i,s){for(let r=0;r<t.length-2;r+=2){const o=t[r],a=t[r+1],h=t[r+2],l=t[r+3],c=new F(h-o,l-a),d=new F(c.y,-c.x).normalize(),u=e.length/3;e.push(o,a,0,h,l,0,o,a,s,h,l,s),n.push(d.x,d.y,0,d.x,d.y,0,d.x,d.y,0,d.x,d.y,0),i.push(u,u+1,u+2,u+1,u+3,u+2)}}}class X{constructor(){}cluster(t,e){return 0===t.length?[]:this.clusterSweepLine(t,e)}clusterSweepLine(t,e){const n=t.length;if(n<=1)return 0===n?[]:[[0]];const i=new Array(n),s=new Array(2*n);let r=0;for(let o=0;o<n;o++)i[o]=this.getWorldBounds(t[o],e[o]),s[r++]=[i[o].minX,0,o],s[r++]=[i[o].maxX,1,o];s.sort((t,e)=>t[0]-e[0]||t[1]-e[1]);const o=Array.from({length:n},(t,e)=>e),a=new Array(n).fill(0);function h(t){return o[t]===t?t:o[t]=h(o[t])}function l(t,e){const n=h(t),i=h(e);n!==i&&(a[n]<a[i]?o[n]=i:a[n]>a[i]?o[i]=n:(o[i]=n,a[n]++))}const c=new Set;for(const[,t,e]of s)if(0===t){const t=i[e];for(const n of c){const s=i[n];t.minY<s.maxY+.001&&t.maxY>s.minY-.001&&l(e,n)}c.add(e)}else c.delete(e);const d=new Map;for(let t=0;t<n;t++){const e=h(t);d.has(e)||d.set(e,[]),d.get(e).push(t)}return Array.from(d.values())}getWorldBounds(t,e){return{minX:t.bounds.min.x+e.x,minY:t.bounds.min.y+e.y,maxX:t.bounds.max.x+e.x,maxY:t.bounds.max.y+e.y}}}class K{constructor(t){this.heap=[],this.itemIndex=new Map,this.compare=t}insert(t){const e=this.itemIndex.get(t);if(void 0!==e)return this.siftUp(e),void this.siftDown(e);const n=this.heap.length;this.heap.push(t),this.itemIndex.set(t,n),this.siftUp(n)}extractMin(){const t=this.heap.length;if(!t)return;if(1===t){const t=this.heap.pop();return this.itemIndex.clear(),t}const e=this.heap[0],n=this.heap.pop();return this.heap[0]=n,this.itemIndex.delete(e),this.itemIndex.set(n,0),this.siftDown(0),e}update(t){const e=this.itemIndex.get(t);void 0!==e?(this.siftUp(e),this.siftDown(e)):this.insert(t)}isEmpty(){return!this.heap.length}swap(t,e){const n=this.heap[t],i=this.heap[e];this.heap[t]=i,this.heap[e]=n,this.itemIndex.set(n,e),this.itemIndex.set(i,t)}siftUp(t){const e=this.heap[t];for(;t>0;){const n=t-1>>1,i=this.heap[n];if(this.compare(e,i)>=0)break;this.heap[t]=i,this.itemIndex.set(i,t),t=n}this.heap[t]=e,this.itemIndex.set(e,t)}siftDown(t){const e=this.heap[t],n=this.heap.length,i=n>>1;for(;t<i;){const i=1+(t<<1),s=i+1;let r=t,o=e;const a=this.heap[i];if(this.compare(a,o)<0&&(r=i,o=a),s<n){const t=this.heap[s];this.compare(t,o)<0&&(r=s,o=t)}if(r===t)break;this.heap[t]=o,this.itemIndex.set(o,t),t=r}this.heap[t]=e,this.itemIndex.set(e,t)}}const Z={enabled:!0,areaThreshold:1,colinearThreshold:.0087,minSegmentLength:10};class J{constructor(t){this.stats={pointsRemovedByVisvalingam:0,pointsRemovedByColinear:0,originalPointCount:0},this.config=t}setConfig(t){this.config=t}optimizePath(t){if(!this.config.enabled||t.points.length<=2)return t;this.stats.originalPointCount+=t.points.length;let e=[...t.points];return e.length<5?t:(e=this.simplifyPathVW(e,this.config.areaThreshold),e.length<3?t:(e=this.removeColinearPoints(e,this.config.colinearThreshold),e.length<3?t:{...t,points:e}))}simplifyPathVW(t,e){if(t.length<=3)return t;const n=t.length,i=t.map((t,e)=>({index:e,area:1/0,prev:null,next:null}));for(let t=0;t<i.length;t++)i[t].prev=i[t-1]||null,i[t].next=i[t+1]||null;const s=new K((t,e)=>t.area-e.area);for(let e=1;e<i.length-1;e++){const n=i[e];n.area=this.calculateTriangleArea(t[n.prev.index],t[n.index],t[n.next.index]),s.insert(n)}let r=n;for(;!s.isEmpty()&&r>3;){const n=s.extractMin();if(!n||n.area>e)break;if(this.config.minSegmentLength>0&&n.prev&&n.next){const e=t[n.prev.index],i=t[n.index],s=t[n.next.index],r=e.distanceTo(i),o=i.distanceTo(s);if(r<this.config.minSegmentLength||o<this.config.minSegmentLength)continue}n.prev&&(n.prev.next=n.next),n.next&&(n.next.prev=n.prev),r--,n.prev&&n.prev.prev&&(n.prev.area=this.calculateTriangleArea(t[n.prev.prev.index],t[n.prev.index],t[n.next.index]),s.update(n.prev)),n.next&&n.next.next&&(n.next.area=this.calculateTriangleArea(t[n.prev.index],t[n.next.index],t[n.next.next.index]),s.update(n.next))}const o=[];let a=i[0];for(;a;)o.push(t[a.index]),a=a.next;const h=n-o.length;return this.stats.pointsRemovedByVisvalingam+=h,o}removeColinearPoints(t,e){if(t.length<=2)return t;const n=[t[0]];for(let i=1;i<t.length-1;i++){const s=t[i-1],r=t[i],o=t[i+1],a=new F(r.x-s.x,r.y-s.y),h=new F(o.x-r.x,o.y-r.y),l=Math.abs(a.angle()-h.angle());Math.min(l,2*Math.PI-l)>e||a.length()<this.config.minSegmentLength||h.length()<this.config.minSegmentLength?n.push(r):this.stats.pointsRemovedByColinear++}return n.push(t[t.length-1]),n}calculateTriangleArea(t,e,n){return Math.abs((t.x*(e.y-n.y)+e.x*(n.y-t.y)+n.x*(t.y-e.y))/2)}getStats(){return{...this.stats}}resetStats(){this.stats={pointsRemovedByVisvalingam:0,pointsRemovedByColinear:0,originalPointCount:0}}}const tt={distanceTolerance:.5,angleTolerance:.2},et=1e-6;class nt{constructor(t){this.curveFidelityConfig={...tt,...t}}setCurveFidelityConfig(t){this.curveFidelityConfig={...tt,...t}}polygonizeQuadratic(t,e,n){const i=[];return this.recursiveQuadratic(t.x,t.y,e.x,e.y,n.x,n.y,i),this.addPoint(n.x,n.y,i),i}polygonizeCubic(t,e,n,i){const s=[];return this.recursiveCubic(t.x,t.y,e.x,e.y,n.x,n.y,i.x,i.y,s),this.addPoint(i.x,i.y,s),s}recursiveQuadratic(t,e,n,i,s,r,o,a=0){if(a>16)return;const h=(t+n)/2,l=(e+i)/2,c=(n+s)/2,d=(i+r)/2,u=(h+c)/2,f=(l+d)/2,g=s-t,p=r-e,y=Math.abs((n-s)*p-(i-r)*g),m=this.curveFidelityConfig.distanceTolerance??tt.distanceTolerance,x=m*m;if(y>et){if(y*y<=x*(g*g+p*p)){const a=this.curveFidelityConfig.angleTolerance??tt.angleTolerance;if(!(a>0))return void this.addPoint(n,i,o);{let h=Math.abs(Math.atan2(r-i,s-n)-Math.atan2(i-e,n-t));if(h>=Math.PI&&(h=2*Math.PI-h),h<a)return void this.addPoint(n,i,o)}}}else{const s=g*g+p*p;if(0===s){if((n-t)*(n-t)+(i-e)*(i-e)<=x)return void this.addPoint(n,i,o)}else{const r=((n-t)*g+(i-e)*p)/s;if(r>0&&r<1&&y*y<=x*s)return void this.addPoint(n,i,o)}}this.recursiveQuadratic(t,e,h,l,u,f,o,a+1),this.recursiveQuadratic(u,f,c,d,s,r,o,a+1)}recursiveCubic(t,e,n,i,s,r,o,a,h,l=0){if(l>16)return;const c=(t+n)/2,d=(e+i)/2,u=(n+s)/2,f=(i+r)/2,g=(s+o)/2,p=(r+a)/2,y=(c+u)/2,m=(d+f)/2,x=(u+g)/2,_=(f+p)/2,v=(y+x)/2,b=(m+_)/2,w=o-t,E=a-e,O=Math.abs((n-o)*E-(i-a)*w),L=Math.abs((s-o)*E-(r-a)*w),S=this.curveFidelityConfig.distanceTolerance??tt.distanceTolerance,P=S*S;let T=0;switch(O>et&&(T|=1),L>et&&(T|=2),T){case 0:const l=w*w+E*E;if(0===l){if((n-t)*(n-t)+(i-e)*(i-e)<=P&&(s-t)*(s-t)+(r-e)*(r-e)<=P)return this.addPoint(n,i,h),void this.addPoint(s,r,h)}else{const o=((n-t)*w+(i-e)*E)/l,a=((s-t)*w+(r-e)*E)/l;if(o>0&&o<1&&a>0&&a<1&&(O+L)*(O+L)<=P*l)return this.addPoint(n,i,h),void this.addPoint(s,r,h)}break;case 1:if(L*L<=P*(w*w+E*E)){const t=this.curveFidelityConfig.angleTolerance??tt.angleTolerance;if(!(t>0))return this.addPoint(n,i,h),void this.addPoint(s,r,h);{let e=Math.abs(Math.atan2(a-r,o-s)-Math.atan2(r-i,s-n));if(e>=Math.PI&&(e=2*Math.PI-e),e<t)return this.addPoint(n,i,h),void this.addPoint(s,r,h)}}break;case 2:if(O*O<=P*(w*w+E*E)){const o=this.curveFidelityConfig.angleTolerance??tt.angleTolerance;if(!(o>0))return this.addPoint(n,i,h),void this.addPoint(s,r,h);{let a=Math.abs(Math.atan2(r-i,s-n)-Math.atan2(i-e,n-t));if(a>=Math.PI&&(a=2*Math.PI-a),a<o)return this.addPoint(n,i,h),void this.addPoint(s,r,h)}}break;case 3:if((O+L)*(O+L)<=P*(w*w+E*E)){const l=this.curveFidelityConfig.angleTolerance??tt.angleTolerance;if(!(l>0))return this.addPoint(n,i,h),void this.addPoint(s,r,h);{let c=Math.abs(Math.atan2(r-i,s-n)-Math.atan2(i-e,n-t)),d=Math.abs(Math.atan2(a-r,o-s)-Math.atan2(r-i,s-n));if(c>=Math.PI&&(c=2*Math.PI-c),d>=Math.PI&&(d=2*Math.PI-d),c+d<l)return this.addPoint(n,i,h),void this.addPoint(s,r,h)}}}this.recursiveCubic(t,e,c,d,y,m,v,b,h,l+1),this.recursiveCubic(v,b,x,_,g,p,o,a,h,l+1)}addPoint(t,e,n){const i=new F(t,e);if(0===n.length)return void n.push(i);const s=n[n.length-1],r=i.x-s.x,o=i.y-s.y;r*r+o*o>1e-12&&n.push(i)}}class it{constructor(t,e){this.currentGlyphId=0,this.currentTextIndex=0,this.currentGlyphPaths=[],this.currentPath=null,this.currentPoint=null,this.currentGlyphBounds={min:new F(1/0,1/0),max:new F(-1/0,-1/0)},this.collectedGlyphs=[],this.glyphPositions=[],this.glyphTextIndices=[],this.currentPosition=new F(0,0),this.polygonizer=new nt(t),this.pathOptimizer=new J({...Z,...e})}setPosition(t,e){this.currentPosition.set(t,e)}updatePosition(t,e){this.currentPosition.x+=t,this.currentPosition.y+=e}beginGlyph(t,e){this.currentGlyphPaths.length>0&&this.finishGlyph(),this.currentGlyphId=t,this.currentTextIndex=e,this.currentGlyphPaths=[],this.currentGlyphBounds.min.set(1/0,1/0),this.currentGlyphBounds.max.set(-1/0,-1/0),this.glyphPositions.push(this.currentPosition.clone())}finishGlyph(){this.currentPath&&this.finishPath(),this.currentGlyphPaths.length>0&&(this.collectedGlyphs.push({glyphId:this.currentGlyphId,paths:[...this.currentGlyphPaths],bounds:{min:{x:this.currentGlyphBounds.min.x,y:this.currentGlyphBounds.min.y},max:{x:this.currentGlyphBounds.max.x,y:this.currentGlyphBounds.max.y}}}),this.glyphTextIndices.push(this.currentTextIndex)),this.currentGlyphPaths=[]}onMoveTo(t,e){this.currentPath&&this.finishPath(),this.currentPoint=new F(t,e),this.updateBounds(this.currentPoint),this.currentPath={points:[this.currentPoint],glyphIndex:this.currentGlyphId}}onLineTo(t,e){if(!this.currentPath||!this.currentPoint)return;const n=new F(t,e);this.updateBounds(n),this.currentPath.points.push(n),this.currentPoint=n}onQuadTo(t,e,n,i){if(!this.currentPath||!this.currentPoint)return;const s=this.currentPoint,r=new F(t,e),o=new F(n,i),a=o.x-s.x,h=o.y-s.y;if(Math.abs((r.x-o.x)*h-(r.y-o.y)*a)<et)return void this.onLineTo(n,i);const l=this.polygonizer.polygonizeQuadratic(s,r,o);for(const t of l)this.updateBounds(t);for(let t=0;t<l.length;t++)this.currentPath.points.push(l[t]);this.currentPoint=o}onCubicTo(t,e,n,i,s,r){if(!this.currentPath||!this.currentPoint)return;const o=this.currentPoint,a=new F(t,e),h=new F(n,i),l=new F(s,r),c=l.x-o.x,d=l.y-o.y,u=Math.abs((a.x-l.x)*d-(a.y-l.y)*c),f=Math.abs((h.x-l.x)*d-(h.y-l.y)*c);if(u<et&&f<et)return void this.onLineTo(s,r);const g=this.polygonizer.polygonizeCubic(o,a,h,l);for(const t of g)this.updateBounds(t);for(let t=0;t<g.length;t++)this.currentPath.points.push(g[t]);this.currentPoint=l}onClosePath(){if(!this.currentPath||!this.currentPoint)return;const t=this.currentPath.points[0];this.currentPoint.equals(t)||this.currentPath.points.push(t),this.finishPath()}finishPath(){if(this.currentPath){const t=this.pathOptimizer.optimizePath(this.currentPath);this.currentGlyphPaths.push(t),this.currentPath=null,this.currentPoint=null}}updateBounds(t){this.currentGlyphBounds.min.x=Math.min(this.currentGlyphBounds.min.x,t.x),this.currentGlyphBounds.min.y=Math.min(this.currentGlyphBounds.min.y,t.y),this.currentGlyphBounds.max.x=Math.max(this.currentGlyphBounds.max.x,t.x),this.currentGlyphBounds.max.y=Math.max(this.currentGlyphBounds.max.y,t.y)}getCollectedGlyphs(){return this.currentGlyphPaths.length>0&&this.finishGlyph(),this.collectedGlyphs}getGlyphPositions(){return this.glyphPositions}getTextIndices(){return this.glyphTextIndices}reset(){this.collectedGlyphs=[],this.glyphPositions=[],this.glyphTextIndices=[],this.currentGlyphPaths=[],this.currentPath=null,this.currentPoint=null,this.currentGlyphId=0,this.currentTextIndex=0,this.currentPosition.set(0,0),this.currentGlyphBounds={min:new F(1/0,1/0),max:new F(-1/0,-1/0)}}setCurveFidelityConfig(t){this.polygonizer.setCurveFidelityConfig(t)}setGeometryOptimization(t){this.pathOptimizer.setConfig({...Z,...t})}getOptimizationStats(){return this.pathOptimizer.getStats()}}class st{constructor(){this.moveTo_func=null,this.lineTo_func=null,this.quadTo_func=null,this.cubicTo_func=null,this.closePath_func=null,this.drawFuncsPtr=0,this.position={x:0,y:0}}setPosition(t,e){this.position.x=t,this.position.y=e,this.collector&&this.collector.setPosition(t,e)}updatePosition(t,e){this.position.x+=t,this.position.y+=e,this.collector&&this.collector.updatePosition(t,e)}createDrawFuncs(t,e){if(!t||!t.module||!t.hb)throw new Error("Invalid font object");if(this.collector=e,this.drawFuncsPtr)return;const n=t.module;this.moveTo_func=n.addFunction((t,e,n,i,s)=>{this.collector?.onMoveTo(i,s)},"viiiffi"),this.lineTo_func=n.addFunction((t,e,n,i,s)=>{this.collector?.onLineTo(i,s)},"viiiffi"),this.quadTo_func=n.addFunction((t,e,n,i,s,r,o)=>{this.collector?.onQuadTo(i,s,r,o)},"viiiffffi"),this.cubicTo_func=n.addFunction((t,e,n,i,s,r,o,a,h)=>{this.collector?.onCubicTo(i,s,r,o,a,h)},"viiiffffffi"),this.closePath_func=n.addFunction((t,e,n)=>{this.collector?.onClosePath()},"viiii"),this.drawFuncsPtr=n.exports.hb_draw_funcs_create(),n.exports.hb_draw_funcs_set_move_to_func(this.drawFuncsPtr,this.moveTo_func,0,0),n.exports.hb_draw_funcs_set_line_to_func(this.drawFuncsPtr,this.lineTo_func,0,0),n.exports.hb_draw_funcs_set_quadratic_to_func(this.drawFuncsPtr,this.quadTo_func,0,0),n.exports.hb_draw_funcs_set_cubic_to_func(this.drawFuncsPtr,this.cubicTo_func,0,0),n.exports.hb_draw_funcs_set_close_path_func(this.drawFuncsPtr,this.closePath_func,0,0)}getDrawFuncsPtr(){if(!this.drawFuncsPtr)throw new Error("Draw functions not initialized");return this.drawFuncsPtr}destroy(t){if(!t||!t.module||!t.hb)return;const n=t.module;try{this.drawFuncsPtr&&(n.exports.hb_draw_funcs_destroy(this.drawFuncsPtr),this.drawFuncsPtr=0),null!==this.moveTo_func&&(n.removeFunction(this.moveTo_func),this.moveTo_func=null),null!==this.lineTo_func&&(n.removeFunction(this.lineTo_func),this.lineTo_func=null),null!==this.quadTo_func&&(n.removeFunction(this.quadTo_func),this.quadTo_func=null),null!==this.cubicTo_func&&(n.removeFunction(this.cubicTo_func),this.cubicTo_func=null),null!==this.closePath_func&&(n.removeFunction(this.closePath_func),this.closePath_func=null)}catch(t){e.warn("Error destroying draw callbacks:",t)}this.collector=void 0}}class rt{constructor(t,e){this.fontId="default",this.wordCache=new Map,this.cache=t,this.loadedFont=e,this.tessellator=new Y,this.extruder=new Q,this.clusterer=new X,this.collector=new it,this.drawCallbacks=new st,this.drawCallbacks.createDrawFuncs(this.loadedFont,this.collector)}getOptimizationStats(){return this.collector.getOptimizationStats()}setCurveFidelityConfig(t){this.collector.setCurveFidelityConfig(t)}setGeometryOptimization(t){this.collector.setGeometryOptimization(t)}setFontId(t){this.fontId=t}buildInstancedGeometry(t,e,i,s,r=!1){n.start("GlyphGeometryBuilder.buildInstancedGeometry",{lineCount:t.length,wordCount:t.flat().length,depth:e,removeOverlaps:i});const o=[],a=[],h=[],l=[],c={min:{x:1/0,y:1/0,z:0},max:{x:-1/0,y:-1/0,z:e}};for(let n=0;n<t.length;n++){const d=t[n];for(const t of d){const n=[];for(const e of t.glyphs)n.push(this.getContoursForGlyph(e.g));const d=t.glyphs.map(t=>new I(t.x,t.y,0)),u=this.clusterer.cluster(n,d);if(!r&&u.some(t=>t.length>1)){const r=`${this.fontId}_${t.text}_${e}_${i}`;let d=this.wordCache.get(r);if(!d){const i=[];for(let e=0;e<n.length;e++){const s=n[e],r=t.glyphs[e];for(const t of s.paths)i.push({...t,points:t.points.map(t=>new F(t.x+(r.x??0),t.y+(r.y??0)))})}d=this.tessellateGlyphCluster(i,e,s),this.wordCache.set(r,d)}const u=o.length/3;this.appendGeometry(o,a,h,d,t.position,u);const f=d.vertices.length/3;for(let i=0;i<t.glyphs.length;i++){const s=t.glyphs[i],r=n[i],o=new I(t.position.x+(s.x??0),t.position.y+(s.y??0),t.position.z),a=this.createGlyphInfo(s,u,f,o,r,e);l.push(a),this.updatePlaneBounds(a.bounds,c)}}else for(let r=0;r<t.glyphs.length;r++){const d=t.glyphs[r],u=n[r],f=new I(t.position.x+(d.x??0),t.position.y+(d.y??0),t.position.z);if(0===u.paths.length){const t=this.createGlyphInfo(d,0,0,f,u,e);l.push(t);continue}let g=this.cache.get(this.fontId,d.g,e,i);g||(g=this.tessellateGlyph(u,e,i,s),this.cache.set(this.fontId,d.g,e,i,g));const p=o.length/3;this.appendGeometry(o,a,h,g,f,p);const y=this.createGlyphInfo(d,p,g.vertices.length/3,f,u,e);l.push(y),this.updatePlaneBounds(y.bounds,c)}}}const d=new Float32Array(o),u=new Float32Array(a),f=new Uint32Array(h);return n.end("GlyphGeometryBuilder.buildInstancedGeometry"),{vertices:d,normals:u,indices:f,glyphInfos:l,planeBounds:c}}appendGeometry(t,e,n,i,s,r){for(let e=0;e<i.vertices.length;e+=3)t.push(i.vertices[e]+s.x,i.vertices[e+1]+s.y,i.vertices[e+2]+s.z);for(let t=0;t<i.normals.length;t++)e.push(i.normals[t]);for(let t=0;t<i.indices.length;t++)n.push(i.indices[t]+r)}createGlyphInfo(t,e,n,i,s,r){return{textIndex:t.absoluteTextIndex,lineIndex:t.lineIndex,vertexStart:e,vertexCount:n,bounds:{min:{x:s.bounds.min.x+i.x,y:s.bounds.min.y+i.y,z:i.z},max:{x:s.bounds.max.x+i.x,y:s.bounds.max.y+i.y,z:i.z+r}}}}getContoursForGlyph(t){this.collector.reset(),this.collector.beginGlyph(t,0),this.loadedFont.module.exports.hb_font_draw_glyph(this.loadedFont.font.ptr,t,this.drawCallbacks.getDrawFuncsPtr(),0),this.collector.finishGlyph();const e=this.collector.getCollectedGlyphs()[0];return e||{glyphId:t,paths:[],bounds:{min:{x:0,y:0},max:{x:0,y:0}}}}tessellateGlyphCluster(t,e,n){const i=this.tessellator.process(t,!0,n);return this.extrudeAndPackage(i,e)}extrudeAndPackage(t,e){const n=this.extruder.extrude(t,e,this.loadedFont.upem),i=n.vertices;let s=1/0,r=1/0,o=1/0,a=-1/0,h=-1/0,l=-1/0;for(let t=0;t<i.length;t+=3){const e=i[t],n=i[t+1],c=i[t+2];e<s&&(s=e),e>a&&(a=e),n<r&&(r=n),n>h&&(h=n),c<o&&(o=c),c>l&&(l=c)}const c=new I(s,r,o),d=new I(a,h,l),u=n.vertices.length/3<65536?Uint16Array:Uint32Array;return{geometry:t,vertices:new Float32Array(n.vertices),normals:new Float32Array(n.normals),indices:new u(n.indices),bounds:{min:c,max:d},useCount:1}}tessellateGlyph(t,e,i,s){n.start("GlyphGeometryBuilder.tessellateGlyph",{glyphId:t.glyphId,pathCount:t.paths.length});const r=this.tessellator.process(t.paths,i,s);return this.extrudeAndPackage(r,e)}updatePlaneBounds(t,e){const n=new C(new I(e.min.x,e.min.y,e.min.z),new I(e.max.x,e.max.y,e.max.z)),i=new C(new I(t.min.x,t.min.y,t.min.z),new I(t.max.x,t.max.y,t.max.z));n.union(i),e.min.x=n.min.x,e.min.y=n.min.y,e.min.z=n.min.z,e.max.x=n.max.x,e.max.y=n.max.y,e.max.z=n.max.z}getCacheStats(){return this.cache.getStats()}clearCache(){this.cache.clear(),this.wordCache.clear()}}class ot{constructor(t,e){this.cachedSpaceWidth=new Map,this.loadedFont=t,this.geometryBuilder=e}shapeLines(t,e,i,s,r,o,a){n.start("TextShaper.shapeLines",{lineCount:t.length});const h=new Set;if(o&&"object"==typeof o&&"byText"in o&&o.byText&&a)for(const t of Object.keys(o.byText)){let e=0;for(;-1!==(e=a.indexOf(t,e));)h.add(e),h.add(e+t.length),e+=t.length}const l=[];return t.forEach((t,n)=>{const o=this.shapeLineIntoClusters(t,n,e,i,s,r,h);l.push(o)}),l}shapeLineIntoClusters(t,e,n,i,s,r,o){const a=this.loadedFont.hb.createBuffer();"rtl"===r&&a.setDirection("rtl"),a.addText(t.text),a.guessSegmentProperties(),this.loadedFont.hb.shape(this.loadedFont.font,a);const h=a.json(this.loadedFont.font);a.destroy();const l=[];let c=[],d="",u=new I,f=new I(t.xOffset,-e*n,0);const g=i*this.loadedFont.upem,p=this.calculateSpaceAdjustment(t,s,i);for(let n=0;n<h.length;n++){const i=h[n],s=/\s/.test(t.text[i.cl]);t.endedWithHyphen&&i.cl===t.text.length-1&&"-"===t.text[i.cl]?i.absoluteTextIndex=t.originalEnd:i.absoluteTextIndex=t.originalStart+i.cl,i.lineIndex=e;const r=o.has(i.absoluteTextIndex);(s||r)&&c.length>0&&(l.push({text:d,glyphs:c,position:u.clone()}),c=[],d="");const a=f.clone().add(new I(i.dx,i.dy,0));s||(0===c.length&&u.copy(a),i.x=a.x-u.x,i.y=a.y-u.y,c.push(i),d+=t.text[i.cl]),f.x+=i.ax,f.y+=i.ay,0!==g&&n<h.length-1&&(f.x+=g),s&&(f.x+=p)}return c.length>0&&l.push({text:d,glyphs:c,position:u.clone()}),l}calculateSpaceAdjustment(t,e,n){let i=0;if(void 0!==t.adjustmentRatio&&"justify"===e&&!t.isLastLine){let e=this.cachedSpaceWidth.get(n);void 0===e&&(e=v.measureTextWidth(this.loadedFont," ",n),this.cachedSpaceWidth.set(n,e));const s=.5,r=o;t.adjustmentRatio>0?i=t.adjustmentRatio*e*s:t.adjustmentRatio<0&&(i=t.adjustmentRatio*e*r)}return i}clearCache(){this.geometryBuilder.clearCache()}getCacheStats(){return this.geometryBuilder.getCacheStats()}}class at{constructor(t){this.cache=new Map,this.head=null,this.tail=null,this.stats={hits:0,misses:0,totalGlyphs:0,uniqueGlyphs:0,cacheSize:0,saved:0,memoryUsage:0},t&&(this.maxCacheSize=1024*t*1024)}getCacheKey(t,e,n,i){return`${t}_${e}_${Math.round(1e3*n)/1e3}_${i}`}has(t,e,n,i){const s=this.getCacheKey(t,e,n,i);return this.cache.has(s)}get(t,e,n,i){const s=this.getCacheKey(t,e,n,i),r=this.cache.get(s);return r?(this.stats.hits++,this.stats.saved++,r.data.useCount++,this.moveToHead(r),this.stats.totalGlyphs++,r.data):(this.stats.misses++,void this.stats.totalGlyphs++)}set(t,e,n,i,s){const r=this.getCacheKey(t,e,n,i),o=this.calculateMemoryUsage(s);this.maxCacheSize&&this.stats.memoryUsage+o>this.maxCacheSize&&this.evictLRU(o);const a={key:r,data:s,prev:null,next:null};this.cache.set(r,a),this.addToHead(a),this.stats.uniqueGlyphs=this.cache.size,this.stats.cacheSize++,this.stats.memoryUsage+=o}calculateMemoryUsage(t){let e=0;return e+=4*t.vertices.length,e+=4*t.normals.length,e+=t.indices.length*t.indices.BYTES_PER_ELEMENT,e+=24,e+=256,e}evictLRU(t){let e=0;for(;this.tail&&e<t;){const t=this.calculateMemoryUsage(this.tail.data),n=this.tail;this.removeTail(),this.cache.delete(n.key),this.stats.memoryUsage-=t,this.stats.cacheSize--,e+=t}}addToHead(t){this.head?(t.next=this.head,this.head.prev=t,this.head=t):this.head=this.tail=t}removeNode(t){t.prev?t.prev.next=t.next:this.head=t.next,t.next?t.next.prev=t.prev:this.tail=t.prev}removeTail(){this.tail&&this.removeNode(this.tail)}moveToHead(t){t!==this.head&&(this.removeNode(t),this.addToHead(t))}clear(){this.cache.clear(),this.head=null,this.tail=null,this.stats={hits:0,misses:0,totalGlyphs:0,uniqueGlyphs:0,cacheSize:0,saved:0,memoryUsage:0}}getStats(){const t=this.stats.totalGlyphs>0?this.stats.hits/this.stats.totalGlyphs*100:0;return this.stats.uniqueGlyphs=this.cache.size,{...this.stats,hitRate:t,memoryUsageMB:this.stats.memoryUsage/1048576}}}const ht=new at(250);function lt(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}function ct(t){if(t.__esModule)return t;var e=t.default;if("function"==typeof e){var n=function t(){return this instanceof t?Reflect.construct(e,arguments,this.constructor):e.apply(this,arguments)};n.prototype=e.prototype}else n={};return Object.defineProperty(n,"__esModule",{value:!0}),Object.keys(t).forEach(function(e){var i=Object.getOwnPropertyDescriptor(t,e);Object.defineProperty(n,e,i.get?i:{enumerable:!0,get:function(){return t[e]}})}),n}var dt={exports:{}};var ut=ct(Object.freeze({__proto__:null,default:{},readFileSync:()=>{throw new Error("fs not available in browser")}}));!function(t){var e,n=(e="undefined"!=typeof document?document.currentScript?.src:void 0,async function(t={}){var n=t,i="object"==typeof window,s="undefined"!=typeof WorkerGlobalScope,r="object"==typeof process&&process.versions?.node&&"renderer"!=process.type,o=(t,e)=>{throw e};"undefined"!=typeof __filename?e=__filename:s&&(e=self.location.href);var a,h,l="";if(r){var c=ut;l=__dirname+"/",h=t=>(t=_(t)?new URL(t):t,c.readFileSync(t)),a=async(t,e=!0)=>(t=_(t)?new URL(t):t,c.readFileSync(t,e?void 0:"utf8")),process.argv.length>1&&process.argv[1].replace(/\\/g,"/"),process.argv.slice(2),o=(t,e)=>{throw process.exitCode=t,e}}else if(i||s){try{l=new URL(".",e).href}catch{}s&&(h=t=>{var e=new XMLHttpRequest;return e.open("GET",t,!1),e.responseType="arraybuffer",e.send(null),new Uint8Array(e.response)}),a=async t=>{if(_(t))return new Promise((e,n)=>{var i=new XMLHttpRequest;i.open("GET",t,!0),i.responseType="arraybuffer",i.onload=()=>{200==i.status||0==i.status&&i.response?e(i.response):n(i.status)},i.onerror=n,i.send(null)});var e=await fetch(t,{credentials:"same-origin"});if(e.ok)return e.arrayBuffer();throw new Error(e.status+" : "+e.url)}}console.log.bind(console);var d,u,f,g,p,y,m=console.error.bind(console),x=!1,_=t=>t.startsWith("file://"),v=!1;function b(){var t=p.buffer;n.HEAP8=new Int8Array(t),n.HEAPU8=y=new Uint8Array(t),n.HEAP32=new Int32Array(t),n.HEAPU32=new Uint32Array(t),n.HEAPF32=new Float32Array(t),new BigInt64Array(t),new BigUint64Array(t)}var w,E=0,O=null;function L(t){n.onAbort?.(t),m(t="Aborted("+t+")"),x=!0,t+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(t);throw g?.(e),e}function S(){return t="hb.wasm",n.locateFile?n.locateFile(t,l):l+t;var t}async function P(t){if(!d)try{var e=await a(t);return new Uint8Array(e)}catch{}return function(t){if(t==w&&d)return new Uint8Array(d);if(h)return h(t);throw"both async and sync fetching of the wasm failed"}(t)}async function T(t,e,n){if(!t&&!_(e)&&!r)try{var i=fetch(e,{credentials:"same-origin"});return await WebAssembly.instantiateStreaming(i,n)}catch(t){m(`wasm streaming compile failed: ${t}`),m("falling back to ArrayBuffer instantiation")}return async function(t,e){try{var n=await P(t);return await WebAssembly.instantiate(n,e)}catch(t){m(`failed to asynchronously prepare wasm: ${t}`),L(t)}}(e,n)}class F{name="ExitStatus";constructor(t){this.message=`Program terminated with exit(${t})`,this.status=t}}var I,C,U,A=t=>{for(;t.length>0;)t.shift()(n)},B=[],R=t=>B.push(t),z=[],D=t=>z.push(t),k=!0,M=0,G={},N=t=>{if(t instanceof F||"unwind"==t)return u;o(1,t)},H=()=>k||M>0,q=t=>{u=t,H()||(n.onExit?.(t),x=!0),o(t,new F(t))},W=(t,e)=>{u=t,q(t)},V=t=>{if(!x)try{t(),(()=>{if(!H())try{W(u)}catch(t){N(t)}})()}catch(t){N(t)}},j=(t,e)=>Math.ceil(t/e)*e,$=t=>{var e=(t-p.buffer.byteLength+65535)/65536|0;try{return p.grow(e),b(),1}catch(t){}},Y=t=>{const e=t.length;return[e%128|128,e>>7,...t]},Q={i:127,p:127,j:126,f:125,d:124,e:111},X=t=>Y(Array.from(t,t=>Q[t])),K=t=>I.get(t),Z=t=>(C||(C=new WeakMap,((t,e)=>{if(C)for(var n=t;n<t+e;n++){var i=K(n);i&&C.set(i,n)}})(0,I.length)),C.get(t)||0),J=[],tt=(t,e)=>I.set(t,e);n.noExitRuntime&&(k=n.noExitRuntime),n.print&&n.print,n.printErr&&(m=n.printErr),n.wasmBinary&&(d=n.wasmBinary),n.arguments&&n.arguments,n.thisProgram&&n.thisProgram,n.wasmMemory=p,n.wasmExports=nt,n.addFunction=(t,e)=>{var n=Z(t);if(n)return n;var i=J.length?J.pop():I.grow(1);try{tt(i,t)}catch(n){if(!(n instanceof TypeError))throw n;var s=((t,e)=>{var n=Uint8Array.of(0,97,115,109,1,0,0,0,1,...Y([1,96,...X(e.slice(1)),...X("v"===e[0]?"":e[0])]),2,7,1,1,101,1,102,0,0,7,5,1,1,102,0,0),i=new WebAssembly.Module(n);return new WebAssembly.Instance(i,{e:{f:t}}).exports.f})(t,e);tt(i,s)}return C.set(t,i),i},n.removeFunction=t=>{C.delete(K(t)),tt(t,null),J.push(t)};var et={_abort_js:()=>L(""),_emscripten_runtime_keepalive_clear:()=>{k=!1,M=0},_setitimer_js:(t,e)=>{if(G[t]&&(clearTimeout(G[t].id),delete G[t]),!e)return 0;var n=setTimeout(()=>{delete G[t],V(()=>U(t,performance.now()))},e);return G[t]={id:n,timeout_ms:e},0},emscripten_resize_heap:t=>{var e=y.length,n=2147483648;if((t>>>=0)>n)return!1;for(var i=1;i<=4;i*=2){var s=e*(1+.2/i);s=Math.min(s,t+100663296);var r=Math.min(n,j(Math.max(t,s),65536));if($(r))return!0}return!1},proc_exit:q},nt=await async function(){function t(t,e){return nt=t.exports,n.wasmExports=nt,p=nt.memory,n.wasmMemory=p,b(),I=nt.__indirect_function_table,function(t){n._hb_blob_create=t.hb_blob_create,n._hb_blob_destroy=t.hb_blob_destroy,n._hb_blob_get_length=t.hb_blob_get_length,n._hb_blob_get_data=t.hb_blob_get_data,n._hb_buffer_serialize_glyphs=t.hb_buffer_serialize_glyphs,n._hb_buffer_create=t.hb_buffer_create,n._hb_buffer_destroy=t.hb_buffer_destroy,n._hb_buffer_get_content_type=t.hb_buffer_get_content_type,n._hb_buffer_set_direction=t.hb_buffer_set_direction,n._hb_buffer_set_script=t.hb_buffer_set_script,n._hb_buffer_set_language=t.hb_buffer_set_language,n._hb_buffer_set_flags=t.hb_buffer_set_flags,n._hb_buffer_set_cluster_level=t.hb_buffer_set_cluster_level,n._hb_buffer_get_length=t.hb_buffer_get_length,n._hb_buffer_get_glyph_infos=t.hb_buffer_get_glyph_infos,n._hb_buffer_get_glyph_positions=t.hb_buffer_get_glyph_positions,n._hb_glyph_info_get_glyph_flags=t.hb_glyph_info_get_glyph_flags,n._hb_buffer_guess_segment_properties=t.hb_buffer_guess_segment_properties,n._hb_buffer_add_utf8=t.hb_buffer_add_utf8,n._hb_buffer_add_utf16=t.hb_buffer_add_utf16,n._hb_buffer_set_message_func=t.hb_buffer_set_message_func,n._hb_language_from_string=t.hb_language_from_string,n._hb_script_from_string=t.hb_script_from_string,n._hb_version=t.hb_version,n._hb_version_string=t.hb_version_string,n._hb_feature_from_string=t.hb_feature_from_string,n._malloc=t.malloc,n._free=t.free,n._hb_draw_funcs_set_move_to_func=t.hb_draw_funcs_set_move_to_func,n._hb_draw_funcs_set_line_to_func=t.hb_draw_funcs_set_line_to_func,n._hb_draw_funcs_set_quadratic_to_func=t.hb_draw_funcs_set_quadratic_to_func,n._hb_draw_funcs_set_cubic_to_func=t.hb_draw_funcs_set_cubic_to_func,n._hb_draw_funcs_set_close_path_func=t.hb_draw_funcs_set_close_path_func,n._hb_draw_funcs_create=t.hb_draw_funcs_create,n._hb_draw_funcs_destroy=t.hb_draw_funcs_destroy,n._hb_face_create=t.hb_face_create,n._hb_face_destroy=t.hb_face_destroy,n._hb_face_reference_table=t.hb_face_reference_table,n._hb_face_get_upem=t.hb_face_get_upem,n._hb_face_collect_unicodes=t.hb_face_collect_unicodes,n._hb_font_draw_glyph=t.hb_font_draw_glyph,n._hb_font_glyph_to_string=t.hb_font_glyph_to_string,n._hb_font_create=t.hb_font_create,n._hb_font_set_variations=t.hb_font_set_variations,n._hb_font_destroy=t.hb_font_destroy,n._hb_font_set_scale=t.hb_font_set_scale,n._hb_set_create=t.hb_set_create,n._hb_set_destroy=t.hb_set_destroy,n._hb_ot_var_get_axis_infos=t.hb_ot_var_get_axis_infos,n._hb_set_get_population=t.hb_set_get_population,n._hb_set_next_many=t.hb_set_next_many,n._hb_shape=t.hb_shape,U=t._emscripten_timeout}(nt),function(){if(E--,n.monitorRunDependencies?.(E),0==E&&O){var t=O;O=null,t()}}(),nt}E++,n.monitorRunDependencies?.(E);var e={env:et,wasi_snapshot_preview1:et};if(n.instantiateWasm)return new Promise((i,s)=>{n.instantiateWasm(e,(e,n)=>{i(t(e))})});w??=S();var i=function(e){return t(e.instance)}(await T(d,w,e));return i}();return function(){if(n.preInit)for("function"==typeof n.preInit&&(n.preInit=[n.preInit]);n.preInit.length>0;)n.preInit.shift()()}(),function t(){function e(){n.calledRun=!0,x||(v=!0,nt.__wasm_call_ctors(),f?.(n),n.onRuntimeInitialized?.(),function(){if(n.postRun)for("function"==typeof n.postRun&&(n.postRun=[n.postRun]);n.postRun.length;)R(n.postRun.shift());A(B)}())}E>0?O=t:(function(){if(n.preRun)for("function"==typeof n.preRun&&(n.preRun=[n.preRun]);n.preRun.length;)D(n.preRun.shift());A(z)}(),E>0?O=t:n.setStatus?(n.setStatus("Running..."),setTimeout(()=>{setTimeout(()=>n.setStatus(""),1),e()},1)):e())}(),v?n:new Promise((t,e)=>{f=t,g=e})});t.exports=n,t.exports.default=n}(dt);var ft=lt(dt.exports),gt={exports:{}};try{gt.exports=function(t){var e=t.wasmExports,n=new TextDecoder("utf8");let i=t.addFunction,s=t.removeFunction;var r=i(function(t){e.free(t)},"vi");function o(t){return(255&t.charCodeAt(0))<<24|(255&t.charCodeAt(1))<<16|(255&t.charCodeAt(2))<<8|255&t.charCodeAt(3)}var a=o("JSON"),h="",l=e.malloc(256);function c(n){var i=e.malloc(n.length+1);for(let e=0;e<n.length;++e){const s=n.charCodeAt(e);if(s>127)throw new Error("Expected ASCII text");t.HEAPU8[i+e]=s}return t.HEAPU8[i+n.length]=0,{ptr:i,length:n.length,free:function(){e.free(i)}}}function d(t,n,i){var s=0,r=0;i&&(i=i.split(","),s=e.malloc(16*i.length),i.forEach(function(t,n){var i=c(t);e.hb_feature_from_string(i.ptr,-1,s+16*r)&&r++,i.free()})),e.hb_shape(t.ptr,n.ptr,s,r),s&&e.free(s)}return{createBlob:function(n){var i=e.malloc(n.byteLength);t.HEAPU8.set(new Uint8Array(n),i);var s=e.hb_blob_create(i,n.byteLength,2,i,r);return{ptr:s,destroy:function(){e.hb_blob_destroy(s)}}},createFace:function(n,i){var s=e.hb_face_create(n.ptr,i);const r=e.hb_face_get_upem(s);return{ptr:s,upem:r,reference_table:function(n){var i=e.hb_face_reference_table(s,o(n)),r=e.hb_blob_get_length(i);if(r){var a=e.hb_blob_get_data(i,null);return t.HEAPU8.subarray(a,a+r)}},getAxisInfos:function(){var n=e.malloc(2048),i=e.malloc(4);t.HEAPU32[i/4]=64,e.hb_ot_var_get_axis_infos(s,0,i,n);var r={};return Array.from({length:t.HEAPU32[i/4]}).forEach(function(e,i){var s;r[(s=t.HEAPU32[n/4+8*i+1],[String.fromCharCode(s>>24&255),String.fromCharCode(s>>16&255),String.fromCharCode(s>>8&255),String.fromCharCode(255&s)].join(""))]={min:t.HEAPF32[n/4+8*i+4],default:t.HEAPF32[n/4+8*i+5],max:t.HEAPF32[n/4+8*i+6]}}),e.free(i),e.free(n),r},collectUnicodes:function(){var n=e.hb_set_create();e.hb_face_collect_unicodes(s,n);var i=function(n){const i=e.hb_set_get_population(n),s=e.malloc(i<<2),r=s>>2,o=t.HEAPU32.subarray(r,r+i);return t.HEAPU32.set(o,r),e.hb_set_next_many(n,-1,s,i),o}(n);return e.hb_set_destroy(n),i},destroy:function(){e.hb_face_destroy(s)}}},createFont:function(r){var a=e.hb_font_create(r.ptr),c=null,d=null,u=null,f=null,g=null,p=null;function y(t){return c||(d=i(function(t,e,n,i,s,r){h+=`M${i},${s}`},"viiiffi"),u=i(function(t,e,n,i,s,r){h+=`L${i},${s}`},"viiiffi"),f=i(function(t,e,n,i,s,r,o,a,l,c){h+=`C${i},${s} ${r},${o} ${a},${l}`},"viiiffffffi"),g=i(function(t,e,n,i,s,r,o,a){h+=`Q${i},${s} ${r},${o}`},"viiiffffi"),p=i(function(t,e,n,i){h+="Z"},"viiii"),c=e.hb_draw_funcs_create(),e.hb_draw_funcs_set_move_to_func(c,d,0,0),e.hb_draw_funcs_set_line_to_func(c,u,0,0),e.hb_draw_funcs_set_cubic_to_func(c,f,0,0),e.hb_draw_funcs_set_quadratic_to_func(c,g,0,0),e.hb_draw_funcs_set_close_path_func(c,p,0,0)),h="",e.hb_font_draw_glyph(a,t,c,0),h}return{ptr:a,glyphName:function(i){e.hb_font_glyph_to_string(a,i,l,256);var s=t.HEAPU8.subarray(l,l+256);return n.decode(s.slice(0,s.indexOf(0)))},glyphToPath:y,glyphToJson:function(t){return y(t).replace(/([MLQCZ])/g,"|$1 ").split("|").filter(function(t){return t.length}).map(function(t){var e=t.split(/[ ,]/g);return{type:e[0],values:e.slice(1).filter(function(t){return t.length}).map(function(t){return+t})}})},setScale:function(t,n){e.hb_font_set_scale(a,t,n)},setVariations:function(n){var i=Object.entries(n),s=e.malloc(8*i.length);i.forEach(function(e,n){t.HEAPU32[s/4+2*n+0]=o(e[0]),t.HEAPF32[s/4+2*n+1]=e[1]}),e.hb_font_set_variations(a,s,i.length),e.free(s)},destroy:function(){e.hb_font_destroy(a),c&&(e.hb_draw_funcs_destroy(c),c=null,s(d),s(u),s(f),s(g),s(p))}}},createBuffer:function(){var n=e.hb_buffer_create();return{ptr:n,addText:function(i){const s=function(n){const i=e.malloc(2*n.length),s=new Uint16Array(t.wasmMemory.buffer,i,n.length);for(let t=0;t<s.length;++t)s[t]=n.charCodeAt(t);return{ptr:i,length:s.length,free:function(){e.free(i)}}}(i);e.hb_buffer_add_utf16(n,s.ptr,s.length,0,s.length),s.free()},guessSegmentProperties:function(){return e.hb_buffer_guess_segment_properties(n)},setDirection:function(t){e.hb_buffer_set_direction(n,{ltr:4,rtl:5,ttb:6,btt:7}[t]||0)},setFlags:function(t){var i=0;t.forEach(function(t){i|=function(t){return"BOT"==t?1:"EOT"==t?2:"PRESERVE_DEFAULT_IGNORABLES"==t?4:"REMOVE_DEFAULT_IGNORABLES"==t?8:"DO_NOT_INSERT_DOTTED_CIRCLE"==t?16:"PRODUCE_UNSAFE_TO_CONCAT"==t?64:0}(t)}),e.hb_buffer_set_flags(n,i)},setLanguage:function(t){var i=c(t);e.hb_buffer_set_language(n,e.hb_language_from_string(i.ptr,-1)),i.free()},setScript:function(t){var i=c(t);e.hb_buffer_set_script(n,e.hb_script_from_string(i.ptr,-1)),i.free()},setClusterLevel:function(t){e.hb_buffer_set_cluster_level(n,t)},json:function(){for(var i=e.hb_buffer_get_length(n),s=[],r=e.hb_buffer_get_glyph_infos(n,0),o=r/4,a=e.hb_buffer_get_glyph_positions(n,0)/4,h=t.HEAPU32.subarray(o,o+5*i),l=t.HEAP32.subarray(a,a+5*i),c=0;c<i;++c)s.push({g:h[5*c+0],cl:h[5*c+2],ax:l[5*c+0],ay:l[5*c+1],dx:l[5*c+2],dy:l[5*c+3],flags:e.hb_glyph_info_get_glyph_flags(r+20*c)});return s},destroy:function(){e.hb_buffer_destroy(n)}}},shape:d,shapeWithTrace:function(r,o,h,l,c){var u=[],f=0,g=!1,p=1048576,y=e.malloc(p),m=i(function(i,s,r,o){var h=n.decode(t.HEAPU8.subarray(r,t.HEAPU8.indexOf(0,r)));return h.startsWith("start table GSUB")?f=1:h.startsWith("start table GPOS")&&(f=2),f!=c&&(g=!1),0!=c&&f==c&&h.startsWith("end lookup "+l)&&(g=!0),g?0:(e.hb_buffer_serialize_glyphs(i,0,e.hb_buffer_get_length(i),y,p,0,s,a,4),u.push({m:h,t:JSON.parse(n.decode(t.HEAPU8.subarray(y,t.HEAPU8.indexOf(0,y)))),glyphs:2==e.hb_buffer_get_content_type(i)}),1)},"iiiii");return e.hb_buffer_set_message_func(o.ptr,m,0,0),d(r,o,h),e.free(y),s(m),u},version:function(){var n=e.malloc(12);e.hb_version(n,n+4,n+8);var i={major:t.HEAPU32[n/4],minor:t.HEAPU32[(n+4)/4],micro:t.HEAPU32[(n+8)/4]};return e.free(n),i},version_string:function(){var i=e.hb_version_string();return n.decode(t.HEAPU8.subarray(i,t.HEAPU8.indexOf(0,i)))}}}}catch(t){}var pt=lt(gt.exports);let yt=null,mt=null,xt=null;const _t={setWasmPath(t){mt=t,xt=null,yt=null},setWasmBuffer(t){xt=t,mt=null,yt=null},getHarfBuzz:async()=>yt||(yt=new Promise(async(t,e)=>{try{const e={};if(xt)e.wasmBinary=xt;else{if(!mt)throw new Error("HarfBuzz WASM path or buffer must be set before initialization.");e.locateFile=(t,e)=>t.endsWith(".wasm")?mt:e+t}const n=await ft(e),i=pt(n);t({hb:i,module:{addFunction:n.addFunction,exports:n.wasmExports,removeFunction:n.removeFunction}})}catch(t){e(new Error(`Failed to initialize HarfBuzz: ${t}`))}}),yt)};class vt{constructor(t,e){this.text=t,this.glyphsByTextIndex=new Map,e.forEach(t=>{const e=this.glyphsByTextIndex.get(t.textIndex)||[];e.push(t),this.glyphsByTextIndex.set(t.textIndex,e)})}execute(t){const e=[];return t.byText&&e.push(...this.findByText(t.byText)),t.byCharRange&&e.push(...this.findByCharRange(t.byCharRange)),e}findByText(t){const e=[];for(const n of t){let t=0;for(;-1!==(t=this.text.indexOf(n,t));)e.push(this.createTextRange(t,t+n.length,n)),t+=n.length}return e}findByCharRange(t){return t.map(t=>{const e=this.text.slice(t.start,t.end);return this.createTextRange(t.start,t.end,e)})}createTextRange(t,e,n){const i=[],s=new Map;for(let n=t;n<e;n++){const t=this.glyphsByTextIndex.get(n);if(t)for(const e of t){i.push(e);const t=s.get(e.lineIndex)||[];t.push(e),s.set(e.lineIndex,t)}}return{start:t,end:e,originalText:n,bounds:Array.from(s.values()).map(t=>this.calculateBounds(t)),glyphs:i,lineIndices:Array.from(s.keys()).sort((t,e)=>t-e)}}calculateBounds(t){if(0===t.length)return{min:{x:0,y:0,z:0},max:{x:0,y:0,z:0}};const e=new C;for(const n of t){const t=new C(new I(n.bounds.min.x,n.bounds.min.y,n.bounds.min.z),new I(n.bounds.max.x,n.bounds.max.y,n.bounds.max.z));e.union(t)}return{min:{x:e.min.x,y:e.min.y,z:e.min.z},max:{x:e.max.x,y:e.max.y,z:e.max.z}}}}class bt{static{this.patternCache=new Map}static{this.hbInitPromise=null}static{this.fontCache=new Map}static{this.fontIdCounter=0}constructor(t){this.currentFontId="",bt.hbInitPromise||(bt.hbInitPromise=_t.getHarfBuzz()),this.fontLoader=new P(()=>bt.hbInitPromise)}static setHarfBuzzPath(t){_t.setWasmPath(t),bt.hbInitPromise=null}static setHarfBuzzBuffer(t){_t.setWasmBuffer(t),bt.hbInitPromise=null}static init(){return bt.hbInitPromise||(bt.hbInitPromise=_t.getHarfBuzz()),bt.hbInitPromise}static async create(t){if(!t.font)throw new Error("Font is required. Specify options.font as a URL string or ArrayBuffer.");bt.hbInitPromise||(bt.hbInitPromise=_t.getHarfBuzz());const e="string"==typeof t.font?t.font:`buffer-${bt.generateFontContentHash(t.font)}`,n=t.fontVariations?`${e}_${JSON.stringify(t.fontVariations)}`:e;let i=bt.fontCache.get(n);i||(i=await bt.loadAndCacheFont(n,t.font,t.fontVariations));const s=new bt({maxCacheSizeMB:t.maxCacheSizeMB});s.setLoadedFont(i);const{font:r,maxCacheSizeMB:o,...a}=t;return{...await s.createGeometry(a),getLoadedFont:()=>s.getLoadedFont(),getCacheStatistics:()=>s.getCacheStatistics(),clearCache:()=>s.clearCache(),measureTextWidth:(t,e)=>s.measureTextWidth(t,e)}}static async loadAndCacheFont(t,e,n){const i=new bt;await i.loadFont(e,n);const s=i.getLoadedFont();return bt.fontCache.set(t,s),s}static generateFontContentHash(t){if(t){const e=new Uint8Array(t);return`${e[0]}_${e[Math.floor(e.length/2)]}_${e[e.length-1]}_${e.length}`}return""+ ++bt.fontIdCounter}setLoadedFont(t){this.loadedFont=t;const e=bt.generateFontContentHash(t._buffer);this.currentFontId=`font_${e}`,t.fontVariations&&(this.currentFontId+=`_${JSON.stringify(t.fontVariations)}`)}async loadFont(t,i){n.start("Text.loadFont",{fontSrc:"string"==typeof t?t:`buffer(${t.byteLength})`}),bt.hbInitPromise||(bt.hbInitPromise=_t.getHarfBuzz()),await bt.hbInitPromise;const s="string"==typeof t?await fetch(t).then(e=>{if(!e.ok)throw new Error(`Failed to load font from ${t}: HTTP ${e.status} ${e.statusText}`);return e.arrayBuffer()}):t;try{this.loadedFont&&this.destroy(),this.loadedFont=await this.fontLoader.loadFont(s,i);const t=bt.generateFontContentHash(s);this.currentFontId=`font_${t}`,i&&(this.currentFontId+=`_${JSON.stringify(i)}`)}catch(t){throw e.error("Failed to load font:",t),t}finally{n.end("Text.loadFont")}}async createGeometry(t){n.start("Text.createGeometry",{textLength:t.text.length,size:t.size||72,hasLayout:!!t.layout,mode:"cached"});try{if(!this.loadedFont)throw new Error("Font not loaded. Use Text.create() with a font option.");const e=await this.prepareHyphenation(t);if(this.validateOptions(e),t=e,this.updateFontVariations(t),!this.geometryBuilder){const e=t.maxCacheSizeMB?new at(t.maxCacheSizeMB):ht;this.geometryBuilder=new rt(e,this.loadedFont),this.geometryBuilder.setFontId(this.currentFontId)}this.geometryBuilder.setCurveFidelityConfig(t.curveFidelity),this.geometryBuilder.setGeometryOptimization(t.geometryOptimization),this.loadedFont.font.setScale(this.loadedFont.upem,this.loadedFont.upem),this.textShaper||(this.textShaper=new ot(this.loadedFont,this.geometryBuilder));const n=this.prepareLayout(t),i=t.removeOverlaps??this.loadedFont.isVariable??!1,s=this.textShaper.shapeLines(n.lines,n.scaledLineHeight,n.letterSpacing,n.align,n.direction,t.color,t.text),r=this.geometryBuilder.buildInstancedGeometry(s,n.depth,i,this.loadedFont.metrics.isCFF,t.separateGlyphsWithAttributes||!1),o=this.geometryBuilder.getCacheStats(),a=this.finalizeGeometry(r.vertices,r.normals,r.indices,r.glyphInfos,r.planeBounds,t,o,t.text);if(t.separateGlyphsWithAttributes){const t=this.createGlyphAttributes(a.vertices.length/3,a.glyphs);a.glyphAttributes=t}return a}finally{n.end("Text.createGeometry")}}async prepareHyphenation(t){if(!1!==t.layout?.hyphenate&&t.layout?.width){const n=t.layout?.language||"en-us";if(!t.layout?.hyphenationPatterns?.[n])try{if(!bt.patternCache.has(n)){const e=await T(n,t.layout?.patternsPath);bt.patternCache.set(n,e)}return{...t,layout:{...t.layout,hyphenationPatterns:{...t.layout?.hyphenationPatterns,[n]:bt.patternCache.get(n)}}}}catch(i){return e.warn(`Failed to load patterns for ${n}: ${i}`),{...t,layout:{...t.layout,hyphenate:!1}}}}return t}validateOptions(t){if(!t.text)throw new Error("Text content is required");const e=t.maxTextLength??1e5;if(t.text.length>e)throw new Error(`Text exceeds ${e} character limit`)}updateFontVariations(t){t.fontVariations&&this.loadedFont&&JSON.stringify(t.fontVariations)!==JSON.stringify(this.loadedFont.fontVariations)&&(this.loadedFont.font.setVariations(t.fontVariations),this.loadedFont.fontVariations=t.fontVariations)}prepareLayout(t){if(!this.loadedFont)throw new Error("Font not loaded. Use Text.create() with a font option");const{text:e,size:n=72,depth:o=0,lineHeight:a=1,letterSpacing:h=0,layout:l={}}=t,{width:c,direction:d="ltr",align:u=("rtl"===d?"right":"left"),respectExistingBreaks:f=!0,hyphenate:g=!0,language:p="en-us",tolerance:y=i,pretolerance:m=s,emergencyStretch:x=r,autoEmergencyStretch:_,hyphenationPatterns:v,lefthyphenmin:w,righthyphenmin:E,linepenalty:O,adjdemerits:S,hyphenpenalty:P,exhyphenpenalty:T,doublehyphendemerits:F,looseness:I,disableSingleWordDetection:C}=l;let U;void 0!==c&&(U=c*(this.loadedFont.upem/n));const A=o*(this.loadedFont.upem/n);this.textLayout||(this.textLayout=new b(this.loadedFont));const B=this.textLayout.computeLines({text:e,width:U,align:u,direction:d,hyphenate:g,language:p,respectExistingBreaks:f,tolerance:y,pretolerance:m,emergencyStretch:x,autoEmergencyStretch:_,hyphenationPatterns:v,lefthyphenmin:w,righthyphenmin:E,linepenalty:O,adjdemerits:S,hyphenpenalty:P,exhyphenpenalty:T,doublehyphendemerits:F,looseness:I,disableSingleWordDetection:C,letterSpacing:h}),R=L.getVerticalMetrics(this.loadedFont.metrics),z=(R.ascender-R.descender)*a;return{lines:B.lines,scaledLineHeight:z,letterSpacing:h,align:u,direction:d,depth:A,size:n}}applyColorSystem(t,e,n,i){const s=t.length/3,r=new Float32Array(3*s),o=[];if(Array.isArray(n)){for(let t=0;t<s;t++){const e=3*t;r[e]=n[0],r[e+1]=n[1],r[e+2]=n[2]}o.push({start:0,end:i.length,originalText:i,color:n,bounds:[],glyphs:e,lineIndices:[...new Set(e.map(t=>t.lineIndex))]})}else{const t=n.default||[1,1,1];for(let e=0;e<r.length;e+=3)r[e]=t[0],r[e+1]=t[1],r[e+2]=t[2];if(n.byText){new vt(i,e).execute({byText:Object.keys(n.byText)}).forEach(t=>{const e=n.byText[t.originalText];e&&(t.glyphs.forEach(t=>{for(let n=0;n<t.vertexCount;n++){const i=3*(t.vertexStart+n);i>=0&&i<r.length&&(r[i]=e[0],r[i+1]=e[1],r[i+2]=e[2])}}),o.push({start:t.start,end:t.end,originalText:t.originalText,color:e,bounds:t.bounds,glyphs:t.glyphs,lineIndices:t.lineIndices}))})}n.byCharRange&&n.byCharRange.forEach(t=>{const n=[];for(const i of e)if(i.textIndex>=t.start&&i.textIndex<t.end){n.push(i);for(let e=0;e<i.vertexCount;e++){const n=3*(i.vertexStart+e);n>=0&&n<r.length&&(r[n]=t.color[0],r[n+1]=t.color[1],r[n+2]=t.color[2])}}o.push({start:t.start,end:t.end,originalText:i.slice(t.start,t.end),color:t.color,bounds:[],glyphs:n,lineIndices:[...new Set(n.map(t=>t.lineIndex))]})})}return{colors:r,coloredRanges:o}}finalizeGeometry(t,e,n,i,s,r,o,a){const{layout:h={},size:l=72}=r,{width:c,align:d=("rtl"===h.direction?"right":"left")}=h;this.textLayout||(this.textLayout=new b(this.loadedFont));const u=this.textLayout.applyAlignment(t,{width:c,align:d,planeBounds:s}),f=u.offset;s.min.x=u.adjustedBounds.min.x,s.max.x=u.adjustedBounds.max.x;const g=l/this.loadedFont.upem;for(let e=0;e<t.length;e++)t[e]*=g;for(let t=0;t<e.length;t++)e[t]*=g;s.min.x*=g,s.min.y*=g,s.min.z*=g,s.max.x*=g,s.max.y*=g,s.max.z*=g;for(let t=0;t<i.length;t++){const e=i[t];0!==f&&(e.bounds.min.x+=f,e.bounds.max.x+=f),e.bounds.min.x*=g,e.bounds.min.y*=g,e.bounds.min.z*=g,e.bounds.max.x*=g,e.bounds.max.y*=g,e.bounds.max.z*=g}let p,y;if(r.color){const e=this.applyColorSystem(t,i,r.color,r.text);p=e.colors,y=e.coloredRanges}const m=this.geometryBuilder.getOptimizationStats(),x=n.length/3,_=t.length/3;return{vertices:t,normals:e,indices:n,colors:p,glyphs:i,planeBounds:s,stats:{trianglesGenerated:x,verticesGenerated:_,pointsRemovedByVisvalingam:m.pointsRemovedByVisvalingam,pointsRemovedByColinear:m.pointsRemovedByColinear,originalPointCount:m.originalPointCount,...o||{}},query:t=>{if(!a)throw new Error("Original text not available for querying");return new vt(a,i).execute(t)},coloredRanges:y,glyphAttributes:void 0}}getFontMetrics(){if(!this.loadedFont)throw new Error("Font not loaded. Call loadFont() first");return L.getFontMetrics(this.loadedFont.metrics)}static async preloadPatterns(t,n){await Promise.all(t.map(async t=>{if(!bt.patternCache.has(t))try{const e=await T(t,n);bt.patternCache.set(t,e)}catch(n){e.warn(`Failed to pre-load patterns for ${t}: ${n}`)}}))}static registerPattern(t,e){bt.patternCache.set(t,e)}getLoadedFont(){return this.loadedFont}measureTextWidth(t,e=0){if(!this.loadedFont)throw new Error("Font not loaded. Call loadFont() first");return v.measureTextWidth(this.loadedFont,t,e)}getCacheStatistics(){return this.geometryBuilder?this.geometryBuilder.getCacheStats():null}clearCache(){this.geometryBuilder&&this.geometryBuilder.clearCache()}createGlyphAttributes(t,e){const n=new Float32Array(3*t),i=new Float32Array(t),s=new Float32Array(t);return e.forEach((e,r)=>{const o=(e.bounds.min.x+e.bounds.max.x)/2,a=(e.bounds.min.y+e.bounds.max.y)/2,h=(e.bounds.min.z+e.bounds.max.z)/2;for(let l=0;l<e.vertexCount;l++){const c=e.vertexStart+l;c<t&&(n[3*c]=o,n[3*c+1]=a,n[3*c+2]=h,i[c]=r,s[c]=e.lineIndex)}}),{glyphCenter:n,glyphIndex:i,glyphLineIndex:s}}destroy(){if(!this.loadedFont)return;const t=this.loadedFont;try{P.destroyFont(t)}catch(t){e.warn("Error destroying HarfBuzz objects:",t)}finally{this.loadedFont=void 0,this.textLayout=void 0,this.textShaper=void 0}}}export{tt as DEFAULT_CURVE_FIDELITY,L as FontMetadataExtractor,bt as Text,ht as globalGlyphCache};
14
+ const t=!("undefined"==typeof window||!window.THREE_TEXT_LOG)||"undefined"!=typeof globalThis&&"true"===globalThis.process?.env?.THREE_TEXT_LOG;const e=new class{warn(t,...e){console.warn(t,...e)}error(t,...e){console.error(t,...e)}log(e,...n){t&&console.log(e,...n)}};const n=new class{constructor(){this.metrics=[],this.activeTimers=new Map}start(e,n){if(!t)return;const i=performance.now();this.activeTimers.set(e,i),this.metrics.push({name:e,startTime:i,metadata:n})}end(n){if(!t)return null;const i=performance.now(),s=this.activeTimers.get(n);if(void 0===s)return e.warn(`Performance timer "${n}" was not started`),null;const r=i-s;this.activeTimers.delete(n);for(let t=this.metrics.length-1;t>=0;t--){const e=this.metrics[t];if(e.name===n&&!e.endTime){e.endTime=i,e.duration=r;break}}return console.log(`${n}: ${r.toFixed(2)}ms`),r}getSummary(){if(!t)return{};const e={};for(const t of this.metrics){if(!t.duration)continue;const n=e[t.name];n?(n.count++,n.totalDuration+=t.duration,n.avgDuration=n.totalDuration/n.count,n.lastDuration=t.duration):e[t.name]={count:1,avgDuration:t.duration,totalDuration:t.duration,lastDuration:t.duration}}return e}printSummary(){if(!t)return;const e=this.getSummary();console.table(e),console.log("Operations:",Object.keys(e).sort().join(", "))}printBaseline(){if(!t)return;const e=this.getSummary();Object.entries(e).forEach(([t,e])=>{console.log(`BASELINE ${t}: ${e.avgDuration.toFixed(2)}ms avg (${e.count} calls)`)})}clear(){t&&(this.metrics.length=0,this.activeTimers.clear())}time(e,n,i){if(!t)return n();this.start(e,i);try{return n()}finally{this.end(e)}}async timeAsync(e,n,i){if(!t)return n();this.start(e,i);try{return await n()}finally{this.end(e)}}},i=200,s=100,r=0,o=1/3;var a,h;!function(t){t[t.BOX=0]="BOX",t[t.GLUE=1]="GLUE",t[t.PENALTY=2]="PENALTY",t[t.DISCRETIONARY=3]="DISCRETIONARY"}(a||(a={})),function(t){t[t.TIGHT=0]="TIGHT",t[t.NORMAL=1]="NORMAL",t[t.LOOSE=2]="LOOSE",t[t.VERY_LOOSE=3]="VERY_LOOSE"}(h||(h={}));class l{constructor(){this.nodesByKey=new Map,this.activeList=[],this.allNodes=new Set}getKey(t,e){return t<<2|e}insert(t){const e=this.getKey(t.position,t.fitness),n=this.nodesByKey.get(e);n&&t.totalDemerits<n.totalDemerits?(n.totalDemerits=t.totalDemerits,n.previous=t.previous,n.totalWidth=t.totalWidth):n||(this.nodesByKey.set(e,t),this.allNodes.add(t),t.activeListIndex=this.activeList.length,this.activeList.push(t))}findExisting(t,e){return this.nodesByKey.get(this.getKey(t,e))}getAllActive(){return this.activeList}deactivateNode(t){if(t.active&&void 0!==t.activeListIndex){t.active=!1;const e=t.activeListIndex,n=this.activeList.length-1;if(e!==n){const t=this.activeList[n];this.activeList[e]=t,t.activeListIndex=e}this.activeList.pop(),t.activeListIndex=void 0}}size(){return this.allNodes.size}}const c=50,d=50,u=1e4,f=10,g=1e4,p=-1/0,y=2,m=4,x=1e4;class _{static badness(t,e){if(0===t)return 0;if(e<=0)return x;let n;return n=t<=7230584?Math.floor(297*t/e):e>=1663497?Math.floor(t/Math.floor(e/297)):t,n>1290?x:Math.floor((n*n*n+131072)/262144)}static findHyphenationPoints(t,e="en-us",n,i=y,s=m){let r;if(!n||!n[e])return[];if(r=n[e],!r)return[];const o=`.${t.toLowerCase()}.`,a=new Array(o.length).fill(0);for(let t=0;t<o.length;t++){let e=r;for(let n=t;n<o.length;n++){const i=o[n];if(!e.children||!e.children[i])break;if(e=e.children[i],e.patterns)for(let n=0;n<e.patterns.length;n++){const i=t+n;i<a.length&&(a[i]=Math.max(a[i],e.patterns[n]))}}}const h=[];for(let t=2;t<o.length-2;t++)a[t]%2==1&&h.push(t-1);return h.filter(e=>e>=i&&t.length-e>=s)}static itemizeText(t,e,n=!1,i="en-us",s,r=y,o=m,h){const l=[];return l.push(...this.itemizeParagraph(t,e,n,i,s,r,o,h)),l.push({type:a.GLUE,width:0,stretch:1/0,shrink:0,text:"",originIndex:t.length}),l.push({type:a.PENALTY,width:0,penalty:-1/0,text:"",originIndex:t.length}),l}static itemizeParagraph(t,e,n,i,s,r,h,l){const u=[],f=t.match(/\S+|\s+/g)||[];let g=0;for(let t=0;t<f.length;t++){const p=f[t],y=g;if(/\s+/.test(p)){const t=e(p);u.push({type:a.GLUE,width:t,stretch:.5*t,shrink:t*o,text:p,originIndex:y}),g+=p.length}else{const t=p.split(/(-)/);let o=y;for(let f=0;f<t.length;f++){const g=t[f];if(g)if("-"===g)u.push({type:a.DISCRETIONARY,width:e("-"),preBreak:"-",postBreak:"",noBreak:"-",preBreakWidth:e("-"),penalty:l?.exHyphenPenalty??d,flagged:!0,text:"-",originIndex:o}),o+=1;else{if(g.includes("­")){const t=g.split("­");let n=0;for(let i=0;i<t.length;i++){const s=t[i];s.length>0&&(u.push({type:a.BOX,width:e(s),text:s,originIndex:o+n}),n+=s.length),i<t.length-1&&(u.push({type:a.DISCRETIONARY,width:0,preBreak:"-",postBreak:"",noBreak:"",preBreakWidth:e("-"),penalty:l?.hyphenPenalty??c,flagged:!0,text:"",originIndex:o+n}),n+=1)}}else if(n&&g.length>=r+h){const t=_.findHyphenationPoints(g,i,s,r,h);if(t.length>0){let n=0;for(const i of t){const t=g.substring(n,i);u.push({type:a.BOX,width:e(t),text:t,originIndex:o+n}),u.push({type:a.DISCRETIONARY,width:0,preBreak:"-",postBreak:"",noBreak:"",preBreakWidth:e("-"),penalty:l?.hyphenPenalty??c,flagged:!0,text:"",originIndex:o+i}),n=i}const i=g.substring(n);u.push({type:a.BOX,width:e(i),text:i,originIndex:o+n})}else u.push({type:a.BOX,width:e(g),text:g,originIndex:o})}else u.push({type:a.BOX,width:e(g),text:g,originIndex:o});o+=g.length}}g+=p.length}}return u}static hasSingleWordLines(t,e,n){let i=0;for(let s=0;s<e.length-1;s++){const r=e[s];let o=0,h=0;for(let e=i;e<r;e++)t[e].type===a.GLUE&&o++,t[e].type!==a.PENALTY&&(h+=t[e].width);if(0===o&&h>0){if(h/n<.5)return!0}i=r+1}return!1}static breakText(t){n.start("LineBreak.breakText",{textLength:t.text.length,width:t.width,align:t.align||"left",hyphenate:t.hyphenate||!1});const{text:o,width:h,align:l="left",direction:p="ltr",hyphenate:x=!1,language:v="en-us",respectExistingBreaks:b=!0,measureText:w,hyphenationPatterns:E,unitsPerEm:O,tolerance:L=i,pretolerance:S=s,emergencyStretch:P=r,autoEmergencyStretch:T,lefthyphenmin:F=y,righthyphenmin:I=m,linepenalty:C=f,adjdemerits:U=g,hyphenpenalty:A=c,exhyphenpenalty:B=d,doublehyphendemerits:R=u,looseness:z=0,disableSingleWordDetection:D=!1}=t;if(b&&o.includes("\n")){const e=o.split("\n"),i=[];let s=0;for(const n of e){if(0===n.length)i.push({text:"",originalStart:s,originalEnd:s,xOffset:0,isLastLine:!0,naturalWidth:0,endedWithHyphen:!1});else{const e=_.breakText({...t,text:n,respectExistingBreaks:!1});e.forEach(t=>{t.originalStart+=s,t.originalEnd+=s}),i.push(...e)}s+=n.length+1}return n.end("LineBreak.breakText"),i}let k=x;!k||E&&E[v]||(e.warn(`Hyphenation patterns for ${v} not available`),k=!1);let M=P;void 0!==T&&h?M=h*T:!k&&P===r&&h&&(M=.1*h);const G={linePenalty:C,adjDemerits:U,doubleHyphenDemerits:R,hyphenPenalty:A,exHyphenPenalty:B,currentAlign:l,unitsPerEm:O};if(!h||h===1/0){const t=w(o);return n.end("LineBreak.breakText"),[{text:o,originalStart:0,originalEnd:o.length-1,xOffset:0,isLastLine:!0,naturalWidth:t,endedWithHyphen:!1}]}const N=_.itemizeText(o,w,k,v,E,F,I,G);if(0===N.length)return[];let H=0,q=M,W=null;const V=!D;for(;H<5;){let t=k?N.filter(t=>t.type!==a.DISCRETIONARY||t.penalty!==(G?.hyphenPenalty??c)):N,e=_.findBreakpoints(t,h,S,z,!1,0,G);if(0===e.length&&k&&(t=N,e=_.findBreakpoints(t,h,L,z,!1,0,G)),0===e.length&&(t=N,e=_.findBreakpoints(t,h,10001,z,!0,q,G)),0===e.length&&(e=_.findBreakpoints(t,h,1/0,z,!0,q,G)),e.length>0){const n=_.computeCumulativeWidths(t);if(W=_.createLines(o,t,e,h,l,p,n,G),V&&e.length>1&&_.hasSingleWordLines(t,e,h)){q+=.1*h,H++;continue}break}break}if(n.end("LineBreak.breakText"),W&&W.length>0)return W;const j=w(o);return[{text:o,originalStart:0,originalEnd:o.length-1,xOffset:0,adjustmentRatio:0,isLastLine:!0,naturalWidth:j,endedWithHyphen:!1}]}static findBreakpoints(t,e,n=1/0,i=0,s=!1,r=0,o){const c=_.computeCumulativeWidths(t),d=new l;d.insert({position:0,line:0,fitness:h.NORMAL,totalDemerits:0,totalWidth:0,previous:null,active:!0});for(let i=0;i<t.length;i++){const s=t[i];s.type===a.PENALTY&&s.penalty<1/0&&_.considerBreak(t,d,i,e,n,r,c,o),s.type===a.DISCRETIONARY&&s.penalty<1/0&&_.considerBreak(t,d,i,e,n,r,c,o),s.type===a.GLUE&&i>0&&t[i-1].type===a.BOX&&_.considerBreak(t,d,i,e,n,r,c,o),_.deactivateNodes(d,i,e,c.minWidths)}const u=[];let f=null;if(0===i){const t=d.getAllActive();let e=1/0;for(const n of t)n.active&&n.totalDemerits<e&&(e=n.totalDemerits,f=n)}else{const t=d.getAllActive();let e=0,n=1/0;for(const i of t)i.active&&i.totalDemerits<n&&(n=i.totalDemerits,e=i.line);let r=0,o=1/0;for(const n of t){if(!n.active)continue;const t=n.line-e;t<r&&i<=t||t>r&&i>=t?(f=n,r=t,o=n.totalDemerits):t===r&&n.totalDemerits<o&&(f=n,o=n.totalDemerits)}if(!s&&r!==i&&f)return[]}if(!f)return[];for(;f&&f.position>0;)u.unshift(f.position),f=f.previous;return u}static considerBreak(t,e,n,i,s=1/0,r=0,o,h){const l=(t[n].type===a.PENALTY?t[n].penalty:0)<=-1/0,c=e.getAllActive();for(let d=0;d<c.length;d++){const u=c[d];if(!u.active)continue;const f=_.computeAdjustmentRatio(t,u.position,n,u.line,i,o,h),{ratio:g,adjustment:y,stretch:m,shrink:x,totalWidth:v}=f;let b;if(y>0){const t=m+r;b=t<=0?10001:_.badness(y,t)}else b=y<0?x<=0||-y>x?10001:_.badness(-y,x):0;if(!l&&g<-1)continue;const w=_.computeFitnessClass(b,y>0);if(!l&&b>s)continue;let E=0,O=0;let L=(h?.linePenalty??0)+b,S=Math.abs(L)>=1e4?1e8:L*L;const P=t[n].type===a.PENALTY||t[n].type===a.DISCRETIONARY?t[n].penalty:0;0!==P&&(P>0?S+=P*P:P>p&&(S-=P*P));const T=t[n].type===a.PENALTY&&t[n].flagged||t[n].type===a.DISCRETIONARY&&t[n].flagged,F=u.position>0&&(t[u.position].type===a.PENALTY&&t[u.position].flagged||t[u.position].type===a.DISCRETIONARY&&t[u.position].flagged);T&&F&&(E=h?.doubleHyphenDemerits??0,S+=E),Math.abs(w-u.fitness)>1&&(O=h?.adjDemerits??0,S+=O),l&&(S=0);const I=u.totalDemerits+S;let C=e.findExisting(n,w);C?I<C.totalDemerits&&(C.totalDemerits=I,C.previous=u,C.totalWidth=v):e.insert({position:n,line:u.line+1,fitness:w,totalDemerits:I,totalWidth:v,previous:u,active:!0})}}static computeAdjustmentRatio(t,e,n,i,s,r,o){let h=0,l=0,c=0;if(r){h=r.widths[n]-r.widths[e],l=r.stretches[n]-r.stretches[e],c=r.shrinks[n]-r.shrinks[e];for(let i=e;i<n;i++){const e=t[i];e.type===a.PENALTY&&(h-=e.width)}}else for(let i=e;i<n;i++){const e=t[i];e.type!==a.PENALTY&&(h+=e.width,e.type===a.GLUE&&(l+=e.stretch,c+=e.shrink))}n<t.length&&(t[n].type===a.PENALTY||t[n].type===a.DISCRETIONARY)&&(h+=t[n].type===a.PENALTY?t[n].width:t[n].preBreakWidth);const d=s-h;let u;return u=d>0&&l>0?d/l:d<0&&c>0?d/c:0===d?0:d>0?3:-1,{ratio:u,adjustment:d,stretch:l,shrink:c,totalWidth:h}}static computeFitnessClass(t,e){return e?t<=12?h.NORMAL:t<=99?h.LOOSE:h.VERY_LOOSE:t<=12?h.NORMAL:h.TIGHT}static computeCumulativeWidths(t){const e=t.length+1,n=new Array(e),i=new Array(e),s=new Array(e),r=new Array(e);n[0]=0,i[0]=0,s[0]=0,r[0]=0;for(let e=0;e<t.length;e++){const o=t[e];if(n[e+1]=n[e]+o.width,o.type===a.PENALTY)r[e+1]=r[e];else if(o.type===a.GLUE){const t=o;i[e+1]=i[e]+t.stretch,s[e+1]=s[e]+t.shrink,r[e+1]=r[e]+Math.max(0,t.width-t.shrink)}else i[e+1]=i[e],s[e+1]=s[e],r[e+1]=r[e]+o.width}return{widths:n,stretches:i,shrinks:s,minWidths:r}}static deactivateNodes(t,e,n,i){const s=t.getAllActive();for(let r=s.length-1;r>=0;r--){const o=s[r];if(!o.active)continue;i[e]-i[o.position]>n&&t.deactivateNode(o)}}static createLines(t,e,n,i,s,r,o,h){if(0===n.length)return[{text:t,originalStart:0,originalEnd:t.length-1,xOffset:0}];const l=[];let c=0;for(let t=0;t<n.length;t++){const d=n[t],u=!(n[n.length-1]+1<e.length-1)&&t===n.length-1,f=[];let g=-1,p=-1,y=0;for(let t=c;t<d;t++){const n=e[t];if((n.type!==a.PENALTY||n.text)&&(n.type!==a.DISCRETIONARY||n.noBreak)){if(void 0!==n.originIndex){(-1===g||n.originIndex<g)&&(g=n.originIndex);const t=n.text?n.text.length:0,e=n.originIndex+t-1;e>p&&(p=e)}if(n.text)f.push(n.text);else if(n.type===a.DISCRETIONARY){const t=n;t.noBreak&&f.push(t.noBreak)}y+=n.width}}const m=e[d];let x=!1;if(d<e.length)if(m.type===a.PENALTY&&m.flagged)f.push("-"),y+=m.width,x=!0,void 0!==m.originIndex&&(p=m.originIndex-1);else if(m.type===a.DISCRETIONARY){const t=m;t.preBreak&&(f.push(t.preBreak),y+=t.preBreakWidth,x=t.flagged||!1,void 0!==m.originIndex&&(p=m.originIndex-1))}const v=f.join("");let b=0,w=0,E=s;if("justify"===s&&u&&(E="rtl"===r?"right":"left"),"center"===E)b=(i-y)/2;else if("right"===E)b=i-y;else if("justify"===E&&!u){w=_.computeAdjustmentRatio(e,c,d,t,i,o,h).ratio}l.push({text:v,originalStart:g,originalEnd:p,xOffset:b,adjustmentRatio:w,isLastLine:!1,naturalWidth:y,endedWithHyphen:x}),c=d+1}if(c<e.length-1){const t=[];let n=-1,o=-1,h=0;for(let i=c;i<e.length-1;i++){const s=e[i];s.type!==a.PENALTY&&(void 0!==s.originIndex&&((-1===n||s.originIndex<n)&&(n=s.originIndex),s.originIndex>o&&(o=s.originIndex)),s.text&&t.push(s.text),h+=s.width)}const d=t.join("");let u=0,f=s;"justify"===s&&(f="rtl"===r?"right":"left"),"center"===f?u=(i-h)/2:"right"===f&&(u=i-h),l.push({text:d,originalStart:n,originalEnd:o,xOffset:u,adjustmentRatio:0,isLastLine:!0,naturalWidth:h,endedWithHyphen:!1}),l.length>1&&(l[l.length-2].isLastLine=!1),l[l.length-1].isLastLine=!0}else l.length>0&&(l[l.length-1].isLastLine=!0);return l}}class v{static measureTextWidth(t,e,n=0){const i=t.hb.createBuffer();i.addText(e),i.guessSegmentProperties(),t.hb.shape(t.font,i);const s=i.json(t.font),r=n*t.upem;let o=0;return s.forEach((t,n)=>{o+=t.ax;const i=n===s.length-1,a=" "===e||" "===e||/^\s+$/.test(e);0===r||i&&!a||(o+=r)}),i.destroy(),o}}class b{constructor(t){this.loadedFont=t}computeLines(t){const{text:e,width:n,align:i,direction:s,hyphenate:r,language:o,respectExistingBreaks:a,tolerance:h,pretolerance:l,emergencyStretch:c,autoEmergencyStretch:d,hyphenationPatterns:u,lefthyphenmin:f,righthyphenmin:g,linepenalty:p,adjdemerits:y,hyphenpenalty:m,exhyphenpenalty:x,doublehyphendemerits:b,looseness:w,disableSingleWordDetection:E,letterSpacing:O}=t;let L;if(n)L=_.breakText({text:e,width:n,align:i,direction:s,hyphenate:r,language:o,respectExistingBreaks:a,tolerance:h,pretolerance:l,emergencyStretch:c,autoEmergencyStretch:d,hyphenationPatterns:u,lefthyphenmin:f,righthyphenmin:g,linepenalty:p,adjdemerits:y,hyphenpenalty:m,exhyphenpenalty:x,doublehyphendemerits:b,looseness:w,disableSingleWordDetection:E,unitsPerEm:this.loadedFont.upem,measureText:t=>v.measureTextWidth(this.loadedFont,t,O)});else{const t=e.split("\n");L=[];let n=0;for(const e of t)L.push({text:e,originalStart:n,originalEnd:n+e.length-1,xOffset:0}),n+=e.length+1}return{lines:L}}applyAlignment(t,e){const{width:n,align:i,planeBounds:s}=e;let r=0;const o={min:{...s.min},max:{...s.max}};if(n&&("center"===i||"right"===i)){const e=s.max.x-s.min.x;if("center"===i?r=(n-e)/2-s.min.x:"right"===i&&(r=n-s.max.x),0!==r){for(let e=0;e<t.length;e+=3)t[e]+=r;o.min.x+=r,o.max.x+=r}}return{offset:r,adjustedBounds:o}}}const w=1330926671,E=1953784678,O=2001684038;class L{static extractMetadata(t){if(!t||t.byteLength<12)throw new Error("Invalid font buffer: too small to be a valid font file");const e=new DataView(t),n=e.getUint32(0);if(![65536,w,E].includes(n))throw new Error(`Invalid font format. Expected TrueType or OpenType, got signature: 0x${n.toString(16)}`);const i=new Uint8Array(t),s=e.getUint16(4);let r=!1,o=0,a=0,h=0,l=0,c=0,d=0;for(let t=0;t<s;t++){const n=(new TextDecoder).decode(i.slice(12+16*t,12+16*t+4));("CFF "===n||"CFF2"===n)&&(r=!0),"head"===n&&(o=e.getUint32(12+16*t+8)),"hhea"===n&&(a=e.getUint32(12+16*t+8)),"OS/2"===n&&(h=e.getUint32(12+16*t+8)),"fvar"===n&&(d=e.getUint32(12+16*t+8)),"STAT"===n&&(l=e.getUint32(12+16*t+8)),"name"===n&&(c=e.getUint32(12+16*t+8))}const u=o?e.getUint16(o+18):1e3;let f=null;a&&(f={ascender:e.getInt16(a+4),descender:e.getInt16(a+6),lineGap:e.getInt16(a+8)});let g=null;h&&(g={typoAscender:e.getInt16(h+68),typoDescender:e.getInt16(h+70),typoLineGap:e.getInt16(h+72),winAscent:e.getUint16(h+74),winDescent:e.getUint16(h+76)});let p=null;return d&&l&&c&&(p=this.extractAxisNames(e,l,c)),{isCFF:r,unitsPerEm:u,hheaAscender:f?.ascender||null,hheaDescender:f?.descender||null,hheaLineGap:f?.lineGap||null,typoAscender:g?.typoAscender||null,typoDescender:g?.typoDescender||null,typoLineGap:g?.typoLineGap||null,winAscent:g?.winAscent||null,winDescent:g?.winDescent||null,axisNames:p}}static extractAxisNames(t,e,n){try{if(t.getUint16(e)<1)return null;const i=t.getUint16(e+4),s=t.getUint16(e+6),r=t.getUint32(e+8),o={};for(let a=0;a<s;a++){const s=e+r+a*i,h=String.fromCharCode(t.getUint8(s),t.getUint8(s+1),t.getUint8(s+2),t.getUint8(s+3)),l=t.getUint16(s+4),c=this.getNameFromNameTable(t,n,l);c&&(o[h]=c)}return Object.keys(o).length>0?o:null}catch(t){return null}}static getNameFromNameTable(t,e,n){try{const i=t.getUint16(e+2),s=t.getUint16(e+4);for(let r=0;r<i;r++){const i=e+6+12*r,o=t.getUint16(i),a=t.getUint16(i+2),h=t.getUint16(i+4),l=t.getUint16(i+6),c=t.getUint16(i+8),d=t.getUint16(i+10);if(l===n&&(0===o||3===o&&1033===h)){const n=e+s+d,i=new Uint8Array(t.buffer,n,c);if(0===o||3===o&&1===a){let t="";for(let e=0;e<i.length;e+=2)t+=String.fromCharCode(i[e]<<8|i[e+1]);return t}return new TextDecoder("ascii").decode(i)}}return null}catch(t){return null}}static getVerticalMetrics(t){return null!==t.typoAscender&&null!==t.typoDescender?{ascender:t.typoAscender,descender:t.typoDescender,lineGap:0}:null!==t.hheaAscender&&null!==t.hheaDescender?{ascender:t.hheaAscender,descender:t.hheaDescender,lineGap:0}:null!==t.winAscent&&null!==t.winDescent?{ascender:t.winAscent,descender:-t.winDescent,lineGap:0}:{ascender:Math.round(.8*t.unitsPerEm),descender:-Math.round(.2*t.unitsPerEm),lineGap:0}}static getFontMetrics(t){const e=L.getVerticalMetrics(t);return{ascender:e.ascender,descender:e.descender,lineGap:e.lineGap,unitsPerEm:t.unitsPerEm,naturalLineHeight:e.ascender-e.descender}}}class S{static detectFormat(t){if(t.byteLength<4)return"ttf/otf";const e=new DataView(t).getUint32(0);return e===O?"woff":2001684018===e?"woff2":"ttf/otf"}static async decompressWoff(t){const n=new DataView(t),i=new Uint8Array(t);if(n.getUint32(0)!==O)throw new Error("Not a valid WOFF font");const s=n.getUint32(4),r=n.getUint16(12),o=n.getUint32(16);if("undefined"==typeof DecompressionStream)throw new Error("WOFF fonts require DecompressionStream API (Chrome 80+, Firefox 113+, Safari 16.4+). Please use TTF/OTF fonts or upgrade your browser.");const a=new Uint8Array(o),h=new DataView(a.buffer);h.setUint32(0,s),h.setUint16(4,r);const l=2**Math.floor(Math.log2(r))*16;h.setUint16(6,l),h.setUint16(8,Math.floor(Math.log2(r))),h.setUint16(10,16*r-l);let c=12+16*r;const d=[];for(let t=0;t<r;t++){const e=44+20*t;d.push({tag:n.getUint32(e),offset:n.getUint32(e+4),length:n.getUint32(e+8),origLength:n.getUint32(e+12),checksum:n.getUint32(e+16)})}d.sort((t,e)=>t.tag-e.tag);for(let t=0;t<r;t++){const e=d[t],n=12+16*t;if(h.setUint32(n,e.tag),h.setUint32(n+4,e.checksum),h.setUint32(n+8,c),h.setUint32(n+12,e.origLength),e.length===e.origLength)a.set(i.subarray(e.offset,e.offset+e.length),c);else{const t=i.subarray(e.offset,e.offset+e.length),n=await S.decompressZlib(t);if(n.byteLength!==e.origLength)throw new Error(`Decompression failed: expected ${e.origLength} bytes, got ${n.byteLength}`);a.set(new Uint8Array(n),c)}c+=e.origLength;c+=(4-e.origLength%4)%4}return e.log("WOFF font decompressed successfully"),a.buffer.slice(0,c)}static async decompressZlib(t){const e=new ReadableStream({start(e){e.enqueue(t),e.close()}}).pipeThrough(new DecompressionStream("deflate"));return new Response(e).arrayBuffer()}}class P{constructor(t){this.getHarfBuzzInstance=t}async loadFont(t,i){if(n.start("FontLoader.loadFont",{bufferSize:t.byteLength}),!t||t.byteLength<12)throw new Error("Invalid font buffer: too small to be a valid font file");const s=S.detectFormat(t);if("woff"===s)e.log("WOFF font detected, decompressing..."),t=await S.decompressWoff(t);else if("woff2"===s)throw new Error("WOFF2 fonts are not yet supported. Please use WOFF or TTF/OTF format.");const r=new DataView(t).getUint32(0);if(![65536,w,E].includes(r))throw new Error(`Invalid font format. Expected TrueType or OpenType, got signature: 0x${r.toString(16)}`);const{hb:o,module:a}=await this.getHarfBuzzInstance();try{const e=o.createBlob(new Uint8Array(t)),n=o.createFace(e,0),s=o.createFont(n);i&&s.setVariations(i);const r=n.getAxisInfos(),h=Object.keys(r).length>0,l=L.extractMetadata(t);let c;if(h&&r){c={};for(const[t,e]of Object.entries(r))c[t]={...e,name:l.axisNames?.[t]||null}}return{hb:o,fontBlob:e,face:n,font:s,module:a,upem:l.unitsPerEm,metrics:l,fontVariations:i,isVariable:h,variationAxes:c}}catch(t){throw e.error("Failed to load font:",t),t}finally{n.end("FontLoader.loadFont")}}static destroyFont(t){try{t.font&&"function"==typeof t.font.destroy&&t.font.destroy(),t.face&&"function"==typeof t.face.destroy&&t.face.destroy(),t.fontBlob&&"function"==typeof t.fontBlob.destroy&&t.fontBlob.destroy()}catch(t){e.error("Error destroying font resources:",t)}}}async function T(t,e){try{if(e){return(await import(`${e}${t}.js`)).default}if("string"==typeof import.meta?.url){const e=new URL(".",import.meta.url).href,n=new URL(`./patterns/${t}.js`,e).href;return(await import(n)).default}return(await import(`./patterns/${t}.js`)).default}catch(e){throw new Error(`Failed to load hyphenation patterns for ${t}. Consider using static imports: import pattern from 'three-text/patterns/${t}'; Text.registerPattern('${t}', pattern);`)}}class F{constructor(t=0,e=0){this.x=t,this.y=e}set(t,e){return this.x=t,this.y=e,this}clone(){return new F(this.x,this.y)}copy(t){return this.x=t.x,this.y=t.y,this}add(t){return this.x+=t.x,this.y+=t.y,this}sub(t){return this.x-=t.x,this.y-=t.y,this}multiply(t){return this.x*=t,this.y*=t,this}divide(t){return this.x/=t,this.y/=t,this}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}lengthSq(){return this.x*this.x+this.y*this.y}normalize(){const t=this.length();return t>0&&this.divide(t),this}dot(t){return this.x*t.x+this.y*t.y}distanceTo(t){const e=this.x-t.x,n=this.y-t.y;return Math.sqrt(e*e+n*n)}distanceToSquared(t){const e=this.x-t.x,n=this.y-t.y;return e*e+n*n}equals(t){return this.x===t.x&&this.y===t.y}angle(){return Math.atan2(this.y,this.x)}}class I{constructor(t=0,e=0,n=0){this.x=t,this.y=e,this.z=n}set(t,e,n){return this.x=t,this.y=e,this.z=n,this}clone(){return new I(this.x,this.y,this.z)}copy(t){return this.x=t.x,this.y=t.y,this.z=t.z,this}add(t){return this.x+=t.x,this.y+=t.y,this.z+=t.z,this}sub(t){return this.x-=t.x,this.y-=t.y,this.z-=t.z,this}multiply(t){return this.x*=t,this.y*=t,this.z*=t,this}divide(t){return this.x/=t,this.y/=t,this.z/=t,this}length(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)}lengthSq(){return this.x*this.x+this.y*this.y+this.z*this.z}normalize(){const t=this.length();return t>0&&this.divide(t),this}dot(t){return this.x*t.x+this.y*t.y+this.z*t.z}cross(t){const e=this.y*t.z-this.z*t.y,n=this.z*t.x-this.x*t.z,i=this.x*t.y-this.y*t.x;return this.x=e,this.y=n,this.z=i,this}distanceTo(t){const e=this.x-t.x,n=this.y-t.y,i=this.z-t.z;return Math.sqrt(e*e+n*n+i*i)}distanceToSquared(t){const e=this.x-t.x,n=this.y-t.y,i=this.z-t.z;return e*e+n*n+i*i}equals(t){return this.x===t.x&&this.y===t.y&&this.z===t.z}}class C{constructor(t=new I(1/0,1/0,1/0),e=new I(-1/0,-1/0,-1/0)){this.min=t,this.max=e}set(t,e){return this.min.copy(t),this.max.copy(e),this}setFromPoints(t){this.makeEmpty();for(let e=0;e<t.length;e++)this.expandByPoint(t[e]);return this}makeEmpty(){return this.min.x=this.min.y=this.min.z=1/0,this.max.x=this.max.y=this.max.z=-1/0,this}isEmpty(){return this.max.x<this.min.x||this.max.y<this.min.y||this.max.z<this.min.z}expandByPoint(t){return this.min.x=Math.min(this.min.x,t.x),this.min.y=Math.min(this.min.y,t.y),this.min.z=Math.min(this.min.z,t.z),this.max.x=Math.max(this.max.x,t.x),this.max.y=Math.max(this.max.y,t.y),this.max.z=Math.max(this.max.z,t.z),this}expandByScalar(t){return this.min.x-=t,this.min.y-=t,this.min.z-=t,this.max.x+=t,this.max.y+=t,this.max.z+=t,this}containsPoint(t){return t.x>=this.min.x&&t.x<=this.max.x&&t.y>=this.min.y&&t.y<=this.max.y&&t.z>=this.min.z&&t.z<=this.max.z}containsBox(t){return this.min.x<=t.min.x&&t.max.x<=this.max.x&&this.min.y<=t.min.y&&t.max.y<=this.max.y&&this.min.z<=t.min.z&&t.max.z<=this.max.z}intersectsBox(t){return t.max.x>=this.min.x&&t.min.x<=this.max.x&&t.max.y>=this.min.y&&t.min.y<=this.max.y&&t.max.z>=this.min.z&&t.min.z<=this.max.z}getCenter(t=new I){return this.isEmpty()?t.set(0,0,0):t.set(.5*(this.min.x+this.max.x),.5*(this.min.y+this.max.y),.5*(this.min.z+this.max.z))}getSize(t=new I){return this.isEmpty()?t.set(0,0,0):t.set(this.max.x-this.min.x,this.max.y-this.min.y,this.max.z-this.min.z)}clone(){return new C(this.min.clone(),this.max.clone())}copy(t){return this.min.copy(t.min),this.max.copy(t.max),this}union(t){return this.min.x=Math.min(this.min.x,t.min.x),this.min.y=Math.min(this.min.y,t.min.y),this.min.z=Math.min(this.min.z,t.min.z),this.max.x=Math.max(this.max.x,t.max.x),this.max.y=Math.max(this.max.y,t.max.y),this.max.z=Math.max(this.max.z,t.max.z),this}equals(t){return t.min.equals(this.min)&&t.max.equals(this.max)}}var U,A;function B(t,e){if(!t)throw e||"Assertion Failed!"}!function(t){t[t.ODD=0]="ODD",t[t.NONZERO=1]="NONZERO",t[t.POSITIVE=2]="POSITIVE",t[t.NEGATIVE=3]="NEGATIVE",t[t.ABS_GEQ_TWO=4]="ABS_GEQ_TWO"}(U||(U={})),function(t){t[t.POLYGONS=0]="POLYGONS",t[t.CONNECTED_POLYGONS=1]="CONNECTED_POLYGONS",t[t.BOUNDARY_CONTOURS=2]="BOUNDARY_CONTOURS"}(A||(A={}));var R=function(){function t(){}return t.vertEq=function(t,e){return t.s===e.s&&t.t===e.t},t.vertLeq=function(t,e){return t.s<e.s||t.s===e.s&&t.t<=e.t},t.transLeq=function(t,e){return t.t<e.t||t.t===e.t&&t.s<=e.s},t.edgeGoesLeft=function(e){return t.vertLeq(e.Dst,e.Org)},t.edgeGoesRight=function(e){return t.vertLeq(e.Org,e.Dst)},t.vertL1dist=function(t,e){return Math.abs(t.s-e.s)+Math.abs(t.t-e.t)},t.edgeEval=function(e,n,i){B(t.vertLeq(e,n)&&t.vertLeq(n,i));var s=n.s-e.s,r=i.s-n.s;return s+r>0?s<r?n.t-e.t+(e.t-i.t)*(s/(s+r)):n.t-i.t+(i.t-e.t)*(r/(s+r)):0},t.edgeSign=function(e,n,i){B(t.vertLeq(e,n)&&t.vertLeq(n,i));var s=n.s-e.s,r=i.s-n.s;return s+r>0?(n.t-i.t)*s+(n.t-e.t)*r:0},t.transEval=function(e,n,i){B(t.transLeq(e,n)&&t.transLeq(n,i));var s=n.t-e.t,r=i.t-n.t;return s+r>0?s<r?n.s-e.s+(e.s-i.s)*(s/(s+r)):n.s-i.s+(i.s-e.s)*(r/(s+r)):0},t.transSign=function(e,n,i){B(t.transLeq(e,n)&&t.transLeq(n,i));var s=n.t-e.t,r=i.t-n.t;return s+r>0?(n.s-i.s)*s+(n.s-e.s)*r:0},t.vertCCW=function(t,e,n){return t.s*(e.t-n.t)+e.s*(n.t-t.t)+n.s*(t.t-e.t)>=0},t.interpolate=function(t,e,n,i){return(t=t<0?0:t)<=(n=n<0?0:n)?0===n?(e+i)/2:e+t/(t+n)*(i-e):i+n/(t+n)*(e-i)},t.intersect=function(e,n,i,s,r){var o,a,h;t.vertLeq(e,n)||(h=e,e=n,n=h),t.vertLeq(i,s)||(h=i,i=s,s=h),t.vertLeq(e,i)||(h=e,e=i,i=h,h=n,n=s,s=h),t.vertLeq(i,n)?t.vertLeq(n,s)?((o=t.edgeEval(e,i,n))+(a=t.edgeEval(i,n,s))<0&&(o=-o,a=-a),r.s=t.interpolate(o,i.s,a,n.s)):((o=t.edgeSign(e,i,n))+(a=-t.edgeSign(e,s,n))<0&&(o=-o,a=-a),r.s=t.interpolate(o,i.s,a,s.s)):r.s=(i.s+n.s)/2,t.transLeq(e,n)||(h=e,e=n,n=h),t.transLeq(i,s)||(h=i,i=s,s=h),t.transLeq(e,i)||(h=e,e=i,i=h,h=n,n=s,s=h),t.transLeq(i,n)?t.transLeq(n,s)?((o=t.transEval(e,i,n))+(a=t.transEval(i,n,s))<0&&(o=-o,a=-a),r.t=t.interpolate(o,i.t,a,n.t)):((o=t.transSign(e,i,n))+(a=-t.transSign(e,s,n))<0&&(o=-o,a=-a),r.t=t.interpolate(o,i.t,a,s.t)):r.t=(i.t+n.t)/2},t}(),z=function(){this.next=null,this.prev=null,this.anEdge=null,this.trail=null,this.n=0,this.marked=!1,this.inside=!1},D=function(){function t(t){this.side=t,this.next=null,this.Org=null,this.Sym=null,this.Onext=null,this.Lnext=null,this.Lface=null,this.activeRegion=null,this.winding=0}return Object.defineProperty(t.prototype,"Rface",{get:function(){return this.Sym.Lface},set:function(t){this.Sym.Lface=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"Dst",{get:function(){return this.Sym.Org},set:function(t){this.Sym.Org=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"Oprev",{get:function(){return this.Sym.Lnext},set:function(t){this.Sym.Lnext=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"Lprev",{get:function(){return this.Onext.Sym},set:function(t){this.Onext.Sym=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"Dprev",{get:function(){return this.Lnext.Sym},set:function(t){this.Lnext.Sym=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"Rprev",{get:function(){return this.Sym.Onext},set:function(t){this.Sym.Onext=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"Dnext",{get:function(){return this.Sym.Onext.Sym},set:function(t){this.Sym.Onext.Sym=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"Rnext",{get:function(){return this.Sym.Lnext.Sym},set:function(t){this.Sym.Lnext.Sym=t},enumerable:!0,configurable:!0}),t}(),k=function(){this.next=null,this.prev=null,this.anEdge=null,this.coords=[0,0,0],this.s=0,this.t=0,this.pqHandle=0,this.n=0,this.idx=0},M=function(){function t(){var t=new k,e=new z,n=new D(0),i=new D(1);t.next=t.prev=t,t.anEdge=null,e.next=e.prev=e,n.next=n,n.Sym=i,i.next=i,i.Sym=n,this.vHead=t,this.fHead=e,this.eHead=n,this.eHeadSym=i}return t.prototype.makeEdge_=function(t){var e=new D(0),n=new D(1);t.Sym.side<t.side&&(t=t.Sym);var i=t.Sym.next;return n.next=i,i.Sym.next=e,e.next=t,t.Sym.next=n,e.Sym=n,e.Onext=e,e.Lnext=n,e.Org=null,e.Lface=null,e.winding=0,e.activeRegion=null,n.Sym=e,n.Onext=n,n.Lnext=e,n.Org=null,n.Lface=null,n.winding=0,n.activeRegion=null,e},t.prototype.splice_=function(t,e){var n=t.Onext,i=e.Onext;n.Sym.Lnext=e,i.Sym.Lnext=t,t.Onext=i,e.Onext=n},t.prototype.makeVertex_=function(t,e,n){var i=t;B(i,"Vertex can't be null!");var s=n.prev;i.prev=s,s.next=i,i.next=n,n.prev=i,i.anEdge=e;var r=e;do{r.Org=i,r=r.Onext}while(r!==e)},t.prototype.makeFace_=function(t,e,n){var i=t;B(i,"Face can't be null");var s=n.prev;i.prev=s,s.next=i,i.next=n,n.prev=i,i.anEdge=e,i.trail=null,i.marked=!1,i.inside=n.inside;var r=e;do{r.Lface=i,r=r.Lnext}while(r!==e)},t.prototype.killEdge_=function(t){t.Sym.side<t.side&&(t=t.Sym);var e=t.next,n=t.Sym.next;e.Sym.next=n,n.Sym.next=e},t.prototype.killVertex_=function(t,e){var n=t.anEdge,i=n;do{i.Org=e,i=i.Onext}while(i!==n);var s=t.prev,r=t.next;r.prev=s,s.next=r},t.prototype.killFace_=function(t,e){var n=t.anEdge,i=n;do{i.Lface=e,i=i.Lnext}while(i!==n);var s=t.prev,r=t.next;r.prev=s,s.next=r},t.prototype.makeEdge=function(){var t=new k,e=new k,n=new z,i=this.makeEdge_(this.eHead);return this.makeVertex_(t,i,this.vHead),this.makeVertex_(e,i.Sym,this.vHead),this.makeFace_(n,i,this.fHead),i},t.prototype.splice=function(t,e){var n=!1,i=!1;if(t!==e){if(e.Org!==t.Org&&(i=!0,this.killVertex_(e.Org,t.Org)),e.Lface!==t.Lface&&(n=!0,this.killFace_(e.Lface,t.Lface)),this.splice_(e,t),!i){var s=new k;this.makeVertex_(s,e,t.Org),t.Org.anEdge=t}if(!n){var r=new z;this.makeFace_(r,e,t.Lface),t.Lface.anEdge=t}}},t.prototype.delete=function(t){var e=t.Sym,n=!1;if(t.Lface!==t.Rface&&(n=!0,this.killFace_(t.Lface,t.Rface)),t.Onext===t)this.killVertex_(t.Org,null);else if(t.Rface.anEdge=t.Oprev,t.Org.anEdge=t.Onext,this.splice_(t,t.Oprev),!n){var i=new z;this.makeFace_(i,t,t.Lface)}e.Onext===e?(this.killVertex_(e.Org,null),this.killFace_(e.Lface,null)):(t.Lface.anEdge=e.Oprev,e.Org.anEdge=e.Onext,this.splice_(e,e.Oprev)),this.killEdge_(t)},t.prototype.addEdgeVertex=function(t){var e=this.makeEdge_(t),n=e.Sym;this.splice_(e,t.Lnext),e.Org=t.Dst;var i=new k;return this.makeVertex_(i,n,e.Org),e.Lface=n.Lface=t.Lface,e},t.prototype.splitEdge=function(t){var e=this.addEdgeVertex(t).Sym;return this.splice_(t.Sym,t.Sym.Oprev),this.splice_(t.Sym,e),t.Dst=e.Org,e.Dst.anEdge=e.Sym,e.Rface=t.Rface,e.winding=t.winding,e.Sym.winding=t.Sym.winding,e},t.prototype.connect=function(t,e){var n=!1,i=this.makeEdge_(t),s=i.Sym;if(e.Lface!==t.Lface&&(n=!0,this.killFace_(e.Lface,t.Lface)),this.splice_(i,t.Lnext),this.splice_(s,e),i.Org=t.Dst,s.Org=e.Org,i.Lface=s.Lface=t.Lface,t.Lface.anEdge=s,!n){var r=new z;this.makeFace_(r,i,t.Lface)}return i},t.prototype.zapFace=function(t){var e,n,i,s,r,o=t.anEdge;n=o.Lnext;do{n=(e=n).Lnext,e.Lface=null,null===e.Rface&&(e.Onext===e?this.killVertex_(e.Org,null):(e.Org.anEdge=e.Onext,this.splice_(e,e.Oprev)),(i=e.Sym).Onext===i?this.killVertex_(i.Org,null):(i.Org.anEdge=i.Onext,this.splice_(i,i.Oprev)),this.killEdge_(e))}while(e!=o);s=t.prev,(r=t.next).prev=s,s.next=r},t.prototype.countFaceVerts_=function(t){var e=t.anEdge,n=0;do{n++,e=e.Lnext}while(e!==t.anEdge);return n},t.prototype.mergeConvexFaces=function(t){var e,n,i,s,r;for(e=this.fHead.next;e!==this.fHead;e=e.next)if(e.inside)for(r=(n=e.anEdge).Org;i=n.Lnext,(s=n.Sym)&&s.Lface&&s.Lface.inside&&this.countFaceVerts_(e)+this.countFaceVerts_(s.Lface)-2<=t&&R.vertCCW(n.Lprev.Org,n.Org,s.Lnext.Lnext.Org)&&R.vertCCW(s.Lprev.Org,s.Org,n.Lnext.Lnext.Org)&&(i=s.Lnext,this.delete(s),n=null,s=null),!n||n.Lnext.Org!==r;)n=i;return!0},t.prototype.check=function(){var t,e,n,i,s,r,o=this.fHead,a=this.vHead,h=this.eHead;for(e=o,e=o;(t=e.next)!==o;e=t){B(t.prev===e),s=t.anEdge;do{B(s.Sym!==s),B(s.Sym.Sym===s),B(s.Lnext.Onext.Sym===s),B(s.Onext.Sym.Lnext===s),B(s.Lface===t),s=s.Lnext}while(s!==t.anEdge)}for(B(t.prev===e&&null===t.anEdge),i=a,i=a;(n=i.next)!==a;i=n){B(n.prev===i),s=n.anEdge;do{B(s.Sym!==s),B(s.Sym.Sym===s),B(s.Lnext.Onext.Sym===s),B(s.Onext.Sym.Lnext===s),B(s.Org===n),s=s.Onext}while(s!==n.anEdge)}for(B(n.prev===i&&null===n.anEdge),r=h,r=h;(s=r.next)!==h;r=s)B(s.Sym.next===r.Sym),B(s.Sym!==s),B(s.Sym.Sym===s),B(null!==s.Org),B(null!==s.Dst),B(s.Lnext.Onext.Sym===s),B(s.Onext.Sym.Lnext===s);B(s.Sym.next===r.Sym&&s.Sym===this.eHeadSym&&s.Sym.Sym===s&&null===s.Org&&null===s.Dst&&null===s.Lface&&null===s.Rface)},t}(),G=function(){this.handle=null},N=function(){this.key=null,this.node=0},H=function(){function t(t,e){this.leq=e,this.max=0,this.nodes=[],this.handles=[],this.initialized=!1,this.freeList=0,this.size=0,this.max=t,this.nodes=[],this.handles=[];for(var n=0;n<t+1;n++)this.nodes[n]=new G,this.handles[n]=new N;this.initialized=!1,this.nodes[1].handle=1,this.handles[1].key=null}return t.prototype.floatDown_=function(t){var e,n,i,s=this.nodes,r=this.handles;for(e=s[t].handle;;){if((i=t<<1)<this.size&&this.leq(r[s[i+1].handle].key,r[s[i].handle].key)&&++i,B(i<=this.max),n=s[i].handle,i>this.size||this.leq(r[e].key,r[n].key)){s[t].handle=e,r[e].node=t;break}s[t].handle=n,r[n].node=t,t=i}},t.prototype.floatUp_=function(t){var e,n,i,s=this.nodes,r=this.handles;for(e=s[t].handle;;){if(n=s[i=t>>1].handle,0===i||this.leq(r[n].key,r[e].key)){s[t].handle=e,r[e].node=t;break}s[t].handle=n,r[n].node=t,t=i}},t.prototype.init=function(){for(var t=this.size;t>=1;--t)this.floatDown_(t);this.initialized=!0},t.prototype.min=function(){return this.handles[this.nodes[1].handle].key},t.prototype.insert=function(t){var e,n;if(2*(e=++this.size)>this.max){var i,s;for(this.max*=2,s=this.nodes.length,this.nodes.length=this.max+1,i=s;i<this.nodes.length;i++)this.nodes[i]=new G;for(s=this.handles.length,this.handles.length=this.max+1,i=s;i<this.handles.length;i++)this.handles[i]=new N}return 0===this.freeList?n=e:(n=this.freeList,this.freeList=this.handles[n].node),this.nodes[e].handle=n,this.handles[n].node=e,this.handles[n].key=t,this.initialized&&this.floatUp_(e),n},t.prototype.extractMin=function(){var t=this.nodes,e=this.handles,n=t[1].handle,i=e[n].key;return this.size>0&&(t[1].handle=t[this.size].handle,e[t[1].handle].node=1,e[n].key=null,e[n].node=this.freeList,this.freeList=n,--this.size,this.size>0&&this.floatDown_(1)),i},t.prototype.delete=function(t){var e,n=this.nodes,i=this.handles;B(t>=1&&t<=this.max&&null!==i[t].key),n[e=i[t].node].handle=n[this.size].handle,i[n[e].handle].node=e,--this.size,e<=this.size&&(e<=1||this.leq(i[n[e>>1].handle].key,i[n[e].handle].key)?this.floatDown_(e):this.floatUp_(e)),i[t].key=null,i[t].node=this.freeList,this.freeList=t},t}(),q=function(){this.eUp=null,this.nodeUp=null,this.windingNumber=0,this.inside=!1,this.sentinel=!1,this.dirty=!1,this.fixUpperEdge=!1},W=function(){this.key=null,this.next=null,this.prev=null},V=function(){function t(t,e){this.frame=t,this.leq=e,this.head=new W,this.head.next=this.head,this.head.prev=this.head}return t.prototype.min=function(){return this.head.next},t.prototype.max=function(){return this.head.prev},t.prototype.insert=function(t){return this.insertBefore(this.head,t)},t.prototype.search=function(t){var e=this.head;do{e=e.next}while(null!==e.key&&!this.leq(this.frame,t,e.key));return e},t.prototype.insertBefore=function(t,e){do{t=t.prev}while(null!==t.key&&!this.leq(this.frame,t.key,e));var n=new W;return n.key=e,n.next=t.next,t.next.prev=n,n.prev=t,t.next=n,n},t.prototype.delete=function(t){t.next.prev=t.prev,t.prev.next=t.next},t}(),j=function(){function t(){}return t.regionBelow=function(t){return t.nodeUp.prev.key},t.regionAbove=function(t){return t.nodeUp.next.key},t.debugEvent=function(t){},t.addWinding=function(t,e){t.winding+=e.winding,t.Sym.winding+=e.Sym.winding},t.edgeLeq=function(t,e,n){var i=t.event,s=e.eUp,r=n.eUp;return s.Dst===i?r.Dst===i?R.vertLeq(s.Org,r.Org)?R.edgeSign(r.Dst,s.Org,r.Org)<=0:R.edgeSign(s.Dst,r.Org,s.Org)>=0:R.edgeSign(r.Dst,i,r.Org)<=0:r.Dst===i?R.edgeSign(s.Dst,i,s.Org)>=0:R.edgeEval(s.Dst,i,s.Org)>=R.edgeEval(r.Dst,i,r.Org)},t.deleteRegion=function(t,e){e.fixUpperEdge&&B(0===e.eUp.winding),e.eUp.activeRegion=null,t.dict.delete(e.nodeUp)},t.fixUpperEdge=function(t,e,n){B(e.fixUpperEdge),t.mesh.delete(e.eUp),e.fixUpperEdge=!1,e.eUp=n,n.activeRegion=e},t.topLeftRegion=function(e,n){var i,s=n.eUp.Org;do{n=t.regionAbove(n)}while(n.eUp.Org===s);if(n.fixUpperEdge){if(null===(i=e.mesh.connect(t.regionBelow(n).eUp.Sym,n.eUp.Lnext)))return null;t.fixUpperEdge(e,n,i),n=t.regionAbove(n)}return n},t.topRightRegion=function(e){var n=e.eUp.Dst;do{e=t.regionAbove(e)}while(e.eUp.Dst===n);return e},t.addRegionBelow=function(t,e,n){var i=new q;return i.eUp=n,i.nodeUp=t.dict.insertBefore(e.nodeUp,i),i.fixUpperEdge=!1,i.sentinel=!1,i.dirty=!1,n.activeRegion=i,i},t.isWindingInside=function(t,e){switch(t.windingRule){case U.ODD:return!!(1&e);case U.NONZERO:return 0!==e;case U.POSITIVE:return e>0;case U.NEGATIVE:return e<0;case U.ABS_GEQ_TWO:return e>=2||e<=-2}throw new Error("Invalid winding rulle")},t.computeWinding=function(e,n){n.windingNumber=t.regionAbove(n).windingNumber+n.eUp.winding,n.inside=t.isWindingInside(e,n.windingNumber)},t.finishRegion=function(e,n){var i=n.eUp,s=i.Lface;s.inside=n.inside,s.anEdge=i,t.deleteRegion(e,n)},t.finishLeftRegions=function(e,n,i){for(var s,r=null,o=n,a=n.eUp;o!==i;){if(o.fixUpperEdge=!1,(s=(r=t.regionBelow(o)).eUp).Org!=a.Org){if(!r.fixUpperEdge){t.finishRegion(e,o);break}s=e.mesh.connect(a.Lprev,s.Sym),t.fixUpperEdge(e,r,s)}a.Onext!==s&&(e.mesh.splice(s.Oprev,s),e.mesh.splice(a,s)),t.finishRegion(e,o),a=r.eUp,o=r}return a},t.addRightEdges=function(e,n,i,s,r,o){var a,h,l,c,d=!0;l=i;do{B(R.vertLeq(l.Org,l.Dst)),t.addRegionBelow(e,n,l.Sym),l=l.Onext}while(l!==s);for(null===r&&(r=t.regionBelow(n).eUp.Rprev),h=n,c=r;(l=(a=t.regionBelow(h)).eUp.Sym).Org===c.Org;)l.Onext!==c&&(e.mesh.splice(l.Oprev,l),e.mesh.splice(c.Oprev,l)),a.windingNumber=h.windingNumber-l.winding,a.inside=t.isWindingInside(e,a.windingNumber),h.dirty=!0,!d&&t.checkForRightSplice(e,h)&&(t.addWinding(l,c),t.deleteRegion(e,h),e.mesh.delete(c)),d=!1,h=a,c=l;h.dirty=!0,B(h.windingNumber-l.winding===a.windingNumber),o&&t.walkDirtyRegions(e,h)},t.spliceMergeVertices=function(t,e,n){t.mesh.splice(e,n)},t.vertexWeights=function(t,e,n){var i=R.vertL1dist(e,t),s=R.vertL1dist(n,t),r=.5*s/(i+s),o=.5*i/(i+s);t.coords[0]+=r*e.coords[0]+o*n.coords[0],t.coords[1]+=r*e.coords[1]+o*n.coords[1],t.coords[2]+=r*e.coords[2]+o*n.coords[2]},t.getIntersectData=function(e,n,i,s,r,o){n.coords[0]=n.coords[1]=n.coords[2]=0,n.idx=-1,t.vertexWeights(n,i,s),t.vertexWeights(n,r,o)},t.checkForRightSplice=function(e,n){var i=t.regionBelow(n),s=n.eUp,r=i.eUp;if(R.vertLeq(s.Org,r.Org)){if(R.edgeSign(r.Dst,s.Org,r.Org)>0)return!1;R.vertEq(s.Org,r.Org)?s.Org!==r.Org&&(e.pq.delete(s.Org.pqHandle),t.spliceMergeVertices(e,r.Oprev,s)):(e.mesh.splitEdge(r.Sym),e.mesh.splice(s,r.Oprev),n.dirty=i.dirty=!0)}else{if(R.edgeSign(s.Dst,r.Org,s.Org)<0)return!1;t.regionAbove(n).dirty=n.dirty=!0,e.mesh.splitEdge(s.Sym),e.mesh.splice(r.Oprev,s)}return!0},t.checkForLeftSplice=function(e,n){var i,s=t.regionBelow(n),r=n.eUp,o=s.eUp;if(B(!R.vertEq(r.Dst,o.Dst)),R.vertLeq(r.Dst,o.Dst)){if(R.edgeSign(r.Dst,o.Dst,r.Org)<0)return!1;t.regionAbove(n).dirty=n.dirty=!0,i=e.mesh.splitEdge(r),e.mesh.splice(o.Sym,i),i.Lface.inside=n.inside}else{if(R.edgeSign(o.Dst,r.Dst,o.Org)>0)return!1;n.dirty=s.dirty=!0,i=e.mesh.splitEdge(o),e.mesh.splice(r.Lnext,o.Sym),i.Rface.inside=n.inside}return!0},t.checkForIntersect=function(e,n){var i,s,r=t.regionBelow(n),o=n.eUp,a=r.eUp,h=o.Org,l=a.Org,c=o.Dst,d=a.Dst,u=new k;if(B(!R.vertEq(d,c)),B(R.edgeSign(c,e.event,h)<=0),B(R.edgeSign(d,e.event,l)>=0),B(h!==e.event&&l!==e.event),B(!n.fixUpperEdge&&!r.fixUpperEdge),h===l)return!1;if(Math.min(h.t,c.t)>Math.max(l.t,d.t))return!1;if(R.vertLeq(h,l)){if(R.edgeSign(d,h,l)>0)return!1}else if(R.edgeSign(c,l,h)<0)return!1;return t.debugEvent(e),R.intersect(c,h,d,l,u),B(Math.min(h.t,c.t)<=u.t),B(u.t<=Math.max(l.t,d.t)),B(Math.min(d.s,c.s)<=u.s),B(u.s<=Math.max(l.s,h.s)),R.vertLeq(u,e.event)&&(u.s=e.event.s,u.t=e.event.t),i=R.vertLeq(h,l)?h:l,R.vertLeq(i,u)&&(u.s=i.s,u.t=i.t),R.vertEq(u,h)||R.vertEq(u,l)?(t.checkForRightSplice(e,n),!1):!R.vertEq(c,e.event)&&R.edgeSign(c,e.event,u)>=0||!R.vertEq(d,e.event)&&R.edgeSign(d,e.event,u)<=0?d===e.event?(e.mesh.splitEdge(o.Sym),e.mesh.splice(a.Sym,o),n=t.topLeftRegion(e,n),o=t.regionBelow(n).eUp,t.finishLeftRegions(e,t.regionBelow(n),r),t.addRightEdges(e,n,o.Oprev,o,o,!0),!0):c===e.event?(e.mesh.splitEdge(a.Sym),e.mesh.splice(o.Lnext,a.Oprev),r=n,n=t.topRightRegion(n),s=t.regionBelow(n).eUp.Rprev,r.eUp=a.Oprev,a=t.finishLeftRegions(e,r,null),t.addRightEdges(e,n,a.Onext,o.Rprev,s,!0),!0):(R.edgeSign(c,e.event,u)>=0&&(t.regionAbove(n).dirty=n.dirty=!0,e.mesh.splitEdge(o.Sym),o.Org.s=e.event.s,o.Org.t=e.event.t),R.edgeSign(d,e.event,u)<=0&&(n.dirty=r.dirty=!0,e.mesh.splitEdge(a.Sym),a.Org.s=e.event.s,a.Org.t=e.event.t),!1):(e.mesh.splitEdge(o.Sym),e.mesh.splitEdge(a.Sym),e.mesh.splice(a.Oprev,o),o.Org.s=u.s,o.Org.t=u.t,o.Org.pqHandle=e.pq.insert(o.Org),t.getIntersectData(e,o.Org,h,c,l,d),t.regionAbove(n).dirty=n.dirty=r.dirty=!0,!1)},t.walkDirtyRegions=function(e,n){for(var i,s,r=t.regionBelow(n);;){for(;r.dirty;)n=r,r=t.regionBelow(r);if(!n.dirty&&(r=n,null===(n=t.regionAbove(n))||!n.dirty))return;if(n.dirty=!1,i=n.eUp,s=r.eUp,i.Dst!==s.Dst&&t.checkForLeftSplice(e,n)&&(r.fixUpperEdge?(t.deleteRegion(e,r),e.mesh.delete(s),s=(r=t.regionBelow(n)).eUp):n.fixUpperEdge&&(t.deleteRegion(e,n),e.mesh.delete(i),i=(n=t.regionAbove(r)).eUp)),i.Org!==s.Org)if(i.Dst===s.Dst||n.fixUpperEdge||r.fixUpperEdge||i.Dst!==e.event&&s.Dst!==e.event)t.checkForRightSplice(e,n);else if(t.checkForIntersect(e,n))return;i.Org===s.Org&&i.Dst===s.Dst&&(t.addWinding(s,i),t.deleteRegion(e,n),e.mesh.delete(i),n=t.regionAbove(r))}},t.connectRightVertex=function(e,n,i){var s,r=i.Onext,o=t.regionBelow(n),a=n.eUp,h=o.eUp,l=!1;a.Dst!==h.Dst&&t.checkForIntersect(e,n),R.vertEq(a.Org,e.event)&&(e.mesh.splice(r.Oprev,a),n=t.topLeftRegion(e,n),r=t.regionBelow(n).eUp,t.finishLeftRegions(e,t.regionBelow(n),o),l=!0),R.vertEq(h.Org,e.event)&&(e.mesh.splice(i,h.Oprev),i=t.finishLeftRegions(e,o,null),l=!0),l?t.addRightEdges(e,n,i.Onext,r,r,!0):(s=R.vertLeq(h.Org,a.Org)?h.Oprev:a,s=e.mesh.connect(i.Lprev,s),t.addRightEdges(e,n,s,s.Onext,s.Onext,!1),s.Sym.activeRegion.fixUpperEdge=!0,t.walkDirtyRegions(e,n))},t.connectLeftDegenerate=function(e,n,i){var s,r,o,a,h;return s=n.eUp,R.vertEq(s.Org,i)?(B(!1),void t.spliceMergeVertices(e,s,i.anEdge)):R.vertEq(s.Dst,i)?(B(!1),n=t.topRightRegion(n),r=a=(o=(h=t.regionBelow(n)).eUp.Sym).Onext,h.fixUpperEdge&&(B(r!==o),t.deleteRegion(e,h),e.mesh.delete(o),o=r.Oprev),e.mesh.splice(i.anEdge,o),R.edgeGoesLeft(r)||(r=null),void t.addRightEdges(e,n,o.Onext,a,r,!0)):(e.mesh.splitEdge(s.Sym),n.fixUpperEdge&&(e.mesh.delete(s.Onext),n.fixUpperEdge=!1),e.mesh.splice(i.anEdge,s),void t.sweepEvent(e,i))},t.connectLeftVertex=function(e,n){var i,s,r,o,a,h,l=new q;if(l.eUp=n.anEdge.Sym,i=e.dict.search(l).key,s=t.regionBelow(i))if(o=i.eUp,a=s.eUp,0!==R.edgeSign(o.Dst,n,o.Org))if(r=R.vertLeq(a.Dst,o.Dst)?i:s,i.inside||r.fixUpperEdge){if(r===i)h=e.mesh.connect(n.anEdge.Sym,o.Lnext);else h=e.mesh.connect(a.Dnext,n.anEdge).Sym;r.fixUpperEdge?t.fixUpperEdge(e,r,h):t.computeWinding(e,t.addRegionBelow(e,i,h)),t.sweepEvent(e,n)}else t.addRightEdges(e,i,n.anEdge,n.anEdge,null,!0);else t.connectLeftDegenerate(e,i,n)},t.sweepEvent=function(e,n){e.event=n,t.debugEvent(e);for(var i=n.anEdge;null===i.activeRegion;)if((i=i.Onext)===n.anEdge)return void t.connectLeftVertex(e,n);var s=t.topLeftRegion(e,i.activeRegion);B(null!==s);var r=t.regionBelow(s),o=r.eUp,a=t.finishLeftRegions(e,r,null);a.Onext===o?t.connectRightVertex(e,s,a):t.addRightEdges(e,s,a.Onext,o,o,!0)},t.addSentinel=function(t,e,n,i){var s=new q,r=t.mesh.makeEdge();r.Org.s=n,r.Org.t=i,r.Dst.s=e,r.Dst.t=i,t.event=r.Dst,s.eUp=r,s.windingNumber=0,s.inside=!1,s.fixUpperEdge=!1,s.sentinel=!0,s.dirty=!1,s.nodeUp=t.dict.insert(s)},t.initEdgeDict=function(e){e.dict=new V(e,t.edgeLeq);var n=e.bmax[0]-e.bmin[0],i=e.bmax[1]-e.bmin[1],s=e.bmin[0]-n,r=e.bmax[0]+n,o=e.bmin[1]-i,a=e.bmax[1]+i;t.addSentinel(e,s,r,o),t.addSentinel(e,s,r,a)},t.doneEdgeDict=function(e){for(var n,i=0;null!==(n=e.dict.min().key);)n.sentinel||(B(n.fixUpperEdge),B(1===++i)),B(0===n.windingNumber),t.deleteRegion(e,n)},t.removeDegenerateEdges=function(e){var n,i,s,r=e.mesh.eHead;for(n=r.next;n!==r;n=i)i=n.next,s=n.Lnext,R.vertEq(n.Org,n.Dst)&&n.Lnext.Lnext!==n&&(t.spliceMergeVertices(e,s,n),e.mesh.delete(n),s=(n=s).Lnext),s.Lnext===n&&(s!==n&&(s!==i&&s!==i.Sym||(i=i.next),e.mesh.delete(s)),n!==i&&n!==i.Sym||(i=i.next),e.mesh.delete(n))},t.initPriorityQ=function(t){var e,n,i,s=0;for(n=(i=t.mesh.vHead).next;n!==i;n=n.next)s++;for(s+=8,e=t.pq=new H(s,R.vertLeq),n=(i=t.mesh.vHead).next;n!==i;n=n.next)n.pqHandle=e.insert(n);return n===i&&(e.init(),!0)},t.donePriorityQ=function(t){t.pq=null},t.removeDegenerateFaces=function(e,n){var i,s,r;for(i=n.fHead.next;i!==n.fHead;i=s)s=i.next,B((r=i.anEdge).Lnext!==r),r.Lnext.Lnext===r&&(t.addWinding(r.Onext,r),e.mesh.delete(r));return!0},t.computeInterior=function(e,n){var i,s;if(void 0===n&&(n=!0),t.removeDegenerateEdges(e),!t.initPriorityQ(e))return!1;for(t.initEdgeDict(e);null!==(i=e.pq.extractMin());){for(;null!==(s=e.pq.min())&&R.vertEq(s,i);)s=e.pq.extractMin(),t.spliceMergeVertices(e,i.anEdge,s.anEdge);t.sweepEvent(e,i)}return e.event=e.dict.min().key.eUp.Org,t.debugEvent(e),t.doneEdgeDict(e),t.donePriorityQ(e),!!t.removeDegenerateFaces(e,e.mesh)&&(n&&e.mesh.check(),!0)},t}(),$=function(){function t(){this.mesh=new M,this.normal=[0,0,0],this.sUnit=[0,0,0],this.tUnit=[0,0,0],this.bmin=[0,0],this.bmax=[0,0],this.windingRule=U.ODD,this.dict=null,this.pq=null,this.event=null,this.vertexIndexCounter=0,this.vertices=[],this.vertexIndices=[],this.vertexCount=0,this.elements=[],this.elementCount=0}return t.prototype.dot_=function(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]},t.prototype.normalize_=function(t){var e=t[0]*t[0]+t[1]*t[1]+t[2]*t[2];if(!e)throw"Zero-size vector!";e=Math.sqrt(e),t[0]/=e,t[1]/=e,t[2]/=e},t.prototype.longAxis_=function(t){var e=0;return Math.abs(t[1])>Math.abs(t[0])&&(e=1),Math.abs(t[2])>Math.abs(t[e])&&(e=2),e},t.prototype.computeNormal_=function(t){var e,n,i,s,r,o,a=[0,0,0],h=[0,0,0],l=[0,0,0],c=[0,0,0],d=[0,0,0],u=[null,null,null],f=[null,null,null],g=this.mesh.vHead;e=g.next;for(var p=0;p<3;++p)s=e.coords[p],h[p]=s,f[p]=e,a[p]=s,u[p]=e;for(e=g.next;e!==g;e=e.next)for(var y=0;y<3;++y)(s=e.coords[y])<h[y]&&(h[y]=s,f[y]=e),s>a[y]&&(a[y]=s,u[y]=e);var m=0;if(a[1]-h[1]>a[0]-h[0]&&(m=1),a[2]-h[2]>a[m]-h[m]&&(m=2),h[m]>=a[m])return t[0]=0,t[1]=0,void(t[2]=1);for(o=0,n=f[m],i=u[m],l[0]=n.coords[0]-i.coords[0],l[1]=n.coords[1]-i.coords[1],l[2]=n.coords[2]-i.coords[2],e=g.next;e!==g;e=e.next)c[0]=e.coords[0]-i.coords[0],c[1]=e.coords[1]-i.coords[1],c[2]=e.coords[2]-i.coords[2],d[0]=l[1]*c[2]-l[2]*c[1],d[1]=l[2]*c[0]-l[0]*c[2],d[2]=l[0]*c[1]-l[1]*c[0],(r=d[0]*d[0]+d[1]*d[1]+d[2]*d[2])>o&&(o=r,t[0]=d[0],t[1]=d[1],t[2]=d[2]);o<=0&&(t[0]=t[1]=t[2]=0,t[this.longAxis_(l)]=1)},t.prototype.checkOrientation_=function(){for(var t,e,n=this.mesh.fHead,i=this.mesh.vHead,s=0,r=n.next;r!==n;r=r.next)if(!((e=r.anEdge).winding<=0))do{s+=(e.Org.s-e.Dst.s)*(e.Org.t+e.Dst.t),e=e.Lnext}while(e!==r.anEdge);if(s<0){for(t=i.next;t!==i;t=t.next)t.t=-t.t;this.tUnit[0]=-this.tUnit[0],this.tUnit[1]=-this.tUnit[1],this.tUnit[2]=-this.tUnit[2]}},t.prototype.projectPolygon_=function(){var t,e,n=this.mesh.vHead,i=[0,0,0],s=!1;i[0]=this.normal[0],i[1]=this.normal[1],i[2]=this.normal[2],i[0]||i[1]||i[2]||(this.computeNormal_(i),s=!0),t=this.sUnit,e=this.tUnit;var r=this.longAxis_(i);t[r]=0,t[(r+1)%3]=1,t[(r+2)%3]=0,e[r]=0,e[(r+1)%3]=0,e[(r+2)%3]=i[r]>0?1:-1;for(var o=n.next;o!==n;o=o.next)o.s=this.dot_(o.coords,t),o.t=this.dot_(o.coords,e);s&&this.checkOrientation_();for(var a=!0,h=n.next;h!==n;h=h.next)a?(this.bmin[0]=this.bmax[0]=h.s,this.bmin[1]=this.bmax[1]=h.t,a=!1):(h.s<this.bmin[0]&&(this.bmin[0]=h.s),h.s>this.bmax[0]&&(this.bmax[0]=h.s),h.t<this.bmin[1]&&(this.bmin[1]=h.t),h.t>this.bmax[1]&&(this.bmax[1]=h.t))},t.prototype.addWinding_=function(t,e){t.winding+=e.winding,t.Sym.winding+=e.Sym.winding},t.prototype.tessellateMonoRegion_=function(t,e){var n,i;if((n=e.anEdge).Lnext===n||n.Lnext.Lnext===n)throw"Mono region invalid";for(;R.vertLeq(n.Dst,n.Org);n=n.Lprev);for(;R.vertLeq(n.Org,n.Dst);n=n.Lnext);i=n.Lprev;for(;n.Lnext!==i;)if(R.vertLeq(n.Dst,i.Org)){for(;i.Lnext!==n&&(R.edgeGoesLeft(i.Lnext)||R.edgeSign(i.Org,i.Dst,i.Lnext.Dst)<=0);)i=t.connect(i.Lnext,i).Sym;i=i.Lprev}else{for(;i.Lnext!==n&&(R.edgeGoesRight(n.Lprev)||R.edgeSign(n.Dst,n.Org,n.Lprev.Org)>=0);)n=t.connect(n,n.Lprev).Sym;n=n.Lnext}if(i.Lnext===n)throw"Mono region invalid";for(;i.Lnext.Lnext!==n;)i=t.connect(i.Lnext,i).Sym;return!0},t.prototype.tessellateInterior_=function(t){for(var e,n=t.fHead.next;n!==t.fHead;n=e)if(e=n.next,n.inside&&!this.tessellateMonoRegion_(t,n))return!1;return!0},t.prototype.discardExterior_=function(t){for(var e,n=t.fHead.next;n!==t.fHead;n=e)e=n.next,n.inside||t.zapFace(n)},t.prototype.setWindingNumber_=function(t,e,n){for(var i,s=t.eHead.next;s!==t.eHead;s=i)i=s.next,s.Rface.inside!==s.Lface.inside?s.winding=s.Lface.inside?e:-e:n?t.delete(s):s.winding=0},t.prototype.getNeighbourFace_=function(t){return t.Rface&&t.Rface.inside?t.Rface.n:-1},t.prototype.outputPolymesh_=function(t,e,n,i){var s,r,o=0,a=0;n>3&&t.mergeConvexFaces(n);for(var h=t.vHead.next;h!==t.vHead;h=h.next)h.n=-1;for(var l=t.fHead.next;l!==t.fHead;l=l.next)if(l.n=-1,l.inside){s=l.anEdge,r=0;do{-1===(h=s.Org).n&&(h.n=a,a++),r++,s=s.Lnext}while(s!==l.anEdge);if(r>n)throw"Face vertex greater that support polygon";l.n=o,++o}this.elementCount=o,e===A.CONNECTED_POLYGONS&&(o*=2),this.elements=[],this.elements.length=o*n,this.vertexCount=a,this.vertices=[],this.vertices.length=a*i,this.vertexIndices=[],this.vertexIndices.length=a;for(h=t.vHead.next;h!==t.vHead;h=h.next)if(-1!==h.n){var c=h.n*i;this.vertices[c+0]=h.coords[0],this.vertices[c+1]=h.coords[1],i>2&&(this.vertices[c+2]=h.coords[2]),this.vertexIndices[h.n]=h.idx}var d=0;for(l=t.fHead.next;l!==t.fHead;l=l.next)if(l.inside){s=l.anEdge,r=0;do{h=s.Org;this.elements[d++]=h.n,r++,s=s.Lnext}while(s!==l.anEdge);for(var u=r;u<n;++u)this.elements[d++]=-1;if(e===A.CONNECTED_POLYGONS){s=l.anEdge;do{this.elements[d++]=this.getNeighbourFace_(s),s=s.Lnext}while(s!==l.anEdge);for(var f=r;f<n;++f)this.elements[d++]=-1}}},t.prototype.outputContours_=function(t,e){var n,i,s=0,r=0;this.vertexCount=0,this.elementCount=0;for(var o=t.fHead.next;o!==t.fHead;o=o.next)if(o.inside){i=n=o.anEdge;do{this.vertexCount++,n=n.Lnext}while(n!==i);this.elementCount++}this.elements=[],this.elements.length=2*this.elementCount,this.vertices=[],this.vertices.length=this.vertexCount*e,this.vertexIndices=[],this.vertexIndices.length=this.vertexCount;var a=0,h=0,l=0;s=0;for(o=t.fHead.next;o!==t.fHead;o=o.next)if(o.inside){r=0,i=n=o.anEdge;do{this.vertices[a++]=n.Org.coords[0],this.vertices[a++]=n.Org.coords[1],e>2&&(this.vertices[a++]=n.Org.coords[2]),this.vertexIndices[h++]=n.Org.idx,r++,n=n.Lnext}while(n!==i);this.elements[l++]=s,this.elements[l++]=r,s+=r}},t.prototype.addContour=function(t,e){null===this.mesh&&(this.mesh=new M),t<2&&(t=2),t>3&&(t=3);for(var n=null,i=0;i<e.length;i+=t)null===n?(n=this.mesh.makeEdge(),this.mesh.splice(n,n.Sym)):(this.mesh.splitEdge(n),n=n.Lnext),n.Org.coords[0]=e[i+0],n.Org.coords[1]=e[i+1],n.Org.coords[2]=t>2?e[i+2]:0,n.Org.idx=this.vertexIndexCounter++,n.winding=1,n.Sym.winding=-1},t.prototype.tesselate=function(t,e,n,i,s,r){if(void 0===t&&(t=U.ODD),void 0===e&&(e=A.POLYGONS),void 0===r&&(r=!0),this.vertices=[],this.elements=[],this.vertexIndices=[],this.vertexIndexCounter=0,s&&(this.normal[0]=s[0],this.normal[1]=s[1],this.normal[2]=s[2]),this.windingRule=t,i<2&&(i=2),i>3&&(i=3),!this.mesh)return!1;this.projectPolygon_(),j.computeInterior(this,r);var o=this.mesh;return e===A.BOUNDARY_CONTOURS?this.setWindingNumber_(o,1,!0):this.tessellateInterior_(o),r&&o.check(),e===A.BOUNDARY_CONTOURS?this.outputContours_(o,i):this.outputPolymesh_(o,e,n,i),!0},t}();U.ODD,U.NONZERO,U.POSITIVE,U.NEGATIVE,U.ABS_GEQ_TWO,A.POLYGONS,A.CONNECTED_POLYGONS,A.BOUNDARY_CONTOURS;class Y{process(t,n=!0,i=!1){if(0===t.length)return{triangles:{vertices:[],indices:[]},contours:[]};const s=t.filter(t=>t.points.length>=3);return 0===s.length?{triangles:{vertices:[],indices:[]},contours:[]}:(e.log(`Tessellator: removeOverlaps=${n}, processing ${s.length} paths`),this.tessellate(s,n,i))}tessellate(t,n,i){const s=i||n?t:t.map(t=>this.reverseWinding(t));let r=this.pathsToContours(s);if(n){e.log("Two-pass: boundary extraction then triangulation");const t=this.performTessellation(r,A.BOUNDARY_CONTOURS);if(!t)return e.warn("Tess2 returned empty result from boundary pass"),{triangles:{vertices:[],indices:[]},contours:[]};r=this.boundaryToContours(t),e.log(`Boundary pass created ${r.length} contours. Starting triangulation pass.`)}else e.log("Single-pass triangulation for "+(i?"CFF":"TTF"));const o=this.performTessellation(r,A.POLYGONS);if(!o){const t=n?"Tess2 returned empty result from triangulation pass":"Tess2 returned empty result from single-pass triangulation";return e.warn(t),{triangles:{vertices:[],indices:[]},contours:r}}return{triangles:{vertices:Array.from(o.vertices),indices:Array.from(o.elements)},contours:r}}pathsToContours(t){return t.map(t=>{const e=[];for(const n of t.points)e.push(n.x,n.y);return e})}performTessellation(t,e){const n=function(t){var e=t.windingRule,n=void 0===e?U.ODD:e,i=t.elementType,s=void 0===i?A.POLYGONS:i,r=t.polySize,o=void 0===r?3:r,a=t.vertexSize,h=void 0===a?2:a,l=t.normal,c=void 0===l?[0,0,1]:l,d=t.contours,u=void 0===d?[]:d,f=t.strict,g=void 0===f||f,p=t.debug,y=void 0!==p&&p;if(!u&&g)throw new Error("Contours can't be empty");if(u){for(var m=new $,x=0;x<u.length;x++)m.addContour(h||2,u[x]);return m.tesselate(n,s,o,h,c,g),{vertices:m.vertices,vertexIndices:m.vertexIndices,vertexCount:m.vertexCount,elements:m.elements,elementCount:m.elementCount,mesh:y?m.mesh:void 0}}}({contours:t,windingRule:U.NONZERO,elementType:e,polySize:3,vertexSize:2,strict:!1});return n?.vertices&&n?.elements?n:null}boundaryToContours(t){const e=[];for(let n=0;n<t.elements.length;n+=2){const i=t.elements[n],s=t.elements[n+1],r=[];for(let e=0;e<s;e++){const n=2*(i+e);r.push(t.vertices[n],t.vertices[n+1])}r.length>2&&(r[0]===r[r.length-2]&&r[1]===r[r.length-1]||r.push(r[0],r[1])),e.push(r)}return e}reverseWinding(t){return{...t,points:[...t.points].reverse()}}}class Q{constructor(){}extrude(t,e=0,n){const i=[],s=[],r=[];if(0===e)this.addFlatFaces(t.triangles,i,s,r);else{this.addFrontAndBackFaces(t.triangles,i,s,r,e,n);for(const n of t.contours)this.addSideWalls(n,i,s,r,e)}return{vertices:i,normals:s,indices:r}}addFlatFaces(t,e,n,i){const s=e.length/3,r=t.vertices,o=t.indices;for(let t=0;t<r.length;t+=2)e.push(r[t],r[t+1],0),n.push(0,0,-1);for(let t=0;t<o.length;t++)i.push(s+o[t])}addFrontAndBackFaces(t,e,n,i,s,r){const o=e.length/3,a=t.vertices,h=t.indices;for(let t=0;t<a.length;t+=2)e.push(a[t],a[t+1],0),n.push(0,0,-1);const l=25e-6*r,c=s<=l?l:s;for(let t=0;t<a.length;t+=2)e.push(a[t],a[t+1],c),n.push(0,0,1);const d=a.length/2;for(let t=0;t<h.length;t++)i.push(o+h[t]);for(let t=h.length-1;t>=0;t--)i.push(o+h[t]+d)}addSideWalls(t,e,n,i,s){for(let r=0;r<t.length-2;r+=2){const o=t[r],a=t[r+1],h=t[r+2],l=t[r+3],c=new F(h-o,l-a),d=new F(c.y,-c.x).normalize(),u=e.length/3;e.push(o,a,0,h,l,0,o,a,s,h,l,s),n.push(d.x,d.y,0,d.x,d.y,0,d.x,d.y,0,d.x,d.y,0),i.push(u,u+1,u+2,u+1,u+3,u+2)}}}class X{constructor(){}cluster(t,e){return 0===t.length?[]:this.clusterSweepLine(t,e)}clusterSweepLine(t,e){const n=t.length;if(n<=1)return 0===n?[]:[[0]];const i=new Array(n),s=new Array(2*n);let r=0;for(let o=0;o<n;o++)i[o]=this.getWorldBounds(t[o],e[o]),s[r++]=[i[o].minX,0,o],s[r++]=[i[o].maxX,1,o];s.sort((t,e)=>t[0]-e[0]||t[1]-e[1]);const o=Array.from({length:n},(t,e)=>e),a=new Array(n).fill(0);function h(t){return o[t]===t?t:o[t]=h(o[t])}function l(t,e){const n=h(t),i=h(e);n!==i&&(a[n]<a[i]?o[n]=i:a[n]>a[i]?o[i]=n:(o[i]=n,a[n]++))}const c=new Set;for(const[,t,e]of s)if(0===t){const t=i[e];for(const n of c){const s=i[n];t.minY<s.maxY+.001&&t.maxY>s.minY-.001&&l(e,n)}c.add(e)}else c.delete(e);const d=new Map;for(let t=0;t<n;t++){const e=h(t);d.has(e)||d.set(e,[]),d.get(e).push(t)}return Array.from(d.values())}getWorldBounds(t,e){return{minX:t.bounds.min.x+e.x,minY:t.bounds.min.y+e.y,maxX:t.bounds.max.x+e.x,maxY:t.bounds.max.y+e.y}}}class K{constructor(t){this.heap=[],this.itemIndex=new Map,this.compare=t}insert(t){const e=this.itemIndex.get(t);if(void 0!==e)return this.siftUp(e),void this.siftDown(e);const n=this.heap.length;this.heap.push(t),this.itemIndex.set(t,n),this.siftUp(n)}extractMin(){const t=this.heap.length;if(!t)return;if(1===t){const t=this.heap.pop();return this.itemIndex.clear(),t}const e=this.heap[0],n=this.heap.pop();return this.heap[0]=n,this.itemIndex.delete(e),this.itemIndex.set(n,0),this.siftDown(0),e}update(t){const e=this.itemIndex.get(t);void 0!==e?(this.siftUp(e),this.siftDown(e)):this.insert(t)}isEmpty(){return!this.heap.length}swap(t,e){const n=this.heap[t],i=this.heap[e];this.heap[t]=i,this.heap[e]=n,this.itemIndex.set(n,e),this.itemIndex.set(i,t)}siftUp(t){const e=this.heap[t];for(;t>0;){const n=t-1>>1,i=this.heap[n];if(this.compare(e,i)>=0)break;this.heap[t]=i,this.itemIndex.set(i,t),t=n}this.heap[t]=e,this.itemIndex.set(e,t)}siftDown(t){const e=this.heap[t],n=this.heap.length,i=n>>1;for(;t<i;){const i=1+(t<<1),s=i+1;let r=t,o=e;const a=this.heap[i];if(this.compare(a,o)<0&&(r=i,o=a),s<n){const t=this.heap[s];this.compare(t,o)<0&&(r=s,o=t)}if(r===t)break;this.heap[t]=o,this.itemIndex.set(o,t),t=r}this.heap[t]=e,this.itemIndex.set(e,t)}}const Z={enabled:!0,areaThreshold:1,colinearThreshold:.0087,minSegmentLength:10};class J{constructor(t){this.stats={pointsRemovedByVisvalingam:0,pointsRemovedByColinear:0,originalPointCount:0},this.config=t}setConfig(t){this.config=t}optimizePath(t){if(!this.config.enabled||t.points.length<=2)return t;this.stats.originalPointCount+=t.points.length;let e=[...t.points];return e.length<5?t:(e=this.simplifyPathVW(e,this.config.areaThreshold),e.length<3?t:(e=this.removeColinearPoints(e,this.config.colinearThreshold),e.length<3?t:{...t,points:e}))}simplifyPathVW(t,e){if(t.length<=3)return t;const n=t.length,i=t.map((t,e)=>({index:e,area:1/0,prev:null,next:null}));for(let t=0;t<i.length;t++)i[t].prev=i[t-1]||null,i[t].next=i[t+1]||null;const s=new K((t,e)=>t.area-e.area);for(let e=1;e<i.length-1;e++){const n=i[e];n.area=this.calculateTriangleArea(t[n.prev.index],t[n.index],t[n.next.index]),s.insert(n)}let r=n;for(;!s.isEmpty()&&r>3;){const n=s.extractMin();if(!n||n.area>e)break;if(this.config.minSegmentLength>0&&n.prev&&n.next){const e=t[n.prev.index],i=t[n.index],s=t[n.next.index],r=e.distanceTo(i),o=i.distanceTo(s);if(r<this.config.minSegmentLength||o<this.config.minSegmentLength)continue}n.prev&&(n.prev.next=n.next),n.next&&(n.next.prev=n.prev),r--,n.prev&&n.prev.prev&&(n.prev.area=this.calculateTriangleArea(t[n.prev.prev.index],t[n.prev.index],t[n.next.index]),s.update(n.prev)),n.next&&n.next.next&&(n.next.area=this.calculateTriangleArea(t[n.prev.index],t[n.next.index],t[n.next.next.index]),s.update(n.next))}const o=[];let a=i[0];for(;a;)o.push(t[a.index]),a=a.next;const h=n-o.length;return this.stats.pointsRemovedByVisvalingam+=h,o}removeColinearPoints(t,e){if(t.length<=2)return t;const n=[t[0]];for(let i=1;i<t.length-1;i++){const s=t[i-1],r=t[i],o=t[i+1],a=new F(r.x-s.x,r.y-s.y),h=new F(o.x-r.x,o.y-r.y),l=Math.abs(a.angle()-h.angle());Math.min(l,2*Math.PI-l)>e||a.length()<this.config.minSegmentLength||h.length()<this.config.minSegmentLength?n.push(r):this.stats.pointsRemovedByColinear++}return n.push(t[t.length-1]),n}calculateTriangleArea(t,e,n){return Math.abs((t.x*(e.y-n.y)+e.x*(n.y-t.y)+n.x*(t.y-e.y))/2)}getStats(){return{...this.stats}}resetStats(){this.stats={pointsRemovedByVisvalingam:0,pointsRemovedByColinear:0,originalPointCount:0}}}const tt={distanceTolerance:.5,angleTolerance:.2},et=1e-6;class nt{constructor(t){this.curveFidelityConfig={...tt,...t}}setCurveFidelityConfig(t){this.curveFidelityConfig={...tt,...t}}polygonizeQuadratic(t,e,n){const i=[];return this.recursiveQuadratic(t.x,t.y,e.x,e.y,n.x,n.y,i),this.addPoint(n.x,n.y,i),i}polygonizeCubic(t,e,n,i){const s=[];return this.recursiveCubic(t.x,t.y,e.x,e.y,n.x,n.y,i.x,i.y,s),this.addPoint(i.x,i.y,s),s}recursiveQuadratic(t,e,n,i,s,r,o,a=0){if(a>16)return;const h=(t+n)/2,l=(e+i)/2,c=(n+s)/2,d=(i+r)/2,u=(h+c)/2,f=(l+d)/2,g=s-t,p=r-e,y=Math.abs((n-s)*p-(i-r)*g),m=this.curveFidelityConfig.distanceTolerance??tt.distanceTolerance,x=m*m;if(y>et){if(y*y<=x*(g*g+p*p)){const a=this.curveFidelityConfig.angleTolerance??tt.angleTolerance;if(!(a>0))return void this.addPoint(n,i,o);{let h=Math.abs(Math.atan2(r-i,s-n)-Math.atan2(i-e,n-t));if(h>=Math.PI&&(h=2*Math.PI-h),h<a)return void this.addPoint(n,i,o)}}}else{const s=g*g+p*p;if(0===s){if((n-t)*(n-t)+(i-e)*(i-e)<=x)return void this.addPoint(n,i,o)}else{const r=((n-t)*g+(i-e)*p)/s;if(r>0&&r<1&&y*y<=x*s)return void this.addPoint(n,i,o)}}this.recursiveQuadratic(t,e,h,l,u,f,o,a+1),this.recursiveQuadratic(u,f,c,d,s,r,o,a+1)}recursiveCubic(t,e,n,i,s,r,o,a,h,l=0){if(l>16)return;const c=(t+n)/2,d=(e+i)/2,u=(n+s)/2,f=(i+r)/2,g=(s+o)/2,p=(r+a)/2,y=(c+u)/2,m=(d+f)/2,x=(u+g)/2,_=(f+p)/2,v=(y+x)/2,b=(m+_)/2,w=o-t,E=a-e,O=Math.abs((n-o)*E-(i-a)*w),L=Math.abs((s-o)*E-(r-a)*w),S=this.curveFidelityConfig.distanceTolerance??tt.distanceTolerance,P=S*S;let T=0;switch(O>et&&(T|=1),L>et&&(T|=2),T){case 0:const l=w*w+E*E;if(0===l){if((n-t)*(n-t)+(i-e)*(i-e)<=P&&(s-t)*(s-t)+(r-e)*(r-e)<=P)return this.addPoint(n,i,h),void this.addPoint(s,r,h)}else{const o=((n-t)*w+(i-e)*E)/l,a=((s-t)*w+(r-e)*E)/l;if(o>0&&o<1&&a>0&&a<1&&(O+L)*(O+L)<=P*l)return this.addPoint(n,i,h),void this.addPoint(s,r,h)}break;case 1:if(L*L<=P*(w*w+E*E)){const t=this.curveFidelityConfig.angleTolerance??tt.angleTolerance;if(!(t>0))return this.addPoint(n,i,h),void this.addPoint(s,r,h);{let e=Math.abs(Math.atan2(a-r,o-s)-Math.atan2(r-i,s-n));if(e>=Math.PI&&(e=2*Math.PI-e),e<t)return this.addPoint(n,i,h),void this.addPoint(s,r,h)}}break;case 2:if(O*O<=P*(w*w+E*E)){const o=this.curveFidelityConfig.angleTolerance??tt.angleTolerance;if(!(o>0))return this.addPoint(n,i,h),void this.addPoint(s,r,h);{let a=Math.abs(Math.atan2(r-i,s-n)-Math.atan2(i-e,n-t));if(a>=Math.PI&&(a=2*Math.PI-a),a<o)return this.addPoint(n,i,h),void this.addPoint(s,r,h)}}break;case 3:if((O+L)*(O+L)<=P*(w*w+E*E)){const l=this.curveFidelityConfig.angleTolerance??tt.angleTolerance;if(!(l>0))return this.addPoint(n,i,h),void this.addPoint(s,r,h);{let c=Math.abs(Math.atan2(r-i,s-n)-Math.atan2(i-e,n-t)),d=Math.abs(Math.atan2(a-r,o-s)-Math.atan2(r-i,s-n));if(c>=Math.PI&&(c=2*Math.PI-c),d>=Math.PI&&(d=2*Math.PI-d),c+d<l)return this.addPoint(n,i,h),void this.addPoint(s,r,h)}}}this.recursiveCubic(t,e,c,d,y,m,v,b,h,l+1),this.recursiveCubic(v,b,x,_,g,p,o,a,h,l+1)}addPoint(t,e,n){const i=new F(t,e);if(0===n.length)return void n.push(i);const s=n[n.length-1],r=i.x-s.x,o=i.y-s.y;r*r+o*o>1e-12&&n.push(i)}}class it{constructor(t,e){this.currentGlyphId=0,this.currentTextIndex=0,this.currentGlyphPaths=[],this.currentPath=null,this.currentPoint=null,this.currentGlyphBounds={min:new F(1/0,1/0),max:new F(-1/0,-1/0)},this.collectedGlyphs=[],this.glyphPositions=[],this.glyphTextIndices=[],this.currentPosition=new F(0,0),this.polygonizer=new nt(t),this.pathOptimizer=new J({...Z,...e})}setPosition(t,e){this.currentPosition.set(t,e)}updatePosition(t,e){this.currentPosition.x+=t,this.currentPosition.y+=e}beginGlyph(t,e){this.currentGlyphPaths.length>0&&this.finishGlyph(),this.currentGlyphId=t,this.currentTextIndex=e,this.currentGlyphPaths=[],this.currentGlyphBounds.min.set(1/0,1/0),this.currentGlyphBounds.max.set(-1/0,-1/0),this.glyphPositions.push(this.currentPosition.clone())}finishGlyph(){this.currentPath&&this.finishPath(),this.currentGlyphPaths.length>0&&(this.collectedGlyphs.push({glyphId:this.currentGlyphId,paths:[...this.currentGlyphPaths],bounds:{min:{x:this.currentGlyphBounds.min.x,y:this.currentGlyphBounds.min.y},max:{x:this.currentGlyphBounds.max.x,y:this.currentGlyphBounds.max.y}}}),this.glyphTextIndices.push(this.currentTextIndex)),this.currentGlyphPaths=[]}onMoveTo(t,e){this.currentPath&&this.finishPath(),this.currentPoint=new F(t,e),this.updateBounds(this.currentPoint),this.currentPath={points:[this.currentPoint],glyphIndex:this.currentGlyphId}}onLineTo(t,e){if(!this.currentPath||!this.currentPoint)return;const n=new F(t,e);this.updateBounds(n),this.currentPath.points.push(n),this.currentPoint=n}onQuadTo(t,e,n,i){if(!this.currentPath||!this.currentPoint)return;const s=this.currentPoint,r=new F(t,e),o=new F(n,i),a=o.x-s.x,h=o.y-s.y;if(Math.abs((r.x-o.x)*h-(r.y-o.y)*a)<et)return void this.onLineTo(n,i);const l=this.polygonizer.polygonizeQuadratic(s,r,o);for(const t of l)this.updateBounds(t);for(let t=0;t<l.length;t++)this.currentPath.points.push(l[t]);this.currentPoint=o}onCubicTo(t,e,n,i,s,r){if(!this.currentPath||!this.currentPoint)return;const o=this.currentPoint,a=new F(t,e),h=new F(n,i),l=new F(s,r),c=l.x-o.x,d=l.y-o.y,u=Math.abs((a.x-l.x)*d-(a.y-l.y)*c),f=Math.abs((h.x-l.x)*d-(h.y-l.y)*c);if(u<et&&f<et)return void this.onLineTo(s,r);const g=this.polygonizer.polygonizeCubic(o,a,h,l);for(const t of g)this.updateBounds(t);for(let t=0;t<g.length;t++)this.currentPath.points.push(g[t]);this.currentPoint=l}onClosePath(){if(!this.currentPath||!this.currentPoint)return;const t=this.currentPath.points[0];this.currentPoint.equals(t)||this.currentPath.points.push(t),this.finishPath()}finishPath(){if(this.currentPath){const t=this.pathOptimizer.optimizePath(this.currentPath);this.currentGlyphPaths.push(t),this.currentPath=null,this.currentPoint=null}}updateBounds(t){this.currentGlyphBounds.min.x=Math.min(this.currentGlyphBounds.min.x,t.x),this.currentGlyphBounds.min.y=Math.min(this.currentGlyphBounds.min.y,t.y),this.currentGlyphBounds.max.x=Math.max(this.currentGlyphBounds.max.x,t.x),this.currentGlyphBounds.max.y=Math.max(this.currentGlyphBounds.max.y,t.y)}getCollectedGlyphs(){return this.currentGlyphPaths.length>0&&this.finishGlyph(),this.collectedGlyphs}getGlyphPositions(){return this.glyphPositions}getTextIndices(){return this.glyphTextIndices}reset(){this.collectedGlyphs=[],this.glyphPositions=[],this.glyphTextIndices=[],this.currentGlyphPaths=[],this.currentPath=null,this.currentPoint=null,this.currentGlyphId=0,this.currentTextIndex=0,this.currentPosition.set(0,0),this.currentGlyphBounds={min:new F(1/0,1/0),max:new F(-1/0,-1/0)}}setCurveFidelityConfig(t){this.polygonizer.setCurveFidelityConfig(t)}setGeometryOptimization(t){this.pathOptimizer.setConfig({...Z,...t})}getOptimizationStats(){return this.pathOptimizer.getStats()}}class st{constructor(){this.moveTo_func=null,this.lineTo_func=null,this.quadTo_func=null,this.cubicTo_func=null,this.closePath_func=null,this.drawFuncsPtr=0,this.position={x:0,y:0}}setPosition(t,e){this.position.x=t,this.position.y=e,this.collector&&this.collector.setPosition(t,e)}updatePosition(t,e){this.position.x+=t,this.position.y+=e,this.collector&&this.collector.updatePosition(t,e)}createDrawFuncs(t,e){if(!t||!t.module||!t.hb)throw new Error("Invalid font object");if(this.collector=e,this.drawFuncsPtr)return;const n=t.module;this.moveTo_func=n.addFunction((t,e,n,i,s)=>{this.collector?.onMoveTo(i,s)},"viiiffi"),this.lineTo_func=n.addFunction((t,e,n,i,s)=>{this.collector?.onLineTo(i,s)},"viiiffi"),this.quadTo_func=n.addFunction((t,e,n,i,s,r,o)=>{this.collector?.onQuadTo(i,s,r,o)},"viiiffffi"),this.cubicTo_func=n.addFunction((t,e,n,i,s,r,o,a,h)=>{this.collector?.onCubicTo(i,s,r,o,a,h)},"viiiffffffi"),this.closePath_func=n.addFunction((t,e,n)=>{this.collector?.onClosePath()},"viiii"),this.drawFuncsPtr=n.exports.hb_draw_funcs_create(),n.exports.hb_draw_funcs_set_move_to_func(this.drawFuncsPtr,this.moveTo_func,0,0),n.exports.hb_draw_funcs_set_line_to_func(this.drawFuncsPtr,this.lineTo_func,0,0),n.exports.hb_draw_funcs_set_quadratic_to_func(this.drawFuncsPtr,this.quadTo_func,0,0),n.exports.hb_draw_funcs_set_cubic_to_func(this.drawFuncsPtr,this.cubicTo_func,0,0),n.exports.hb_draw_funcs_set_close_path_func(this.drawFuncsPtr,this.closePath_func,0,0)}getDrawFuncsPtr(){if(!this.drawFuncsPtr)throw new Error("Draw functions not initialized");return this.drawFuncsPtr}destroy(t){if(!t||!t.module||!t.hb)return;const n=t.module;try{this.drawFuncsPtr&&(n.exports.hb_draw_funcs_destroy(this.drawFuncsPtr),this.drawFuncsPtr=0),null!==this.moveTo_func&&(n.removeFunction(this.moveTo_func),this.moveTo_func=null),null!==this.lineTo_func&&(n.removeFunction(this.lineTo_func),this.lineTo_func=null),null!==this.quadTo_func&&(n.removeFunction(this.quadTo_func),this.quadTo_func=null),null!==this.cubicTo_func&&(n.removeFunction(this.cubicTo_func),this.cubicTo_func=null),null!==this.closePath_func&&(n.removeFunction(this.closePath_func),this.closePath_func=null)}catch(t){e.warn("Error destroying draw callbacks:",t)}this.collector=void 0}}class rt{constructor(t,e){this.fontId="default",this.wordCache=new Map,this.cache=t,this.loadedFont=e,this.tessellator=new Y,this.extruder=new Q,this.clusterer=new X,this.collector=new it,this.drawCallbacks=new st,this.drawCallbacks.createDrawFuncs(this.loadedFont,this.collector)}getOptimizationStats(){return this.collector.getOptimizationStats()}setCurveFidelityConfig(t){this.collector.setCurveFidelityConfig(t)}setGeometryOptimization(t){this.collector.setGeometryOptimization(t)}setFontId(t){this.fontId=t}buildInstancedGeometry(t,e,i,s,r=!1){n.start("GlyphGeometryBuilder.buildInstancedGeometry",{lineCount:t.length,wordCount:t.flat().length,depth:e,removeOverlaps:i});const o=[],a=[],h=[],l=[],c={min:{x:1/0,y:1/0,z:0},max:{x:-1/0,y:-1/0,z:e}};for(let n=0;n<t.length;n++){const d=t[n];for(const t of d){const n=[];for(const e of t.glyphs)n.push(this.getContoursForGlyph(e.g));const d=t.glyphs.map(t=>new I(t.x,t.y,0)),u=this.clusterer.cluster(n,d);if(!r&&u.some(t=>t.length>1)){const r=`${this.fontId}_${t.text}_${e}_${i}`;let d=this.wordCache.get(r);if(!d){const i=[];for(let e=0;e<n.length;e++){const s=n[e],r=t.glyphs[e];for(const t of s.paths)i.push({...t,points:t.points.map(t=>new F(t.x+(r.x??0),t.y+(r.y??0)))})}d=this.tessellateGlyphCluster(i,e,s),this.wordCache.set(r,d)}const u=o.length/3;this.appendGeometry(o,a,h,d,t.position,u);const f=d.vertices.length/3;for(let i=0;i<t.glyphs.length;i++){const s=t.glyphs[i],r=n[i],o=new I(t.position.x+(s.x??0),t.position.y+(s.y??0),t.position.z),a=this.createGlyphInfo(s,u,f,o,r,e);l.push(a),this.updatePlaneBounds(a.bounds,c)}}else for(let r=0;r<t.glyphs.length;r++){const d=t.glyphs[r],u=n[r],f=new I(t.position.x+(d.x??0),t.position.y+(d.y??0),t.position.z);if(0===u.paths.length){const t=this.createGlyphInfo(d,0,0,f,u,e);l.push(t);continue}let g=this.cache.get(this.fontId,d.g,e,i);g||(g=this.tessellateGlyph(u,e,i,s),this.cache.set(this.fontId,d.g,e,i,g));const p=o.length/3;this.appendGeometry(o,a,h,g,f,p);const y=this.createGlyphInfo(d,p,g.vertices.length/3,f,u,e);l.push(y),this.updatePlaneBounds(y.bounds,c)}}}const d=new Float32Array(o),u=new Float32Array(a),f=new Uint32Array(h);return n.end("GlyphGeometryBuilder.buildInstancedGeometry"),{vertices:d,normals:u,indices:f,glyphInfos:l,planeBounds:c}}appendGeometry(t,e,n,i,s,r){for(let e=0;e<i.vertices.length;e+=3)t.push(i.vertices[e]+s.x,i.vertices[e+1]+s.y,i.vertices[e+2]+s.z);for(let t=0;t<i.normals.length;t++)e.push(i.normals[t]);for(let t=0;t<i.indices.length;t++)n.push(i.indices[t]+r)}createGlyphInfo(t,e,n,i,s,r){return{textIndex:t.absoluteTextIndex,lineIndex:t.lineIndex,vertexStart:e,vertexCount:n,bounds:{min:{x:s.bounds.min.x+i.x,y:s.bounds.min.y+i.y,z:i.z},max:{x:s.bounds.max.x+i.x,y:s.bounds.max.y+i.y,z:i.z+r}}}}getContoursForGlyph(t){this.collector.reset(),this.collector.beginGlyph(t,0),this.loadedFont.module.exports.hb_font_draw_glyph(this.loadedFont.font.ptr,t,this.drawCallbacks.getDrawFuncsPtr(),0),this.collector.finishGlyph();const e=this.collector.getCollectedGlyphs()[0];return e||{glyphId:t,paths:[],bounds:{min:{x:0,y:0},max:{x:0,y:0}}}}tessellateGlyphCluster(t,e,n){const i=this.tessellator.process(t,!0,n);return this.extrudeAndPackage(i,e)}extrudeAndPackage(t,e){const n=this.extruder.extrude(t,e,this.loadedFont.upem),i=n.vertices;let s=1/0,r=1/0,o=1/0,a=-1/0,h=-1/0,l=-1/0;for(let t=0;t<i.length;t+=3){const e=i[t],n=i[t+1],c=i[t+2];e<s&&(s=e),e>a&&(a=e),n<r&&(r=n),n>h&&(h=n),c<o&&(o=c),c>l&&(l=c)}const c=new I(s,r,o),d=new I(a,h,l),u=n.vertices.length/3<65536?Uint16Array:Uint32Array;return{geometry:t,vertices:new Float32Array(n.vertices),normals:new Float32Array(n.normals),indices:new u(n.indices),bounds:{min:c,max:d},useCount:1}}tessellateGlyph(t,e,i,s){n.start("GlyphGeometryBuilder.tessellateGlyph",{glyphId:t.glyphId,pathCount:t.paths.length});const r=this.tessellator.process(t.paths,i,s);return this.extrudeAndPackage(r,e)}updatePlaneBounds(t,e){const n=new C(new I(e.min.x,e.min.y,e.min.z),new I(e.max.x,e.max.y,e.max.z)),i=new C(new I(t.min.x,t.min.y,t.min.z),new I(t.max.x,t.max.y,t.max.z));n.union(i),e.min.x=n.min.x,e.min.y=n.min.y,e.min.z=n.min.z,e.max.x=n.max.x,e.max.y=n.max.y,e.max.z=n.max.z}getCacheStats(){return this.cache.getStats()}clearCache(){this.cache.clear(),this.wordCache.clear()}}class ot{constructor(t,e){this.cachedSpaceWidth=new Map,this.loadedFont=t,this.geometryBuilder=e}shapeLines(t,e,i,s,r,o,a){n.start("TextShaper.shapeLines",{lineCount:t.length});const h=new Set;if(o&&"object"==typeof o&&"byText"in o&&o.byText&&a)for(const t of Object.keys(o.byText)){let e=0;for(;-1!==(e=a.indexOf(t,e));)h.add(e),h.add(e+t.length),e+=t.length}const l=[];return t.forEach((t,n)=>{const o=this.shapeLineIntoClusters(t,n,e,i,s,r,h);l.push(o)}),l}shapeLineIntoClusters(t,e,n,i,s,r,o){const a=this.loadedFont.hb.createBuffer();"rtl"===r&&a.setDirection("rtl"),a.addText(t.text),a.guessSegmentProperties(),this.loadedFont.hb.shape(this.loadedFont.font,a);const h=a.json(this.loadedFont.font);a.destroy();const l=[];let c=[],d="",u=new I,f=new I(t.xOffset,-e*n,0);const g=i*this.loadedFont.upem,p=this.calculateSpaceAdjustment(t,s,i);for(let n=0;n<h.length;n++){const i=h[n],s=/\s/.test(t.text[i.cl]);t.endedWithHyphen&&i.cl===t.text.length-1&&"-"===t.text[i.cl]?i.absoluteTextIndex=t.originalEnd:i.absoluteTextIndex=t.originalStart+i.cl,i.lineIndex=e;const r=o.has(i.absoluteTextIndex);(s||r)&&c.length>0&&(l.push({text:d,glyphs:c,position:u.clone()}),c=[],d="");const a=f.clone().add(new I(i.dx,i.dy,0));s||(0===c.length&&u.copy(a),i.x=a.x-u.x,i.y=a.y-u.y,c.push(i),d+=t.text[i.cl]),f.x+=i.ax,f.y+=i.ay,0!==g&&n<h.length-1&&(f.x+=g),s&&(f.x+=p)}return c.length>0&&l.push({text:d,glyphs:c,position:u.clone()}),l}calculateSpaceAdjustment(t,e,n){let i=0;if(void 0!==t.adjustmentRatio&&"justify"===e&&!t.isLastLine){let e=this.cachedSpaceWidth.get(n);void 0===e&&(e=v.measureTextWidth(this.loadedFont," ",n),this.cachedSpaceWidth.set(n,e));const s=.5,r=o;t.adjustmentRatio>0?i=t.adjustmentRatio*e*s:t.adjustmentRatio<0&&(i=t.adjustmentRatio*e*r)}return i}clearCache(){this.geometryBuilder.clearCache()}getCacheStats(){return this.geometryBuilder.getCacheStats()}}class at{constructor(t){this.cache=new Map,this.head=null,this.tail=null,this.stats={hits:0,misses:0,totalGlyphs:0,uniqueGlyphs:0,cacheSize:0,saved:0,memoryUsage:0},t&&(this.maxCacheSize=1024*t*1024)}getCacheKey(t,e,n,i){return`${t}_${e}_${Math.round(1e3*n)/1e3}_${i}`}has(t,e,n,i){const s=this.getCacheKey(t,e,n,i);return this.cache.has(s)}get(t,e,n,i){const s=this.getCacheKey(t,e,n,i),r=this.cache.get(s);return r?(this.stats.hits++,this.stats.saved++,r.data.useCount++,this.moveToHead(r),this.stats.totalGlyphs++,r.data):(this.stats.misses++,void this.stats.totalGlyphs++)}set(t,e,n,i,s){const r=this.getCacheKey(t,e,n,i),o=this.calculateMemoryUsage(s);this.maxCacheSize&&this.stats.memoryUsage+o>this.maxCacheSize&&this.evictLRU(o);const a={key:r,data:s,prev:null,next:null};this.cache.set(r,a),this.addToHead(a),this.stats.uniqueGlyphs=this.cache.size,this.stats.cacheSize++,this.stats.memoryUsage+=o}calculateMemoryUsage(t){let e=0;return e+=4*t.vertices.length,e+=4*t.normals.length,e+=t.indices.length*t.indices.BYTES_PER_ELEMENT,e+=24,e+=256,e}evictLRU(t){let e=0;for(;this.tail&&e<t;){const t=this.calculateMemoryUsage(this.tail.data),n=this.tail;this.removeTail(),this.cache.delete(n.key),this.stats.memoryUsage-=t,this.stats.cacheSize--,e+=t}}addToHead(t){this.head?(t.next=this.head,this.head.prev=t,this.head=t):this.head=this.tail=t}removeNode(t){t.prev?t.prev.next=t.next:this.head=t.next,t.next?t.next.prev=t.prev:this.tail=t.prev}removeTail(){this.tail&&this.removeNode(this.tail)}moveToHead(t){t!==this.head&&(this.removeNode(t),this.addToHead(t))}clear(){this.cache.clear(),this.head=null,this.tail=null,this.stats={hits:0,misses:0,totalGlyphs:0,uniqueGlyphs:0,cacheSize:0,saved:0,memoryUsage:0}}getStats(){const t=this.stats.totalGlyphs>0?this.stats.hits/this.stats.totalGlyphs*100:0;return this.stats.uniqueGlyphs=this.cache.size,{...this.stats,hitRate:t,memoryUsageMB:this.stats.memoryUsage/1048576}}}const ht=new at(250);function lt(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}function ct(t){if(t.__esModule)return t;var e=t.default;if("function"==typeof e){var n=function t(){return this instanceof t?Reflect.construct(e,arguments,this.constructor):e.apply(this,arguments)};n.prototype=e.prototype}else n={};return Object.defineProperty(n,"__esModule",{value:!0}),Object.keys(t).forEach(function(e){var i=Object.getOwnPropertyDescriptor(t,e);Object.defineProperty(n,e,i.get?i:{enumerable:!0,get:function(){return t[e]}})}),n}var dt={exports:{}};var ut=ct(Object.freeze({__proto__:null,default:{},readFileSync:()=>{throw new Error("fs not available in browser")}}));!function(t){var e,n=(e="undefined"!=typeof document?document.currentScript?.src:void 0,async function(t={}){var n=t,i="object"==typeof window,s="undefined"!=typeof WorkerGlobalScope,r="object"==typeof process&&process.versions?.node&&"renderer"!=process.type,o=(t,e)=>{throw e};"undefined"!=typeof __filename?e=__filename:s&&(e=self.location.href);var a,h,l="";if(r){var c=ut;l=__dirname+"/",h=t=>(t=_(t)?new URL(t):t,c.readFileSync(t)),a=async(t,e=!0)=>(t=_(t)?new URL(t):t,c.readFileSync(t,e?void 0:"utf8")),process.argv.length>1&&process.argv[1].replace(/\\/g,"/"),process.argv.slice(2),o=(t,e)=>{throw process.exitCode=t,e}}else if(i||s){try{l=new URL(".",e).href}catch{}s&&(h=t=>{var e=new XMLHttpRequest;return e.open("GET",t,!1),e.responseType="arraybuffer",e.send(null),new Uint8Array(e.response)}),a=async t=>{if(_(t))return new Promise((e,n)=>{var i=new XMLHttpRequest;i.open("GET",t,!0),i.responseType="arraybuffer",i.onload=()=>{200==i.status||0==i.status&&i.response?e(i.response):n(i.status)},i.onerror=n,i.send(null)});var e=await fetch(t,{credentials:"same-origin"});if(e.ok)return e.arrayBuffer();throw new Error(e.status+" : "+e.url)}}console.log.bind(console);var d,u,f,g,p,y,m=console.error.bind(console),x=!1,_=t=>t.startsWith("file://"),v=!1;function b(){var t=p.buffer;n.HEAP8=new Int8Array(t),n.HEAPU8=y=new Uint8Array(t),n.HEAP32=new Int32Array(t),n.HEAPU32=new Uint32Array(t),n.HEAPF32=new Float32Array(t),new BigInt64Array(t),new BigUint64Array(t)}var w,E=0,O=null;function L(t){n.onAbort?.(t),m(t="Aborted("+t+")"),x=!0,t+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(t);throw g?.(e),e}function S(){return t="hb.wasm",n.locateFile?n.locateFile(t,l):l+t;var t}async function P(t){if(!d)try{var e=await a(t);return new Uint8Array(e)}catch{}return function(t){if(t==w&&d)return new Uint8Array(d);if(h)return h(t);throw"both async and sync fetching of the wasm failed"}(t)}async function T(t,e,n){if(!t&&!_(e)&&!r)try{var i=fetch(e,{credentials:"same-origin"});return await WebAssembly.instantiateStreaming(i,n)}catch(t){m(`wasm streaming compile failed: ${t}`),m("falling back to ArrayBuffer instantiation")}return async function(t,e){try{var n=await P(t);return await WebAssembly.instantiate(n,e)}catch(t){m(`failed to asynchronously prepare wasm: ${t}`),L(t)}}(e,n)}class F{name="ExitStatus";constructor(t){this.message=`Program terminated with exit(${t})`,this.status=t}}var I,C,U,A=t=>{for(;t.length>0;)t.shift()(n)},B=[],R=t=>B.push(t),z=[],D=t=>z.push(t),k=!0,M=0,G={},N=t=>{if(t instanceof F||"unwind"==t)return u;o(1,t)},H=()=>k||M>0,q=t=>{u=t,H()||(n.onExit?.(t),x=!0),o(t,new F(t))},W=(t,e)=>{u=t,q(t)},V=t=>{if(!x)try{t(),(()=>{if(!H())try{W(u)}catch(t){N(t)}})()}catch(t){N(t)}},j=(t,e)=>Math.ceil(t/e)*e,$=t=>{var e=(t-p.buffer.byteLength+65535)/65536|0;try{return p.grow(e),b(),1}catch(t){}},Y=t=>{const e=t.length;return[e%128|128,e>>7,...t]},Q={i:127,p:127,j:126,f:125,d:124,e:111},X=t=>Y(Array.from(t,t=>Q[t])),K=t=>I.get(t),Z=t=>(C||(C=new WeakMap,((t,e)=>{if(C)for(var n=t;n<t+e;n++){var i=K(n);i&&C.set(i,n)}})(0,I.length)),C.get(t)||0),J=[],tt=(t,e)=>I.set(t,e);n.noExitRuntime&&(k=n.noExitRuntime),n.print&&n.print,n.printErr&&(m=n.printErr),n.wasmBinary&&(d=n.wasmBinary),n.arguments&&n.arguments,n.thisProgram&&n.thisProgram,n.wasmMemory=p,n.wasmExports=nt,n.addFunction=(t,e)=>{var n=Z(t);if(n)return n;var i=J.length?J.pop():I.grow(1);try{tt(i,t)}catch(n){if(!(n instanceof TypeError))throw n;var s=((t,e)=>{var n=Uint8Array.of(0,97,115,109,1,0,0,0,1,...Y([1,96,...X(e.slice(1)),...X("v"===e[0]?"":e[0])]),2,7,1,1,101,1,102,0,0,7,5,1,1,102,0,0),i=new WebAssembly.Module(n);return new WebAssembly.Instance(i,{e:{f:t}}).exports.f})(t,e);tt(i,s)}return C.set(t,i),i},n.removeFunction=t=>{C.delete(K(t)),tt(t,null),J.push(t)};var et={_abort_js:()=>L(""),_emscripten_runtime_keepalive_clear:()=>{k=!1,M=0},_setitimer_js:(t,e)=>{if(G[t]&&(clearTimeout(G[t].id),delete G[t]),!e)return 0;var n=setTimeout(()=>{delete G[t],V(()=>U(t,performance.now()))},e);return G[t]={id:n,timeout_ms:e},0},emscripten_resize_heap:t=>{var e=y.length,n=2147483648;if((t>>>=0)>n)return!1;for(var i=1;i<=4;i*=2){var s=e*(1+.2/i);s=Math.min(s,t+100663296);var r=Math.min(n,j(Math.max(t,s),65536));if($(r))return!0}return!1},proc_exit:q},nt=await async function(){function t(t,e){return nt=t.exports,n.wasmExports=nt,p=nt.memory,n.wasmMemory=p,b(),I=nt.__indirect_function_table,function(t){n._hb_blob_create=t.hb_blob_create,n._hb_blob_destroy=t.hb_blob_destroy,n._hb_blob_get_length=t.hb_blob_get_length,n._hb_blob_get_data=t.hb_blob_get_data,n._hb_buffer_serialize_glyphs=t.hb_buffer_serialize_glyphs,n._hb_buffer_create=t.hb_buffer_create,n._hb_buffer_destroy=t.hb_buffer_destroy,n._hb_buffer_get_content_type=t.hb_buffer_get_content_type,n._hb_buffer_set_direction=t.hb_buffer_set_direction,n._hb_buffer_set_script=t.hb_buffer_set_script,n._hb_buffer_set_language=t.hb_buffer_set_language,n._hb_buffer_set_flags=t.hb_buffer_set_flags,n._hb_buffer_set_cluster_level=t.hb_buffer_set_cluster_level,n._hb_buffer_get_length=t.hb_buffer_get_length,n._hb_buffer_get_glyph_infos=t.hb_buffer_get_glyph_infos,n._hb_buffer_get_glyph_positions=t.hb_buffer_get_glyph_positions,n._hb_glyph_info_get_glyph_flags=t.hb_glyph_info_get_glyph_flags,n._hb_buffer_guess_segment_properties=t.hb_buffer_guess_segment_properties,n._hb_buffer_add_utf8=t.hb_buffer_add_utf8,n._hb_buffer_add_utf16=t.hb_buffer_add_utf16,n._hb_buffer_set_message_func=t.hb_buffer_set_message_func,n._hb_language_from_string=t.hb_language_from_string,n._hb_script_from_string=t.hb_script_from_string,n._hb_version=t.hb_version,n._hb_version_string=t.hb_version_string,n._hb_feature_from_string=t.hb_feature_from_string,n._malloc=t.malloc,n._free=t.free,n._hb_draw_funcs_set_move_to_func=t.hb_draw_funcs_set_move_to_func,n._hb_draw_funcs_set_line_to_func=t.hb_draw_funcs_set_line_to_func,n._hb_draw_funcs_set_quadratic_to_func=t.hb_draw_funcs_set_quadratic_to_func,n._hb_draw_funcs_set_cubic_to_func=t.hb_draw_funcs_set_cubic_to_func,n._hb_draw_funcs_set_close_path_func=t.hb_draw_funcs_set_close_path_func,n._hb_draw_funcs_create=t.hb_draw_funcs_create,n._hb_draw_funcs_destroy=t.hb_draw_funcs_destroy,n._hb_face_create=t.hb_face_create,n._hb_face_destroy=t.hb_face_destroy,n._hb_face_reference_table=t.hb_face_reference_table,n._hb_face_get_upem=t.hb_face_get_upem,n._hb_face_collect_unicodes=t.hb_face_collect_unicodes,n._hb_font_draw_glyph=t.hb_font_draw_glyph,n._hb_font_glyph_to_string=t.hb_font_glyph_to_string,n._hb_font_create=t.hb_font_create,n._hb_font_set_variations=t.hb_font_set_variations,n._hb_font_destroy=t.hb_font_destroy,n._hb_font_set_scale=t.hb_font_set_scale,n._hb_set_create=t.hb_set_create,n._hb_set_destroy=t.hb_set_destroy,n._hb_ot_var_get_axis_infos=t.hb_ot_var_get_axis_infos,n._hb_set_get_population=t.hb_set_get_population,n._hb_set_next_many=t.hb_set_next_many,n._hb_shape=t.hb_shape,U=t._emscripten_timeout}(nt),function(){if(E--,n.monitorRunDependencies?.(E),0==E&&O){var t=O;O=null,t()}}(),nt}E++,n.monitorRunDependencies?.(E);var e={env:et,wasi_snapshot_preview1:et};if(n.instantiateWasm)return new Promise((i,s)=>{n.instantiateWasm(e,(e,n)=>{i(t(e))})});w??=S();var i=function(e){return t(e.instance)}(await T(d,w,e));return i}();return function(){if(n.preInit)for("function"==typeof n.preInit&&(n.preInit=[n.preInit]);n.preInit.length>0;)n.preInit.shift()()}(),function t(){function e(){n.calledRun=!0,x||(v=!0,nt.__wasm_call_ctors(),f?.(n),n.onRuntimeInitialized?.(),function(){if(n.postRun)for("function"==typeof n.postRun&&(n.postRun=[n.postRun]);n.postRun.length;)R(n.postRun.shift());A(B)}())}E>0?O=t:(function(){if(n.preRun)for("function"==typeof n.preRun&&(n.preRun=[n.preRun]);n.preRun.length;)D(n.preRun.shift());A(z)}(),E>0?O=t:n.setStatus?(n.setStatus("Running..."),setTimeout(()=>{setTimeout(()=>n.setStatus(""),1),e()},1)):e())}(),v?n:new Promise((t,e)=>{f=t,g=e})});t.exports=n,t.exports.default=n}(dt);var ft=lt(dt.exports),gt={exports:{}};try{gt.exports=function(t){var e=t.wasmExports,n=new TextDecoder("utf8");let i=t.addFunction,s=t.removeFunction;var r=i(function(t){e.free(t)},"vi");function o(t){return(255&t.charCodeAt(0))<<24|(255&t.charCodeAt(1))<<16|(255&t.charCodeAt(2))<<8|255&t.charCodeAt(3)}var a=o("JSON"),h="",l=e.malloc(256);function c(n){var i=e.malloc(n.length+1);for(let e=0;e<n.length;++e){const s=n.charCodeAt(e);if(s>127)throw new Error("Expected ASCII text");t.HEAPU8[i+e]=s}return t.HEAPU8[i+n.length]=0,{ptr:i,length:n.length,free:function(){e.free(i)}}}function d(t,n,i){var s=0,r=0;i&&(i=i.split(","),s=e.malloc(16*i.length),i.forEach(function(t,n){var i=c(t);e.hb_feature_from_string(i.ptr,-1,s+16*r)&&r++,i.free()})),e.hb_shape(t.ptr,n.ptr,s,r),s&&e.free(s)}return{createBlob:function(n){var i=e.malloc(n.byteLength);t.HEAPU8.set(new Uint8Array(n),i);var s=e.hb_blob_create(i,n.byteLength,2,i,r);return{ptr:s,destroy:function(){e.hb_blob_destroy(s)}}},createFace:function(n,i){var s=e.hb_face_create(n.ptr,i);const r=e.hb_face_get_upem(s);return{ptr:s,upem:r,reference_table:function(n){var i=e.hb_face_reference_table(s,o(n)),r=e.hb_blob_get_length(i);if(r){var a=e.hb_blob_get_data(i,null);return t.HEAPU8.subarray(a,a+r)}},getAxisInfos:function(){var n=e.malloc(2048),i=e.malloc(4);t.HEAPU32[i/4]=64,e.hb_ot_var_get_axis_infos(s,0,i,n);var r={};return Array.from({length:t.HEAPU32[i/4]}).forEach(function(e,i){var s;r[(s=t.HEAPU32[n/4+8*i+1],[String.fromCharCode(s>>24&255),String.fromCharCode(s>>16&255),String.fromCharCode(s>>8&255),String.fromCharCode(255&s)].join(""))]={min:t.HEAPF32[n/4+8*i+4],default:t.HEAPF32[n/4+8*i+5],max:t.HEAPF32[n/4+8*i+6]}}),e.free(i),e.free(n),r},collectUnicodes:function(){var n=e.hb_set_create();e.hb_face_collect_unicodes(s,n);var i=function(n){const i=e.hb_set_get_population(n),s=e.malloc(i<<2),r=s>>2,o=t.HEAPU32.subarray(r,r+i);return t.HEAPU32.set(o,r),e.hb_set_next_many(n,-1,s,i),o}(n);return e.hb_set_destroy(n),i},destroy:function(){e.hb_face_destroy(s)}}},createFont:function(r){var a=e.hb_font_create(r.ptr),c=null,d=null,u=null,f=null,g=null,p=null;function y(t){return c||(d=i(function(t,e,n,i,s,r){h+=`M${i},${s}`},"viiiffi"),u=i(function(t,e,n,i,s,r){h+=`L${i},${s}`},"viiiffi"),f=i(function(t,e,n,i,s,r,o,a,l,c){h+=`C${i},${s} ${r},${o} ${a},${l}`},"viiiffffffi"),g=i(function(t,e,n,i,s,r,o,a){h+=`Q${i},${s} ${r},${o}`},"viiiffffi"),p=i(function(t,e,n,i){h+="Z"},"viiii"),c=e.hb_draw_funcs_create(),e.hb_draw_funcs_set_move_to_func(c,d,0,0),e.hb_draw_funcs_set_line_to_func(c,u,0,0),e.hb_draw_funcs_set_cubic_to_func(c,f,0,0),e.hb_draw_funcs_set_quadratic_to_func(c,g,0,0),e.hb_draw_funcs_set_close_path_func(c,p,0,0)),h="",e.hb_font_draw_glyph(a,t,c,0),h}return{ptr:a,glyphName:function(i){e.hb_font_glyph_to_string(a,i,l,256);var s=t.HEAPU8.subarray(l,l+256);return n.decode(s.slice(0,s.indexOf(0)))},glyphToPath:y,glyphToJson:function(t){return y(t).replace(/([MLQCZ])/g,"|$1 ").split("|").filter(function(t){return t.length}).map(function(t){var e=t.split(/[ ,]/g);return{type:e[0],values:e.slice(1).filter(function(t){return t.length}).map(function(t){return+t})}})},setScale:function(t,n){e.hb_font_set_scale(a,t,n)},setVariations:function(n){var i=Object.entries(n),s=e.malloc(8*i.length);i.forEach(function(e,n){t.HEAPU32[s/4+2*n+0]=o(e[0]),t.HEAPF32[s/4+2*n+1]=e[1]}),e.hb_font_set_variations(a,s,i.length),e.free(s)},destroy:function(){e.hb_font_destroy(a),c&&(e.hb_draw_funcs_destroy(c),c=null,s(d),s(u),s(f),s(g),s(p))}}},createBuffer:function(){var n=e.hb_buffer_create();return{ptr:n,addText:function(i){const s=function(n){const i=e.malloc(2*n.length),s=new Uint16Array(t.wasmMemory.buffer,i,n.length);for(let t=0;t<s.length;++t)s[t]=n.charCodeAt(t);return{ptr:i,length:s.length,free:function(){e.free(i)}}}(i);e.hb_buffer_add_utf16(n,s.ptr,s.length,0,s.length),s.free()},guessSegmentProperties:function(){return e.hb_buffer_guess_segment_properties(n)},setDirection:function(t){e.hb_buffer_set_direction(n,{ltr:4,rtl:5,ttb:6,btt:7}[t]||0)},setFlags:function(t){var i=0;t.forEach(function(t){i|=function(t){return"BOT"==t?1:"EOT"==t?2:"PRESERVE_DEFAULT_IGNORABLES"==t?4:"REMOVE_DEFAULT_IGNORABLES"==t?8:"DO_NOT_INSERT_DOTTED_CIRCLE"==t?16:"PRODUCE_UNSAFE_TO_CONCAT"==t?64:0}(t)}),e.hb_buffer_set_flags(n,i)},setLanguage:function(t){var i=c(t);e.hb_buffer_set_language(n,e.hb_language_from_string(i.ptr,-1)),i.free()},setScript:function(t){var i=c(t);e.hb_buffer_set_script(n,e.hb_script_from_string(i.ptr,-1)),i.free()},setClusterLevel:function(t){e.hb_buffer_set_cluster_level(n,t)},json:function(){for(var i=e.hb_buffer_get_length(n),s=[],r=e.hb_buffer_get_glyph_infos(n,0),o=r/4,a=e.hb_buffer_get_glyph_positions(n,0)/4,h=t.HEAPU32.subarray(o,o+5*i),l=t.HEAP32.subarray(a,a+5*i),c=0;c<i;++c)s.push({g:h[5*c+0],cl:h[5*c+2],ax:l[5*c+0],ay:l[5*c+1],dx:l[5*c+2],dy:l[5*c+3],flags:e.hb_glyph_info_get_glyph_flags(r+20*c)});return s},destroy:function(){e.hb_buffer_destroy(n)}}},shape:d,shapeWithTrace:function(r,o,h,l,c){var u=[],f=0,g=!1,p=1048576,y=e.malloc(p),m=i(function(i,s,r,o){var h=n.decode(t.HEAPU8.subarray(r,t.HEAPU8.indexOf(0,r)));return h.startsWith("start table GSUB")?f=1:h.startsWith("start table GPOS")&&(f=2),f!=c&&(g=!1),0!=c&&f==c&&h.startsWith("end lookup "+l)&&(g=!0),g?0:(e.hb_buffer_serialize_glyphs(i,0,e.hb_buffer_get_length(i),y,p,0,s,a,4),u.push({m:h,t:JSON.parse(n.decode(t.HEAPU8.subarray(y,t.HEAPU8.indexOf(0,y)))),glyphs:2==e.hb_buffer_get_content_type(i)}),1)},"iiiii");return e.hb_buffer_set_message_func(o.ptr,m,0,0),d(r,o,h),e.free(y),s(m),u},version:function(){var n=e.malloc(12);e.hb_version(n,n+4,n+8);var i={major:t.HEAPU32[n/4],minor:t.HEAPU32[(n+4)/4],micro:t.HEAPU32[(n+8)/4]};return e.free(n),i},version_string:function(){var i=e.hb_version_string();return n.decode(t.HEAPU8.subarray(i,t.HEAPU8.indexOf(0,i)))}}}}catch(t){}var pt=lt(gt.exports);let yt=null,mt=null,xt=null;const _t={setWasmPath(t){mt=t,xt=null,yt=null},setWasmBuffer(t){xt=t,mt=null,yt=null},getHarfBuzz:async()=>yt||(yt=new Promise(async(t,e)=>{try{const e={};if(xt)e.wasmBinary=xt;else{if(!mt)throw new Error("HarfBuzz WASM path or buffer must be set before initialization.");e.locateFile=(t,e)=>t.endsWith(".wasm")?mt:e+t}const n=await ft(e),i=pt(n);t({hb:i,module:{addFunction:n.addFunction,exports:n.wasmExports,removeFunction:n.removeFunction}})}catch(t){e(new Error(`Failed to initialize HarfBuzz: ${t}`))}}),yt)};class vt{constructor(t,e){this.text=t,this.glyphsByTextIndex=new Map,e.forEach(t=>{const e=this.glyphsByTextIndex.get(t.textIndex)||[];e.push(t),this.glyphsByTextIndex.set(t.textIndex,e)})}execute(t){const e=[];return t.byText&&e.push(...this.findByText(t.byText)),t.byCharRange&&e.push(...this.findByCharRange(t.byCharRange)),e}findByText(t){const e=[];for(const n of t){let t=0;for(;-1!==(t=this.text.indexOf(n,t));)e.push(this.createTextRange(t,t+n.length,n)),t+=n.length}return e}findByCharRange(t){return t.map(t=>{const e=this.text.slice(t.start,t.end);return this.createTextRange(t.start,t.end,e)})}createTextRange(t,e,n){const i=[],s=new Map;for(let n=t;n<e;n++){const t=this.glyphsByTextIndex.get(n);if(t)for(const e of t){i.push(e);const t=s.get(e.lineIndex)||[];t.push(e),s.set(e.lineIndex,t)}}return{start:t,end:e,originalText:n,bounds:Array.from(s.values()).map(t=>this.calculateBounds(t)),glyphs:i,lineIndices:Array.from(s.keys()).sort((t,e)=>t-e)}}calculateBounds(t){if(0===t.length)return{min:{x:0,y:0,z:0},max:{x:0,y:0,z:0}};const e=new C;for(const n of t){const t=new C(new I(n.bounds.min.x,n.bounds.min.y,n.bounds.min.z),new I(n.bounds.max.x,n.bounds.max.y,n.bounds.max.z));e.union(t)}return{min:{x:e.min.x,y:e.min.y,z:e.min.z},max:{x:e.max.x,y:e.max.y,z:e.max.z}}}}class bt{static{this.patternCache=new Map}static{this.hbInitPromise=null}static{this.fontCache=new Map}static{this.fontIdCounter=0}constructor(t){this.currentFontId="",bt.hbInitPromise||(bt.hbInitPromise=_t.getHarfBuzz()),this.fontLoader=new P(()=>bt.hbInitPromise)}static setHarfBuzzPath(t){_t.setWasmPath(t),bt.hbInitPromise=null}static setHarfBuzzBuffer(t){_t.setWasmBuffer(t),bt.hbInitPromise=null}static init(){return bt.hbInitPromise||(bt.hbInitPromise=_t.getHarfBuzz()),bt.hbInitPromise}static async create(t){if(!t.font)throw new Error("Font is required. Specify options.font as a URL string or ArrayBuffer.");bt.hbInitPromise||(bt.hbInitPromise=_t.getHarfBuzz());const e="string"==typeof t.font?t.font:`buffer-${bt.generateFontContentHash(t.font)}`,n=t.fontVariations?`${e}_${JSON.stringify(t.fontVariations)}`:e;let i=bt.fontCache.get(n);i||(i=await bt.loadAndCacheFont(n,t.font,t.fontVariations));const s=new bt({maxCacheSizeMB:t.maxCacheSizeMB});s.setLoadedFont(i);const{font:r,maxCacheSizeMB:o,...a}=t;return{...await s.createGeometry(a),getLoadedFont:()=>s.getLoadedFont(),getCacheStatistics:()=>s.getCacheStatistics(),clearCache:()=>s.clearCache(),measureTextWidth:(t,e)=>s.measureTextWidth(t,e)}}static async loadAndCacheFont(t,e,n){const i=new bt;await i.loadFont(e,n);const s=i.getLoadedFont();return bt.fontCache.set(t,s),s}static generateFontContentHash(t){if(t){const e=new Uint8Array(t);return`${e[0]}_${e[Math.floor(e.length/2)]}_${e[e.length-1]}_${e.length}`}return""+ ++bt.fontIdCounter}setLoadedFont(t){this.loadedFont=t;const e=bt.generateFontContentHash(t._buffer);this.currentFontId=`font_${e}`,t.fontVariations&&(this.currentFontId+=`_${JSON.stringify(t.fontVariations)}`)}async loadFont(t,i){n.start("Text.loadFont",{fontSrc:"string"==typeof t?t:`buffer(${t.byteLength})`}),bt.hbInitPromise||(bt.hbInitPromise=_t.getHarfBuzz()),await bt.hbInitPromise;const s="string"==typeof t?await fetch(t).then(e=>{if(!e.ok)throw new Error(`Failed to load font from ${t}: HTTP ${e.status} ${e.statusText}`);return e.arrayBuffer()}):t;try{this.loadedFont&&this.destroy(),this.loadedFont=await this.fontLoader.loadFont(s,i);const t=bt.generateFontContentHash(s);this.currentFontId=`font_${t}`,i&&(this.currentFontId+=`_${JSON.stringify(i)}`)}catch(t){throw e.error("Failed to load font:",t),t}finally{n.end("Text.loadFont")}}async createGeometry(t){n.start("Text.createGeometry",{textLength:t.text.length,size:t.size||72,hasLayout:!!t.layout,mode:"cached"});try{if(!this.loadedFont)throw new Error("Font not loaded. Use Text.create() with a font option.");const e=await this.prepareHyphenation(t);if(this.validateOptions(e),t=e,this.updateFontVariations(t),!this.geometryBuilder){const e=t.maxCacheSizeMB?new at(t.maxCacheSizeMB):ht;this.geometryBuilder=new rt(e,this.loadedFont),this.geometryBuilder.setFontId(this.currentFontId)}this.geometryBuilder.setCurveFidelityConfig(t.curveFidelity),this.geometryBuilder.setGeometryOptimization(t.geometryOptimization),this.loadedFont.font.setScale(this.loadedFont.upem,this.loadedFont.upem),this.textShaper||(this.textShaper=new ot(this.loadedFont,this.geometryBuilder));const n=this.prepareLayout(t),i=t.removeOverlaps??this.loadedFont.isVariable??!1,s=this.textShaper.shapeLines(n.lines,n.scaledLineHeight,n.letterSpacing,n.align,n.direction,t.color,t.text),r=this.geometryBuilder.buildInstancedGeometry(s,n.depth,i,this.loadedFont.metrics.isCFF,t.separateGlyphsWithAttributes||!1),o=this.geometryBuilder.getCacheStats(),a=this.finalizeGeometry(r.vertices,r.normals,r.indices,r.glyphInfos,r.planeBounds,t,o,t.text);if(t.separateGlyphsWithAttributes){const t=this.createGlyphAttributes(a.vertices.length/3,a.glyphs);a.glyphAttributes=t}return a}finally{n.end("Text.createGeometry")}}async prepareHyphenation(t){if(!1!==t.layout?.hyphenate&&t.layout?.width){const n=t.layout?.language||"en-us";if(!t.layout?.hyphenationPatterns?.[n])try{if(!bt.patternCache.has(n)){const e=await T(n,t.layout?.patternsPath);bt.patternCache.set(n,e)}return{...t,layout:{...t.layout,hyphenationPatterns:{...t.layout?.hyphenationPatterns,[n]:bt.patternCache.get(n)}}}}catch(i){return e.warn(`Failed to load patterns for ${n}: ${i}`),{...t,layout:{...t.layout,hyphenate:!1}}}}return t}validateOptions(t){if(!t.text)throw new Error("Text content is required");const e=t.maxTextLength??1e5;if(t.text.length>e)throw new Error(`Text exceeds ${e} character limit`)}updateFontVariations(t){t.fontVariations&&this.loadedFont&&JSON.stringify(t.fontVariations)!==JSON.stringify(this.loadedFont.fontVariations)&&(this.loadedFont.font.setVariations(t.fontVariations),this.loadedFont.fontVariations=t.fontVariations)}prepareLayout(t){if(!this.loadedFont)throw new Error("Font not loaded. Use Text.create() with a font option");const{text:e,size:n=72,depth:o=0,lineHeight:a=1,letterSpacing:h=0,layout:l={}}=t,{width:c,direction:d="ltr",align:u=("rtl"===d?"right":"left"),respectExistingBreaks:f=!0,hyphenate:g=!0,language:p="en-us",tolerance:y=i,pretolerance:m=s,emergencyStretch:x=r,autoEmergencyStretch:_,hyphenationPatterns:v,lefthyphenmin:w,righthyphenmin:E,linepenalty:O,adjdemerits:S,hyphenpenalty:P,exhyphenpenalty:T,doublehyphendemerits:F,looseness:I,disableSingleWordDetection:C}=l;let U;void 0!==c&&(U=c*(this.loadedFont.upem/n));const A=o*(this.loadedFont.upem/n);this.textLayout||(this.textLayout=new b(this.loadedFont));const B=this.textLayout.computeLines({text:e,width:U,align:u,direction:d,hyphenate:g,language:p,respectExistingBreaks:f,tolerance:y,pretolerance:m,emergencyStretch:x,autoEmergencyStretch:_,hyphenationPatterns:v,lefthyphenmin:w,righthyphenmin:E,linepenalty:O,adjdemerits:S,hyphenpenalty:P,exhyphenpenalty:T,doublehyphendemerits:F,looseness:I,disableSingleWordDetection:C,letterSpacing:h}),R=L.getVerticalMetrics(this.loadedFont.metrics),z=(R.ascender-R.descender)*a;return{lines:B.lines,scaledLineHeight:z,letterSpacing:h,align:u,direction:d,depth:A,size:n}}applyColorSystem(t,e,n,i){const s=t.length/3,r=new Float32Array(3*s),o=[];if(Array.isArray(n)){for(let t=0;t<s;t++){const e=3*t;r[e]=n[0],r[e+1]=n[1],r[e+2]=n[2]}o.push({start:0,end:i.length,originalText:i,color:n,bounds:[],glyphs:e,lineIndices:[...new Set(e.map(t=>t.lineIndex))]})}else{const t=n.default||[1,1,1];for(let e=0;e<r.length;e+=3)r[e]=t[0],r[e+1]=t[1],r[e+2]=t[2];if(n.byText){new vt(i,e).execute({byText:Object.keys(n.byText)}).forEach(t=>{const e=n.byText[t.originalText];e&&(t.glyphs.forEach(t=>{for(let n=0;n<t.vertexCount;n++){const i=3*(t.vertexStart+n);i>=0&&i<r.length&&(r[i]=e[0],r[i+1]=e[1],r[i+2]=e[2])}}),o.push({start:t.start,end:t.end,originalText:t.originalText,color:e,bounds:t.bounds,glyphs:t.glyphs,lineIndices:t.lineIndices}))})}n.byCharRange&&n.byCharRange.forEach(t=>{const n=[];for(const i of e)if(i.textIndex>=t.start&&i.textIndex<t.end){n.push(i);for(let e=0;e<i.vertexCount;e++){const n=3*(i.vertexStart+e);n>=0&&n<r.length&&(r[n]=t.color[0],r[n+1]=t.color[1],r[n+2]=t.color[2])}}o.push({start:t.start,end:t.end,originalText:i.slice(t.start,t.end),color:t.color,bounds:[],glyphs:n,lineIndices:[...new Set(n.map(t=>t.lineIndex))]})})}return{colors:r,coloredRanges:o}}finalizeGeometry(t,e,n,i,s,r,o,a){const{layout:h={},size:l=72}=r,{width:c,align:d=("rtl"===h.direction?"right":"left")}=h;this.textLayout||(this.textLayout=new b(this.loadedFont));const u=this.textLayout.applyAlignment(t,{width:c,align:d,planeBounds:s}),f=u.offset;s.min.x=u.adjustedBounds.min.x,s.max.x=u.adjustedBounds.max.x;const g=l/this.loadedFont.upem;for(let e=0;e<t.length;e++)t[e]*=g;s.min.x*=g,s.min.y*=g,s.min.z*=g,s.max.x*=g,s.max.y*=g,s.max.z*=g;for(let t=0;t<i.length;t++){const e=i[t];0!==f&&(e.bounds.min.x+=f,e.bounds.max.x+=f),e.bounds.min.x*=g,e.bounds.min.y*=g,e.bounds.min.z*=g,e.bounds.max.x*=g,e.bounds.max.y*=g,e.bounds.max.z*=g}let p,y;if(r.color){const e=this.applyColorSystem(t,i,r.color,r.text);p=e.colors,y=e.coloredRanges}const m=this.geometryBuilder.getOptimizationStats(),x=n.length/3,_=t.length/3;return{vertices:t,normals:e,indices:n,colors:p,glyphs:i,planeBounds:s,stats:{trianglesGenerated:x,verticesGenerated:_,pointsRemovedByVisvalingam:m.pointsRemovedByVisvalingam,pointsRemovedByColinear:m.pointsRemovedByColinear,originalPointCount:m.originalPointCount,...o||{}},query:t=>{if(!a)throw new Error("Original text not available for querying");return new vt(a,i).execute(t)},coloredRanges:y,glyphAttributes:void 0}}getFontMetrics(){if(!this.loadedFont)throw new Error("Font not loaded. Call loadFont() first");return L.getFontMetrics(this.loadedFont.metrics)}static async preloadPatterns(t,n){await Promise.all(t.map(async t=>{if(!bt.patternCache.has(t))try{const e=await T(t,n);bt.patternCache.set(t,e)}catch(n){e.warn(`Failed to pre-load patterns for ${t}: ${n}`)}}))}static registerPattern(t,e){bt.patternCache.set(t,e)}getLoadedFont(){return this.loadedFont}measureTextWidth(t,e=0){if(!this.loadedFont)throw new Error("Font not loaded. Call loadFont() first");return v.measureTextWidth(this.loadedFont,t,e)}getCacheStatistics(){return this.geometryBuilder?this.geometryBuilder.getCacheStats():null}clearCache(){this.geometryBuilder&&this.geometryBuilder.clearCache()}createGlyphAttributes(t,e){const n=new Float32Array(3*t),i=new Float32Array(t),s=new Float32Array(t);return e.forEach((e,r)=>{const o=(e.bounds.min.x+e.bounds.max.x)/2,a=(e.bounds.min.y+e.bounds.max.y)/2,h=(e.bounds.min.z+e.bounds.max.z)/2;for(let l=0;l<e.vertexCount;l++){const c=e.vertexStart+l;c<t&&(n[3*c]=o,n[3*c+1]=a,n[3*c+2]=h,i[c]=r,s[c]=e.lineIndex)}}),{glyphCenter:n,glyphIndex:i,glyphLineIndex:s}}destroy(){if(!this.loadedFont)return;const t=this.loadedFont;try{P.destroyFont(t)}catch(t){e.warn("Error destroying HarfBuzz objects:",t)}finally{this.loadedFont=void 0,this.textLayout=void 0,this.textShaper=void 0}}}export{tt as DEFAULT_CURVE_FIDELITY,L as FontMetadataExtractor,bt as Text,ht as globalGlyphCache};
package/dist/index.umd.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * three-text v0.2.0
2
+ * three-text v0.2.2
3
3
  * Copyright (C) 2025 Countertype LLC
4
4
  *
5
5
  * This program is free software: you can redistribute it and/or modify
@@ -4177,7 +4177,7 @@
4177
4177
  const triangleIndices = triangulatedData.indices;
4178
4178
  for (let i = 0; i < points.length; i += 2) {
4179
4179
  vertices.push(points[i], points[i + 1], 0);
4180
- normals.push(0, 0, 1); // Front-facing normal for DoubleSide compatibility
4180
+ normals.push(0, 0, -1);
4181
4181
  }
4182
4182
  // Add triangle indices
4183
4183
  for (let i = 0; i < triangleIndices.length; i++) {
@@ -6788,13 +6788,10 @@
6788
6788
  planeBounds.min.x = alignmentResult.adjustedBounds.min.x;
6789
6789
  planeBounds.max.x = alignmentResult.adjustedBounds.max.x;
6790
6790
  const finalScale = size / this.loadedFont.upem;
6791
- // Scale vertices and normals directly
6791
+ // Scale vertices only (normals are unit vectors, don't scale)
6792
6792
  for (let i = 0; i < vertices.length; i++) {
6793
6793
  vertices[i] *= finalScale;
6794
6794
  }
6795
- for (let i = 0; i < normals.length; i++) {
6796
- normals[i] *= finalScale;
6797
- }
6798
6795
  planeBounds.min.x *= finalScale;
6799
6796
  planeBounds.min.y *= finalScale;
6800
6797
  planeBounds.min.z *= finalScale;