@chartbuddy.io/embed 1.7.52 → 1.7.53
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/README.md +26 -0
- package/chartbuddy-embed.global.js +1 -1
- package/chartbuddy-embed.mjs +1 -1
- package/chartbuddy-embed.single.global.js +1 -1
- package/chartbuddy-embed.single.mjs +1 -1
- package/llms.txt +22 -0
- package/package.json +1 -1
- package/webapp-entry.js +1 -1
package/README.md
CHANGED
|
@@ -92,6 +92,20 @@ const { ref, insight, ready, error } = useInsight({ chartData, editable: true })
|
|
|
92
92
|
|
|
93
93
|
`chartData` is compared by identity — memoize it if you build it inline.
|
|
94
94
|
|
|
95
|
+
Without a bundler, a plain HTML page needs an import map mapping **both** `react`
|
|
96
|
+
and the subpath (which needs the explicit `.mjs` file):
|
|
97
|
+
|
|
98
|
+
```html
|
|
99
|
+
<script type="importmap">{"imports":{
|
|
100
|
+
"react": "https://esm.sh/react@19",
|
|
101
|
+
"react-dom/client": "https://esm.sh/react-dom@19/client",
|
|
102
|
+
"@chartbuddy.io/embed/react": "https://unpkg.com/@chartbuddy.io/embed/react.mjs"
|
|
103
|
+
}}</script>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Use `React.createElement` there — no build step means no JSX. For a standalone
|
|
107
|
+
artifact, plain `new Insight()` or the custom element is simpler than either.
|
|
108
|
+
|
|
95
109
|
### With Vue 3
|
|
96
110
|
|
|
97
111
|
```vue
|
|
@@ -232,6 +246,18 @@ Aliases: `bubble` → `scatter`, `donut` → `pie`.
|
|
|
232
246
|
Beta: `barMekko`.
|
|
233
247
|
CHARTBUDDY:GENERATED-CHART-TYPES:END
|
|
234
248
|
|
|
249
|
+
Aliases are input-only and **seed defaults** — they are not just renames:
|
|
250
|
+
|
|
251
|
+
| You pass | Resolves to | Seeded |
|
|
252
|
+
|---|---|---|
|
|
253
|
+
| `'donut'` | `pie` | `pie.innerRadiusRatio: 0.5` (a real hole) |
|
|
254
|
+
| `'pie'` | `pie` | `pie.innerRadiusRatio: 0` (a full pie) |
|
|
255
|
+
| `'bubble'` | `scatter` | a larger point diameter |
|
|
256
|
+
|
|
257
|
+
For a donut, just pass `chartType: 'donut'` — setting `innerRadiusRatio` yourself
|
|
258
|
+
is only needed to override the hole size. `getChartData()` reports the canonical
|
|
259
|
+
type, so a donut round-trips as `pie` + `innerRadiusRatio: 0.5`.
|
|
260
|
+
|
|
235
261
|
### Validation
|
|
236
262
|
|
|
237
263
|
Chart data is validated at the API boundary — both `new Insight({ chartData })`
|
|
@@ -125,7 +125,7 @@ var ChartBuddyEmbed=(()=>{var H=Object.defineProperty;var ge=Object.getOwnProper
|
|
|
125
125
|
<button type="button" class="cb-embed-menu-item" data-action="dragExport" role="menuitem">Drag to slide</button>
|
|
126
126
|
`;return e==="edit"?`${t}
|
|
127
127
|
<button type="button" class="cb-embed-menu-item" data-action="done" role="menuitem">Done</button>`:`${t}
|
|
128
|
-
<button type="button" class="cb-embed-menu-item" data-action="edit" role="menuitem">Edit</button>`}var A=class{constructor(t,r,n="view"){this.hideTimer=null;this.destroyed=!1;Ee(),this.host=t,getComputedStyle(t).position==="static"&&(t.style.position="relative"),this.root=document.createElement("div"),this.root.className="cb-embed-chrome-root",this.root.setAttribute("data-cb-embed-chrome","1"),this.root.setAttribute("data-cb-embed-chrome-mode",n),this.ball=document.createElement("button"),this.ball.type="button",this.ball.className="cb-embed-ball",this.ball.setAttribute("aria-label","ChartBuddy actions"),this.ball.setAttribute("aria-haspopup","menu"),this.ball.setAttribute("aria-expanded","false"),this.ball.innerHTML=Ce,this.menu=document.createElement("div"),this.menu.className="cb-embed-menu",this.menu.setAttribute("role","menu"),this.menu.innerHTML=we(n),this.root.appendChild(this.ball),this.root.appendChild(this.menu),t.appendChild(this.root),this.ball.addEventListener("click",i=>{i.stopPropagation(),this.toggleMenu()}),this.menu.addEventListener("click",i=>{let a=i.target?.closest?.("[data-action]");if(!a)return;i.stopPropagation();let s=a.getAttribute("data-action");this.closeMenu(),this.dispatch(s,r)}),this.onHostEnter=()=>{this.destroyed||(this.clearHideTimer(),this.root.classList.add("is-visible"))},this.onHostLeave=()=>{this.destroyed||this.scheduleHide()},this.onDocPointer=i=>{if(this.destroyed||!this.root.classList.contains("is-menu-open"))return;let a=i.target;a&&this.root.contains(a)||this.closeMenu()},this.onKeyDown=i=>{i.key==="Escape"&&this.closeMenu()},t.addEventListener("pointerenter",this.onHostEnter),t.addEventListener("pointerleave",this.onHostLeave),document.addEventListener("pointerdown",this.onDocPointer,!0),document.addEventListener("keydown",this.onKeyDown)}async dispatch(t,r){try{t==="download"?await r.onDownload():t==="dragExport"?await r.onDragExport():t==="edit"?await r.onEdit?.():t==="done"&&await r.onDone?.()}catch(n){console.error("[chartbuddy/embed] chrome action failed:",n)}}toggleMenu(){this.root.classList.contains("is-menu-open")?this.closeMenu():this.openMenu()}openMenu(){this.clearHideTimer(),this.root.classList.add("is-visible","is-menu-open"),this.ball.setAttribute("aria-expanded","true")}closeMenu(){this.root.classList.remove("is-menu-open"),this.ball.setAttribute("aria-expanded","false")}scheduleHide(){this.clearHideTimer(),this.hideTimer=setTimeout(()=>{this.root.classList.contains("is-menu-open")||this.root.classList.remove("is-visible")},80)}clearHideTimer(){this.hideTimer&&(clearTimeout(this.hideTimer),this.hideTimer=null)}destroy(){this.destroyed||(this.destroyed=!0,this.clearHideTimer(),this.host.removeEventListener("pointerenter",this.onHostEnter),this.host.removeEventListener("pointerleave",this.onHostLeave),document.removeEventListener("pointerdown",this.onDocPointer,!0),document.removeEventListener("keydown",this.onKeyDown),this.root.remove())}};var x={vertical:{domain:"bottom",primaryRange:"left",secondaryRange:"right"},horizontal:{domain:"left",primaryRange:"bottom",secondaryRange:"top"}};function ke(e,t="vertical"){if(!e||typeof e!="object")return!1;let r=x[t]||x.vertical;return e[r.domain]?.id==="domain"&&e[r.primaryRange]?.id==="primaryRange"}function Ie(e,t="vertical"){let r=x[t]||x.vertical,n=o=>o==="left"?-90:o==="right"?90:0,i={},a=null;for(let o of["left","right","top","bottom"]){let l=e?.[o];if(!l)continue;let m=JSON.parse(JSON.stringify(l));l.id==="domain"||l.id==="primaryRange"||l.id==="secondaryRange"?i[l.id]=m:a=m}let s={},d=(o,l)=>{if(o){if(o.position=l,o.axisTitle){if(o.axisTitle.id){let m=String(o.axisTitle.id).split("-");m.length>=2&&(m[m.length-2]=l,o.axisTitle.id=m.join("-"))}o.axisTitle.rotation=n(l)}o.id==="domain"&&o.labels&&typeof o.labels=="object"&&(o.labels.position=l),s[l]=o}};d(i.domain,r.domain),d(i.primaryRange,r.primaryRange),d(i.secondaryRange,r.secondaryRange);for(let o of["left","right","top","bottom"])if(!s[o]){let l=a?JSON.parse(JSON.stringify(a)):{id:"unused",enabled:!1,visible:!1,scaleType:"band",labels:{visible:!1},axisTitle:{id:`multiline-${o}-title`,text:"",visible:!1}};d(l,o)}return s}function W(e){if(!e||typeof e!="object")return e;let t=e.orientation==="horizontal"?"horizontal":"vertical";return e.orientation=t,!e.axes||ke(e.axes,t)||(e.axes=Ie(e.axes,t)),e}var S="1.7.52";var h={clusteredBar:{label:"Clustered Bar",description:"Side-by-side bars comparing series within each category.",optionBag:"bar",family:"bar",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"clustered-bar"},stackedBar:{label:"Stacked Bar",description:"Bars stacked to show composition and category totals.",optionBag:"bar",family:"bar",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"stacked-bar"},stackedBar100:{label:"100% Stacked Bar",description:"Stacked bars normalized to 100% to compare mix, not size.",optionBag:"bar",family:"bar",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"stacked-bar"},line:{label:"Line Chart",description:"Trends over an ordered domain, one line per series.",optionBag:"line",family:"line",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"line"},area:{label:"Area Chart",description:"Filled lines showing magnitude over an ordered domain.",optionBag:"area",family:"area",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"area"},area100:{label:"100% Area Chart",description:"Area chart normalized to 100% to show changing mix.",optionBag:"area",family:"area",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"area"},pie:{label:"Pie Chart",description:"Share of a single total across categories.",optionBag:"pie",family:"pie",seriesLayout:"categoryValue",minRows:2,minCols:2,status:"stable",docsSlug:"pie"},scatter:{label:"Scatter Plot",description:"Points positioned by two metrics, optionally sized and grouped.",optionBag:"scatter",family:"scatter",seriesLayout:"pointRows",minRows:2,minCols:3,status:"stable",docsSlug:"scatter"},waterfall:{label:"Waterfall",description:"Running total showing how contributions bridge two values.",optionBag:"waterfall",family:"waterfall",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"waterfall"},mekko:{label:"Marimekko",description:"Variable-width stacked bars where both axes are percentages.",optionBag:"mekko",family:"mekko",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"mekko"},barMekko:{label:"Bar Mekko",description:"Bars whose width encodes one metric and height another; first data row sets widths.",optionBag:"barMekko",family:"mekko",seriesLayout:"widthRowThenHeightRows",minRows:3,minCols:2,status:"beta",docsSlug:"mekko"},combo:{label:"Combo Chart",description:"Mixed bar and line series on shared or dual axes.",optionBag:"combo",family:"combo",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"combo"}},T={bubble:"scatter",donut:"pie"},Ae=[];var V=Object.keys(h).sort(),X=Object.keys(T).sort(),R=[...V,...X].sort(),Se=X.filter(e=>!Ae.includes(e)),xt=[...V,...Se].sort();var p={kind:"string",description:"CSS color."},Q={kind:"string",nullable:!0,description:"CSS color; null derives it from the series color."},v={kind:"number",min:0,max:1},u={kind:"object",values:{kind:"unknown"},description:"Per-index overrides; keys are indices, values are style patches."},D={kind:"array",items:Q},O={kind:"array",items:{kind:"number",min:0,nullable:!0}},$={kind:"array",items:{kind:"string",nullable:!0}},Te={id:{kind:"string"},visible:{kind:"boolean"},text:{kind:"string"},fontFamily:{kind:"string"},fontSize:{kind:"number",min:0},fontColor:{kind:"string"},backgroundColor:{kind:"string"},textAlign:{kind:"string"},width:{kind:"number",min:0},height:{kind:"number",min:0},x:{kind:"number"},y:{kind:"number"},movable:{kind:"boolean"},deletable:{kind:"boolean"}},P={kind:"object",fields:Te},Re={shape:{kind:"string",enum:["circle","square","diamond","triangle"]},radius:{kind:"number",min:0,description:"Radius in px."},fill:Q,stroke:p,strokeWidth:{kind:"number",min:0},strokeDashArray:{kind:"string"},series:u,overrides:u},J={kind:"object",fields:Re},Z={kind:"string",enum:["linear","cardinal","step","basis","monotone"]},De={kind:"object",fields:{visible:{kind:"boolean"},color:p,width:{kind:"number",min:0},dashArray:{kind:"string"},opacity:v,overrides:u}},ee={id:{kind:"string"},version:{kind:"string",description:"App version the config was last migrated to. Drives the migrators."},title:P,subtitle:P,footnote:P,isDataTransposed:{kind:"boolean",description:"When true (default), seriesData rows are series."},seriesDataSource:{kind:"unknown"},orientation:{kind:"string",enum:["vertical","horizontal"]},backgroundColor:p,canvas:{kind:"object",fields:{width:{kind:"number",min:0},height:{kind:"number",min:0}}},chartPositionPercentages:{kind:"object",fields:{left:{kind:"number"},right:{kind:"number"},top:{kind:"number"},bottom:{kind:"number"}}},legend:{kind:"object",fields:{visible:{kind:"boolean"},colors:{kind:"array",items:p},position:{kind:"string"}}},axes:{kind:"object",description:"Axes keyed by physical side (left/right/top/bottom).",values:{kind:"object",fields:{id:{kind:"string"},axisTitle:P,gridlines:De}}},annotations:{kind:"object",fields:{cagrs:u,differenceArrows:u,levelArrows:u,levelLines:u}},seriesLabels:{kind:"object",fields:{visible:{kind:"boolean"},fontSize:{kind:"number",min:0},fontColor:p,fontFamily:{kind:"string"},overrides:u}},multilines:{kind:"array",items:{kind:"object",fields:{id:{kind:"string"},deletable:{kind:"boolean"},type:{kind:"string"},text:{kind:"string"},x:{kind:"number"},y:{kind:"number"}}}},origin:{kind:"object"}},N={bar:{padding:{kind:"number",min:0,max:1,description:"Gap between bars, 0\u20131."},cornerRadius:{kind:"number",min:0},reverseStackOrder:{kind:"boolean"},seriesStrokes:D,seriesStrokeWidths:O,seriesStrokeDashArrays:$,series:{kind:"array",items:{kind:"object"}},overrides:u},line:{width:{kind:"number",min:0,description:"Stroke width in px."},strokeDashArray:{kind:"string"},drawPoints:{kind:"boolean"},curveType:Z,curveParameter:{kind:"number"},shadowIntensity:{kind:"number",min:0},padding:{kind:"number",min:0,max:1},pointMarker:J,overrides:u},area:{width:{kind:"number",min:0},strokeDashArray:{kind:"string"},drawPoints:{kind:"boolean"},curveType:Z,curveParameter:{kind:"number"},shadowIntensity:{kind:"number",min:0},fillOpacity:v,fillType:{kind:"string",enum:["solid","gradient"]},fillOpacityTop:v,fillOpacityBottom:v,gradientTarget:{kind:"string"},strokeOpacity:v,pointMarker:J,dataLabels:{kind:"object",fields:{overrides:u}},overrides:u},scatter:{diameter:{kind:"number",min:0,description:"Marker diameter in px. The bubble alias seeds a larger default."},shape:{kind:"string"},shapes:{kind:"array",items:{kind:"string"}},seriesStrokes:D,seriesStrokeWidths:O,seriesStrokeDashArrays:$,overrides:u},pie:{innerRadiusRatio:{kind:"number",min:0,max:1,description:"0 is a full pie; the donut alias seeds 0.5."},scaleFactor:{kind:"number",min:0},labelVisibilityThreshold:{kind:"number",min:0},explode:{kind:"array",items:{kind:"number"},description:"Per-slice explode offsets."},line:{kind:"object",fields:{color:p,width:{kind:"number",min:0},dashArray:{kind:"string"}}},seriesStrokes:D,seriesStrokeWidths:O,seriesStrokeDashArrays:$,overrides:u},waterfall:{totalBarColor:p,totalLegendLabel:{kind:"string"},seriesStrokes:D,seriesStrokeWidths:O,connectorOverrides:u,columns:{kind:"object",description:"Per-column structural metadata, keyed by column index.",values:{kind:"object",fields:{isTotal:{kind:"boolean"},startBar:{kind:"boolean"},showSegments:{kind:"boolean"}}}},overrides:u},mekko:{showTotals:{kind:"boolean",description:"Legacy fallback for charts predating annotations.totals.visible."},overrides:u},barMekko:{sort:{kind:"string",enum:["heightDesc","heightAsc","widthDesc","widthAsc","dataOrder","desc","asc"],description:"Column order along the width axis."},overrides:u},combo:{seriesTypes:{kind:"object",description:"Per-series render type, keyed by series index.",values:{kind:"string",enum:["bar","line","area"]}},baseChartType:{kind:"string",enum:["clusteredBar","stackedBar"],nullable:!0}}},j=Object.keys(N).sort();function Oe(e){return typeof e=="string"&&Object.prototype.hasOwnProperty.call(h,e)}function te(e){return typeof e=="string"&&Object.prototype.hasOwnProperty.call(T,e)}function G(e){return Oe(e)||te(e)}function ne(e){return te(e)?T[e]:e}function U(e,t){let r=new Array(t.length+1),n=new Array(t.length+1);for(let i=0;i<=t.length;i++)r[i]=i;for(let i=1;i<=e.length;i++){n[0]=i;for(let a=1;a<=t.length;a++){let s=e[i-1]===t[a-1]?0:1;n[a]=Math.min(r[a]+1,n[a-1]+1,r[a-1]+s)}for(let a=0;a<=t.length;a++)r[a]=n[a]}return r[t.length]}function re(e){let t=e.toLowerCase(),r=null,n=1/0;for(let a of R){let s=U(t,a.toLowerCase());s<n&&(n=s,r=a)}let i=Math.max(2,Math.floor(t.length/3));return n<=i?r:null}var Pe=2e4,Me=20;function c(e){return e===null?"null":Array.isArray(e)?"array":typeof e}function M(e){return typeof e=="string"?`"${e}"`:typeof e=="bigint"||typeof e=="symbol"||e==null||typeof e!="object"?String(e):c(e)}function _e(e,t){let r=e.toLowerCase(),n,i=1/0;for(let s of t){let d=U(r,s.toLowerCase());d<i&&(i=d,n=s)}let a=Math.max(2,Math.floor(r.length/3));return i<=a?n:void 0}var _=class{constructor(t){this.max=t;this.issues=[]}get full(){return this.issues.length>=this.max}add(t,r,n,i={}){if(this.full)return;let{severity:a="error",...s}=i,d={path:t,code:r,message:n,severity:a};this.issues.push(Object.fromEntries(Object.entries({...d,...s}).filter(([,o])=>o!==void 0)))}};function g(e,t,r,n){if(!(e===void 0||n.full)){if(e===null){if(t.kind==="unknown"||"nullable"in t&&t.nullable)return;n.add(r,"wrong-type",`expected ${t.kind}, received null`,{expected:t.kind,received:"null"});return}switch(t.kind){case"unknown":return;case"union":{if(!t.anyOf.some(a=>{let s=new _(1);return g(e,a,r,s),s.issues.length===0})){let a=t.anyOf.map(s=>s.kind).join(" | ");n.add(r,"wrong-type",`expected ${a}, received ${c(e)}`,{expected:a,received:c(e)})}return}case"string":{if(typeof e!="string"){n.add(r,"wrong-type",`expected string, received ${c(e)}`,{expected:"string",received:c(e)});return}t.enum&&!t.enum.includes(e)&&n.add(r,"not-in-enum",`${M(e)} is not valid; expected one of ${t.enum.map(i=>`"${i}"`).join(", ")}`,{expected:t.enum.map(i=>`"${i}"`).join(" | "),received:M(e),allowed:t.enum,suggestion:_e(e,t.enum)});return}case"number":{if(typeof e!="number"){n.add(r,"wrong-type",`expected number, received ${c(e)}`,{expected:"number",received:c(e)});return}if(!Number.isFinite(e)){n.add(r,"wrong-type",`expected a finite number, received ${e}`,{expected:"finite number",received:String(e)});return}if(t.integer&&!Number.isInteger(e)){n.add(r,"wrong-type",`expected an integer, received ${e}`,{expected:"integer",received:String(e)});return}if(t.min!==void 0&&e<t.min){n.add(r,"out-of-range",`${e} is below the minimum of ${t.min}`,{expected:`>= ${t.min}`,received:String(e)});return}t.max!==void 0&&e>t.max&&n.add(r,"out-of-range",`${e} is above the maximum of ${t.max}`,{expected:`<= ${t.max}`,received:String(e)});return}case"boolean":{typeof e!="boolean"&&n.add(r,"wrong-type",`expected boolean, received ${c(e)}`,{expected:"boolean",received:c(e)});return}case"array":{if(!Array.isArray(e)){n.add(r,"wrong-type",`expected array, received ${c(e)}`,{expected:"array",received:c(e)});return}if(t.minItems!==void 0&&e.length<t.minItems){n.add(r,"out-of-range",`expected at least ${t.minItems} item(s), received ${e.length}`,{expected:`array with >= ${t.minItems} item(s)`,received:`array of ${e.length}`});return}if(!t.items)return;for(let i=0;i<e.length&&!n.full;i++)g(e[i],t.items,`${r}[${i}]`,n);return}case"object":{if(typeof e!="object"||Array.isArray(e)){n.add(r,"wrong-type",`expected object, received ${c(e)}`,{expected:"object",received:c(e)});return}let i=e;if(t.fields)for(let[a,s]of Object.entries(t.fields)){if(n.full)return;g(i[a],s,`${r}.${a}`,n)}if(t.values)for(let[a,s]of Object.entries(i)){if(n.full)return;g(s,t.values,`${r}.${a}`,n)}return}}}}var ie={seriesRows:"row 0 is the category header; each later row is one series",categoryValue:"each row is [Category, Value]",pointRows:"row 0 names the metrics; each later row is one point",widthRowThenHeightRows:"row 1 sizes the bars (never drawn); rows 2+ are stacked height segments"};function Le(e,t,r){if(e===void 0)return;if(!Array.isArray(e)){r.add("seriesData","series-data-shape",`expected a 2D array, received ${c(e)}`,{expected:"2D array",received:c(e)});return}let n=t?h[t]:void 0;n&&e.length<n.minRows&&r.add("seriesData","series-data-shape",`${n.label} needs at least ${n.minRows} rows (${ie[n.seriesLayout]}), received ${e.length}`,{expected:`>= ${n.minRows} rows (${ie[n.seriesLayout]})`,received:`${e.length} rows`});let i=0,a=[];for(let s=0;s<e.length&&!r.full;s++){let d=e[s];if(!Array.isArray(d)){r.add(`seriesData[${s}]`,"series-data-shape",`expected a row array, received ${c(d)}`,{expected:"array",received:c(d)});continue}a.push(d.length),n&&d.length<n.minCols&&r.add(`seriesData[${s}]`,"series-data-shape",`${n.label} needs at least ${n.minCols} columns per row, received ${d.length}`,{expected:`>= ${n.minCols} columns`,received:`${d.length} columns`});for(let o=0;o<d.length;o++){if(r.full||i>=Pe)return;i++;let l=d[o];if(l===null)continue;let m=typeof l;m!=="string"&&m!=="number"&&m!=="boolean"?r.add(`seriesData[${s}][${o}]`,"series-data-shape",`cells must be string, number, boolean, or null; received ${c(l)}`,{expected:"string | number | boolean | null",received:c(l)}):m==="number"&&!Number.isFinite(l)&&r.add(`seriesData[${s}][${o}]`,"series-data-shape",`cells must be finite numbers; received ${l}`,{expected:"finite number",received:String(l)})}}if(a.length>=2){let s=Math.min(...a),d=Math.max(...a);s!==d&&r.add("seriesData","ragged-series-data",`rows have unequal lengths (shortest ${s}, longest ${d}); charts expect a rectangular grid`,{severity:"warning",expected:`every row ${d} cells`,received:`rows of ${s}\u2013${d} cells`})}}function b(e,t={}){let r=new _(t.maxIssues??Me);if(!e||typeof e!="object"||Array.isArray(e))return r.add("","not-an-object",`expected a chart-data object, received ${c(e)}`,{expected:"object",received:c(e)}),ae(r.issues);let n=e,i=null;if(n.chartType!==void 0)if(typeof n.chartType!="string"||!G(n.chartType)){let d=typeof n.chartType=="string"?re(n.chartType):null;r.add("chartType","unknown-chart-type",`${M(n.chartType)} is not a known chart type.${d?` Did you mean "${d}"?`:""}`,{expected:"a ChartType or alias",received:M(n.chartType),allowed:R,suggestion:d??void 0})}else i=ne(n.chartType);(t.requireSomething??!0)&&n.chartType===void 0&&n.seriesData===void 0&&r.add("","empty-patch","expected at least one of chartType or seriesData; a patch with neither cannot change the chart",{expected:"chartType and/or seriesData",received:"neither"}),Le(n.seriesData,i,r);let a=j.filter(d=>n[d]!==void 0);if(!(t.form==="resolved"||t.form!=="patch"&&a.length===j.length)&&i){let d=h[i]?.optionBag;for(let o of a){if(r.full)break;o!==d&&r.add(o,"foreign-option-bag",`${o} options do not apply to a ${i} chart, which reads "${d}"`,{expected:d?`"${d}"`:void 0,received:`"${o}"`,suggestion:d})}}for(let d of a){if(r.full)break;g(n[d],{kind:"object",fields:N[d]},d,r)}for(let[d,o]of Object.entries(ee)){if(r.full)break;g(n[d],o,d,r)}return ae(r.issues)}function ae(e){let t=e.filter(n=>n.severity==="error"),r=e.filter(n=>n.severity==="warning");return{valid:t.length===0,issues:e,errors:t,warnings:r}}function C(e,t="[chartbuddy]"){let r=e.map(i=>` \u2022 ${i.path?`${i.path}: `:""}${i.message}`+(i.severity==="warning"?" (warning)":"")),n=e.length===1?"problem":"problems";return`${t} invalid chart data \u2014 ${e.length} ${n}:
|
|
128
|
+
<button type="button" class="cb-embed-menu-item" data-action="edit" role="menuitem">Edit</button>`}var A=class{constructor(t,r,n="view"){this.hideTimer=null;this.destroyed=!1;Ee(),this.host=t,getComputedStyle(t).position==="static"&&(t.style.position="relative"),this.root=document.createElement("div"),this.root.className="cb-embed-chrome-root",this.root.setAttribute("data-cb-embed-chrome","1"),this.root.setAttribute("data-cb-embed-chrome-mode",n),this.ball=document.createElement("button"),this.ball.type="button",this.ball.className="cb-embed-ball",this.ball.setAttribute("aria-label","ChartBuddy actions"),this.ball.setAttribute("aria-haspopup","menu"),this.ball.setAttribute("aria-expanded","false"),this.ball.innerHTML=Ce,this.menu=document.createElement("div"),this.menu.className="cb-embed-menu",this.menu.setAttribute("role","menu"),this.menu.innerHTML=we(n),this.root.appendChild(this.ball),this.root.appendChild(this.menu),t.appendChild(this.root),this.ball.addEventListener("click",i=>{i.stopPropagation(),this.toggleMenu()}),this.menu.addEventListener("click",i=>{let a=i.target?.closest?.("[data-action]");if(!a)return;i.stopPropagation();let s=a.getAttribute("data-action");this.closeMenu(),this.dispatch(s,r)}),this.onHostEnter=()=>{this.destroyed||(this.clearHideTimer(),this.root.classList.add("is-visible"))},this.onHostLeave=()=>{this.destroyed||this.scheduleHide()},this.onDocPointer=i=>{if(this.destroyed||!this.root.classList.contains("is-menu-open"))return;let a=i.target;a&&this.root.contains(a)||this.closeMenu()},this.onKeyDown=i=>{i.key==="Escape"&&this.closeMenu()},t.addEventListener("pointerenter",this.onHostEnter),t.addEventListener("pointerleave",this.onHostLeave),document.addEventListener("pointerdown",this.onDocPointer,!0),document.addEventListener("keydown",this.onKeyDown)}async dispatch(t,r){try{t==="download"?await r.onDownload():t==="dragExport"?await r.onDragExport():t==="edit"?await r.onEdit?.():t==="done"&&await r.onDone?.()}catch(n){console.error("[chartbuddy/embed] chrome action failed:",n)}}toggleMenu(){this.root.classList.contains("is-menu-open")?this.closeMenu():this.openMenu()}openMenu(){this.clearHideTimer(),this.root.classList.add("is-visible","is-menu-open"),this.ball.setAttribute("aria-expanded","true")}closeMenu(){this.root.classList.remove("is-menu-open"),this.ball.setAttribute("aria-expanded","false")}scheduleHide(){this.clearHideTimer(),this.hideTimer=setTimeout(()=>{this.root.classList.contains("is-menu-open")||this.root.classList.remove("is-visible")},80)}clearHideTimer(){this.hideTimer&&(clearTimeout(this.hideTimer),this.hideTimer=null)}destroy(){this.destroyed||(this.destroyed=!0,this.clearHideTimer(),this.host.removeEventListener("pointerenter",this.onHostEnter),this.host.removeEventListener("pointerleave",this.onHostLeave),document.removeEventListener("pointerdown",this.onDocPointer,!0),document.removeEventListener("keydown",this.onKeyDown),this.root.remove())}};var x={vertical:{domain:"bottom",primaryRange:"left",secondaryRange:"right"},horizontal:{domain:"left",primaryRange:"bottom",secondaryRange:"top"}};function ke(e,t="vertical"){if(!e||typeof e!="object")return!1;let r=x[t]||x.vertical;return e[r.domain]?.id==="domain"&&e[r.primaryRange]?.id==="primaryRange"}function Ie(e,t="vertical"){let r=x[t]||x.vertical,n=o=>o==="left"?-90:o==="right"?90:0,i={},a=null;for(let o of["left","right","top","bottom"]){let l=e?.[o];if(!l)continue;let m=JSON.parse(JSON.stringify(l));l.id==="domain"||l.id==="primaryRange"||l.id==="secondaryRange"?i[l.id]=m:a=m}let s={},d=(o,l)=>{if(o){if(o.position=l,o.axisTitle){if(o.axisTitle.id){let m=String(o.axisTitle.id).split("-");m.length>=2&&(m[m.length-2]=l,o.axisTitle.id=m.join("-"))}o.axisTitle.rotation=n(l)}o.id==="domain"&&o.labels&&typeof o.labels=="object"&&(o.labels.position=l),s[l]=o}};d(i.domain,r.domain),d(i.primaryRange,r.primaryRange),d(i.secondaryRange,r.secondaryRange);for(let o of["left","right","top","bottom"])if(!s[o]){let l=a?JSON.parse(JSON.stringify(a)):{id:"unused",enabled:!1,visible:!1,scaleType:"band",labels:{visible:!1},axisTitle:{id:`multiline-${o}-title`,text:"",visible:!1}};d(l,o)}return s}function W(e){if(!e||typeof e!="object")return e;let t=e.orientation==="horizontal"?"horizontal":"vertical";return e.orientation=t,!e.axes||ke(e.axes,t)||(e.axes=Ie(e.axes,t)),e}var S="1.7.53";var h={clusteredBar:{label:"Clustered Bar",description:"Side-by-side bars comparing series within each category.",optionBag:"bar",family:"bar",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"clustered-bar"},stackedBar:{label:"Stacked Bar",description:"Bars stacked to show composition and category totals.",optionBag:"bar",family:"bar",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"stacked-bar"},stackedBar100:{label:"100% Stacked Bar",description:"Stacked bars normalized to 100% to compare mix, not size.",optionBag:"bar",family:"bar",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"stacked-bar"},line:{label:"Line Chart",description:"Trends over an ordered domain, one line per series.",optionBag:"line",family:"line",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"line"},area:{label:"Area Chart",description:"Filled lines showing magnitude over an ordered domain.",optionBag:"area",family:"area",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"area"},area100:{label:"100% Area Chart",description:"Area chart normalized to 100% to show changing mix.",optionBag:"area",family:"area",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"area"},pie:{label:"Pie Chart",description:"Share of a single total across categories.",optionBag:"pie",family:"pie",seriesLayout:"categoryValue",minRows:2,minCols:2,status:"stable",docsSlug:"pie"},scatter:{label:"Scatter Plot",description:"Points positioned by two metrics, optionally sized and grouped.",optionBag:"scatter",family:"scatter",seriesLayout:"pointRows",minRows:2,minCols:3,status:"stable",docsSlug:"scatter"},waterfall:{label:"Waterfall",description:"Running total showing how contributions bridge two values.",optionBag:"waterfall",family:"waterfall",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"waterfall"},mekko:{label:"Marimekko",description:"Variable-width stacked bars where both axes are percentages.",optionBag:"mekko",family:"mekko",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"mekko"},barMekko:{label:"Bar Mekko",description:"Bars whose width encodes one metric and height another; first data row sets widths.",optionBag:"barMekko",family:"mekko",seriesLayout:"widthRowThenHeightRows",minRows:3,minCols:2,status:"beta",docsSlug:"mekko"},combo:{label:"Combo Chart",description:"Mixed bar and line series on shared or dual axes.",optionBag:"combo",family:"combo",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"combo"}},T={bubble:"scatter",donut:"pie"},Ae=[];var V=Object.keys(h).sort(),X=Object.keys(T).sort(),R=[...V,...X].sort(),Se=X.filter(e=>!Ae.includes(e)),xt=[...V,...Se].sort();var p={kind:"string",description:"CSS color."},Q={kind:"string",nullable:!0,description:"CSS color; null derives it from the series color."},v={kind:"number",min:0,max:1},u={kind:"object",values:{kind:"unknown"},description:"Per-index overrides; keys are indices, values are style patches."},D={kind:"array",items:Q},O={kind:"array",items:{kind:"number",min:0,nullable:!0}},$={kind:"array",items:{kind:"string",nullable:!0}},Te={id:{kind:"string"},visible:{kind:"boolean"},text:{kind:"string"},fontFamily:{kind:"string"},fontSize:{kind:"number",min:0},fontColor:{kind:"string"},backgroundColor:{kind:"string"},textAlign:{kind:"string"},width:{kind:"number",min:0},height:{kind:"number",min:0},x:{kind:"number"},y:{kind:"number"},movable:{kind:"boolean"},deletable:{kind:"boolean"}},P={kind:"object",fields:Te},Re={shape:{kind:"string",enum:["circle","square","diamond","triangle"]},radius:{kind:"number",min:0,description:"Radius in px."},fill:Q,stroke:p,strokeWidth:{kind:"number",min:0},strokeDashArray:{kind:"string"},series:u,overrides:u},J={kind:"object",fields:Re},Z={kind:"string",enum:["linear","cardinal","step","basis","monotone"]},De={kind:"object",fields:{visible:{kind:"boolean"},color:p,width:{kind:"number",min:0},dashArray:{kind:"string"},opacity:v,overrides:u}},ee={id:{kind:"string"},version:{kind:"string",description:"App version the config was last migrated to. Drives the migrators."},title:P,subtitle:P,footnote:P,isDataTransposed:{kind:"boolean",description:"When true (default), seriesData rows are series."},seriesDataSource:{kind:"unknown"},orientation:{kind:"string",enum:["vertical","horizontal"]},backgroundColor:p,canvas:{kind:"object",fields:{width:{kind:"number",min:0},height:{kind:"number",min:0}}},chartPositionPercentages:{kind:"object",fields:{left:{kind:"number"},right:{kind:"number"},top:{kind:"number"},bottom:{kind:"number"}}},legend:{kind:"object",fields:{visible:{kind:"boolean"},colors:{kind:"array",items:p},position:{kind:"string"}}},axes:{kind:"object",description:"Axes keyed by physical side (left/right/top/bottom).",values:{kind:"object",fields:{id:{kind:"string"},axisTitle:P,gridlines:De}}},annotations:{kind:"object",fields:{cagrs:u,differenceArrows:u,levelArrows:u,levelLines:u}},seriesLabels:{kind:"object",fields:{visible:{kind:"boolean"},fontSize:{kind:"number",min:0},fontColor:p,fontFamily:{kind:"string"},overrides:u}},multilines:{kind:"array",items:{kind:"object",fields:{id:{kind:"string"},deletable:{kind:"boolean"},type:{kind:"string"},text:{kind:"string"},x:{kind:"number"},y:{kind:"number"}}}},origin:{kind:"object"}},N={bar:{padding:{kind:"number",min:0,max:1,description:"Gap between bars, 0\u20131."},cornerRadius:{kind:"number",min:0},reverseStackOrder:{kind:"boolean"},seriesStrokes:D,seriesStrokeWidths:O,seriesStrokeDashArrays:$,series:{kind:"array",items:{kind:"object"}},overrides:u},line:{width:{kind:"number",min:0,description:"Stroke width in px."},strokeDashArray:{kind:"string"},drawPoints:{kind:"boolean"},curveType:Z,curveParameter:{kind:"number"},shadowIntensity:{kind:"number",min:0},padding:{kind:"number",min:0,max:1},pointMarker:J,overrides:u},area:{width:{kind:"number",min:0},strokeDashArray:{kind:"string"},drawPoints:{kind:"boolean"},curveType:Z,curveParameter:{kind:"number"},shadowIntensity:{kind:"number",min:0},fillOpacity:v,fillType:{kind:"string",enum:["solid","gradient"]},fillOpacityTop:v,fillOpacityBottom:v,gradientTarget:{kind:"string"},strokeOpacity:v,pointMarker:J,dataLabels:{kind:"object",fields:{overrides:u}},overrides:u},scatter:{diameter:{kind:"number",min:0,description:"Marker diameter in px. The bubble alias seeds a larger default."},shape:{kind:"string"},shapes:{kind:"array",items:{kind:"string"}},seriesStrokes:D,seriesStrokeWidths:O,seriesStrokeDashArrays:$,overrides:u},pie:{innerRadiusRatio:{kind:"number",min:0,max:1,description:"0 is a full pie; the donut alias seeds 0.5."},scaleFactor:{kind:"number",min:0},labelVisibilityThreshold:{kind:"number",min:0},explode:{kind:"array",items:{kind:"number"},description:"Per-slice explode offsets."},line:{kind:"object",fields:{color:p,width:{kind:"number",min:0},dashArray:{kind:"string"}}},seriesStrokes:D,seriesStrokeWidths:O,seriesStrokeDashArrays:$,overrides:u},waterfall:{totalBarColor:p,totalLegendLabel:{kind:"string"},seriesStrokes:D,seriesStrokeWidths:O,connectorOverrides:u,columns:{kind:"object",description:"Per-column structural metadata, keyed by column index.",values:{kind:"object",fields:{isTotal:{kind:"boolean"},startBar:{kind:"boolean"},showSegments:{kind:"boolean"}}}},overrides:u},mekko:{showTotals:{kind:"boolean",description:"Legacy fallback for charts predating annotations.totals.visible."},overrides:u},barMekko:{sort:{kind:"string",enum:["heightDesc","heightAsc","widthDesc","widthAsc","dataOrder","desc","asc"],description:"Column order along the width axis."},overrides:u},combo:{seriesTypes:{kind:"object",description:"Per-series render type, keyed by series index.",values:{kind:"string",enum:["bar","line","area"]}},baseChartType:{kind:"string",enum:["clusteredBar","stackedBar"],nullable:!0}}},j=Object.keys(N).sort();function Oe(e){return typeof e=="string"&&Object.prototype.hasOwnProperty.call(h,e)}function te(e){return typeof e=="string"&&Object.prototype.hasOwnProperty.call(T,e)}function G(e){return Oe(e)||te(e)}function ne(e){return te(e)?T[e]:e}function U(e,t){let r=new Array(t.length+1),n=new Array(t.length+1);for(let i=0;i<=t.length;i++)r[i]=i;for(let i=1;i<=e.length;i++){n[0]=i;for(let a=1;a<=t.length;a++){let s=e[i-1]===t[a-1]?0:1;n[a]=Math.min(r[a]+1,n[a-1]+1,r[a-1]+s)}for(let a=0;a<=t.length;a++)r[a]=n[a]}return r[t.length]}function re(e){let t=e.toLowerCase(),r=null,n=1/0;for(let a of R){let s=U(t,a.toLowerCase());s<n&&(n=s,r=a)}let i=Math.max(2,Math.floor(t.length/3));return n<=i?r:null}var Pe=2e4,Me=20;function c(e){return e===null?"null":Array.isArray(e)?"array":typeof e}function M(e){return typeof e=="string"?`"${e}"`:typeof e=="bigint"||typeof e=="symbol"||e==null||typeof e!="object"?String(e):c(e)}function _e(e,t){let r=e.toLowerCase(),n,i=1/0;for(let s of t){let d=U(r,s.toLowerCase());d<i&&(i=d,n=s)}let a=Math.max(2,Math.floor(r.length/3));return i<=a?n:void 0}var _=class{constructor(t){this.max=t;this.issues=[]}get full(){return this.issues.length>=this.max}add(t,r,n,i={}){if(this.full)return;let{severity:a="error",...s}=i,d={path:t,code:r,message:n,severity:a};this.issues.push(Object.fromEntries(Object.entries({...d,...s}).filter(([,o])=>o!==void 0)))}};function g(e,t,r,n){if(!(e===void 0||n.full)){if(e===null){if(t.kind==="unknown"||"nullable"in t&&t.nullable)return;n.add(r,"wrong-type",`expected ${t.kind}, received null`,{expected:t.kind,received:"null"});return}switch(t.kind){case"unknown":return;case"union":{if(!t.anyOf.some(a=>{let s=new _(1);return g(e,a,r,s),s.issues.length===0})){let a=t.anyOf.map(s=>s.kind).join(" | ");n.add(r,"wrong-type",`expected ${a}, received ${c(e)}`,{expected:a,received:c(e)})}return}case"string":{if(typeof e!="string"){n.add(r,"wrong-type",`expected string, received ${c(e)}`,{expected:"string",received:c(e)});return}t.enum&&!t.enum.includes(e)&&n.add(r,"not-in-enum",`${M(e)} is not valid; expected one of ${t.enum.map(i=>`"${i}"`).join(", ")}`,{expected:t.enum.map(i=>`"${i}"`).join(" | "),received:M(e),allowed:t.enum,suggestion:_e(e,t.enum)});return}case"number":{if(typeof e!="number"){n.add(r,"wrong-type",`expected number, received ${c(e)}`,{expected:"number",received:c(e)});return}if(!Number.isFinite(e)){n.add(r,"wrong-type",`expected a finite number, received ${e}`,{expected:"finite number",received:String(e)});return}if(t.integer&&!Number.isInteger(e)){n.add(r,"wrong-type",`expected an integer, received ${e}`,{expected:"integer",received:String(e)});return}if(t.min!==void 0&&e<t.min){n.add(r,"out-of-range",`${e} is below the minimum of ${t.min}`,{expected:`>= ${t.min}`,received:String(e)});return}t.max!==void 0&&e>t.max&&n.add(r,"out-of-range",`${e} is above the maximum of ${t.max}`,{expected:`<= ${t.max}`,received:String(e)});return}case"boolean":{typeof e!="boolean"&&n.add(r,"wrong-type",`expected boolean, received ${c(e)}`,{expected:"boolean",received:c(e)});return}case"array":{if(!Array.isArray(e)){n.add(r,"wrong-type",`expected array, received ${c(e)}`,{expected:"array",received:c(e)});return}if(t.minItems!==void 0&&e.length<t.minItems){n.add(r,"out-of-range",`expected at least ${t.minItems} item(s), received ${e.length}`,{expected:`array with >= ${t.minItems} item(s)`,received:`array of ${e.length}`});return}if(!t.items)return;for(let i=0;i<e.length&&!n.full;i++)g(e[i],t.items,`${r}[${i}]`,n);return}case"object":{if(typeof e!="object"||Array.isArray(e)){n.add(r,"wrong-type",`expected object, received ${c(e)}`,{expected:"object",received:c(e)});return}let i=e;if(t.fields)for(let[a,s]of Object.entries(t.fields)){if(n.full)return;g(i[a],s,`${r}.${a}`,n)}if(t.values)for(let[a,s]of Object.entries(i)){if(n.full)return;g(s,t.values,`${r}.${a}`,n)}return}}}}var ie={seriesRows:"row 0 is the category header; each later row is one series",categoryValue:"each row is [Category, Value]",pointRows:"row 0 names the metrics; each later row is one point",widthRowThenHeightRows:"row 1 sizes the bars (never drawn); rows 2+ are stacked height segments"};function Le(e,t,r){if(e===void 0)return;if(!Array.isArray(e)){r.add("seriesData","series-data-shape",`expected a 2D array, received ${c(e)}`,{expected:"2D array",received:c(e)});return}let n=t?h[t]:void 0;n&&e.length<n.minRows&&r.add("seriesData","series-data-shape",`${n.label} needs at least ${n.minRows} rows (${ie[n.seriesLayout]}), received ${e.length}`,{expected:`>= ${n.minRows} rows (${ie[n.seriesLayout]})`,received:`${e.length} rows`});let i=0,a=[];for(let s=0;s<e.length&&!r.full;s++){let d=e[s];if(!Array.isArray(d)){r.add(`seriesData[${s}]`,"series-data-shape",`expected a row array, received ${c(d)}`,{expected:"array",received:c(d)});continue}a.push(d.length),n&&d.length<n.minCols&&r.add(`seriesData[${s}]`,"series-data-shape",`${n.label} needs at least ${n.minCols} columns per row, received ${d.length}`,{expected:`>= ${n.minCols} columns`,received:`${d.length} columns`});for(let o=0;o<d.length;o++){if(r.full||i>=Pe)return;i++;let l=d[o];if(l===null)continue;let m=typeof l;m!=="string"&&m!=="number"&&m!=="boolean"?r.add(`seriesData[${s}][${o}]`,"series-data-shape",`cells must be string, number, boolean, or null; received ${c(l)}`,{expected:"string | number | boolean | null",received:c(l)}):m==="number"&&!Number.isFinite(l)&&r.add(`seriesData[${s}][${o}]`,"series-data-shape",`cells must be finite numbers; received ${l}`,{expected:"finite number",received:String(l)})}}if(a.length>=2){let s=Math.min(...a),d=Math.max(...a);s!==d&&r.add("seriesData","ragged-series-data",`rows have unequal lengths (shortest ${s}, longest ${d}); charts expect a rectangular grid`,{severity:"warning",expected:`every row ${d} cells`,received:`rows of ${s}\u2013${d} cells`})}}function b(e,t={}){let r=new _(t.maxIssues??Me);if(!e||typeof e!="object"||Array.isArray(e))return r.add("","not-an-object",`expected a chart-data object, received ${c(e)}`,{expected:"object",received:c(e)}),ae(r.issues);let n=e,i=null;if(n.chartType!==void 0)if(typeof n.chartType!="string"||!G(n.chartType)){let d=typeof n.chartType=="string"?re(n.chartType):null;r.add("chartType","unknown-chart-type",`${M(n.chartType)} is not a known chart type.${d?` Did you mean "${d}"?`:""}`,{expected:"a ChartType or alias",received:M(n.chartType),allowed:R,suggestion:d??void 0})}else i=ne(n.chartType);(t.requireSomething??!0)&&n.chartType===void 0&&n.seriesData===void 0&&r.add("","empty-patch","expected at least one of chartType or seriesData; a patch with neither cannot change the chart",{expected:"chartType and/or seriesData",received:"neither"}),Le(n.seriesData,i,r);let a=j.filter(d=>n[d]!==void 0);if(!(t.form==="resolved"||t.form!=="patch"&&a.length===j.length)&&i){let d=h[i]?.optionBag;for(let o of a){if(r.full)break;o!==d&&r.add(o,"foreign-option-bag",`${o} options do not apply to a ${i} chart, which reads "${d}"`,{expected:d?`"${d}"`:void 0,received:`"${o}"`,suggestion:d})}}for(let d of a){if(r.full)break;g(n[d],{kind:"object",fields:N[d]},d,r)}for(let[d,o]of Object.entries(ee)){if(r.full)break;g(n[d],o,d,r)}return ae(r.issues)}function ae(e){let t=e.filter(n=>n.severity==="error"),r=e.filter(n=>n.severity==="warning");return{valid:t.length===0,issues:e,errors:t,warnings:r}}function C(e,t="[chartbuddy]"){let r=e.map(i=>` \u2022 ${i.path?`${i.path}: `:""}${i.message}`+(i.severity==="warning"?" (warning)":"")),n=e.length===1?"problem":"problems";return`${t} invalid chart data \u2014 ${e.length} ${n}:
|
|
129
129
|
${r.join(`
|
|
130
130
|
`)}`}var y=class e extends Error{constructor(r,n){super(r);this.name="ChartDataValidationError";this.issues=n,this.errors=n.filter(i=>i.severity==="error"),this.warnings=n.filter(i=>i.severity==="warning"),Object.setPrototypeOf(this,e.prototype)}toJSON(){return{name:this.name,message:this.message,issues:this.issues}}};function E(e,t="[chartbuddy]",r={}){let{issues:n,errors:i,warnings:a}=b(e,r);if(a.length>0&&console.warn(C(a,t)),i.length>0)throw new y(C(i,t),n)}var f=class e{static{this.globalInstance=null}constructor(t){this.listeners=new Map,this.debugMode=t?.debug??!1}static global(){return e.globalInstance||(e.globalInstance=new e({debug:!1})),e.globalInstance}static resetGlobal(){e.globalInstance=null}on(t,r){return this.listeners.has(t)||this.listeners.set(t,new Set),this.listeners.get(t).add(r),()=>{this.off(t,r)}}once(t,r){let n=i=>{this.off(t,n),r(i)};return this.on(t,n)}emit(t,r){let n=this.listeners.get(t);if(this.debugMode&&console.log(`[EventBus] Emitting "${t}"`,r),!n)return;Array.from(n).forEach(a=>{try{a(r)}catch(s){console.error(`[EventBus] Error in listener for "${t}":`,s)}})}off(t,r){let n=this.listeners.get(t);n&&(r?(n.delete(r),n.size===0&&this.listeners.delete(t)):this.listeners.delete(t))}clear(){this.listeners.clear()}listenerCount(t){let r=this.listeners.get(t);return r?r.size:0}eventNames(){return Array.from(this.listeners.keys())}removeListeners(t){t.forEach(r=>{this.listeners.delete(r)})}};var L={CREATED:"chart.created",TYPE_CHANGED:"chart.type_changed",DELETED:"chart.deleted",SAVED:"chart.saved",DOWNLOADED:"chart.downloaded",OPENED:"chart.opened",CD_CHANGED:"chart.cd_changed"};var Be="chartbuddy-webapp-shell-chart-config",Fe="#ffffff";function He(){try{if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch{}return`i${Date.now().toString(36)}${Math.random().toString(36).slice(2,10)}`}function Ve(e){let t=String(e??"").trim();if(!t)throw new Error("[chartbuddy/embed] instanceId must be a non-empty string");if(!/^[A-Za-z0-9_.:-]+$/.test(t))throw new Error('[chartbuddy/embed] instanceId may only contain letters, digits, "_", ".", ":", "-"');return t}function $e(e){let t=e?Ve(e):He(),r=`cb-${t}`;return{instanceId:t,app:`${r}-app`,chart:`${r}-chart`,status:`${r}-status`,logs:`${r}-logs`,toggle:`${r}-toggle`,reset:`${r}-reset`,importBtn:`${r}-import`,importFile:`${r}-import-file`,overlay:`${r}-edit-overlay`}}function B(e){return`chartbuddy-embed-chart-config:${e}`}function de(e){return`chartbuddy-embed-chart-size:${e}`}function Ne(e){try{let t=window.localStorage.getItem(B(e));if(!t)return null;let r=JSON.parse(t);return ce(r)?r:null}catch{return null}}function je(e,t){try{window.localStorage.setItem(B(e),JSON.stringify(t))}catch{}}function Ge(e,t){if(e.persist===!0){let r=Ne(t);if(r)return r}return e.chartData}var z="__CHARTBUDDY_INSIGHTS__",k=new Map;function le(){if(!(typeof window>"u"))try{window[z]=I()}catch{}}function Ue(e){if(k.has(e.instanceId))throw new Error(`[chartbuddy/embed] duplicate instanceId "${e.instanceId}" \u2014 each Insight on the page must have a unique id. Reusing one silently overwrote the registry entry and could cross-contaminate persisted state.`);k.set(e.instanceId,e),le()}function ze(e){k.get(e.instanceId)===e&&(k.delete(e.instanceId),le())}function I(){let e={};return k.forEach((t,r)=>{e[r]=t}),e}async function Y(e={}){let t={},r=I();for(let[n,i]of Object.entries(r)){let a={chartData:i.getChartData()};e.png&&(a.pngBase64=await i.toPngBase64({scale:e.scale,background:e.background})),t[n]=a}return{schemaVersion:1,version:S,charts:t}}function Ye(e){let t=typeof e=="string"?document.querySelector(e):e;if(!t)throw new Error(`[chartbuddy/embed] mount target not found: ${String(e)}`);return t}function ce(e){return!!e&&typeof e=="object"&&typeof e.chartType=="string"&&Array.isArray(e.seriesData)}function se(e,t){E(e,`[chartbuddy/embed] ${t}:`)}function qe(e,t,r){if(e.innerHTML="",e.setAttribute("data-cb-instance",r.instanceId),e.style.position=e.style.position||"relative",e.style.minHeight||(e.style.minHeight="240px"),t){let d=document.createElement("div");d.className="webapp-toolbar",d.innerHTML=`
|
|
131
131
|
<button id="${r.reset}" type="button">Reset All</button>
|
package/chartbuddy-embed.mjs
CHANGED
|
@@ -125,7 +125,7 @@ var pe=`<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="
|
|
|
125
125
|
<button type="button" class="cb-embed-menu-item" data-action="dragExport" role="menuitem">Drag to slide</button>
|
|
126
126
|
`;return e==="edit"?`${t}
|
|
127
127
|
<button type="button" class="cb-embed-menu-item" data-action="done" role="menuitem">Done</button>`:`${t}
|
|
128
|
-
<button type="button" class="cb-embed-menu-item" data-action="edit" role="menuitem">Edit</button>`}var w=class{constructor(t,r,n="view"){this.hideTimer=null;this.destroyed=!1;he(),this.host=t,getComputedStyle(t).position==="static"&&(t.style.position="relative"),this.root=document.createElement("div"),this.root.className="cb-embed-chrome-root",this.root.setAttribute("data-cb-embed-chrome","1"),this.root.setAttribute("data-cb-embed-chrome-mode",n),this.ball=document.createElement("button"),this.ball.type="button",this.ball.className="cb-embed-ball",this.ball.setAttribute("aria-label","ChartBuddy actions"),this.ball.setAttribute("aria-haspopup","menu"),this.ball.setAttribute("aria-expanded","false"),this.ball.innerHTML=pe,this.menu=document.createElement("div"),this.menu.className="cb-embed-menu",this.menu.setAttribute("role","menu"),this.menu.innerHTML=ge(n),this.root.appendChild(this.ball),this.root.appendChild(this.menu),t.appendChild(this.root),this.ball.addEventListener("click",i=>{i.stopPropagation(),this.toggleMenu()}),this.menu.addEventListener("click",i=>{let a=i.target?.closest?.("[data-action]");if(!a)return;i.stopPropagation();let s=a.getAttribute("data-action");this.closeMenu(),this.dispatch(s,r)}),this.onHostEnter=()=>{this.destroyed||(this.clearHideTimer(),this.root.classList.add("is-visible"))},this.onHostLeave=()=>{this.destroyed||this.scheduleHide()},this.onDocPointer=i=>{if(this.destroyed||!this.root.classList.contains("is-menu-open"))return;let a=i.target;a&&this.root.contains(a)||this.closeMenu()},this.onKeyDown=i=>{i.key==="Escape"&&this.closeMenu()},t.addEventListener("pointerenter",this.onHostEnter),t.addEventListener("pointerleave",this.onHostLeave),document.addEventListener("pointerdown",this.onDocPointer,!0),document.addEventListener("keydown",this.onKeyDown)}async dispatch(t,r){try{t==="download"?await r.onDownload():t==="dragExport"?await r.onDragExport():t==="edit"?await r.onEdit?.():t==="done"&&await r.onDone?.()}catch(n){console.error("[chartbuddy/embed] chrome action failed:",n)}}toggleMenu(){this.root.classList.contains("is-menu-open")?this.closeMenu():this.openMenu()}openMenu(){this.clearHideTimer(),this.root.classList.add("is-visible","is-menu-open"),this.ball.setAttribute("aria-expanded","true")}closeMenu(){this.root.classList.remove("is-menu-open"),this.ball.setAttribute("aria-expanded","false")}scheduleHide(){this.clearHideTimer(),this.hideTimer=setTimeout(()=>{this.root.classList.contains("is-menu-open")||this.root.classList.remove("is-visible")},80)}clearHideTimer(){this.hideTimer&&(clearTimeout(this.hideTimer),this.hideTimer=null)}destroy(){this.destroyed||(this.destroyed=!0,this.clearHideTimer(),this.host.removeEventListener("pointerenter",this.onHostEnter),this.host.removeEventListener("pointerleave",this.onHostLeave),document.removeEventListener("pointerdown",this.onDocPointer,!0),document.removeEventListener("keydown",this.onKeyDown),this.root.remove())}};var b={vertical:{domain:"bottom",primaryRange:"left",secondaryRange:"right"},horizontal:{domain:"left",primaryRange:"bottom",secondaryRange:"top"}};function ye(e,t="vertical"){if(!e||typeof e!="object")return!1;let r=b[t]||b.vertical;return e[r.domain]?.id==="domain"&&e[r.primaryRange]?.id==="primaryRange"}function be(e,t="vertical"){let r=b[t]||b.vertical,n=o=>o==="left"?-90:o==="right"?90:0,i={},a=null;for(let o of["left","right","top","bottom"]){let l=e?.[o];if(!l)continue;let m=JSON.parse(JSON.stringify(l));l.id==="domain"||l.id==="primaryRange"||l.id==="secondaryRange"?i[l.id]=m:a=m}let s={},d=(o,l)=>{if(o){if(o.position=l,o.axisTitle){if(o.axisTitle.id){let m=String(o.axisTitle.id).split("-");m.length>=2&&(m[m.length-2]=l,o.axisTitle.id=m.join("-"))}o.axisTitle.rotation=n(l)}o.id==="domain"&&o.labels&&typeof o.labels=="object"&&(o.labels.position=l),s[l]=o}};d(i.domain,r.domain),d(i.primaryRange,r.primaryRange),d(i.secondaryRange,r.secondaryRange);for(let o of["left","right","top","bottom"])if(!s[o]){let l=a?JSON.parse(JSON.stringify(a)):{id:"unused",enabled:!1,visible:!1,scaleType:"band",labels:{visible:!1},axisTitle:{id:`multiline-${o}-title`,text:"",visible:!1}};d(l,o)}return s}function z(e){if(!e||typeof e!="object")return e;let t=e.orientation==="horizontal"?"horizontal":"vertical";return e.orientation=t,!e.axes||ye(e.axes,t)||(e.axes=be(e.axes,t)),e}var F="1.7.52";var h={clusteredBar:{label:"Clustered Bar",description:"Side-by-side bars comparing series within each category.",optionBag:"bar",family:"bar",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"clustered-bar"},stackedBar:{label:"Stacked Bar",description:"Bars stacked to show composition and category totals.",optionBag:"bar",family:"bar",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"stacked-bar"},stackedBar100:{label:"100% Stacked Bar",description:"Stacked bars normalized to 100% to compare mix, not size.",optionBag:"bar",family:"bar",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"stacked-bar"},line:{label:"Line Chart",description:"Trends over an ordered domain, one line per series.",optionBag:"line",family:"line",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"line"},area:{label:"Area Chart",description:"Filled lines showing magnitude over an ordered domain.",optionBag:"area",family:"area",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"area"},area100:{label:"100% Area Chart",description:"Area chart normalized to 100% to show changing mix.",optionBag:"area",family:"area",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"area"},pie:{label:"Pie Chart",description:"Share of a single total across categories.",optionBag:"pie",family:"pie",seriesLayout:"categoryValue",minRows:2,minCols:2,status:"stable",docsSlug:"pie"},scatter:{label:"Scatter Plot",description:"Points positioned by two metrics, optionally sized and grouped.",optionBag:"scatter",family:"scatter",seriesLayout:"pointRows",minRows:2,minCols:3,status:"stable",docsSlug:"scatter"},waterfall:{label:"Waterfall",description:"Running total showing how contributions bridge two values.",optionBag:"waterfall",family:"waterfall",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"waterfall"},mekko:{label:"Marimekko",description:"Variable-width stacked bars where both axes are percentages.",optionBag:"mekko",family:"mekko",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"mekko"},barMekko:{label:"Bar Mekko",description:"Bars whose width encodes one metric and height another; first data row sets widths.",optionBag:"barMekko",family:"mekko",seriesLayout:"widthRowThenHeightRows",minRows:3,minCols:2,status:"beta",docsSlug:"mekko"},combo:{label:"Combo Chart",description:"Mixed bar and line series on shared or dual axes.",optionBag:"combo",family:"combo",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"combo"}},k={bubble:"scatter",donut:"pie"},fe=[];var H=Object.keys(h).sort(),Y=Object.keys(k).sort(),I=[...H,...Y].sort(),xe=Y.filter(e=>!fe.includes(e)),dt=[...H,...xe].sort();var p={kind:"string",description:"CSS color."},W={kind:"string",nullable:!0,description:"CSS color; null derives it from the series color."},f={kind:"number",min:0,max:1},u={kind:"object",values:{kind:"unknown"},description:"Per-index overrides; keys are indices, values are style patches."},A={kind:"array",items:W},S={kind:"array",items:{kind:"number",min:0,nullable:!0}},V={kind:"array",items:{kind:"string",nullable:!0}},ve={id:{kind:"string"},visible:{kind:"boolean"},text:{kind:"string"},fontFamily:{kind:"string"},fontSize:{kind:"number",min:0},fontColor:{kind:"string"},backgroundColor:{kind:"string"},textAlign:{kind:"string"},width:{kind:"number",min:0},height:{kind:"number",min:0},x:{kind:"number"},y:{kind:"number"},movable:{kind:"boolean"},deletable:{kind:"boolean"}},T={kind:"object",fields:ve},Ce={shape:{kind:"string",enum:["circle","square","diamond","triangle"]},radius:{kind:"number",min:0,description:"Radius in px."},fill:W,stroke:p,strokeWidth:{kind:"number",min:0},strokeDashArray:{kind:"string"},series:u,overrides:u},q={kind:"object",fields:Ce},K={kind:"string",enum:["linear","cardinal","step","basis","monotone"]},Ee={kind:"object",fields:{visible:{kind:"boolean"},color:p,width:{kind:"number",min:0},dashArray:{kind:"string"},opacity:f,overrides:u}},X={id:{kind:"string"},version:{kind:"string",description:"App version the config was last migrated to. Drives the migrators."},title:T,subtitle:T,footnote:T,isDataTransposed:{kind:"boolean",description:"When true (default), seriesData rows are series."},seriesDataSource:{kind:"unknown"},orientation:{kind:"string",enum:["vertical","horizontal"]},backgroundColor:p,canvas:{kind:"object",fields:{width:{kind:"number",min:0},height:{kind:"number",min:0}}},chartPositionPercentages:{kind:"object",fields:{left:{kind:"number"},right:{kind:"number"},top:{kind:"number"},bottom:{kind:"number"}}},legend:{kind:"object",fields:{visible:{kind:"boolean"},colors:{kind:"array",items:p},position:{kind:"string"}}},axes:{kind:"object",description:"Axes keyed by physical side (left/right/top/bottom).",values:{kind:"object",fields:{id:{kind:"string"},axisTitle:T,gridlines:Ee}}},annotations:{kind:"object",fields:{cagrs:u,differenceArrows:u,levelArrows:u,levelLines:u}},seriesLabels:{kind:"object",fields:{visible:{kind:"boolean"},fontSize:{kind:"number",min:0},fontColor:p,fontFamily:{kind:"string"},overrides:u}},multilines:{kind:"array",items:{kind:"object",fields:{id:{kind:"string"},deletable:{kind:"boolean"},type:{kind:"string"},text:{kind:"string"},x:{kind:"number"},y:{kind:"number"}}}},origin:{kind:"object"}},$={bar:{padding:{kind:"number",min:0,max:1,description:"Gap between bars, 0\u20131."},cornerRadius:{kind:"number",min:0},reverseStackOrder:{kind:"boolean"},seriesStrokes:A,seriesStrokeWidths:S,seriesStrokeDashArrays:V,series:{kind:"array",items:{kind:"object"}},overrides:u},line:{width:{kind:"number",min:0,description:"Stroke width in px."},strokeDashArray:{kind:"string"},drawPoints:{kind:"boolean"},curveType:K,curveParameter:{kind:"number"},shadowIntensity:{kind:"number",min:0},padding:{kind:"number",min:0,max:1},pointMarker:q,overrides:u},area:{width:{kind:"number",min:0},strokeDashArray:{kind:"string"},drawPoints:{kind:"boolean"},curveType:K,curveParameter:{kind:"number"},shadowIntensity:{kind:"number",min:0},fillOpacity:f,fillType:{kind:"string",enum:["solid","gradient"]},fillOpacityTop:f,fillOpacityBottom:f,gradientTarget:{kind:"string"},strokeOpacity:f,pointMarker:q,dataLabels:{kind:"object",fields:{overrides:u}},overrides:u},scatter:{diameter:{kind:"number",min:0,description:"Marker diameter in px. The bubble alias seeds a larger default."},shape:{kind:"string"},shapes:{kind:"array",items:{kind:"string"}},seriesStrokes:A,seriesStrokeWidths:S,seriesStrokeDashArrays:V,overrides:u},pie:{innerRadiusRatio:{kind:"number",min:0,max:1,description:"0 is a full pie; the donut alias seeds 0.5."},scaleFactor:{kind:"number",min:0},labelVisibilityThreshold:{kind:"number",min:0},explode:{kind:"array",items:{kind:"number"},description:"Per-slice explode offsets."},line:{kind:"object",fields:{color:p,width:{kind:"number",min:0},dashArray:{kind:"string"}}},seriesStrokes:A,seriesStrokeWidths:S,seriesStrokeDashArrays:V,overrides:u},waterfall:{totalBarColor:p,totalLegendLabel:{kind:"string"},seriesStrokes:A,seriesStrokeWidths:S,connectorOverrides:u,columns:{kind:"object",description:"Per-column structural metadata, keyed by column index.",values:{kind:"object",fields:{isTotal:{kind:"boolean"},startBar:{kind:"boolean"},showSegments:{kind:"boolean"}}}},overrides:u},mekko:{showTotals:{kind:"boolean",description:"Legacy fallback for charts predating annotations.totals.visible."},overrides:u},barMekko:{sort:{kind:"string",enum:["heightDesc","heightAsc","widthDesc","widthAsc","dataOrder","desc","asc"],description:"Column order along the width axis."},overrides:u},combo:{seriesTypes:{kind:"object",description:"Per-series render type, keyed by series index.",values:{kind:"string",enum:["bar","line","area"]}},baseChartType:{kind:"string",enum:["clusteredBar","stackedBar"],nullable:!0}}},N=Object.keys($).sort();function we(e){return typeof e=="string"&&Object.prototype.hasOwnProperty.call(h,e)}function J(e){return typeof e=="string"&&Object.prototype.hasOwnProperty.call(k,e)}function j(e){return we(e)||J(e)}function Z(e){return J(e)?k[e]:e}function G(e,t){let r=new Array(t.length+1),n=new Array(t.length+1);for(let i=0;i<=t.length;i++)r[i]=i;for(let i=1;i<=e.length;i++){n[0]=i;for(let a=1;a<=t.length;a++){let s=e[i-1]===t[a-1]?0:1;n[a]=Math.min(r[a]+1,n[a-1]+1,r[a-1]+s)}for(let a=0;a<=t.length;a++)r[a]=n[a]}return r[t.length]}function Q(e){let t=e.toLowerCase(),r=null,n=1/0;for(let a of I){let s=G(t,a.toLowerCase());s<n&&(n=s,r=a)}let i=Math.max(2,Math.floor(t.length/3));return n<=i?r:null}var ke=2e4,Ie=20;function c(e){return e===null?"null":Array.isArray(e)?"array":typeof e}function R(e){return typeof e=="string"?`"${e}"`:typeof e=="bigint"||typeof e=="symbol"||e==null||typeof e!="object"?String(e):c(e)}function Ae(e,t){let r=e.toLowerCase(),n,i=1/0;for(let s of t){let d=G(r,s.toLowerCase());d<i&&(i=d,n=s)}let a=Math.max(2,Math.floor(r.length/3));return i<=a?n:void 0}var D=class{constructor(t){this.max=t;this.issues=[]}get full(){return this.issues.length>=this.max}add(t,r,n,i={}){if(this.full)return;let{severity:a="error",...s}=i,d={path:t,code:r,message:n,severity:a};this.issues.push(Object.fromEntries(Object.entries({...d,...s}).filter(([,o])=>o!==void 0)))}};function g(e,t,r,n){if(!(e===void 0||n.full)){if(e===null){if(t.kind==="unknown"||"nullable"in t&&t.nullable)return;n.add(r,"wrong-type",`expected ${t.kind}, received null`,{expected:t.kind,received:"null"});return}switch(t.kind){case"unknown":return;case"union":{if(!t.anyOf.some(a=>{let s=new D(1);return g(e,a,r,s),s.issues.length===0})){let a=t.anyOf.map(s=>s.kind).join(" | ");n.add(r,"wrong-type",`expected ${a}, received ${c(e)}`,{expected:a,received:c(e)})}return}case"string":{if(typeof e!="string"){n.add(r,"wrong-type",`expected string, received ${c(e)}`,{expected:"string",received:c(e)});return}t.enum&&!t.enum.includes(e)&&n.add(r,"not-in-enum",`${R(e)} is not valid; expected one of ${t.enum.map(i=>`"${i}"`).join(", ")}`,{expected:t.enum.map(i=>`"${i}"`).join(" | "),received:R(e),allowed:t.enum,suggestion:Ae(e,t.enum)});return}case"number":{if(typeof e!="number"){n.add(r,"wrong-type",`expected number, received ${c(e)}`,{expected:"number",received:c(e)});return}if(!Number.isFinite(e)){n.add(r,"wrong-type",`expected a finite number, received ${e}`,{expected:"finite number",received:String(e)});return}if(t.integer&&!Number.isInteger(e)){n.add(r,"wrong-type",`expected an integer, received ${e}`,{expected:"integer",received:String(e)});return}if(t.min!==void 0&&e<t.min){n.add(r,"out-of-range",`${e} is below the minimum of ${t.min}`,{expected:`>= ${t.min}`,received:String(e)});return}t.max!==void 0&&e>t.max&&n.add(r,"out-of-range",`${e} is above the maximum of ${t.max}`,{expected:`<= ${t.max}`,received:String(e)});return}case"boolean":{typeof e!="boolean"&&n.add(r,"wrong-type",`expected boolean, received ${c(e)}`,{expected:"boolean",received:c(e)});return}case"array":{if(!Array.isArray(e)){n.add(r,"wrong-type",`expected array, received ${c(e)}`,{expected:"array",received:c(e)});return}if(t.minItems!==void 0&&e.length<t.minItems){n.add(r,"out-of-range",`expected at least ${t.minItems} item(s), received ${e.length}`,{expected:`array with >= ${t.minItems} item(s)`,received:`array of ${e.length}`});return}if(!t.items)return;for(let i=0;i<e.length&&!n.full;i++)g(e[i],t.items,`${r}[${i}]`,n);return}case"object":{if(typeof e!="object"||Array.isArray(e)){n.add(r,"wrong-type",`expected object, received ${c(e)}`,{expected:"object",received:c(e)});return}let i=e;if(t.fields)for(let[a,s]of Object.entries(t.fields)){if(n.full)return;g(i[a],s,`${r}.${a}`,n)}if(t.values)for(let[a,s]of Object.entries(i)){if(n.full)return;g(s,t.values,`${r}.${a}`,n)}return}}}}var ee={seriesRows:"row 0 is the category header; each later row is one series",categoryValue:"each row is [Category, Value]",pointRows:"row 0 names the metrics; each later row is one point",widthRowThenHeightRows:"row 1 sizes the bars (never drawn); rows 2+ are stacked height segments"};function Se(e,t,r){if(e===void 0)return;if(!Array.isArray(e)){r.add("seriesData","series-data-shape",`expected a 2D array, received ${c(e)}`,{expected:"2D array",received:c(e)});return}let n=t?h[t]:void 0;n&&e.length<n.minRows&&r.add("seriesData","series-data-shape",`${n.label} needs at least ${n.minRows} rows (${ee[n.seriesLayout]}), received ${e.length}`,{expected:`>= ${n.minRows} rows (${ee[n.seriesLayout]})`,received:`${e.length} rows`});let i=0,a=[];for(let s=0;s<e.length&&!r.full;s++){let d=e[s];if(!Array.isArray(d)){r.add(`seriesData[${s}]`,"series-data-shape",`expected a row array, received ${c(d)}`,{expected:"array",received:c(d)});continue}a.push(d.length),n&&d.length<n.minCols&&r.add(`seriesData[${s}]`,"series-data-shape",`${n.label} needs at least ${n.minCols} columns per row, received ${d.length}`,{expected:`>= ${n.minCols} columns`,received:`${d.length} columns`});for(let o=0;o<d.length;o++){if(r.full||i>=ke)return;i++;let l=d[o];if(l===null)continue;let m=typeof l;m!=="string"&&m!=="number"&&m!=="boolean"?r.add(`seriesData[${s}][${o}]`,"series-data-shape",`cells must be string, number, boolean, or null; received ${c(l)}`,{expected:"string | number | boolean | null",received:c(l)}):m==="number"&&!Number.isFinite(l)&&r.add(`seriesData[${s}][${o}]`,"series-data-shape",`cells must be finite numbers; received ${l}`,{expected:"finite number",received:String(l)})}}if(a.length>=2){let s=Math.min(...a),d=Math.max(...a);s!==d&&r.add("seriesData","ragged-series-data",`rows have unequal lengths (shortest ${s}, longest ${d}); charts expect a rectangular grid`,{severity:"warning",expected:`every row ${d} cells`,received:`rows of ${s}\u2013${d} cells`})}}function v(e,t={}){let r=new D(t.maxIssues??Ie);if(!e||typeof e!="object"||Array.isArray(e))return r.add("","not-an-object",`expected a chart-data object, received ${c(e)}`,{expected:"object",received:c(e)}),te(r.issues);let n=e,i=null;if(n.chartType!==void 0)if(typeof n.chartType!="string"||!j(n.chartType)){let d=typeof n.chartType=="string"?Q(n.chartType):null;r.add("chartType","unknown-chart-type",`${R(n.chartType)} is not a known chart type.${d?` Did you mean "${d}"?`:""}`,{expected:"a ChartType or alias",received:R(n.chartType),allowed:I,suggestion:d??void 0})}else i=Z(n.chartType);(t.requireSomething??!0)&&n.chartType===void 0&&n.seriesData===void 0&&r.add("","empty-patch","expected at least one of chartType or seriesData; a patch with neither cannot change the chart",{expected:"chartType and/or seriesData",received:"neither"}),Se(n.seriesData,i,r);let a=N.filter(d=>n[d]!==void 0);if(!(t.form==="resolved"||t.form!=="patch"&&a.length===N.length)&&i){let d=h[i]?.optionBag;for(let o of a){if(r.full)break;o!==d&&r.add(o,"foreign-option-bag",`${o} options do not apply to a ${i} chart, which reads "${d}"`,{expected:d?`"${d}"`:void 0,received:`"${o}"`,suggestion:d})}}for(let d of a){if(r.full)break;g(n[d],{kind:"object",fields:$[d]},d,r)}for(let[d,o]of Object.entries(X)){if(r.full)break;g(n[d],o,d,r)}return te(r.issues)}function te(e){let t=e.filter(n=>n.severity==="error"),r=e.filter(n=>n.severity==="warning");return{valid:t.length===0,issues:e,errors:t,warnings:r}}function O(e,t="[chartbuddy]"){let r=e.map(i=>` \u2022 ${i.path?`${i.path}: `:""}${i.message}`+(i.severity==="warning"?" (warning)":"")),n=e.length===1?"problem":"problems";return`${t} invalid chart data \u2014 ${e.length} ${n}:
|
|
128
|
+
<button type="button" class="cb-embed-menu-item" data-action="edit" role="menuitem">Edit</button>`}var w=class{constructor(t,r,n="view"){this.hideTimer=null;this.destroyed=!1;he(),this.host=t,getComputedStyle(t).position==="static"&&(t.style.position="relative"),this.root=document.createElement("div"),this.root.className="cb-embed-chrome-root",this.root.setAttribute("data-cb-embed-chrome","1"),this.root.setAttribute("data-cb-embed-chrome-mode",n),this.ball=document.createElement("button"),this.ball.type="button",this.ball.className="cb-embed-ball",this.ball.setAttribute("aria-label","ChartBuddy actions"),this.ball.setAttribute("aria-haspopup","menu"),this.ball.setAttribute("aria-expanded","false"),this.ball.innerHTML=pe,this.menu=document.createElement("div"),this.menu.className="cb-embed-menu",this.menu.setAttribute("role","menu"),this.menu.innerHTML=ge(n),this.root.appendChild(this.ball),this.root.appendChild(this.menu),t.appendChild(this.root),this.ball.addEventListener("click",i=>{i.stopPropagation(),this.toggleMenu()}),this.menu.addEventListener("click",i=>{let a=i.target?.closest?.("[data-action]");if(!a)return;i.stopPropagation();let s=a.getAttribute("data-action");this.closeMenu(),this.dispatch(s,r)}),this.onHostEnter=()=>{this.destroyed||(this.clearHideTimer(),this.root.classList.add("is-visible"))},this.onHostLeave=()=>{this.destroyed||this.scheduleHide()},this.onDocPointer=i=>{if(this.destroyed||!this.root.classList.contains("is-menu-open"))return;let a=i.target;a&&this.root.contains(a)||this.closeMenu()},this.onKeyDown=i=>{i.key==="Escape"&&this.closeMenu()},t.addEventListener("pointerenter",this.onHostEnter),t.addEventListener("pointerleave",this.onHostLeave),document.addEventListener("pointerdown",this.onDocPointer,!0),document.addEventListener("keydown",this.onKeyDown)}async dispatch(t,r){try{t==="download"?await r.onDownload():t==="dragExport"?await r.onDragExport():t==="edit"?await r.onEdit?.():t==="done"&&await r.onDone?.()}catch(n){console.error("[chartbuddy/embed] chrome action failed:",n)}}toggleMenu(){this.root.classList.contains("is-menu-open")?this.closeMenu():this.openMenu()}openMenu(){this.clearHideTimer(),this.root.classList.add("is-visible","is-menu-open"),this.ball.setAttribute("aria-expanded","true")}closeMenu(){this.root.classList.remove("is-menu-open"),this.ball.setAttribute("aria-expanded","false")}scheduleHide(){this.clearHideTimer(),this.hideTimer=setTimeout(()=>{this.root.classList.contains("is-menu-open")||this.root.classList.remove("is-visible")},80)}clearHideTimer(){this.hideTimer&&(clearTimeout(this.hideTimer),this.hideTimer=null)}destroy(){this.destroyed||(this.destroyed=!0,this.clearHideTimer(),this.host.removeEventListener("pointerenter",this.onHostEnter),this.host.removeEventListener("pointerleave",this.onHostLeave),document.removeEventListener("pointerdown",this.onDocPointer,!0),document.removeEventListener("keydown",this.onKeyDown),this.root.remove())}};var b={vertical:{domain:"bottom",primaryRange:"left",secondaryRange:"right"},horizontal:{domain:"left",primaryRange:"bottom",secondaryRange:"top"}};function ye(e,t="vertical"){if(!e||typeof e!="object")return!1;let r=b[t]||b.vertical;return e[r.domain]?.id==="domain"&&e[r.primaryRange]?.id==="primaryRange"}function be(e,t="vertical"){let r=b[t]||b.vertical,n=o=>o==="left"?-90:o==="right"?90:0,i={},a=null;for(let o of["left","right","top","bottom"]){let l=e?.[o];if(!l)continue;let m=JSON.parse(JSON.stringify(l));l.id==="domain"||l.id==="primaryRange"||l.id==="secondaryRange"?i[l.id]=m:a=m}let s={},d=(o,l)=>{if(o){if(o.position=l,o.axisTitle){if(o.axisTitle.id){let m=String(o.axisTitle.id).split("-");m.length>=2&&(m[m.length-2]=l,o.axisTitle.id=m.join("-"))}o.axisTitle.rotation=n(l)}o.id==="domain"&&o.labels&&typeof o.labels=="object"&&(o.labels.position=l),s[l]=o}};d(i.domain,r.domain),d(i.primaryRange,r.primaryRange),d(i.secondaryRange,r.secondaryRange);for(let o of["left","right","top","bottom"])if(!s[o]){let l=a?JSON.parse(JSON.stringify(a)):{id:"unused",enabled:!1,visible:!1,scaleType:"band",labels:{visible:!1},axisTitle:{id:`multiline-${o}-title`,text:"",visible:!1}};d(l,o)}return s}function z(e){if(!e||typeof e!="object")return e;let t=e.orientation==="horizontal"?"horizontal":"vertical";return e.orientation=t,!e.axes||ye(e.axes,t)||(e.axes=be(e.axes,t)),e}var F="1.7.53";var h={clusteredBar:{label:"Clustered Bar",description:"Side-by-side bars comparing series within each category.",optionBag:"bar",family:"bar",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"clustered-bar"},stackedBar:{label:"Stacked Bar",description:"Bars stacked to show composition and category totals.",optionBag:"bar",family:"bar",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"stacked-bar"},stackedBar100:{label:"100% Stacked Bar",description:"Stacked bars normalized to 100% to compare mix, not size.",optionBag:"bar",family:"bar",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"stacked-bar"},line:{label:"Line Chart",description:"Trends over an ordered domain, one line per series.",optionBag:"line",family:"line",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"line"},area:{label:"Area Chart",description:"Filled lines showing magnitude over an ordered domain.",optionBag:"area",family:"area",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"area"},area100:{label:"100% Area Chart",description:"Area chart normalized to 100% to show changing mix.",optionBag:"area",family:"area",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"area"},pie:{label:"Pie Chart",description:"Share of a single total across categories.",optionBag:"pie",family:"pie",seriesLayout:"categoryValue",minRows:2,minCols:2,status:"stable",docsSlug:"pie"},scatter:{label:"Scatter Plot",description:"Points positioned by two metrics, optionally sized and grouped.",optionBag:"scatter",family:"scatter",seriesLayout:"pointRows",minRows:2,minCols:3,status:"stable",docsSlug:"scatter"},waterfall:{label:"Waterfall",description:"Running total showing how contributions bridge two values.",optionBag:"waterfall",family:"waterfall",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"waterfall"},mekko:{label:"Marimekko",description:"Variable-width stacked bars where both axes are percentages.",optionBag:"mekko",family:"mekko",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"mekko"},barMekko:{label:"Bar Mekko",description:"Bars whose width encodes one metric and height another; first data row sets widths.",optionBag:"barMekko",family:"mekko",seriesLayout:"widthRowThenHeightRows",minRows:3,minCols:2,status:"beta",docsSlug:"mekko"},combo:{label:"Combo Chart",description:"Mixed bar and line series on shared or dual axes.",optionBag:"combo",family:"combo",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"combo"}},k={bubble:"scatter",donut:"pie"},fe=[];var H=Object.keys(h).sort(),Y=Object.keys(k).sort(),I=[...H,...Y].sort(),xe=Y.filter(e=>!fe.includes(e)),dt=[...H,...xe].sort();var p={kind:"string",description:"CSS color."},W={kind:"string",nullable:!0,description:"CSS color; null derives it from the series color."},f={kind:"number",min:0,max:1},u={kind:"object",values:{kind:"unknown"},description:"Per-index overrides; keys are indices, values are style patches."},A={kind:"array",items:W},S={kind:"array",items:{kind:"number",min:0,nullable:!0}},V={kind:"array",items:{kind:"string",nullable:!0}},ve={id:{kind:"string"},visible:{kind:"boolean"},text:{kind:"string"},fontFamily:{kind:"string"},fontSize:{kind:"number",min:0},fontColor:{kind:"string"},backgroundColor:{kind:"string"},textAlign:{kind:"string"},width:{kind:"number",min:0},height:{kind:"number",min:0},x:{kind:"number"},y:{kind:"number"},movable:{kind:"boolean"},deletable:{kind:"boolean"}},T={kind:"object",fields:ve},Ce={shape:{kind:"string",enum:["circle","square","diamond","triangle"]},radius:{kind:"number",min:0,description:"Radius in px."},fill:W,stroke:p,strokeWidth:{kind:"number",min:0},strokeDashArray:{kind:"string"},series:u,overrides:u},q={kind:"object",fields:Ce},K={kind:"string",enum:["linear","cardinal","step","basis","monotone"]},Ee={kind:"object",fields:{visible:{kind:"boolean"},color:p,width:{kind:"number",min:0},dashArray:{kind:"string"},opacity:f,overrides:u}},X={id:{kind:"string"},version:{kind:"string",description:"App version the config was last migrated to. Drives the migrators."},title:T,subtitle:T,footnote:T,isDataTransposed:{kind:"boolean",description:"When true (default), seriesData rows are series."},seriesDataSource:{kind:"unknown"},orientation:{kind:"string",enum:["vertical","horizontal"]},backgroundColor:p,canvas:{kind:"object",fields:{width:{kind:"number",min:0},height:{kind:"number",min:0}}},chartPositionPercentages:{kind:"object",fields:{left:{kind:"number"},right:{kind:"number"},top:{kind:"number"},bottom:{kind:"number"}}},legend:{kind:"object",fields:{visible:{kind:"boolean"},colors:{kind:"array",items:p},position:{kind:"string"}}},axes:{kind:"object",description:"Axes keyed by physical side (left/right/top/bottom).",values:{kind:"object",fields:{id:{kind:"string"},axisTitle:T,gridlines:Ee}}},annotations:{kind:"object",fields:{cagrs:u,differenceArrows:u,levelArrows:u,levelLines:u}},seriesLabels:{kind:"object",fields:{visible:{kind:"boolean"},fontSize:{kind:"number",min:0},fontColor:p,fontFamily:{kind:"string"},overrides:u}},multilines:{kind:"array",items:{kind:"object",fields:{id:{kind:"string"},deletable:{kind:"boolean"},type:{kind:"string"},text:{kind:"string"},x:{kind:"number"},y:{kind:"number"}}}},origin:{kind:"object"}},$={bar:{padding:{kind:"number",min:0,max:1,description:"Gap between bars, 0\u20131."},cornerRadius:{kind:"number",min:0},reverseStackOrder:{kind:"boolean"},seriesStrokes:A,seriesStrokeWidths:S,seriesStrokeDashArrays:V,series:{kind:"array",items:{kind:"object"}},overrides:u},line:{width:{kind:"number",min:0,description:"Stroke width in px."},strokeDashArray:{kind:"string"},drawPoints:{kind:"boolean"},curveType:K,curveParameter:{kind:"number"},shadowIntensity:{kind:"number",min:0},padding:{kind:"number",min:0,max:1},pointMarker:q,overrides:u},area:{width:{kind:"number",min:0},strokeDashArray:{kind:"string"},drawPoints:{kind:"boolean"},curveType:K,curveParameter:{kind:"number"},shadowIntensity:{kind:"number",min:0},fillOpacity:f,fillType:{kind:"string",enum:["solid","gradient"]},fillOpacityTop:f,fillOpacityBottom:f,gradientTarget:{kind:"string"},strokeOpacity:f,pointMarker:q,dataLabels:{kind:"object",fields:{overrides:u}},overrides:u},scatter:{diameter:{kind:"number",min:0,description:"Marker diameter in px. The bubble alias seeds a larger default."},shape:{kind:"string"},shapes:{kind:"array",items:{kind:"string"}},seriesStrokes:A,seriesStrokeWidths:S,seriesStrokeDashArrays:V,overrides:u},pie:{innerRadiusRatio:{kind:"number",min:0,max:1,description:"0 is a full pie; the donut alias seeds 0.5."},scaleFactor:{kind:"number",min:0},labelVisibilityThreshold:{kind:"number",min:0},explode:{kind:"array",items:{kind:"number"},description:"Per-slice explode offsets."},line:{kind:"object",fields:{color:p,width:{kind:"number",min:0},dashArray:{kind:"string"}}},seriesStrokes:A,seriesStrokeWidths:S,seriesStrokeDashArrays:V,overrides:u},waterfall:{totalBarColor:p,totalLegendLabel:{kind:"string"},seriesStrokes:A,seriesStrokeWidths:S,connectorOverrides:u,columns:{kind:"object",description:"Per-column structural metadata, keyed by column index.",values:{kind:"object",fields:{isTotal:{kind:"boolean"},startBar:{kind:"boolean"},showSegments:{kind:"boolean"}}}},overrides:u},mekko:{showTotals:{kind:"boolean",description:"Legacy fallback for charts predating annotations.totals.visible."},overrides:u},barMekko:{sort:{kind:"string",enum:["heightDesc","heightAsc","widthDesc","widthAsc","dataOrder","desc","asc"],description:"Column order along the width axis."},overrides:u},combo:{seriesTypes:{kind:"object",description:"Per-series render type, keyed by series index.",values:{kind:"string",enum:["bar","line","area"]}},baseChartType:{kind:"string",enum:["clusteredBar","stackedBar"],nullable:!0}}},N=Object.keys($).sort();function we(e){return typeof e=="string"&&Object.prototype.hasOwnProperty.call(h,e)}function J(e){return typeof e=="string"&&Object.prototype.hasOwnProperty.call(k,e)}function j(e){return we(e)||J(e)}function Z(e){return J(e)?k[e]:e}function G(e,t){let r=new Array(t.length+1),n=new Array(t.length+1);for(let i=0;i<=t.length;i++)r[i]=i;for(let i=1;i<=e.length;i++){n[0]=i;for(let a=1;a<=t.length;a++){let s=e[i-1]===t[a-1]?0:1;n[a]=Math.min(r[a]+1,n[a-1]+1,r[a-1]+s)}for(let a=0;a<=t.length;a++)r[a]=n[a]}return r[t.length]}function Q(e){let t=e.toLowerCase(),r=null,n=1/0;for(let a of I){let s=G(t,a.toLowerCase());s<n&&(n=s,r=a)}let i=Math.max(2,Math.floor(t.length/3));return n<=i?r:null}var ke=2e4,Ie=20;function c(e){return e===null?"null":Array.isArray(e)?"array":typeof e}function R(e){return typeof e=="string"?`"${e}"`:typeof e=="bigint"||typeof e=="symbol"||e==null||typeof e!="object"?String(e):c(e)}function Ae(e,t){let r=e.toLowerCase(),n,i=1/0;for(let s of t){let d=G(r,s.toLowerCase());d<i&&(i=d,n=s)}let a=Math.max(2,Math.floor(r.length/3));return i<=a?n:void 0}var D=class{constructor(t){this.max=t;this.issues=[]}get full(){return this.issues.length>=this.max}add(t,r,n,i={}){if(this.full)return;let{severity:a="error",...s}=i,d={path:t,code:r,message:n,severity:a};this.issues.push(Object.fromEntries(Object.entries({...d,...s}).filter(([,o])=>o!==void 0)))}};function g(e,t,r,n){if(!(e===void 0||n.full)){if(e===null){if(t.kind==="unknown"||"nullable"in t&&t.nullable)return;n.add(r,"wrong-type",`expected ${t.kind}, received null`,{expected:t.kind,received:"null"});return}switch(t.kind){case"unknown":return;case"union":{if(!t.anyOf.some(a=>{let s=new D(1);return g(e,a,r,s),s.issues.length===0})){let a=t.anyOf.map(s=>s.kind).join(" | ");n.add(r,"wrong-type",`expected ${a}, received ${c(e)}`,{expected:a,received:c(e)})}return}case"string":{if(typeof e!="string"){n.add(r,"wrong-type",`expected string, received ${c(e)}`,{expected:"string",received:c(e)});return}t.enum&&!t.enum.includes(e)&&n.add(r,"not-in-enum",`${R(e)} is not valid; expected one of ${t.enum.map(i=>`"${i}"`).join(", ")}`,{expected:t.enum.map(i=>`"${i}"`).join(" | "),received:R(e),allowed:t.enum,suggestion:Ae(e,t.enum)});return}case"number":{if(typeof e!="number"){n.add(r,"wrong-type",`expected number, received ${c(e)}`,{expected:"number",received:c(e)});return}if(!Number.isFinite(e)){n.add(r,"wrong-type",`expected a finite number, received ${e}`,{expected:"finite number",received:String(e)});return}if(t.integer&&!Number.isInteger(e)){n.add(r,"wrong-type",`expected an integer, received ${e}`,{expected:"integer",received:String(e)});return}if(t.min!==void 0&&e<t.min){n.add(r,"out-of-range",`${e} is below the minimum of ${t.min}`,{expected:`>= ${t.min}`,received:String(e)});return}t.max!==void 0&&e>t.max&&n.add(r,"out-of-range",`${e} is above the maximum of ${t.max}`,{expected:`<= ${t.max}`,received:String(e)});return}case"boolean":{typeof e!="boolean"&&n.add(r,"wrong-type",`expected boolean, received ${c(e)}`,{expected:"boolean",received:c(e)});return}case"array":{if(!Array.isArray(e)){n.add(r,"wrong-type",`expected array, received ${c(e)}`,{expected:"array",received:c(e)});return}if(t.minItems!==void 0&&e.length<t.minItems){n.add(r,"out-of-range",`expected at least ${t.minItems} item(s), received ${e.length}`,{expected:`array with >= ${t.minItems} item(s)`,received:`array of ${e.length}`});return}if(!t.items)return;for(let i=0;i<e.length&&!n.full;i++)g(e[i],t.items,`${r}[${i}]`,n);return}case"object":{if(typeof e!="object"||Array.isArray(e)){n.add(r,"wrong-type",`expected object, received ${c(e)}`,{expected:"object",received:c(e)});return}let i=e;if(t.fields)for(let[a,s]of Object.entries(t.fields)){if(n.full)return;g(i[a],s,`${r}.${a}`,n)}if(t.values)for(let[a,s]of Object.entries(i)){if(n.full)return;g(s,t.values,`${r}.${a}`,n)}return}}}}var ee={seriesRows:"row 0 is the category header; each later row is one series",categoryValue:"each row is [Category, Value]",pointRows:"row 0 names the metrics; each later row is one point",widthRowThenHeightRows:"row 1 sizes the bars (never drawn); rows 2+ are stacked height segments"};function Se(e,t,r){if(e===void 0)return;if(!Array.isArray(e)){r.add("seriesData","series-data-shape",`expected a 2D array, received ${c(e)}`,{expected:"2D array",received:c(e)});return}let n=t?h[t]:void 0;n&&e.length<n.minRows&&r.add("seriesData","series-data-shape",`${n.label} needs at least ${n.minRows} rows (${ee[n.seriesLayout]}), received ${e.length}`,{expected:`>= ${n.minRows} rows (${ee[n.seriesLayout]})`,received:`${e.length} rows`});let i=0,a=[];for(let s=0;s<e.length&&!r.full;s++){let d=e[s];if(!Array.isArray(d)){r.add(`seriesData[${s}]`,"series-data-shape",`expected a row array, received ${c(d)}`,{expected:"array",received:c(d)});continue}a.push(d.length),n&&d.length<n.minCols&&r.add(`seriesData[${s}]`,"series-data-shape",`${n.label} needs at least ${n.minCols} columns per row, received ${d.length}`,{expected:`>= ${n.minCols} columns`,received:`${d.length} columns`});for(let o=0;o<d.length;o++){if(r.full||i>=ke)return;i++;let l=d[o];if(l===null)continue;let m=typeof l;m!=="string"&&m!=="number"&&m!=="boolean"?r.add(`seriesData[${s}][${o}]`,"series-data-shape",`cells must be string, number, boolean, or null; received ${c(l)}`,{expected:"string | number | boolean | null",received:c(l)}):m==="number"&&!Number.isFinite(l)&&r.add(`seriesData[${s}][${o}]`,"series-data-shape",`cells must be finite numbers; received ${l}`,{expected:"finite number",received:String(l)})}}if(a.length>=2){let s=Math.min(...a),d=Math.max(...a);s!==d&&r.add("seriesData","ragged-series-data",`rows have unequal lengths (shortest ${s}, longest ${d}); charts expect a rectangular grid`,{severity:"warning",expected:`every row ${d} cells`,received:`rows of ${s}\u2013${d} cells`})}}function v(e,t={}){let r=new D(t.maxIssues??Ie);if(!e||typeof e!="object"||Array.isArray(e))return r.add("","not-an-object",`expected a chart-data object, received ${c(e)}`,{expected:"object",received:c(e)}),te(r.issues);let n=e,i=null;if(n.chartType!==void 0)if(typeof n.chartType!="string"||!j(n.chartType)){let d=typeof n.chartType=="string"?Q(n.chartType):null;r.add("chartType","unknown-chart-type",`${R(n.chartType)} is not a known chart type.${d?` Did you mean "${d}"?`:""}`,{expected:"a ChartType or alias",received:R(n.chartType),allowed:I,suggestion:d??void 0})}else i=Z(n.chartType);(t.requireSomething??!0)&&n.chartType===void 0&&n.seriesData===void 0&&r.add("","empty-patch","expected at least one of chartType or seriesData; a patch with neither cannot change the chart",{expected:"chartType and/or seriesData",received:"neither"}),Se(n.seriesData,i,r);let a=N.filter(d=>n[d]!==void 0);if(!(t.form==="resolved"||t.form!=="patch"&&a.length===N.length)&&i){let d=h[i]?.optionBag;for(let o of a){if(r.full)break;o!==d&&r.add(o,"foreign-option-bag",`${o} options do not apply to a ${i} chart, which reads "${d}"`,{expected:d?`"${d}"`:void 0,received:`"${o}"`,suggestion:d})}}for(let d of a){if(r.full)break;g(n[d],{kind:"object",fields:$[d]},d,r)}for(let[d,o]of Object.entries(X)){if(r.full)break;g(n[d],o,d,r)}return te(r.issues)}function te(e){let t=e.filter(n=>n.severity==="error"),r=e.filter(n=>n.severity==="warning");return{valid:t.length===0,issues:e,errors:t,warnings:r}}function O(e,t="[chartbuddy]"){let r=e.map(i=>` \u2022 ${i.path?`${i.path}: `:""}${i.message}`+(i.severity==="warning"?" (warning)":"")),n=e.length===1?"problem":"problems";return`${t} invalid chart data \u2014 ${e.length} ${n}:
|
|
129
129
|
${r.join(`
|
|
130
130
|
`)}`}var x=class e extends Error{constructor(r,n){super(r);this.name="ChartDataValidationError";this.issues=n,this.errors=n.filter(i=>i.severity==="error"),this.warnings=n.filter(i=>i.severity==="warning"),Object.setPrototypeOf(this,e.prototype)}toJSON(){return{name:this.name,message:this.message,issues:this.issues}}};function P(e,t="[chartbuddy]",r={}){let{issues:n,errors:i,warnings:a}=v(e,r);if(a.length>0&&console.warn(O(a,t)),i.length>0)throw new x(O(i,t),n)}var y=class e{static{this.globalInstance=null}constructor(t){this.listeners=new Map,this.debugMode=t?.debug??!1}static global(){return e.globalInstance||(e.globalInstance=new e({debug:!1})),e.globalInstance}static resetGlobal(){e.globalInstance=null}on(t,r){return this.listeners.has(t)||this.listeners.set(t,new Set),this.listeners.get(t).add(r),()=>{this.off(t,r)}}once(t,r){let n=i=>{this.off(t,n),r(i)};return this.on(t,n)}emit(t,r){let n=this.listeners.get(t);if(this.debugMode&&console.log(`[EventBus] Emitting "${t}"`,r),!n)return;Array.from(n).forEach(a=>{try{a(r)}catch(s){console.error(`[EventBus] Error in listener for "${t}":`,s)}})}off(t,r){let n=this.listeners.get(t);n&&(r?(n.delete(r),n.size===0&&this.listeners.delete(t)):this.listeners.delete(t))}clear(){this.listeners.clear()}listenerCount(t){let r=this.listeners.get(t);return r?r.size:0}eventNames(){return Array.from(this.listeners.keys())}removeListeners(t){t.forEach(r=>{this.listeners.delete(r)})}};var M={CREATED:"chart.created",TYPE_CHANGED:"chart.type_changed",DELETED:"chart.deleted",SAVED:"chart.saved",DOWNLOADED:"chart.downloaded",OPENED:"chart.opened",CD_CHANGED:"chart.cd_changed"};var Te="chartbuddy-webapp-shell-chart-config",Re="#ffffff";function De(){try{if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch{}return`i${Date.now().toString(36)}${Math.random().toString(36).slice(2,10)}`}function Oe(e){let t=String(e??"").trim();if(!t)throw new Error("[chartbuddy/embed] instanceId must be a non-empty string");if(!/^[A-Za-z0-9_.:-]+$/.test(t))throw new Error('[chartbuddy/embed] instanceId may only contain letters, digits, "_", ".", ":", "-"');return t}function Pe(e){let t=e?Oe(e):De(),r=`cb-${t}`;return{instanceId:t,app:`${r}-app`,chart:`${r}-chart`,status:`${r}-status`,logs:`${r}-logs`,toggle:`${r}-toggle`,reset:`${r}-reset`,importBtn:`${r}-import`,importFile:`${r}-import-file`,overlay:`${r}-edit-overlay`}}function _(e){return`chartbuddy-embed-chart-config:${e}`}function ie(e){return`chartbuddy-embed-chart-size:${e}`}function Me(e){try{let t=window.localStorage.getItem(_(e));if(!t)return null;let r=JSON.parse(t);return de(r)?r:null}catch{return null}}function _e(e,t){try{window.localStorage.setItem(_(e),JSON.stringify(t))}catch{}}function Le(e,t){if(e.persist===!0){let r=Me(t);if(r)return r}return e.chartData}var ae="__CHARTBUDDY_INSIGHTS__",E=new Map;function oe(){if(!(typeof window>"u"))try{window[ae]=L()}catch{}}function Be(e){if(E.has(e.instanceId))throw new Error(`[chartbuddy/embed] duplicate instanceId "${e.instanceId}" \u2014 each Insight on the page must have a unique id. Reusing one silently overwrote the registry entry and could cross-contaminate persisted state.`);E.set(e.instanceId,e),oe()}function Fe(e){E.get(e.instanceId)===e&&(E.delete(e.instanceId),oe())}function L(){let e={};return E.forEach((t,r)=>{e[r]=t}),e}async function se(e={}){let t={},r=L();for(let[n,i]of Object.entries(r)){let a={chartData:i.getChartData()};e.png&&(a.pngBase64=await i.toPngBase64({scale:e.scale,background:e.background})),t[n]=a}return{schemaVersion:1,version:F,charts:t}}function He(e){let t=typeof e=="string"?document.querySelector(e):e;if(!t)throw new Error(`[chartbuddy/embed] mount target not found: ${String(e)}`);return t}function de(e){return!!e&&typeof e=="object"&&typeof e.chartType=="string"&&Array.isArray(e.seriesData)}function re(e,t){P(e,`[chartbuddy/embed] ${t}:`)}function Ve(e,t,r){if(e.innerHTML="",e.setAttribute("data-cb-instance",r.instanceId),e.style.position=e.style.position||"relative",e.style.minHeight||(e.style.minHeight="240px"),t){let d=document.createElement("div");d.className="webapp-toolbar",d.innerHTML=`
|
|
131
131
|
<button id="${r.reset}" type="button">Reset All</button>
|
|
@@ -47,7 +47,7 @@ var ChartBuddyEmbed=(()=>{var RF=Object.create;var Xg=Object.defineProperty;var
|
|
|
47
47
|
pointer-events: none;
|
|
48
48
|
font-size: 72px;
|
|
49
49
|
white-space: nowrap;
|
|
50
|
-
`,document.body.appendChild(t),this.warmupContainer=t,t}async warmUpFontsBlocking(e){let t=[...new Set(e.filter(i=>typeof i=="string").map(i=>i.trim()).filter(i=>i.length>0).filter(i=>!this.isSystemFont(i)))];if(t.length===0)return;if(this.loadGoogleFonts(t),document.readyState==="loading"||!document.body){await this.ensureFontsReady(t);return}let n=this.getWarmupContainer(),r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,;:!?";t.forEach(i=>{let a=`cb-font-warmup-${i.replace(/[^a-z0-9]+/gi,"-").toLowerCase()}`;if(!n.querySelector(`[data-font-warmup-id="${a}"]`)){let o=document.createElement("span");o.dataset.fontWarmupId=a,o.style.fontFamily=`"${i}"`,o.textContent=r,n.appendChild(o);let l=document.createElement("span");l.dataset.fontWarmupId=`${a}-bold`,l.style.fontFamily=`"${i}"`,l.style.fontWeight="700",l.textContent=r,n.appendChild(l);let d=document.createElement("span");d.dataset.fontWarmupId=`${a}-italic`,d.style.fontFamily=`"${i}"`,d.style.fontStyle="italic",d.textContent=r,n.appendChild(d)}}),n.offsetHeight,await this.ensureFontsReady(t),await this.markFontsWarmed(t)}loadFont(e){this.loadedFonts.has(e)||this.isSystemFont(e)||this.loadGoogleFonts([e])}ensureFontLoaded(e){this.isSystemFont(e)||this.loadedFonts.has(e)||this.loadGoogleFonts([e])}extractFontsFromChartData(e){let t=new Set;if(!e||typeof e!="object")return t;let n=(r,i=new WeakSet)=>{if(!(r===null||typeof r!="object")&&!i.has(r)){if(i.add(r),Array.isArray(r)){r.forEach(a=>n(a,i));return}if("fontFamily"in r&&typeof r.fontFamily=="string"&&r.fontFamily.trim()){let a=r.fontFamily.trim();this.isSystemFont(a)||t.add(a)}if("labelFontFamily"in r&&typeof r.labelFontFamily=="string"&&r.labelFontFamily.trim()){let a=r.labelFontFamily.trim();this.isSystemFont(a)||t.add(a)}for(let a in r)if(Object.prototype.hasOwnProperty.call(r,a))try{n(r[a],i)}catch{}}};return n(e),t}loadFontsFromChartData(e,t){if(!e)return;let n=this.extractFontsFromChartData(e);if(n.size===0){t&&t();return}let r=this.getAvailableFonts(),i=new Set(r.map(o=>o.toLowerCase())),a=Array.from(n).filter(o=>{let l=o.toLowerCase();return!(this.loadedFonts.has(o)||i.has(l))});if(a.length===0){console.log("[FontService] All fonts from chart data are already available (in cache/backend)"),t&&this.ensureFontsReady(Array.from(n)).then(()=>t()).catch(()=>t());return}console.log("[FontService] Loading fonts from chart data (not in organization list):",a),this.loadGoogleFonts(a),t&&this.ensureFontsReady(Array.from(n)).then(()=>t()).catch(()=>t())}getUnknownFontsFromChartData(e){if(!e)return[];let t=this.extractFontsFromChartData(e);if(t.size===0)return[];let n=new Set(this.getAvailableFonts().map(r=>r.toLowerCase()));return Array.from(t).filter(r=>this.loadedFonts.has(r)?!1:!n.has(r.toLowerCase()))}prepareFontsForChartData(e){if(!e)return{hasUnknownFonts:!1,readyPromise:Promise.resolve()};let t=this.extractFontsFromChartData(e);if(t.size===0)return{hasUnknownFonts:!1,readyPromise:Promise.resolve()};let n=this.getUnknownFontsFromChartData(e),r=n.length>0;return r&&console.log("[FontService] Blocking initial chart render for unknown fonts:",n),this.loadFontsFromChartData(e),{hasUnknownFonts:r,readyPromise:r?this.warmUpFontsBlocking(Array.from(t)):this.ensureFontsReady(Array.from(t))}}reset(){this.customFonts=[],this.loadedFonts.clear(),this.fontDeclarationPromises.clear(),this.fontReadyPromises.clear(),this.warmedFonts.clear(),this.initialized=!1,this.defaultFont="Arial",this.warmupContainer&&this.warmupContainer.parentNode&&this.warmupContainer.parentNode.removeChild(this.warmupContainer),this.warmupContainer=null,this.defaultFonts=["Arial","Calibri","Helvetica","Verdana","Tahoma","Trebuchet MS","Times New Roman","Courier New"]}},Ct=pv.getInstance()});var bL={};Kg(bL,{colorService:()=>Sr,default:()=>UF});var gv,Sr,UF,Os=or(()=>{I();gv=class h{constructor(){this.defaultColors=["#98df8a","#17becf","#2c808c","#98df8a","#e377c2","#7f7f7f","#bcbd22","#17becf","#393b79","#637939","#8c6d31","#843c39","#7b4173","#a55194","#c7c7c7","#ffbb78","#98df8a","#ff9896","#ff7f0e","#2ca02c","#d62728","#9467bd","#8c564b","#e377c2","#7f7f7f","#bcbd22","#17becf","#393b79","#637939","#8c6d31","#843c39","#7b4173","#a55194","#c7c7c7","#ffbb78","#98df8a","#ff9896"];this.customColors=[];this.initialized=!1;this.resolveReady=()=>{};this.readyPromise=new Promise(e=>{this.resolveReady=e})}static getInstance(){return h.instance||(h.instance=new h),h.instance}initialize(e){console.log("[ColorService] Initializing with settings:",e),this.setOrganizationColors(e.colorScheme||[])}isInitialized(){return this.initialized}async ready(){return this.readyPromise}getAvailableColors(){let e=[];this.customColors&&this.customColors.length>0&&e.push(...this.customColors),e.push(...this.defaultColors),console.log("[ColorService] getAvailableColors result count:",e.length);let t=new Set;return e.filter(n=>{if(!n)return!1;let r=n.toUpperCase();return t.has(r)?!1:(t.add(r),!0)})}setOrganizationColors(e){this.customColors=Array.isArray(e)?[...e]:[],console.log("[ColorService] Organization colors updated:",this.customColors.length),this.initialized||(this.initialized=!0,this.resolveReady())}getDefaultColors(){return[...this.defaultColors]}getCustomColors(){return[...this.customColors]}hasColor(e){let t=this.getAvailableColors(),n=e.toUpperCase();return t.some(r=>r.toUpperCase()===n)}addCustomColor(e){let t=e.toUpperCase();this.customColors.some(n=>n.toUpperCase()===t)||this.customColors.push(e)}removeCustomColor(e){let t=e.toUpperCase();this.customColors=this.customColors.filter(n=>n.toUpperCase()!==t)}reset(){this.customColors=[],this.initialized=!1,this.defaultColors=["#242424","#484848","#6D6D6D","#919191","#B6B6B6","#DADADA","#FFFFFF","#8B0000","#FF4500","#FFD700","#ADFF2F","#1E90FF","#0000FF","#8B00FF","#FF00FF","#F1E6E6","#FFE6E6","#FFF0E6","#F2FFE6","#E6F3FF","#E6E6FF","#F3E6FF","#FFE6FF","#D9CCCC","#FFCCCC","#FFE1CC","#E6FFCC","#CCE6FF","#CCCCFF","#E6CCFF","#FFCCFF","#B38B8B","#FFB3B3","#FFD9B3","#CCFFB3","#B3CCFF","#B3B3FF","#CCB3FF","#FFB3FF","#806666","#E69999","#FFCC99","#99FF99","#99CCFF","#9999FF","#CC99FF","#FF99FF","#4D3333","#CC6666","#FFB366","#66CC66","#6699FF","#6666FF","#9966FF","#FF66FF"]}},Sr=gv.getInstance(),UF=Sr});function Aa(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(h){let e=Math.random()*16|0;return(h==="x"?e:e&3|8).toString(16)})}var Vh=or(()=>{I()});var co,Zg=or(()=>{I();Vh();co=class{constructor(e,t="chart_",n=null){this.platform=e,this.storagePrefix=t,this.recentColorsKey="recent_colors",this.organizationColorsKey="organization_colors",this.presentationColorsKey="presentation_colors",this.maxRecentColors=8,this.chartbuddyUrl=n}setChartbuddyUrl(e){this.chartbuddyUrl=e}isStorageAvailable(){return!!this.platform}getStorageKey(e){return`${this.storagePrefix}${e}`}static generateUUID(){return Aa()}async removeItems(e,t){e.length>0&&this.platform&&(await this.platform.storage.remove(e),console.log(`[Storage] Removed keys: ${e.join(", ")}`)),t&&t()}async remove(e=null,t){if(!this.platform){t&&t();return}let n=await this.platform.storage.get(null),r=[];for(let i in n)(!e||i.startsWith(e))&&r.push(i);r.length>0&&(await this.platform.storage.remove(r),console.log(`[Storage] Removed ${r.length} keys with prefix: ${e||"all"}`)),t&&t()}async removeAllData(e){if(!this.platform){e&&e(new Error("Platform not initialized"));return}try{let t=await this.platform.storage.get(null),n=Object.keys(t);if(n.length===0){e&&e(null,0);return}await this.platform.storage.remove(n),console.log(`[Storage] Successfully removed all ${n.length} items`),e&&e(null,n.length)}catch(t){e&&e(t)}}async clearAll(e){return this.removeAllData(e)}async getOrganizationColors(e){if(!this.platform){console.warn("[Storage] Cannot get organization colors: Platform not initialized"),e([]);return}let n=(await this.platform.storage.get([this.organizationColorsKey]))[this.organizationColorsKey]||[];console.log(`[Storage] Retrieved ${n.length} organization colors from storage`),e(n)}async getDefaultColors(){return this.platform?(await this.platform.storage.get([this.organizationColorsKey]))[this.organizationColorsKey]||[]:[]}async setOrganizationColors(e,t){if(!Array.isArray(e)||!this.platform){console.warn("[Storage] Cannot set organization colors: Invalid input or platform not initialized"),t&&t();return}console.log(`[Storage] Persisting ${e.length} organization colors to storage`),await this.platform.storage.set({[this.organizationColorsKey]:e}),t&&t()}async clearOrganizationColors(e){if(!this.platform){e&&e();return}await this.platform.storage.remove([this.organizationColorsKey]),e&&e()}async getPresentationColors(e,t){if(!e||!this.platform){t([]);return}let n=`${this.presentationColorsKey}_${e}`,r=await this.platform.storage.get([n]);t(r[n]||[])}async setPresentationColors(e,t,n){if(!e||!Array.isArray(t)||!this.platform){n&&n();return}let r=`${this.presentationColorsKey}_${e}`;await this.platform.storage.set({[r]:t}),n&&n()}async getRecentColors(e){if(!this.platform){e([]);return}let t=await this.platform.storage.get([this.recentColorsKey]);e(t[this.recentColorsKey]||[])}async addRecentColor(e,t){let n=this.normalizeColorToHex(e);if(!n||!this.platform){t&&t([]);return}this.getRecentColors(async r=>{r=r.filter(i=>i!==n),r.unshift(n),r=r.slice(0,this.maxRecentColors),this.platform&&await this.platform.storage.set({[this.recentColorsKey]:r}),t&&t(r)})}async clearRecentColors(e){this.platform&&await this.platform.storage.remove([this.recentColorsKey]),e&&e()}static googleRgbToHex(e){if(!e)return null;let t=Math.round((e.red||0)*255),n=Math.round((e.green||0)*255),r=Math.round((e.blue||0)*255);return`#${t.toString(16).padStart(2,"0")}${n.toString(16).padStart(2,"0")}${r.toString(16).padStart(2,"0")}`}normalizeColorToHex(e){if(!e||typeof e!="string")return null;let t=e.trim();if(t.startsWith("#")){let r=t.toUpperCase();return r.length===4&&(r="#"+r[1]+r[1]+r[2]+r[2]+r[3]+r[3]),/^#[0-9A-F]{6}$/.test(r)?r:null}if(/^[0-9A-Fa-f]{6}$/.test(t))return"#"+t.toUpperCase();let n=t.match(/^rgba?\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*[\d.]+)?\s*\)$/i);if(n){let r=Math.min(255,Math.max(0,parseInt(n[1],10))),i=Math.min(255,Math.max(0,parseInt(n[2],10))),a=Math.min(255,Math.max(0,parseInt(n[3],10)));return"#"+r.toString(16).padStart(2,"0").toUpperCase()+i.toString(16).padStart(2,"0").toUpperCase()+a.toString(16).padStart(2,"0").toUpperCase()}return null}async saveLastOpenedChartId(e){await this.platform.storage.set({lastOpenedChartId:e})}async getLastOpenedChartId(e){let t=await this.platform.storage.get(["lastOpenedChartId"]);e(t.lastOpenedChartId||null)}async getTemplates(){if(!this.chartbuddyUrl)return[];try{let t=(await this.platform.storage.get(["token"])).token;if(!t)return[];let n=await fetch(`${this.chartbuddyUrl}/api/chart-templates`,{method:"GET",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"}});if(n.ok){let r=await n.json();return Array.isArray(r)?r:r?.data&&Array.isArray(r.data)?r.data:[]}}catch(e){console.error("[Storage] Failed to fetch templates:",e)}return[]}}});var ai,ho,bc=or(()=>{I();ai="1.7.52",ho="chart-buddy"});var mv,bv,yv,zh,yL=or(()=>{I();Zg();bc();mv=class{async get(e){return new Promise(t=>{chrome.storage.local.get(e,n=>{t(n)})})}async set(e){return new Promise(t=>{chrome.storage.local.set(e,()=>{t()})})}async remove(e){return new Promise(t=>{chrome.storage.local.remove(e,()=>{t()})})}async clear(){return new Promise(e=>{chrome.storage.local.clear(()=>{e()})})}},bv=class{getURL(e){return chrome.runtime.getURL(e)}getVersion(){return ai}getAppName(){return ho}isDevelopmentBuild(){return!1}getManifest(){return chrome.runtime.getManifest()}async sendMessage(e){return new Promise((t,n)=>{chrome.runtime.sendMessage(e,r=>{chrome.runtime.lastError?n(chrome.runtime.lastError):t(r)})})}},yv=class{detect(){let e=window.location.href;return e.includes("canva.com")?"Canva":e.includes("docs.google.com/presentation")?"GSlides":e.includes("docs.google.com/spreadsheets")||e.includes("sheets.google.com")?"GSheets":e.includes("notion.com")||e.includes("notion.so")?"Notion":e.includes("figma.com")?"Figma":e.includes("miro.com")?"Miro":e.includes("powerbi.com")?"PowerBI":e.includes("onedrive.live.com")||e.includes("microsoft365.com")?"PowerPoint":"WebApp"}getPresentationId(){let t=window.location.href.match(/\/presentation\/d\/([a-zA-Z0-9-_]+)/);return t?t[1]:null}},zh=class{constructor(){this.type="extension";this.storage=new mv;this.runtime=new bv;this.host=new yv;this.chartBuddyStorage=new co(this)}};typeof window<"u"&&(window.ChromeExtensionProvider=zh)});var xv,vv,wv,Ps,Sv=or(()=>{I();Zg();bc();xv=class{constructor(){this.prefix="cb_"}async get(e){let t={},n=[];return typeof e=="string"?n=[e]:Array.isArray(e)?n=e:e&&typeof e=="object"&&(n=Object.keys(e),Object.assign(t,e)),n.forEach(r=>{let i=localStorage.getItem(this.prefix+r);if(i!==null)try{t[r]=JSON.parse(i)}catch{t[r]=i}}),t}async set(e){Object.entries(e).forEach(([t,n])=>{localStorage.setItem(this.prefix+t,JSON.stringify(n))})}async remove(e){(Array.isArray(e)?e:[e]).forEach(n=>localStorage.removeItem(this.prefix+n))}async clear(){Object.keys(localStorage).forEach(e=>{e.startsWith(this.prefix)&&localStorage.removeItem(e)})}},vv=class{getURL(e){return e}getVersion(){return ai}getAppName(){return ho}isDevelopmentBuild(){return!1}getManifest(){return{version:ai,name:ho,_sys_ctx:this.isDevelopmentBuild()?"d8n3x5q1":"kz6p9m2v"}}async sendMessage(e){return console.log("[WebApp] Mock sendMessage:",e),null}},wv=class{detect(){return"WebApp"}getPresentationId(){return"webapp-mock-presentation-id"}},Ps=class{constructor(){this.type="webapp";this.storage=new xv;this.runtime=new vv;this.host=new wv;this.chartBuddyStorage=new co(this)}};typeof window<"u"&&(window.WebAppProvider=Ps)});function yc(){if(typeof window>"u")return!1;let h=window;return typeof h.__TAURI__<"u"||typeof h.__TAURI_INTERNALS__<"u"?!0:typeof navigator<"u"&&/tauri/i.test(navigator.userAgent)}var Cv,kv,Av,Qg,Hh=or(()=>{I();Zg();bc();Cv=class{constructor(){this.prefix="cb_";this.map=new Map}storageKey(e){return`${this.prefix}${e}`}async get(e){let t={},n=[];return typeof e=="string"?n=[e]:Array.isArray(e)?n=e:e&&typeof e=="object"&&(n=Object.keys(e),Object.assign(t,e)),n.forEach(r=>{let i=this.map.get(this.storageKey(r));if(i!==void 0)try{t[r]=JSON.parse(i)}catch{t[r]=i}}),t}async set(e){Object.entries(e).forEach(([t,n])=>{this.map.set(this.storageKey(t),JSON.stringify(n))})}async remove(e){(Array.isArray(e)?e:[e]).forEach(n=>this.map.delete(this.storageKey(n)))}async clear(){let e=[];this.map.forEach((t,n)=>{n.startsWith(this.prefix)&&e.push(n)}),e.forEach(t=>this.map.delete(t))}},kv=class{getURL(e){return e}getVersion(){return ai}getAppName(){return ho}isDevelopmentBuild(){return!1}getManifest(){return{version:ai,name:ho,_sys_ctx:this.isDevelopmentBuild()?"d8n3x5q1":"kz6p9m2v"}}async sendMessage(e){return console.log("[Tauri] sendMessage (no-op):",e),null}},Av=class{detect(){return"Tauri"}getPresentationId(){return"tauri-desktop"}},Qg=class{constructor(){this.type="tauri";this.storage=new Cv;this.runtime=new kv;this.host=new Av;this.chartBuddyStorage=new co(this)}}});var _r,Mv,Wh=or(()=>{I();yL();Sv();Hh();_r=class{static setPlatform(e){this.instance=e}static getPlatform(){let e=yc();return e&&this.instance!==void 0&&this.instance.type!=="tauri"&&(this.instance=void 0),this.instance?this.instance:e?(this.instance=new Qg,this.instance):(typeof chrome<"u"&&chrome.runtime&&typeof chrome.runtime.getURL=="function"&&!!chrome.runtime.id?this.instance=new zh:this.instance=new Ps,this.instance)}},Mv=_r.getPlatform()});var qF,Dv,Ei,om,TL=or(()=>{I();qF=["Arial","Calibri","Helvetica","Verdana","Tahoma","Trebuchet MS","Times New Roman","Courier New"],Dv={isExpired:!1,isActive:!0,daysRemaining:null,expiresAt:null},Ei={uploadMethod:"google-drive",featureFlags:{},canManageFeatureFlags:!1,organizationSettings:{colorScheme:["#3B82F6","#10B981","#F59E0B","#9fa90f"],fonts:qF,customFonts:[],defaultFont:"Arial"},trialStatus:Dv},om={production:"https://chartbuddy.io",acceptance:"https://cb-acc.xyz",current:"production"}});function _v(h){if(h.fonts!==void 0){if(!Array.isArray(h.fonts))return console.warn("[FontCacheManager] Invalid fonts: expected array, got",typeof h.fonts),!1;if(!h.fonts.every(e=>typeof e=="string"&&e.trim().length>0))return console.warn("[FontCacheManager] Invalid fonts: contains non-string or empty values"),!1}if(h.customFonts!==void 0){if(!Array.isArray(h.customFonts))return console.warn("[FontCacheManager] Invalid customFonts: expected array, got",typeof h.customFonts),!1;if(!h.customFonts.every(e=>typeof e=="string"&&e.trim().length>0))return console.warn("[FontCacheManager] Invalid customFonts: contains non-string or empty values"),!1}return h.useDefaultFonts!==void 0&&typeof h.useDefaultFonts!="boolean"?(console.warn("[FontCacheManager] Invalid useDefaultFonts: expected boolean, got",typeof h.useDefaultFonts),!1):!0}var sm,Bs,Ov=or(()=>{I();Wh();sm=class h{static{this.STORAGE_KEY="chartbuddy_fonts_cache"}static{this.CACHE_VERSION="1.0"}constructor(){}static getInstance(){return h.instance||(h.instance=new h),h.instance}async getCachedFonts(){try{let t=(await _r.getPlatform().storage.get([h.STORAGE_KEY]))[h.STORAGE_KEY];if(!t)return null;if(typeof t!="object"||t===null)return console.warn("[FontCacheManager] Invalid cache data type, clearing"),await this.clearCache(),null;if(t.version!==h.CACHE_VERSION)return console.log("[FontCacheManager] Cache version mismatch, invalidating"),await this.clearCache(),null;let n={fonts:t.fonts,customFonts:t.customFonts,defaultFont:t.defaultFont,useDefaultFonts:t.useDefaultFonts};return _v(n)?(console.log("[FontCacheManager] Loaded fonts from cache:",{defaultFont:t.defaultFont,fonts:t.fonts?.length??0,customFonts:t.customFonts?.length??0,cachedAt:new Date(t.cachedAt).toISOString()}),n):(console.warn("[FontCacheManager] Cached data validation failed, clearing cache"),await this.clearCache(),null)}catch(e){return console.warn("[FontCacheManager] Failed to get cached fonts:",e),null}}async saveFontsToCache(e){if(!_v(e))throw new Error("[FontCacheManager] Invalid font settings, cannot save to cache");try{let t={fonts:e.fonts,customFonts:e.customFonts,defaultFont:e.defaultFont,useDefaultFonts:e.useDefaultFonts,cachedAt:Date.now(),version:h.CACHE_VERSION},r=JSON.stringify(t).length,i=100*1024;r>i&&(console.warn(`[FontCacheManager] Cache size (${r} bytes) exceeds limit (${i} bytes), clearing old cache`),await this.clearCache()),await _r.getPlatform().storage.set({[h.STORAGE_KEY]:t})}catch(t){throw console.error("[FontCacheManager] Failed to save fonts to cache:",t),t}}async validateAndSyncFonts(e){if(!_v(e))return console.warn("[FontCacheManager] Invalid backend font settings, using cached data"),{hasChanges:!1,fonts:await this.getCachedFonts()??{fonts:[],customFonts:[],defaultFont:"Arial",useDefaultFonts:!0}};let t=null;try{console.log("[FontCacheManager] Validating fonts against cache..."),t=await this.getCachedFonts();let n=this.fontsHaveChanged(t,e);return n&&await this.saveFontsToCache(e),{hasChanges:n,fonts:e}}catch(n){return console.error("[FontCacheManager] Error validating fonts:",n),{hasChanges:!1,fonts:t??{fonts:[],customFonts:[],defaultFont:"Arial",useDefaultFonts:!0}}}}fontsHaveChanged(e,t){if(!e)return!0;let n=(r,i)=>!r&&!i?!0:!r||!i||r.length!==i.length?!1:r.every((a,o)=>a===i[o]);return!n(e.fonts,t.fonts)||!n(e.customFonts,t.customFonts)||e.defaultFont!==t.defaultFont||e.useDefaultFonts!==t.useDefaultFonts}async clearCache(){try{await _r.getPlatform().storage.remove([h.STORAGE_KEY]),console.log("[FontCacheManager] Cache cleared")}catch(e){console.warn("[FontCacheManager] Failed to clear cache:",e)}}},Bs=sm.getInstance()});var DL={};Kg(DL,{CHARTBUDDY_CONFIG_UPDATED_EVENT:()=>EL,ConfigManager:()=>pt,getConfigManager:()=>Or});function Or(){return pt.getInstance()}var EL,pt,Kn=or(()=>{I();TL();Wh();Mi();Ov();Os();EL="chartbuddy:config-updated",pt=class h{constructor(){this.debugEnabled=!1;this.debugAxisBinding=!0;this.loadingPromise=void 0;this.fontPreloadPromise=void 0;this.onLoadCallbacks=[];if(this.config={chartbuddyUrl:this.detectEnvironmentUrl(),bootOptions:{...Ei},environment:{...om},loaded:!1,loadedAt:void 0},this.config.environment.current=this.detectEnvironment(),this.debugEnabled=this.computeDebugEnabled(this.config.chartbuddyUrl),typeof window<"u"&&window.localStorage)try{window.localStorage.getItem("CHARTBUDDY_DEBUG_MODE")==="true"&&(this.debugEnabled=!0),window.localStorage.getItem("CHARTBUDDY_DEBUG_AXIS_BINDING")==="false"&&(this.debugAxisBinding=!1)}catch{}}static{this.instance=void 0}computeDebugEnabled(e){let t=e.includes("cb-acc.xyz")||e.includes("stag"),n=e.includes("localhost")||e.includes("127.0.0.1"),r=_r.getPlatform().runtime.isDevelopmentBuild();return t||n||r}static getInstance(){return h.instance===void 0&&(h.instance=new h),h.instance}isDebugEnabled(){return this.debugEnabled}isDebugAxisBindingEnabled(){return this.debugAxisBinding}isWaterfallSegmentedBarsEnabled(){return!0}isChartOrientationEnabled(){return!0}isBarMekkoEnabled(){return this.config?.bootOptions?.featureFlags?.barMekko===!0}isDevelopment(){let e=this.config.chartbuddyUrl;return e.includes("localhost")||e.includes("127.0.0.1")}isAcceptance(){return this.config.chartbuddyUrl.includes("cb-acc.xyz")}isProduction(){return!this.isDevelopment()&&!this.isAcceptance()}setDebugMode(e){this.debugEnabled=e}setDebugAxisBindingMode(e){this.debugAxisBinding=e}detectEnvironmentUrl(){return om.production}detectEnvironment(){return this.config.chartbuddyUrl.includes("cb-acc.xyz")?"acceptance":"production"}getConfig(){return{...this.config}}getChartbuddyUrl(){return this.config.chartbuddyUrl}getBootOptions(){return{...this.config.bootOptions}}getEnvironment(){return{...this.config.environment}}getTrialStatus(){return{...this.config.bootOptions.trialStatus}}isTrialExpired(){return this.config.bootOptions.trialStatus.isExpired}isLoaded(){return this.config.loaded}onLoad(e){this.config.loaded?e():this.onLoadCallbacks.push(e)}setChartbuddyUrl(e){this.config.chartbuddyUrl=e,this.config.environment.current=this.detectEnvironment(),this.debugEnabled=this.computeDebugEnabled(e)}async loadConfig(){if(this.loadingPromise)return this.loadingPromise;if(this.config.loaded&&this.config.loadedAt&&Date.now()-this.config.loadedAt<3e5){console.log("[ConfigManager] Config already loaded recently, skipping reload");return}this.loadingPromise=this.loadConfigInternal();try{await this.loadingPromise}finally{this.loadingPromise=void 0}}async preloadFontSettings(){if(this.fontPreloadPromise)return this.fontPreloadPromise;this.fontPreloadPromise=this.preloadFontSettingsInternal();try{await this.fontPreloadPromise}finally{this.fontPreloadPromise=void 0}}async loadConfigInternal(){try{if(_r.getPlatform().type==="webapp"){console.log("[ConfigManager] Standalone mode (WebApp): using local defaults"),this.config.bootOptions={...Ei},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks();return}console.log("[ConfigManager] Loading configuration from backend...");let t=await this.getAuthToken();if(!t){console.warn("[ConfigManager] No authentication token available, using defaults"),Bs.clearCache().catch(r=>{console.warn("[ConfigManager] Failed to clear font cache on auth failure:",r)}),this.config.bootOptions={...Ei},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks();return}let n=await this.fetchAuthenticatedJson("/api/user/boot-settings",t);if(n.ok){let r=await n.json(),i=r.uploadMethod??Ei.uploadMethod,a=r.featureFlags??Ei.featureFlags,o=r.canManageFeatureFlags??Ei.canManageFeatureFlags,l=r.organizationSettings??Ei.organizationSettings,d=r.trialStatus??Dv;this.config.bootOptions={uploadMethod:i,featureFlags:a,canManageFeatureFlags:o,organizationSettings:l,trialStatus:d},console.log("[ConfigManager] Organization Settings received:",{colorSchemeCount:l.colorScheme?.length||0,fontCount:l.fonts?.length||0}),this.config.loaded=!0,this.config.loadedAt=Date.now(),console.log("[ConfigManager] \u2705 Configuration loaded successfully:",{uploadMethod:this.config.bootOptions.uploadMethod,loadedAt:new Date(this.config.loadedAt).toISOString()}),await this.initializeFontService(),this.initializeColorService();let u={fonts:l.fonts??[],customFonts:l.customFonts??[],defaultFont:l.defaultFont??"Noto Sans"};this.validateFontCache(u).catch(g=>{console.warn("[ConfigManager] Background font validation failed:",g)}),this.triggerOnLoadCallbacks()}else console.warn(`[ConfigManager] Failed to fetch boot settings (HTTP ${n.status}), using defaults`),(n.status===401||n.status===403)&&Bs.clearCache().catch(r=>{console.warn("[ConfigManager] Failed to clear font cache on auth failure:",r)}),this.config.bootOptions={...Ei},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks()}catch(e){console.error("[ConfigManager] Error loading configuration:",e),console.log("[ConfigManager] Using default configuration"),this.config.bootOptions={...Ei},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks()}}async preloadFontSettingsInternal(){try{let e=await this.getAuthToken();if(!e)return;let t=await this.fetchAuthenticatedJson("/api/user/font-settings",e);if(!t.ok){(t.status===401||t.status===403)&&Bs.clearCache().catch(r=>{console.warn("[ConfigManager] Failed to clear font cache on preload auth failure:",r)});return}let n=await t.json();Ct.isInitialized()?Ct.reinitialize(n):Ct.primeEarly(n)}catch(e){console.warn("[ConfigManager] Font preload failed:",e)}}triggerOnLoadCallbacks(){console.log(`[ConfigManager] Triggering ${this.onLoadCallbacks.length} onLoad callbacks`),this.onLoadCallbacks.forEach(e=>{try{e()}catch(t){console.error("[ConfigManager] Error in onLoad callback:",t)}}),this.onLoadCallbacks=[],typeof window<"u"&&window.dispatchEvent(new CustomEvent(EL,{detail:{bootOptions:this.getBootOptions(),loadedAt:this.config.loadedAt}}))}async initializeFontService(){if(Ct.isInitialized()){console.log("[ConfigManager] FontService already initialized, skipping");return}try{let e=await Bs.getCachedFonts();if(e){Ct.initialize(e);return}let t=this.config.bootOptions.organizationSettings,n={fonts:t.fonts??[],customFonts:t.customFonts??[],defaultFont:t.defaultFont??"Noto Sans"};Ct.initialize(n)}catch(e){console.warn("[ConfigManager] Failed to initialize FontService:",e)}}initializeColorService(){try{let t=this.config.bootOptions.organizationSettings.colorScheme||[];Sr.initialize({colorScheme:t});let n=_r.getPlatform();n&&n.chartBuddyStorage&&n.chartBuddyStorage.setOrganizationColors(t).then(()=>console.log("[ConfigManager] Organization colors persisted to storage")).catch(r=>console.warn("[ConfigManager] Failed to persist organization colors:",r)),console.log("[ConfigManager] ColorService initialized")}catch(e){console.warn("[ConfigManager] Failed to initialize ColorService:",e)}}async validateFontCache(e){try{let t=await Bs.validateAndSyncFonts(e);t.hasChanges?(console.log("[ConfigManager] Font settings changed, updating"),Ct.reinitialize(t.fonts)):console.log("[ConfigManager] Font settings unchanged, keeping current initialization")}catch(t){console.warn("[ConfigManager] Font validation failed:",t)}}async getAuthToken(){return(await this.getChromeStorage(["token"])).token}fetchAuthenticatedJson(e,t){return fetch(`${this.config.chartbuddyUrl}${e}`,{method:"GET",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"}})}async getChromeStorage(e){try{let t=await _r.getPlatform().storage.get(e),n={};for(let r of e)n[r]=t[r];return n}catch(t){return console.warn("[ConfigManager] Failed to get chrome storage:",t),{}}}async reloadConfig(){this.config.loaded=!1,this.config.loadedAt=void 0,await this.loadConfig()}reset(){this.config={chartbuddyUrl:this.detectEnvironmentUrl(),bootOptions:{...Ei},environment:{...om},loaded:!1,loadedAt:void 0},this.config.environment.current=this.detectEnvironment(),this.loadingPromise=void 0,this.fontPreloadPromise=void 0}}});var Xv=VF((Yv,jv)=>{I();(h=>{let e=(()=>{let _=0;return{escape:function(Y){return Y.replace(/([.*+?^${}()|[\]/\\])/g,"\\$1")},isDataUrl:function(Y){return Y.search(/^(data:)/)!==-1},canvasToBlob:function(Y){return Y.toBlob?new Promise(function(J){Y.toBlob(J)}):(J=>new Promise(function(te){var ae=g(J.toDataURL().split(",")[1]),re=ae.length,le=new Uint8Array(re);for(let ye=0;ye<re;ye++)le[ye]=ae.charCodeAt(ye);te(new Blob([le],{type:"image/png"}))}))(Y)},resolveUrl:function(Y,J){var te=document.implementation.createHTMLDocument(),ae=te.createElement("base"),re=(te.head.appendChild(ae),te.createElement("a"));return te.body.appendChild(re),ae.href=J,re.href=Y,re.href},getAndEncode:function(Y){let J=l.impl.urlCache.find(function(te){return te.url===Y});return J||(J={url:Y,promise:null},l.impl.urlCache.push(J)),J.promise===null&&(l.impl.options.cacheBust&&(Y+=(/\?/.test(Y)?"&":"?")+new Date().getTime()),J.promise=new Promise(function(te){let ae=new XMLHttpRequest;function re(Q){console.error(Q),te("")}function le(){var Q=l.impl.options.imagePlaceholder;Q?te(Q):re("Status:"+ae.status+" while fetching resource: "+Y)}if(ae.timeout=l.impl.options.httpTimeout,ae.onerror=le,ae.ontimeout=le,ae.onloadend=function(){if(ae.readyState===XMLHttpRequest.DONE){var Q=ae.status;if(Q===0&&Y.toLowerCase().startsWith("file://")||200<=Q&&Q<=300&&ae.response!==null){Q=ae.response,Q instanceof Blob||re("Expected response to be a Blob, but got: "+typeof Q);let de=new FileReader;de.onloadend=function(){var me=de.result;te(me)};try{de.readAsDataURL(Q)}catch(me){re("Failed to read the response as Data URL: "+me.toString())}}else le()}},0<l.impl.options.useCredentialsFilters.length&&(l.impl.options.useCredentials=0<l.impl.options.useCredentialsFilters.filter(Q=>0<=Y.search(Q)).length),l.impl.options.useCredentials&&(ae.withCredentials=!0),l.impl.options.corsImg&&Y.indexOf("http")===0&&Y.indexOf(window.location.origin)===-1){var ye=(l.impl.options.corsImg.method||"GET").toUpperCase()==="POST"?"POST":"GET";ae.open(ye,(l.impl.options.corsImg.url||"").replace("#{cors}",Y),!0);let Q=!1,de=l.impl.options.corsImg.headers||{},me=(Object.keys(de).forEach(function(Se){de[Se].indexOf("application/json")!==-1&&(Q=!0),ae.setRequestHeader(Se,de[Se])}),(Se=>{try{return JSON.parse(JSON.stringify(Se))}catch(Ce){re("corsImg.data is missing or invalid:"+Ce.toString())}})(l.impl.options.corsImg.data||""));Object.keys(me).forEach(function(Se){typeof me[Se]=="string"&&(me[Se]=me[Se].replace("#{cors}",Y))}),ae.responseType="blob",ae.send(Q?JSON.stringify(me):me)}else ae.open("GET",Y,!0),ae.responseType="blob",ae.send()})),J.promise},uid:function(){return"u"+("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)+_++},asArray:function(Y){var J=[],te=Y.length;for(let ae=0;ae<te;ae++)J.push(Y[ae]);return J},escapeXhtml:function(Y){return Y.replace(/%/g,"%25").replace(/#/g,"%23").replace(/\n/g,"%0A")},makeImage:function(Y){return Y!=="data:,"?new Promise(function(J,te){let ae=document.createElementNS("http://www.w3.org/2000/svg","svg"),re=new Image;l.impl.options.useCredentials&&(re.crossOrigin="use-credentials"),re.onload=function(){document.body.removeChild(ae),window&&window.requestAnimationFrame?window.requestAnimationFrame(function(){J(re)}):J(re)},re.onerror=le=>{document.body.removeChild(ae),te(le)},ae.appendChild(re),re.src=Y,document.body.appendChild(ae)}):Promise.resolve()},width:function(Y){var J=U(Y,"width");if(!isNaN(J))return J;var J=U(Y,"border-left-width"),te=U(Y,"border-right-width");return Y.scrollWidth+J+te},height:function(Y){var J=U(Y,"height");if(!isNaN(J))return J;var J=U(Y,"border-top-width"),te=U(Y,"border-bottom-width");return Y.scrollHeight+J+te},getWindow:P,isElement:q,isElementHostForOpenShadowRoot:function(Y){return q(Y)&&Y.shadowRoot!==null},isShadowRoot:$,isInShadowRoot:V,isHTMLElement:function(Y){return Y instanceof P(Y).HTMLElement},isHTMLCanvasElement:function(Y){return Y instanceof P(Y).HTMLCanvasElement},isHTMLInputElement:function(Y){return Y instanceof P(Y).HTMLInputElement},isHTMLImageElement:function(Y){return Y instanceof P(Y).HTMLImageElement},isHTMLLinkElement:function(Y){return Y instanceof P(Y).HTMLLinkElement},isHTMLScriptElement:function(Y){return Y instanceof P(Y).HTMLScriptElement},isHTMLStyleElement:function(Y){return Y instanceof P(Y).HTMLStyleElement},isHTMLTextAreaElement:function(Y){return Y instanceof P(Y).HTMLTextAreaElement},isShadowSlotElement:function(Y){return V(Y)&&Y instanceof P(Y).HTMLSlotElement},isSVGElement:function(Y){return Y instanceof P(Y).SVGElement},isSVGRectElement:function(Y){return Y instanceof P(Y).SVGRectElement},isDimensionMissing:function(Y){return isNaN(Y)||Y<=0}};function P(Y){return Y=Y?Y.ownerDocument:void 0,(Y?Y.defaultView:void 0)||window||h}function $(Y){return Y instanceof P(Y).ShadowRoot}function V(Y){return Y!=null&&Y.getRootNode!==void 0&&$(Y.getRootNode())}function q(Y){return Y instanceof P(Y).Element}function U(Y,J){if(Y.nodeType===d){let te=u(Y).getPropertyValue(J);if(te.slice(-2)==="px")return te=te.slice(0,-2),parseFloat(te)}return NaN}})(),t=(()=>{let _=/url\(\s*(["']?)((?:\\.|[^\\)])+)\1\s*\)/gm;return{inlineAll:function(U,Y,J){return P(U)?Promise.resolve(U).then($).then(function(te){let ae=Promise.resolve(U);return te.forEach(function(re){ae=ae.then(function(le){return q(le,re,Y,J)})}),ae}):Promise.resolve(U)},shouldProcess:P,impl:{readUrls:$,inline:q,urlAsRegex:V}};function P(U){return U.search(_)!==-1}function $(U){for(var Y,J=[];(Y=_.exec(U))!==null;)J.push(Y[2]);return J.filter(function(te){return!e.isDataUrl(te)})}function V(U){return new RegExp(`url\\((["']?)(${e.escape(U)})\\1\\)`,"gm")}function q(U,Y,J,te){return Promise.resolve(Y).then(function(ae){return J?e.resolveUrl(ae,J):ae}).then(te||e.getAndEncode).then(function(ae){var re=V(Y);return U.replace(re,`url($1${ae}$1)`)})}})(),n={resolveAll:function(){return r().then(function(_){return Promise.all(_.map(function(P){return P.resolve()}))}).then(function(_){return _.join(`
|
|
50
|
+
`,document.body.appendChild(t),this.warmupContainer=t,t}async warmUpFontsBlocking(e){let t=[...new Set(e.filter(i=>typeof i=="string").map(i=>i.trim()).filter(i=>i.length>0).filter(i=>!this.isSystemFont(i)))];if(t.length===0)return;if(this.loadGoogleFonts(t),document.readyState==="loading"||!document.body){await this.ensureFontsReady(t);return}let n=this.getWarmupContainer(),r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,;:!?";t.forEach(i=>{let a=`cb-font-warmup-${i.replace(/[^a-z0-9]+/gi,"-").toLowerCase()}`;if(!n.querySelector(`[data-font-warmup-id="${a}"]`)){let o=document.createElement("span");o.dataset.fontWarmupId=a,o.style.fontFamily=`"${i}"`,o.textContent=r,n.appendChild(o);let l=document.createElement("span");l.dataset.fontWarmupId=`${a}-bold`,l.style.fontFamily=`"${i}"`,l.style.fontWeight="700",l.textContent=r,n.appendChild(l);let d=document.createElement("span");d.dataset.fontWarmupId=`${a}-italic`,d.style.fontFamily=`"${i}"`,d.style.fontStyle="italic",d.textContent=r,n.appendChild(d)}}),n.offsetHeight,await this.ensureFontsReady(t),await this.markFontsWarmed(t)}loadFont(e){this.loadedFonts.has(e)||this.isSystemFont(e)||this.loadGoogleFonts([e])}ensureFontLoaded(e){this.isSystemFont(e)||this.loadedFonts.has(e)||this.loadGoogleFonts([e])}extractFontsFromChartData(e){let t=new Set;if(!e||typeof e!="object")return t;let n=(r,i=new WeakSet)=>{if(!(r===null||typeof r!="object")&&!i.has(r)){if(i.add(r),Array.isArray(r)){r.forEach(a=>n(a,i));return}if("fontFamily"in r&&typeof r.fontFamily=="string"&&r.fontFamily.trim()){let a=r.fontFamily.trim();this.isSystemFont(a)||t.add(a)}if("labelFontFamily"in r&&typeof r.labelFontFamily=="string"&&r.labelFontFamily.trim()){let a=r.labelFontFamily.trim();this.isSystemFont(a)||t.add(a)}for(let a in r)if(Object.prototype.hasOwnProperty.call(r,a))try{n(r[a],i)}catch{}}};return n(e),t}loadFontsFromChartData(e,t){if(!e)return;let n=this.extractFontsFromChartData(e);if(n.size===0){t&&t();return}let r=this.getAvailableFonts(),i=new Set(r.map(o=>o.toLowerCase())),a=Array.from(n).filter(o=>{let l=o.toLowerCase();return!(this.loadedFonts.has(o)||i.has(l))});if(a.length===0){console.log("[FontService] All fonts from chart data are already available (in cache/backend)"),t&&this.ensureFontsReady(Array.from(n)).then(()=>t()).catch(()=>t());return}console.log("[FontService] Loading fonts from chart data (not in organization list):",a),this.loadGoogleFonts(a),t&&this.ensureFontsReady(Array.from(n)).then(()=>t()).catch(()=>t())}getUnknownFontsFromChartData(e){if(!e)return[];let t=this.extractFontsFromChartData(e);if(t.size===0)return[];let n=new Set(this.getAvailableFonts().map(r=>r.toLowerCase()));return Array.from(t).filter(r=>this.loadedFonts.has(r)?!1:!n.has(r.toLowerCase()))}prepareFontsForChartData(e){if(!e)return{hasUnknownFonts:!1,readyPromise:Promise.resolve()};let t=this.extractFontsFromChartData(e);if(t.size===0)return{hasUnknownFonts:!1,readyPromise:Promise.resolve()};let n=this.getUnknownFontsFromChartData(e),r=n.length>0;return r&&console.log("[FontService] Blocking initial chart render for unknown fonts:",n),this.loadFontsFromChartData(e),{hasUnknownFonts:r,readyPromise:r?this.warmUpFontsBlocking(Array.from(t)):this.ensureFontsReady(Array.from(t))}}reset(){this.customFonts=[],this.loadedFonts.clear(),this.fontDeclarationPromises.clear(),this.fontReadyPromises.clear(),this.warmedFonts.clear(),this.initialized=!1,this.defaultFont="Arial",this.warmupContainer&&this.warmupContainer.parentNode&&this.warmupContainer.parentNode.removeChild(this.warmupContainer),this.warmupContainer=null,this.defaultFonts=["Arial","Calibri","Helvetica","Verdana","Tahoma","Trebuchet MS","Times New Roman","Courier New"]}},Ct=pv.getInstance()});var bL={};Kg(bL,{colorService:()=>Sr,default:()=>UF});var gv,Sr,UF,Os=or(()=>{I();gv=class h{constructor(){this.defaultColors=["#98df8a","#17becf","#2c808c","#98df8a","#e377c2","#7f7f7f","#bcbd22","#17becf","#393b79","#637939","#8c6d31","#843c39","#7b4173","#a55194","#c7c7c7","#ffbb78","#98df8a","#ff9896","#ff7f0e","#2ca02c","#d62728","#9467bd","#8c564b","#e377c2","#7f7f7f","#bcbd22","#17becf","#393b79","#637939","#8c6d31","#843c39","#7b4173","#a55194","#c7c7c7","#ffbb78","#98df8a","#ff9896"];this.customColors=[];this.initialized=!1;this.resolveReady=()=>{};this.readyPromise=new Promise(e=>{this.resolveReady=e})}static getInstance(){return h.instance||(h.instance=new h),h.instance}initialize(e){console.log("[ColorService] Initializing with settings:",e),this.setOrganizationColors(e.colorScheme||[])}isInitialized(){return this.initialized}async ready(){return this.readyPromise}getAvailableColors(){let e=[];this.customColors&&this.customColors.length>0&&e.push(...this.customColors),e.push(...this.defaultColors),console.log("[ColorService] getAvailableColors result count:",e.length);let t=new Set;return e.filter(n=>{if(!n)return!1;let r=n.toUpperCase();return t.has(r)?!1:(t.add(r),!0)})}setOrganizationColors(e){this.customColors=Array.isArray(e)?[...e]:[],console.log("[ColorService] Organization colors updated:",this.customColors.length),this.initialized||(this.initialized=!0,this.resolveReady())}getDefaultColors(){return[...this.defaultColors]}getCustomColors(){return[...this.customColors]}hasColor(e){let t=this.getAvailableColors(),n=e.toUpperCase();return t.some(r=>r.toUpperCase()===n)}addCustomColor(e){let t=e.toUpperCase();this.customColors.some(n=>n.toUpperCase()===t)||this.customColors.push(e)}removeCustomColor(e){let t=e.toUpperCase();this.customColors=this.customColors.filter(n=>n.toUpperCase()!==t)}reset(){this.customColors=[],this.initialized=!1,this.defaultColors=["#242424","#484848","#6D6D6D","#919191","#B6B6B6","#DADADA","#FFFFFF","#8B0000","#FF4500","#FFD700","#ADFF2F","#1E90FF","#0000FF","#8B00FF","#FF00FF","#F1E6E6","#FFE6E6","#FFF0E6","#F2FFE6","#E6F3FF","#E6E6FF","#F3E6FF","#FFE6FF","#D9CCCC","#FFCCCC","#FFE1CC","#E6FFCC","#CCE6FF","#CCCCFF","#E6CCFF","#FFCCFF","#B38B8B","#FFB3B3","#FFD9B3","#CCFFB3","#B3CCFF","#B3B3FF","#CCB3FF","#FFB3FF","#806666","#E69999","#FFCC99","#99FF99","#99CCFF","#9999FF","#CC99FF","#FF99FF","#4D3333","#CC6666","#FFB366","#66CC66","#6699FF","#6666FF","#9966FF","#FF66FF"]}},Sr=gv.getInstance(),UF=Sr});function Aa(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(h){let e=Math.random()*16|0;return(h==="x"?e:e&3|8).toString(16)})}var Vh=or(()=>{I()});var co,Zg=or(()=>{I();Vh();co=class{constructor(e,t="chart_",n=null){this.platform=e,this.storagePrefix=t,this.recentColorsKey="recent_colors",this.organizationColorsKey="organization_colors",this.presentationColorsKey="presentation_colors",this.maxRecentColors=8,this.chartbuddyUrl=n}setChartbuddyUrl(e){this.chartbuddyUrl=e}isStorageAvailable(){return!!this.platform}getStorageKey(e){return`${this.storagePrefix}${e}`}static generateUUID(){return Aa()}async removeItems(e,t){e.length>0&&this.platform&&(await this.platform.storage.remove(e),console.log(`[Storage] Removed keys: ${e.join(", ")}`)),t&&t()}async remove(e=null,t){if(!this.platform){t&&t();return}let n=await this.platform.storage.get(null),r=[];for(let i in n)(!e||i.startsWith(e))&&r.push(i);r.length>0&&(await this.platform.storage.remove(r),console.log(`[Storage] Removed ${r.length} keys with prefix: ${e||"all"}`)),t&&t()}async removeAllData(e){if(!this.platform){e&&e(new Error("Platform not initialized"));return}try{let t=await this.platform.storage.get(null),n=Object.keys(t);if(n.length===0){e&&e(null,0);return}await this.platform.storage.remove(n),console.log(`[Storage] Successfully removed all ${n.length} items`),e&&e(null,n.length)}catch(t){e&&e(t)}}async clearAll(e){return this.removeAllData(e)}async getOrganizationColors(e){if(!this.platform){console.warn("[Storage] Cannot get organization colors: Platform not initialized"),e([]);return}let n=(await this.platform.storage.get([this.organizationColorsKey]))[this.organizationColorsKey]||[];console.log(`[Storage] Retrieved ${n.length} organization colors from storage`),e(n)}async getDefaultColors(){return this.platform?(await this.platform.storage.get([this.organizationColorsKey]))[this.organizationColorsKey]||[]:[]}async setOrganizationColors(e,t){if(!Array.isArray(e)||!this.platform){console.warn("[Storage] Cannot set organization colors: Invalid input or platform not initialized"),t&&t();return}console.log(`[Storage] Persisting ${e.length} organization colors to storage`),await this.platform.storage.set({[this.organizationColorsKey]:e}),t&&t()}async clearOrganizationColors(e){if(!this.platform){e&&e();return}await this.platform.storage.remove([this.organizationColorsKey]),e&&e()}async getPresentationColors(e,t){if(!e||!this.platform){t([]);return}let n=`${this.presentationColorsKey}_${e}`,r=await this.platform.storage.get([n]);t(r[n]||[])}async setPresentationColors(e,t,n){if(!e||!Array.isArray(t)||!this.platform){n&&n();return}let r=`${this.presentationColorsKey}_${e}`;await this.platform.storage.set({[r]:t}),n&&n()}async getRecentColors(e){if(!this.platform){e([]);return}let t=await this.platform.storage.get([this.recentColorsKey]);e(t[this.recentColorsKey]||[])}async addRecentColor(e,t){let n=this.normalizeColorToHex(e);if(!n||!this.platform){t&&t([]);return}this.getRecentColors(async r=>{r=r.filter(i=>i!==n),r.unshift(n),r=r.slice(0,this.maxRecentColors),this.platform&&await this.platform.storage.set({[this.recentColorsKey]:r}),t&&t(r)})}async clearRecentColors(e){this.platform&&await this.platform.storage.remove([this.recentColorsKey]),e&&e()}static googleRgbToHex(e){if(!e)return null;let t=Math.round((e.red||0)*255),n=Math.round((e.green||0)*255),r=Math.round((e.blue||0)*255);return`#${t.toString(16).padStart(2,"0")}${n.toString(16).padStart(2,"0")}${r.toString(16).padStart(2,"0")}`}normalizeColorToHex(e){if(!e||typeof e!="string")return null;let t=e.trim();if(t.startsWith("#")){let r=t.toUpperCase();return r.length===4&&(r="#"+r[1]+r[1]+r[2]+r[2]+r[3]+r[3]),/^#[0-9A-F]{6}$/.test(r)?r:null}if(/^[0-9A-Fa-f]{6}$/.test(t))return"#"+t.toUpperCase();let n=t.match(/^rgba?\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*[\d.]+)?\s*\)$/i);if(n){let r=Math.min(255,Math.max(0,parseInt(n[1],10))),i=Math.min(255,Math.max(0,parseInt(n[2],10))),a=Math.min(255,Math.max(0,parseInt(n[3],10)));return"#"+r.toString(16).padStart(2,"0").toUpperCase()+i.toString(16).padStart(2,"0").toUpperCase()+a.toString(16).padStart(2,"0").toUpperCase()}return null}async saveLastOpenedChartId(e){await this.platform.storage.set({lastOpenedChartId:e})}async getLastOpenedChartId(e){let t=await this.platform.storage.get(["lastOpenedChartId"]);e(t.lastOpenedChartId||null)}async getTemplates(){if(!this.chartbuddyUrl)return[];try{let t=(await this.platform.storage.get(["token"])).token;if(!t)return[];let n=await fetch(`${this.chartbuddyUrl}/api/chart-templates`,{method:"GET",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"}});if(n.ok){let r=await n.json();return Array.isArray(r)?r:r?.data&&Array.isArray(r.data)?r.data:[]}}catch(e){console.error("[Storage] Failed to fetch templates:",e)}return[]}}});var ai,ho,bc=or(()=>{I();ai="1.7.53",ho="chart-buddy"});var mv,bv,yv,zh,yL=or(()=>{I();Zg();bc();mv=class{async get(e){return new Promise(t=>{chrome.storage.local.get(e,n=>{t(n)})})}async set(e){return new Promise(t=>{chrome.storage.local.set(e,()=>{t()})})}async remove(e){return new Promise(t=>{chrome.storage.local.remove(e,()=>{t()})})}async clear(){return new Promise(e=>{chrome.storage.local.clear(()=>{e()})})}},bv=class{getURL(e){return chrome.runtime.getURL(e)}getVersion(){return ai}getAppName(){return ho}isDevelopmentBuild(){return!1}getManifest(){return chrome.runtime.getManifest()}async sendMessage(e){return new Promise((t,n)=>{chrome.runtime.sendMessage(e,r=>{chrome.runtime.lastError?n(chrome.runtime.lastError):t(r)})})}},yv=class{detect(){let e=window.location.href;return e.includes("canva.com")?"Canva":e.includes("docs.google.com/presentation")?"GSlides":e.includes("docs.google.com/spreadsheets")||e.includes("sheets.google.com")?"GSheets":e.includes("notion.com")||e.includes("notion.so")?"Notion":e.includes("figma.com")?"Figma":e.includes("miro.com")?"Miro":e.includes("powerbi.com")?"PowerBI":e.includes("onedrive.live.com")||e.includes("microsoft365.com")?"PowerPoint":"WebApp"}getPresentationId(){let t=window.location.href.match(/\/presentation\/d\/([a-zA-Z0-9-_]+)/);return t?t[1]:null}},zh=class{constructor(){this.type="extension";this.storage=new mv;this.runtime=new bv;this.host=new yv;this.chartBuddyStorage=new co(this)}};typeof window<"u"&&(window.ChromeExtensionProvider=zh)});var xv,vv,wv,Ps,Sv=or(()=>{I();Zg();bc();xv=class{constructor(){this.prefix="cb_"}async get(e){let t={},n=[];return typeof e=="string"?n=[e]:Array.isArray(e)?n=e:e&&typeof e=="object"&&(n=Object.keys(e),Object.assign(t,e)),n.forEach(r=>{let i=localStorage.getItem(this.prefix+r);if(i!==null)try{t[r]=JSON.parse(i)}catch{t[r]=i}}),t}async set(e){Object.entries(e).forEach(([t,n])=>{localStorage.setItem(this.prefix+t,JSON.stringify(n))})}async remove(e){(Array.isArray(e)?e:[e]).forEach(n=>localStorage.removeItem(this.prefix+n))}async clear(){Object.keys(localStorage).forEach(e=>{e.startsWith(this.prefix)&&localStorage.removeItem(e)})}},vv=class{getURL(e){return e}getVersion(){return ai}getAppName(){return ho}isDevelopmentBuild(){return!1}getManifest(){return{version:ai,name:ho,_sys_ctx:this.isDevelopmentBuild()?"d8n3x5q1":"kz6p9m2v"}}async sendMessage(e){return console.log("[WebApp] Mock sendMessage:",e),null}},wv=class{detect(){return"WebApp"}getPresentationId(){return"webapp-mock-presentation-id"}},Ps=class{constructor(){this.type="webapp";this.storage=new xv;this.runtime=new vv;this.host=new wv;this.chartBuddyStorage=new co(this)}};typeof window<"u"&&(window.WebAppProvider=Ps)});function yc(){if(typeof window>"u")return!1;let h=window;return typeof h.__TAURI__<"u"||typeof h.__TAURI_INTERNALS__<"u"?!0:typeof navigator<"u"&&/tauri/i.test(navigator.userAgent)}var Cv,kv,Av,Qg,Hh=or(()=>{I();Zg();bc();Cv=class{constructor(){this.prefix="cb_";this.map=new Map}storageKey(e){return`${this.prefix}${e}`}async get(e){let t={},n=[];return typeof e=="string"?n=[e]:Array.isArray(e)?n=e:e&&typeof e=="object"&&(n=Object.keys(e),Object.assign(t,e)),n.forEach(r=>{let i=this.map.get(this.storageKey(r));if(i!==void 0)try{t[r]=JSON.parse(i)}catch{t[r]=i}}),t}async set(e){Object.entries(e).forEach(([t,n])=>{this.map.set(this.storageKey(t),JSON.stringify(n))})}async remove(e){(Array.isArray(e)?e:[e]).forEach(n=>this.map.delete(this.storageKey(n)))}async clear(){let e=[];this.map.forEach((t,n)=>{n.startsWith(this.prefix)&&e.push(n)}),e.forEach(t=>this.map.delete(t))}},kv=class{getURL(e){return e}getVersion(){return ai}getAppName(){return ho}isDevelopmentBuild(){return!1}getManifest(){return{version:ai,name:ho,_sys_ctx:this.isDevelopmentBuild()?"d8n3x5q1":"kz6p9m2v"}}async sendMessage(e){return console.log("[Tauri] sendMessage (no-op):",e),null}},Av=class{detect(){return"Tauri"}getPresentationId(){return"tauri-desktop"}},Qg=class{constructor(){this.type="tauri";this.storage=new Cv;this.runtime=new kv;this.host=new Av;this.chartBuddyStorage=new co(this)}}});var _r,Mv,Wh=or(()=>{I();yL();Sv();Hh();_r=class{static setPlatform(e){this.instance=e}static getPlatform(){let e=yc();return e&&this.instance!==void 0&&this.instance.type!=="tauri"&&(this.instance=void 0),this.instance?this.instance:e?(this.instance=new Qg,this.instance):(typeof chrome<"u"&&chrome.runtime&&typeof chrome.runtime.getURL=="function"&&!!chrome.runtime.id?this.instance=new zh:this.instance=new Ps,this.instance)}},Mv=_r.getPlatform()});var qF,Dv,Ei,om,TL=or(()=>{I();qF=["Arial","Calibri","Helvetica","Verdana","Tahoma","Trebuchet MS","Times New Roman","Courier New"],Dv={isExpired:!1,isActive:!0,daysRemaining:null,expiresAt:null},Ei={uploadMethod:"google-drive",featureFlags:{},canManageFeatureFlags:!1,organizationSettings:{colorScheme:["#3B82F6","#10B981","#F59E0B","#9fa90f"],fonts:qF,customFonts:[],defaultFont:"Arial"},trialStatus:Dv},om={production:"https://chartbuddy.io",acceptance:"https://cb-acc.xyz",current:"production"}});function _v(h){if(h.fonts!==void 0){if(!Array.isArray(h.fonts))return console.warn("[FontCacheManager] Invalid fonts: expected array, got",typeof h.fonts),!1;if(!h.fonts.every(e=>typeof e=="string"&&e.trim().length>0))return console.warn("[FontCacheManager] Invalid fonts: contains non-string or empty values"),!1}if(h.customFonts!==void 0){if(!Array.isArray(h.customFonts))return console.warn("[FontCacheManager] Invalid customFonts: expected array, got",typeof h.customFonts),!1;if(!h.customFonts.every(e=>typeof e=="string"&&e.trim().length>0))return console.warn("[FontCacheManager] Invalid customFonts: contains non-string or empty values"),!1}return h.useDefaultFonts!==void 0&&typeof h.useDefaultFonts!="boolean"?(console.warn("[FontCacheManager] Invalid useDefaultFonts: expected boolean, got",typeof h.useDefaultFonts),!1):!0}var sm,Bs,Ov=or(()=>{I();Wh();sm=class h{static{this.STORAGE_KEY="chartbuddy_fonts_cache"}static{this.CACHE_VERSION="1.0"}constructor(){}static getInstance(){return h.instance||(h.instance=new h),h.instance}async getCachedFonts(){try{let t=(await _r.getPlatform().storage.get([h.STORAGE_KEY]))[h.STORAGE_KEY];if(!t)return null;if(typeof t!="object"||t===null)return console.warn("[FontCacheManager] Invalid cache data type, clearing"),await this.clearCache(),null;if(t.version!==h.CACHE_VERSION)return console.log("[FontCacheManager] Cache version mismatch, invalidating"),await this.clearCache(),null;let n={fonts:t.fonts,customFonts:t.customFonts,defaultFont:t.defaultFont,useDefaultFonts:t.useDefaultFonts};return _v(n)?(console.log("[FontCacheManager] Loaded fonts from cache:",{defaultFont:t.defaultFont,fonts:t.fonts?.length??0,customFonts:t.customFonts?.length??0,cachedAt:new Date(t.cachedAt).toISOString()}),n):(console.warn("[FontCacheManager] Cached data validation failed, clearing cache"),await this.clearCache(),null)}catch(e){return console.warn("[FontCacheManager] Failed to get cached fonts:",e),null}}async saveFontsToCache(e){if(!_v(e))throw new Error("[FontCacheManager] Invalid font settings, cannot save to cache");try{let t={fonts:e.fonts,customFonts:e.customFonts,defaultFont:e.defaultFont,useDefaultFonts:e.useDefaultFonts,cachedAt:Date.now(),version:h.CACHE_VERSION},r=JSON.stringify(t).length,i=100*1024;r>i&&(console.warn(`[FontCacheManager] Cache size (${r} bytes) exceeds limit (${i} bytes), clearing old cache`),await this.clearCache()),await _r.getPlatform().storage.set({[h.STORAGE_KEY]:t})}catch(t){throw console.error("[FontCacheManager] Failed to save fonts to cache:",t),t}}async validateAndSyncFonts(e){if(!_v(e))return console.warn("[FontCacheManager] Invalid backend font settings, using cached data"),{hasChanges:!1,fonts:await this.getCachedFonts()??{fonts:[],customFonts:[],defaultFont:"Arial",useDefaultFonts:!0}};let t=null;try{console.log("[FontCacheManager] Validating fonts against cache..."),t=await this.getCachedFonts();let n=this.fontsHaveChanged(t,e);return n&&await this.saveFontsToCache(e),{hasChanges:n,fonts:e}}catch(n){return console.error("[FontCacheManager] Error validating fonts:",n),{hasChanges:!1,fonts:t??{fonts:[],customFonts:[],defaultFont:"Arial",useDefaultFonts:!0}}}}fontsHaveChanged(e,t){if(!e)return!0;let n=(r,i)=>!r&&!i?!0:!r||!i||r.length!==i.length?!1:r.every((a,o)=>a===i[o]);return!n(e.fonts,t.fonts)||!n(e.customFonts,t.customFonts)||e.defaultFont!==t.defaultFont||e.useDefaultFonts!==t.useDefaultFonts}async clearCache(){try{await _r.getPlatform().storage.remove([h.STORAGE_KEY]),console.log("[FontCacheManager] Cache cleared")}catch(e){console.warn("[FontCacheManager] Failed to clear cache:",e)}}},Bs=sm.getInstance()});var DL={};Kg(DL,{CHARTBUDDY_CONFIG_UPDATED_EVENT:()=>EL,ConfigManager:()=>pt,getConfigManager:()=>Or});function Or(){return pt.getInstance()}var EL,pt,Kn=or(()=>{I();TL();Wh();Mi();Ov();Os();EL="chartbuddy:config-updated",pt=class h{constructor(){this.debugEnabled=!1;this.debugAxisBinding=!0;this.loadingPromise=void 0;this.fontPreloadPromise=void 0;this.onLoadCallbacks=[];if(this.config={chartbuddyUrl:this.detectEnvironmentUrl(),bootOptions:{...Ei},environment:{...om},loaded:!1,loadedAt:void 0},this.config.environment.current=this.detectEnvironment(),this.debugEnabled=this.computeDebugEnabled(this.config.chartbuddyUrl),typeof window<"u"&&window.localStorage)try{window.localStorage.getItem("CHARTBUDDY_DEBUG_MODE")==="true"&&(this.debugEnabled=!0),window.localStorage.getItem("CHARTBUDDY_DEBUG_AXIS_BINDING")==="false"&&(this.debugAxisBinding=!1)}catch{}}static{this.instance=void 0}computeDebugEnabled(e){let t=e.includes("cb-acc.xyz")||e.includes("stag"),n=e.includes("localhost")||e.includes("127.0.0.1"),r=_r.getPlatform().runtime.isDevelopmentBuild();return t||n||r}static getInstance(){return h.instance===void 0&&(h.instance=new h),h.instance}isDebugEnabled(){return this.debugEnabled}isDebugAxisBindingEnabled(){return this.debugAxisBinding}isWaterfallSegmentedBarsEnabled(){return!0}isChartOrientationEnabled(){return!0}isBarMekkoEnabled(){return this.config?.bootOptions?.featureFlags?.barMekko===!0}isDevelopment(){let e=this.config.chartbuddyUrl;return e.includes("localhost")||e.includes("127.0.0.1")}isAcceptance(){return this.config.chartbuddyUrl.includes("cb-acc.xyz")}isProduction(){return!this.isDevelopment()&&!this.isAcceptance()}setDebugMode(e){this.debugEnabled=e}setDebugAxisBindingMode(e){this.debugAxisBinding=e}detectEnvironmentUrl(){return om.production}detectEnvironment(){return this.config.chartbuddyUrl.includes("cb-acc.xyz")?"acceptance":"production"}getConfig(){return{...this.config}}getChartbuddyUrl(){return this.config.chartbuddyUrl}getBootOptions(){return{...this.config.bootOptions}}getEnvironment(){return{...this.config.environment}}getTrialStatus(){return{...this.config.bootOptions.trialStatus}}isTrialExpired(){return this.config.bootOptions.trialStatus.isExpired}isLoaded(){return this.config.loaded}onLoad(e){this.config.loaded?e():this.onLoadCallbacks.push(e)}setChartbuddyUrl(e){this.config.chartbuddyUrl=e,this.config.environment.current=this.detectEnvironment(),this.debugEnabled=this.computeDebugEnabled(e)}async loadConfig(){if(this.loadingPromise)return this.loadingPromise;if(this.config.loaded&&this.config.loadedAt&&Date.now()-this.config.loadedAt<3e5){console.log("[ConfigManager] Config already loaded recently, skipping reload");return}this.loadingPromise=this.loadConfigInternal();try{await this.loadingPromise}finally{this.loadingPromise=void 0}}async preloadFontSettings(){if(this.fontPreloadPromise)return this.fontPreloadPromise;this.fontPreloadPromise=this.preloadFontSettingsInternal();try{await this.fontPreloadPromise}finally{this.fontPreloadPromise=void 0}}async loadConfigInternal(){try{if(_r.getPlatform().type==="webapp"){console.log("[ConfigManager] Standalone mode (WebApp): using local defaults"),this.config.bootOptions={...Ei},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks();return}console.log("[ConfigManager] Loading configuration from backend...");let t=await this.getAuthToken();if(!t){console.warn("[ConfigManager] No authentication token available, using defaults"),Bs.clearCache().catch(r=>{console.warn("[ConfigManager] Failed to clear font cache on auth failure:",r)}),this.config.bootOptions={...Ei},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks();return}let n=await this.fetchAuthenticatedJson("/api/user/boot-settings",t);if(n.ok){let r=await n.json(),i=r.uploadMethod??Ei.uploadMethod,a=r.featureFlags??Ei.featureFlags,o=r.canManageFeatureFlags??Ei.canManageFeatureFlags,l=r.organizationSettings??Ei.organizationSettings,d=r.trialStatus??Dv;this.config.bootOptions={uploadMethod:i,featureFlags:a,canManageFeatureFlags:o,organizationSettings:l,trialStatus:d},console.log("[ConfigManager] Organization Settings received:",{colorSchemeCount:l.colorScheme?.length||0,fontCount:l.fonts?.length||0}),this.config.loaded=!0,this.config.loadedAt=Date.now(),console.log("[ConfigManager] \u2705 Configuration loaded successfully:",{uploadMethod:this.config.bootOptions.uploadMethod,loadedAt:new Date(this.config.loadedAt).toISOString()}),await this.initializeFontService(),this.initializeColorService();let u={fonts:l.fonts??[],customFonts:l.customFonts??[],defaultFont:l.defaultFont??"Noto Sans"};this.validateFontCache(u).catch(g=>{console.warn("[ConfigManager] Background font validation failed:",g)}),this.triggerOnLoadCallbacks()}else console.warn(`[ConfigManager] Failed to fetch boot settings (HTTP ${n.status}), using defaults`),(n.status===401||n.status===403)&&Bs.clearCache().catch(r=>{console.warn("[ConfigManager] Failed to clear font cache on auth failure:",r)}),this.config.bootOptions={...Ei},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks()}catch(e){console.error("[ConfigManager] Error loading configuration:",e),console.log("[ConfigManager] Using default configuration"),this.config.bootOptions={...Ei},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks()}}async preloadFontSettingsInternal(){try{let e=await this.getAuthToken();if(!e)return;let t=await this.fetchAuthenticatedJson("/api/user/font-settings",e);if(!t.ok){(t.status===401||t.status===403)&&Bs.clearCache().catch(r=>{console.warn("[ConfigManager] Failed to clear font cache on preload auth failure:",r)});return}let n=await t.json();Ct.isInitialized()?Ct.reinitialize(n):Ct.primeEarly(n)}catch(e){console.warn("[ConfigManager] Font preload failed:",e)}}triggerOnLoadCallbacks(){console.log(`[ConfigManager] Triggering ${this.onLoadCallbacks.length} onLoad callbacks`),this.onLoadCallbacks.forEach(e=>{try{e()}catch(t){console.error("[ConfigManager] Error in onLoad callback:",t)}}),this.onLoadCallbacks=[],typeof window<"u"&&window.dispatchEvent(new CustomEvent(EL,{detail:{bootOptions:this.getBootOptions(),loadedAt:this.config.loadedAt}}))}async initializeFontService(){if(Ct.isInitialized()){console.log("[ConfigManager] FontService already initialized, skipping");return}try{let e=await Bs.getCachedFonts();if(e){Ct.initialize(e);return}let t=this.config.bootOptions.organizationSettings,n={fonts:t.fonts??[],customFonts:t.customFonts??[],defaultFont:t.defaultFont??"Noto Sans"};Ct.initialize(n)}catch(e){console.warn("[ConfigManager] Failed to initialize FontService:",e)}}initializeColorService(){try{let t=this.config.bootOptions.organizationSettings.colorScheme||[];Sr.initialize({colorScheme:t});let n=_r.getPlatform();n&&n.chartBuddyStorage&&n.chartBuddyStorage.setOrganizationColors(t).then(()=>console.log("[ConfigManager] Organization colors persisted to storage")).catch(r=>console.warn("[ConfigManager] Failed to persist organization colors:",r)),console.log("[ConfigManager] ColorService initialized")}catch(e){console.warn("[ConfigManager] Failed to initialize ColorService:",e)}}async validateFontCache(e){try{let t=await Bs.validateAndSyncFonts(e);t.hasChanges?(console.log("[ConfigManager] Font settings changed, updating"),Ct.reinitialize(t.fonts)):console.log("[ConfigManager] Font settings unchanged, keeping current initialization")}catch(t){console.warn("[ConfigManager] Font validation failed:",t)}}async getAuthToken(){return(await this.getChromeStorage(["token"])).token}fetchAuthenticatedJson(e,t){return fetch(`${this.config.chartbuddyUrl}${e}`,{method:"GET",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"}})}async getChromeStorage(e){try{let t=await _r.getPlatform().storage.get(e),n={};for(let r of e)n[r]=t[r];return n}catch(t){return console.warn("[ConfigManager] Failed to get chrome storage:",t),{}}}async reloadConfig(){this.config.loaded=!1,this.config.loadedAt=void 0,await this.loadConfig()}reset(){this.config={chartbuddyUrl:this.detectEnvironmentUrl(),bootOptions:{...Ei},environment:{...om},loaded:!1,loadedAt:void 0},this.config.environment.current=this.detectEnvironment(),this.loadingPromise=void 0,this.fontPreloadPromise=void 0}}});var Xv=VF((Yv,jv)=>{I();(h=>{let e=(()=>{let _=0;return{escape:function(Y){return Y.replace(/([.*+?^${}()|[\]/\\])/g,"\\$1")},isDataUrl:function(Y){return Y.search(/^(data:)/)!==-1},canvasToBlob:function(Y){return Y.toBlob?new Promise(function(J){Y.toBlob(J)}):(J=>new Promise(function(te){var ae=g(J.toDataURL().split(",")[1]),re=ae.length,le=new Uint8Array(re);for(let ye=0;ye<re;ye++)le[ye]=ae.charCodeAt(ye);te(new Blob([le],{type:"image/png"}))}))(Y)},resolveUrl:function(Y,J){var te=document.implementation.createHTMLDocument(),ae=te.createElement("base"),re=(te.head.appendChild(ae),te.createElement("a"));return te.body.appendChild(re),ae.href=J,re.href=Y,re.href},getAndEncode:function(Y){let J=l.impl.urlCache.find(function(te){return te.url===Y});return J||(J={url:Y,promise:null},l.impl.urlCache.push(J)),J.promise===null&&(l.impl.options.cacheBust&&(Y+=(/\?/.test(Y)?"&":"?")+new Date().getTime()),J.promise=new Promise(function(te){let ae=new XMLHttpRequest;function re(Q){console.error(Q),te("")}function le(){var Q=l.impl.options.imagePlaceholder;Q?te(Q):re("Status:"+ae.status+" while fetching resource: "+Y)}if(ae.timeout=l.impl.options.httpTimeout,ae.onerror=le,ae.ontimeout=le,ae.onloadend=function(){if(ae.readyState===XMLHttpRequest.DONE){var Q=ae.status;if(Q===0&&Y.toLowerCase().startsWith("file://")||200<=Q&&Q<=300&&ae.response!==null){Q=ae.response,Q instanceof Blob||re("Expected response to be a Blob, but got: "+typeof Q);let de=new FileReader;de.onloadend=function(){var me=de.result;te(me)};try{de.readAsDataURL(Q)}catch(me){re("Failed to read the response as Data URL: "+me.toString())}}else le()}},0<l.impl.options.useCredentialsFilters.length&&(l.impl.options.useCredentials=0<l.impl.options.useCredentialsFilters.filter(Q=>0<=Y.search(Q)).length),l.impl.options.useCredentials&&(ae.withCredentials=!0),l.impl.options.corsImg&&Y.indexOf("http")===0&&Y.indexOf(window.location.origin)===-1){var ye=(l.impl.options.corsImg.method||"GET").toUpperCase()==="POST"?"POST":"GET";ae.open(ye,(l.impl.options.corsImg.url||"").replace("#{cors}",Y),!0);let Q=!1,de=l.impl.options.corsImg.headers||{},me=(Object.keys(de).forEach(function(Se){de[Se].indexOf("application/json")!==-1&&(Q=!0),ae.setRequestHeader(Se,de[Se])}),(Se=>{try{return JSON.parse(JSON.stringify(Se))}catch(Ce){re("corsImg.data is missing or invalid:"+Ce.toString())}})(l.impl.options.corsImg.data||""));Object.keys(me).forEach(function(Se){typeof me[Se]=="string"&&(me[Se]=me[Se].replace("#{cors}",Y))}),ae.responseType="blob",ae.send(Q?JSON.stringify(me):me)}else ae.open("GET",Y,!0),ae.responseType="blob",ae.send()})),J.promise},uid:function(){return"u"+("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)+_++},asArray:function(Y){var J=[],te=Y.length;for(let ae=0;ae<te;ae++)J.push(Y[ae]);return J},escapeXhtml:function(Y){return Y.replace(/%/g,"%25").replace(/#/g,"%23").replace(/\n/g,"%0A")},makeImage:function(Y){return Y!=="data:,"?new Promise(function(J,te){let ae=document.createElementNS("http://www.w3.org/2000/svg","svg"),re=new Image;l.impl.options.useCredentials&&(re.crossOrigin="use-credentials"),re.onload=function(){document.body.removeChild(ae),window&&window.requestAnimationFrame?window.requestAnimationFrame(function(){J(re)}):J(re)},re.onerror=le=>{document.body.removeChild(ae),te(le)},ae.appendChild(re),re.src=Y,document.body.appendChild(ae)}):Promise.resolve()},width:function(Y){var J=U(Y,"width");if(!isNaN(J))return J;var J=U(Y,"border-left-width"),te=U(Y,"border-right-width");return Y.scrollWidth+J+te},height:function(Y){var J=U(Y,"height");if(!isNaN(J))return J;var J=U(Y,"border-top-width"),te=U(Y,"border-bottom-width");return Y.scrollHeight+J+te},getWindow:P,isElement:q,isElementHostForOpenShadowRoot:function(Y){return q(Y)&&Y.shadowRoot!==null},isShadowRoot:$,isInShadowRoot:V,isHTMLElement:function(Y){return Y instanceof P(Y).HTMLElement},isHTMLCanvasElement:function(Y){return Y instanceof P(Y).HTMLCanvasElement},isHTMLInputElement:function(Y){return Y instanceof P(Y).HTMLInputElement},isHTMLImageElement:function(Y){return Y instanceof P(Y).HTMLImageElement},isHTMLLinkElement:function(Y){return Y instanceof P(Y).HTMLLinkElement},isHTMLScriptElement:function(Y){return Y instanceof P(Y).HTMLScriptElement},isHTMLStyleElement:function(Y){return Y instanceof P(Y).HTMLStyleElement},isHTMLTextAreaElement:function(Y){return Y instanceof P(Y).HTMLTextAreaElement},isShadowSlotElement:function(Y){return V(Y)&&Y instanceof P(Y).HTMLSlotElement},isSVGElement:function(Y){return Y instanceof P(Y).SVGElement},isSVGRectElement:function(Y){return Y instanceof P(Y).SVGRectElement},isDimensionMissing:function(Y){return isNaN(Y)||Y<=0}};function P(Y){return Y=Y?Y.ownerDocument:void 0,(Y?Y.defaultView:void 0)||window||h}function $(Y){return Y instanceof P(Y).ShadowRoot}function V(Y){return Y!=null&&Y.getRootNode!==void 0&&$(Y.getRootNode())}function q(Y){return Y instanceof P(Y).Element}function U(Y,J){if(Y.nodeType===d){let te=u(Y).getPropertyValue(J);if(te.slice(-2)==="px")return te=te.slice(0,-2),parseFloat(te)}return NaN}})(),t=(()=>{let _=/url\(\s*(["']?)((?:\\.|[^\\)])+)\1\s*\)/gm;return{inlineAll:function(U,Y,J){return P(U)?Promise.resolve(U).then($).then(function(te){let ae=Promise.resolve(U);return te.forEach(function(re){ae=ae.then(function(le){return q(le,re,Y,J)})}),ae}):Promise.resolve(U)},shouldProcess:P,impl:{readUrls:$,inline:q,urlAsRegex:V}};function P(U){return U.search(_)!==-1}function $(U){for(var Y,J=[];(Y=_.exec(U))!==null;)J.push(Y[2]);return J.filter(function(te){return!e.isDataUrl(te)})}function V(U){return new RegExp(`url\\((["']?)(${e.escape(U)})\\1\\)`,"gm")}function q(U,Y,J,te){return Promise.resolve(Y).then(function(ae){return J?e.resolveUrl(ae,J):ae}).then(te||e.getAndEncode).then(function(ae){var re=V(Y);return U.replace(re,`url($1${ae}$1)`)})}})(),n={resolveAll:function(){return r().then(function(_){return Promise.all(_.map(function(P){return P.resolve()}))}).then(function(_){return _.join(`
|
|
51
51
|
`)})},impl:{readAll:r}};function r(){return Promise.resolve(e.asArray(document.styleSheets)).then(function(P){let $=[];return P.forEach(function(V){var q=Object.getPrototypeOf(V);if(Object.prototype.hasOwnProperty.call(q,"cssRules"))try{e.asArray(V.cssRules||[]).forEach($.push.bind($))}catch(U){console.error("domtoimage: Error while reading CSS rules from: "+V.href,U.toString())}}),$}).then(function(P){return P.filter(function($){return $.type===CSSRule.FONT_FACE_RULE}).filter(function($){return t.shouldProcess($.style.getPropertyValue("src"))})}).then(function(P){return P.map(_)});function _(P){return{resolve:function(){var $=(P.parentStyleSheet||{}).href;return t.inlineAll(P.cssText,$)},src:function(){return P.style.getPropertyValue("src")}}}}let i={inlineAll:function _(P){if(!e.isElement(P))return Promise.resolve(P);return $(P).then(function(){return e.isHTMLImageElement(P)?a(P).inline():Promise.all(e.asArray(P.childNodes).map(function(V){return _(V)}))});function $(V){let q=["background","background-image"],U=q.map(function(Y){let J=V.style.getPropertyValue(Y),te=V.style.getPropertyPriority(Y);return J?t.inlineAll(J).then(function(ae){V.style.setProperty(Y,ae,te)}):Promise.resolve()});return Promise.all(U).then(function(){return V})}},impl:{newImage:a}};function a(_){return{inline:function(P){return e.isDataUrl(_.src)?Promise.resolve():Promise.resolve(_.src).then(P||e.getAndEncode).then(function($){return new Promise(function(V){_.onload=V,_.onerror=V,_.src=$})})}}}let o={copyDefaultStyles:!0,imagePlaceholder:void 0,cacheBust:!1,useCredentials:!1,useCredentialsFilters:[],httpTimeout:3e4,styleCaching:"strict",corsImg:void 0,adjustClonedNode:void 0,filterStyles:void 0},l={toSvg:m,toPng:function(_,P){return y(_,P).then(function($){return $.toDataURL()})},toJpeg:function(_,P){return y(_,P).then(function($){return $.toDataURL("image/jpeg",(P?P.quality:void 0)||1)})},toBlob:function(_,P){return y(_,P).then(e.canvasToBlob)},toPixelData:function(_,P){return y(_,P).then(function($){return $.getContext("2d").getImageData(0,0,e.width(_),e.height(_)).data})},toCanvas:y,impl:{fontFaces:n,images:i,util:e,inliner:t,urlCache:[],options:{},copyOptions:function(_){_.copyDefaultStyles===void 0?l.impl.options.copyDefaultStyles=o.copyDefaultStyles:l.impl.options.copyDefaultStyles=_.copyDefaultStyles,l.impl.options.imagePlaceholder=(_.imagePlaceholder===void 0?o:_).imagePlaceholder,l.impl.options.cacheBust=(_.cacheBust===void 0?o:_).cacheBust,l.impl.options.corsImg=(_.corsImg===void 0?o:_).corsImg,l.impl.options.useCredentials=(_.useCredentials===void 0?o:_).useCredentials,l.impl.options.useCredentialsFilters=(_.useCredentialsFilters===void 0?o:_).useCredentialsFilters,l.impl.options.httpTimeout=(_.httpTimeout===void 0?o:_).httpTimeout,l.impl.options.styleCaching=(_.styleCaching===void 0?o:_).styleCaching}}},d=(typeof Yv=="object"&&typeof jv=="object"?jv.exports=l:h.domtoimage=l,(Node===void 0?void 0:Node.ELEMENT_NODE)||1),u=(h===void 0?void 0:h.getComputedStyle)||(window===void 0?void 0:window.getComputedStyle)||globalThis.getComputedStyle,g=(h===void 0?void 0:h.atob)||(window===void 0?void 0:window.atob)||globalThis.atob;function m(_,P){let $=l.impl.util.getWindow(_),V=(P=P||{},l.impl.copyOptions(P),[]);return Promise.resolve(_).then(function(q){if(q.nodeType===d)return q;var U=q,Y=document.createElement("span");return U.replaceWith(Y),Y.append(q),V.push({child:U,wrapper:Y}),Y}).then(function(q){return(function U(Y,J,te,ae){let re=J.filter;if(Y===v||e.isHTMLScriptElement(Y)||e.isHTMLStyleElement(Y)||e.isHTMLLinkElement(Y)||te!==null&&re&&!re(Y))return Promise.resolve();return Promise.resolve(Y).then(le).then(ye).then(function(Ce){return me(Ce,de(Y))}).then(Q).then(function(Ce){return Se(Ce,Y)});function le(Ce){return e.isHTMLCanvasElement(Ce)?e.makeImage(Ce.toDataURL()):Ce.cloneNode(!1)}function ye(Ce){return J.adjustClonedNode&&J.adjustClonedNode(Y,Ce,!1),Promise.resolve(Ce)}function Q(Ce){return J.adjustClonedNode&&J.adjustClonedNode(Y,Ce,!0),Promise.resolve(Ce)}function de(Ce){return e.isElementHostForOpenShadowRoot(Ce)?Ce.shadowRoot:Ce}function me(Ce,_e){let Ee=at(_e),Ue=Promise.resolve();if(Ee.length!==0){let Re=u(Ie(_e));e.asArray(Ee).forEach(function(bt){Ue=Ue.then(function(){return U(bt,J,Re,ae).then(function(it){it&&Ce.appendChild(it)})})})}return Ue.then(function(){return Ce});function Ie(Re){return e.isShadowRoot(Re)?Re.host:Re}function at(Re){if(e.isShadowSlotElement(Re)){let bt=Re.assignedNodes();if(bt&&0<bt.length)return bt}return Re.childNodes}}function Se(Ce,_e){return!e.isElement(Ce)||e.isShadowSlotElement(_e)?Promise.resolve(Ce):Promise.resolve().then(Ue).then(Ie).then(at).then(Re).then(Ee).then(function(){return Ce});function Ee(){e.isHTMLImageElement(Ce)&&(Ce.removeAttribute("loading"),_e.srcset||_e.sizes)&&(Ce.removeAttribute("srcset"),Ce.removeAttribute("sizes"),Ce.src=_e.currentSrc||_e.src)}function Ue(){function bt(We,Xe){Xe.font=We.font,Xe.fontFamily=We.fontFamily,Xe.fontFeatureSettings=We.fontFeatureSettings,Xe.fontKerning=We.fontKerning,Xe.fontSize=We.fontSize,Xe.fontStretch=We.fontStretch,Xe.fontStyle=We.fontStyle,Xe.fontVariant=We.fontVariant,Xe.fontVariantCaps=We.fontVariantCaps,Xe.fontVariantEastAsian=We.fontVariantEastAsian,Xe.fontVariantLigatures=We.fontVariantLigatures,Xe.fontVariantNumeric=We.fontVariantNumeric,Xe.fontVariationSettings=We.fontVariationSettings,Xe.fontWeight=We.fontWeight}function it(We,Xe){let St=u(We);St.cssText?(Xe.style.cssText=St.cssText,bt(St,Xe.style)):(L(J,We,St,te,Xe),te===null&&(["inset-block","inset-block-start","inset-block-end"].forEach(Ne=>Xe.style.removeProperty(Ne)),["left","right","top","bottom"].forEach(Ne=>{Xe.style.getPropertyValue(Ne)&&Xe.style.setProperty(Ne,"0px")})))}it(_e,Ce)}function Ie(){let bt=e.uid();function it(We){let Xe=u(_e,We),St=Xe.getPropertyValue("content");if(St!==""&&St!=="none"){let Ot=function(){let Xt=`.${bt}:`+We,tn=(Xe.cssText?qe:st)();return document.createTextNode(Xt+`{${tn}}`);function qe(){return`${Xe.cssText} content: ${St};`}function st(){return e.asArray(Xe).map(Et).join("; ")+";";function Et(Tt){let Oe=Xe.getPropertyValue(Tt),He=Xe.getPropertyPriority(Tt)?" !important":"";return Tt+": "+Oe+He}}};var Ne=Ot;let Ft=Ce.getAttribute("class")||"",Vt=(Ce.setAttribute("class",Ft+" "+bt),document.createElement("style"));Vt.appendChild(Ot()),Ce.appendChild(Vt)}}[":before",":after"].forEach(function(We){it(We)})}function at(){e.isHTMLTextAreaElement(_e)&&(Ce.innerHTML=_e.value),e.isHTMLInputElement(_e)&&Ce.setAttribute("value",_e.value)}function Re(){e.isSVGElement(Ce)&&(Ce.setAttribute("xmlns","http://www.w3.org/2000/svg"),e.isSVGRectElement(Ce))&&["width","height"].forEach(function(bt){let it=Ce.getAttribute(bt);it&&Ce.style.setProperty(bt,it)})}}})(q,P,null,$)}).then(P.disableEmbedFonts?Promise.resolve(_):w).then(P.disableInlineImages?Promise.resolve(_):S).then(function(q){P.bgcolor&&(q.style.backgroundColor=P.bgcolor),P.width&&(q.style.width=P.width+"px"),P.height&&(q.style.height=P.height+"px"),P.style&&Object.keys(P.style).forEach(function(Y){q.style[Y]=P.style[Y]});let U=null;return typeof P.onclone=="function"&&(U=P.onclone(q)),Promise.resolve(U).then(function(){return q})}).then(function(q){let U=P.width||e.width(_),Y=P.height||e.height(_);return Promise.resolve(q).then(function(J){return J.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),new XMLSerializer().serializeToString(J)}).then(e.escapeXhtml).then(function(J){var te=(e.isDimensionMissing(U)?' width="100%"':` width="${U}"`)+(e.isDimensionMissing(Y)?' height="100%"':` height="${Y}"`);return`<svg xmlns="http://www.w3.org/2000/svg"${(e.isDimensionMissing(U)?"":` width="${U}"`)+(e.isDimensionMissing(Y)?"":` height="${Y}"`)}><foreignObject${te}>${J}</foreignObject></svg>`}).then(function(J){return"data:image/svg+xml;charset=utf-8,"+J})}).then(function(q){for(;0<V.length;){var U=V.pop();U.wrapper.replaceWith(U.child)}return q}).then(function(q){return l.impl.urlCache=[],v&&(document.body.removeChild(v),v=null),E&&clearTimeout(E),E=setTimeout(()=>{E=null,T={}},2e4),q})}function y(_,P){return m(_,P=P||{}).then(e.makeImage).then(function($){var V=typeof P.scale!="number"?1:P.scale,q=((Y,J)=>{let te=P.width||e.width(Y),ae=P.height||e.height(Y);return e.isDimensionMissing(te)&&(te=e.isDimensionMissing(ae)?300:2*ae),e.isDimensionMissing(ae)&&(ae=te/2),(Y=document.createElement("canvas")).width=te*J,Y.height=ae*J,P.bgcolor&&((J=Y.getContext("2d")).fillStyle=P.bgcolor,J.fillRect(0,0,Y.width,Y.height)),Y})(_,V),U=q.getContext("2d");return U.msImageSmoothingEnabled=!1,U.imageSmoothingEnabled=!1,$&&(U.scale(V,V),U.drawImage($,0,0)),q})}let v=null;function w(_){return n.resolveAll().then(function(P){var $;return P!==""&&($=document.createElement("style"),_.appendChild($),$.appendChild(document.createTextNode(P))),_})}function S(_){return i.inlineAll(_).then(function(){return _})}function L(_,P,$,V,q){let U=l.impl.options.copyDefaultStyles?((J,te)=>{var ae,re=(Q=>(J.styleCaching!=="relaxed"?Q:Q.filter((de,me,Se)=>me===0||me===Se.length-1)).join(">"))(te=(Q=>{var de=[];do if(Q.nodeType===d){var me=Q.tagName;if(de.push(me),D.includes(me))break}while(Q=Q.parentNode);return de})(te));{if(T[re])return T[re];te=((Q,de)=>{let me=Q.body;do{var Se=de.pop(),Se=Q.createElement(Se);me.appendChild(Se),me=Se}while(0<de.length);return me.textContent="\u200B",me})((ae=(()=>{if(v)return v.contentWindow;de=document.characterSet||"UTF-8",Q=(Q=document.doctype)?(`<!DOCTYPE ${Ue(Q.name)} ${Ue(Q.publicId)} `+Ue(Q.systemId)).trim()+">":"",(v=document.createElement("iframe")).id="domtoimage-sandbox-"+e.uid(),v.style.top="-9999px",v.style.visibility="hidden",v.style.position="fixed",document.body.appendChild(v);var Q,de,me=v,Se="domtoimage-sandbox";try{return me.contentWindow.document.write(Q+`<html><head><meta charset='${de}'><title>${Se}</title></head><body></body></html>`),me.contentWindow}catch{}var Ce=document.createElement("meta");Ce.setAttribute("charset",de);try{var _e=document.implementation.createHTMLDocument(Se),Ee=(_e.head.appendChild(Ce),Q+_e.documentElement.outerHTML);return me.setAttribute("srcdoc",Ee),me.contentWindow}catch{}return me.contentDocument.head.appendChild(Ce),me.contentDocument.title=Se,me.contentWindow;function Ue(Ie){var at;return Ie?((at=document.createElement("div")).innerText=Ie,at.innerHTML):""}})()).document,te),ae=((Q,de)=>{let me={},Se=Q.getComputedStyle(de);return e.asArray(Se).forEach(function(Ce){me[Ce]=Ce==="width"||Ce==="height"?"auto":Se.getPropertyValue(Ce)}),me})(ae,te);var le=te;do{var ye=le.parentElement;ye!==null&&ye.removeChild(le),le=ye}while(le&&le.tagName!=="BODY");return T[re]=ae}})(_,P):{},Y=q.style;e.asArray($).forEach(function(J){var te,ae,re,le;_.filterStyles&&!_.filterStyles(P,J)||(ae=$.getPropertyValue(J),re=U[J],te=V?V.getPropertyValue(J):void 0,Y.getPropertyValue(J))||(ae!==re||V&&ae!==te)&&(re=$.getPropertyPriority(J),te=Y,ae=ae,re=re,le=0<=["background-clip"].indexOf(J=J),re?(te.setProperty(J,ae,re),le&&te.setProperty("-webkit-"+J,ae,re)):(te.setProperty(J,ae),le&&te.setProperty("-webkit-"+J,ae)))})}let E=null,T={},D=["ADDRESS","ARTICLE","ASIDE","BLOCKQUOTE","DETAILS","DIALOG","DD","DIV","DL","DT","FIELDSET","FIGCAPTION","FIGURE","FOOTER","FORM","H1","H2","H3","H4","H5","H6","HEADER","HGROUP","HR","LI","MAIN","NAV","OL","P","PRE","SECTION","SVG","TABLE","UL","math","svg","BODY","HEAD","HTML"]})(Yv)});var l$={};Kg(l$,{CHARTBUDDY_INSIGHTS_GLOBAL:()=>f1,ChartDataValidationError:()=>Rc,Insight:()=>JE,assertValidChartData:()=>tu,clearPersistedChart:()=>g1,default:()=>s$,formatValidationIssues:()=>eu,getInsights:()=>Ff,snapshotInsights:()=>p1,validateChartData:()=>So,version:()=>ai});I();I();var qg=typeof window<"u"?window:globalThis;qg.__CHARTBUDDY_NO_AUTOBOOT__=!0;qg.__CHARTBUDDY_ARTIFACT__=!0;qg.ChartLabelPlacementWorkerUrl=null;qg.ChartLabelPlacementWasm=null;I();I();I();var ta=window;ta.chrome=ta.chrome||{};ta.chrome.runtime=ta.chrome.runtime||{getURL:h=>h,getManifest:()=>({version:"1.0.0-webapp",name:"Chartbuddy Web"}),sendMessage:h=>(console.log("[WebApp] Mock sendMessage:",h),Promise.resolve(null)),onMessage:{addListener:()=>{}}};ta.chrome.storage=ta.chrome.storage||{local:{get:(h,e)=>{let t=Promise.resolve({});return e&&t.then(e),t},set:(h,e)=>{let t=Promise.resolve();return e&&t.then(e),t},remove:(h,e)=>{let t=Promise.resolve();return e&&t.then(e),t},clear:h=>{let e=Promise.resolve();return h&&e.then(h),e}}};ta.ContextMenuTS||(ta.ContextMenuTS={showAt:()=>{console.log("[WebApp] ContextMenu.showAt suppressed in widget")},close:()=>{},destroy:()=>{}});ta.window.ContextMenuTS=ta.ContextMenuTS;console.log("\u{1F310} WebApp Globals Initialized");I();var HF='.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}',mL="src/ts/shared/css/tippy.css";if(typeof document<"u"&&!document.querySelector('style[data-cb-embed-css="'+mL+'"]')){let h=document.createElement("style");h.setAttribute("data-cb-embed-css",mL),h.textContent=HF,document.head.appendChild(h)}Mi();Os();I();Wh();I();var xc=class{showChartSelectionModal(){console.warn("[NullUIProvider] ChartSelectionModal not available in this build")}showTrialExpiredModal(){console.warn("[NullUIProvider] TrialExpiredModal not available in this build")}showSaveTemplateModal(){console.warn("[NullUIProvider] SaveTemplateModal not available in this build")}showGoogleSheetsConnectionModal(){console.warn("[NullUIProvider] GoogleSheetsConnectionModal not available in this build")}showDeleteConfirmationModal(){console.warn("[NullUIProvider] DeleteConfirmationModal not available in this build")}showInviteModal(){console.warn("[NullUIProvider] InviteModal not available in this build")}removeGoogleSheetsConnection(){console.warn("[NullUIProvider] removeGoogleSheetsConnection not available in this build")}showSeriesOptionsDropdown(){console.warn("[NullUIProvider] SeriesOptionsDropdown not available in this build")}showWaterfallColumnDropdown(){console.warn("[NullUIProvider] WaterfallColumnDropdown not available in this build")}reset(){}};var em=null;function xL(h={}){let e=h.platform||_r.getPlatform(),t=h.ui||new xc,n=h.chartbuddyUrl||"https://chartbuddy-app.com";return{platform:e,ui:t,chartbuddyUrl:n}}function YF(h){return em=h,h}function vL(h={}){return YF(xL(h))}function Ma(){return em||(em=xL()),em}Wh();Sv();I();I();I();I();I();var yt=class h{static{this.globalInstance=null}constructor(e){this.listeners=new Map,this.debugMode=e?.debug??!1}static global(){return h.globalInstance||(h.globalInstance=new h({debug:!1})),h.globalInstance}static resetGlobal(){h.globalInstance=null}on(e,t){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),()=>{this.off(e,t)}}once(e,t){let n=r=>{this.off(e,n),t(r)};return this.on(e,n)}emit(e,t){let n=this.listeners.get(e);if(this.debugMode&&console.log(`[EventBus] Emitting "${e}"`,t),!n)return;Array.from(n).forEach(i=>{try{i(t)}catch(a){console.error(`[EventBus] Error in listener for "${e}":`,a)}})}off(e,t){let n=this.listeners.get(e);n&&(t?(n.delete(t),n.size===0&&this.listeners.delete(e)):this.listeners.delete(e))}clear(){this.listeners.clear()}listenerCount(e){let t=this.listeners.get(e);return t?t.size:0}eventNames(){return Array.from(this.listeners.keys())}removeListeners(e){e.forEach(t=>{this.listeners.delete(t)})}};I();var sr={CREATED:"chart.created",TYPE_CHANGED:"chart.type_changed",DELETED:"chart.deleted",SAVED:"chart.saved",DOWNLOADED:"chart.downloaded",OPENED:"chart.opened",CD_CHANGED:"chart.cd_changed"};var na={CLOSE_ALL_DROPDOWNS:"ui.close_all_dropdowns",DROPDOWN_OPENING:"ui.dropdown_opening"};var Wr={OPERATION_FAILED:"error.operation_failed",UI_INTERACTION_FAILED:"error.ui_interaction_failed",SYSTEM_ERROR:"error.system_error"};I();function tm(h){if(!h||typeof h.closest!="function")return null;let e=h.closest("[data-cb-instance]");if(e){let r=e.getAttribute("data-cb-instance");if(r)return r}let n=h.closest('svg[id^="chart-svg-"]')?.id;return n&&n.startsWith("chart-svg-")?n.slice(10):null}function Is(h,e){let t=h?.instanceId??null;return!t||!e?!0:t===e}I();I();I();I();var vc={clusteredBar:{label:"Clustered Bar",description:"Side-by-side bars comparing series within each category.",optionBag:"bar",family:"bar",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"clustered-bar"},stackedBar:{label:"Stacked Bar",description:"Bars stacked to show composition and category totals.",optionBag:"bar",family:"bar",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"stacked-bar"},stackedBar100:{label:"100% Stacked Bar",description:"Stacked bars normalized to 100% to compare mix, not size.",optionBag:"bar",family:"bar",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"stacked-bar"},line:{label:"Line Chart",description:"Trends over an ordered domain, one line per series.",optionBag:"line",family:"line",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"line"},area:{label:"Area Chart",description:"Filled lines showing magnitude over an ordered domain.",optionBag:"area",family:"area",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"area"},area100:{label:"100% Area Chart",description:"Area chart normalized to 100% to show changing mix.",optionBag:"area",family:"area",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"area"},pie:{label:"Pie Chart",description:"Share of a single total across categories.",optionBag:"pie",family:"pie",seriesLayout:"categoryValue",minRows:2,minCols:2,status:"stable",docsSlug:"pie"},scatter:{label:"Scatter Plot",description:"Points positioned by two metrics, optionally sized and grouped.",optionBag:"scatter",family:"scatter",seriesLayout:"pointRows",minRows:2,minCols:3,status:"stable",docsSlug:"scatter"},waterfall:{label:"Waterfall",description:"Running total showing how contributions bridge two values.",optionBag:"waterfall",family:"waterfall",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"waterfall"},mekko:{label:"Marimekko",description:"Variable-width stacked bars where both axes are percentages.",optionBag:"mekko",family:"mekko",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"mekko"},barMekko:{label:"Bar Mekko",description:"Bars whose width encodes one metric and height another; first data row sets widths.",optionBag:"barMekko",family:"mekko",seriesLayout:"widthRowThenHeightRows",minRows:3,minCols:2,status:"beta",docsSlug:"mekko"},combo:{label:"Combo Chart",description:"Mixed bar and line series on shared or dual axes.",optionBag:"combo",family:"combo",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"combo"}},Gh={bubble:"scatter",donut:"pie"},jF=[],wL={},Lv=Object.keys(vc).sort(),SL=Object.keys(Gh).sort(),nm=[...Lv,...SL].sort(),XF=SL.filter(h=>!jF.includes(h)),fN=[...Lv,...XF].sort(),rm="clusteredBar";function CL(h){return typeof h=="string"&&Object.prototype.hasOwnProperty.call(vc,h)}function Tv(h){return typeof h=="string"&&Object.prototype.hasOwnProperty.call(Gh,h)}function im(h){return CL(h)||Tv(h)}function Rs(h){return Tv(h)?Gh[h]:h}function Ev(h,e){let t=new Array(e.length+1),n=new Array(e.length+1);for(let r=0;r<=e.length;r++)t[r]=r;for(let r=1;r<=h.length;r++){n[0]=r;for(let i=1;i<=e.length;i++){let a=h[r-1]===e[i-1]?0:1;n[i]=Math.min(t[i]+1,n[i-1]+1,t[i-1]+a)}for(let i=0;i<=e.length;i++)t[i]=n[i]}return t[e.length]}function kL(h){let e=h.toLowerCase(),t=null,n=1/0;for(let i of nm){let a=Ev(e,i.toLowerCase());a<n&&(n=a,t=i)}let r=Math.max(2,Math.floor(e.length/3));return n<=r?t:null}function AL(h,e){return CL(h)?h:Tv(h)?Gh[h]:(typeof h=="string"&&h.length>0&&e?.(h),rm)}function ML(h){if(!h||typeof h!="object")return h;let e=h;if(typeof e.chartType=="string"){let t=Rs(e.chartType);t!==e.chartType&&(e.chartType=t)}for(let[t,n]of Object.entries(wL))e[t]!=null&&(e[n]==null&&(e[n]=e[t]),delete e[t]);return h}var KF=["bar","column","gantt","unknown"];function wc(h){return im(h)||KF.includes(h)}var uo=class{static createChart(e,t,n){return this.validateChartType(t),this.validateRequired(e,"chartId"),this.validateRequired(n,"source"),{chartId:e,chartType:t,timestamp:Date.now(),data:{source:n}}}static deleteChart(e,t,n){return this.validateChartType(t),this.validateRequired(e,"chartId"),this.validateRequired(n,"source"),{chartId:e,chartType:t,timestamp:Date.now(),data:{source:n}}}static changeChartType(e,t,n){return this.validateChartType(t),this.validateChartType(n),this.validateRequired(e,"chartId"),{chartId:e,chartType:n,timestamp:Date.now(),data:{oldChartType:t,newChartType:n}}}static downloadChart(e,t){return this.validateChartType(t),this.validateRequired(e,"chartId"),{chartId:e,chartType:t,timestamp:Date.now(),data:{}}}static openChart(e,t,n,r){return this.validateRequired(e,"chartId"),this.validateRequired(t,"source"),this.validateRequired(n,"action"),this.validateRequired(r,"trigger"),{chartId:e,chartType:"unknown",timestamp:Date.now(),data:{source:t,action:n,trigger:r}}}static saveChart(e,t,n){return this.validateChartType(t),this.validateRequired(e,"chartId"),{chartId:e,chartType:t,timestamp:Date.now(),data:{performance:n}}}static validateChartType(e){if(!wc(e))throw new Error(`Invalid chart type: ${e}. Must be one of: bar, line, pie, scatter, area, column, donut, waterfall, mekko, barMekko, clusteredBar, stackedBar, stackedBar100, bubble, unknown`)}static validateRequired(e,t){if(e==null||e==="")throw new Error(`Required field '${t}' is missing or empty`)}};I();I();var Cr=class{static operationFailed(e,t,n,r={}){if(this.validateRequired(t,"operation"),this.validateRequired(n,"component"),this.validateRequired(e,"error"),r.chart_type&&!wc(r.chart_type))throw new Error(`Invalid chart_type in error metadata: ${r.chart_type}`);return{error_name:e.name,error_message:e.message,stack_trace:e.stack?.substring(0,2e3),component:n,operation:t,chart_type:r.chart_type,timestamp:Date.now(),metadata:{...r,auto_tracked:!0}}}static uiInteractionFailed(e,t,n={}){if(this.validateRequired(t,"component"),this.validateRequired(e,"error"),n.chart_type&&!wc(n.chart_type))throw new Error(`Invalid chart_type in error metadata: ${n.chart_type}`);return{error_name:e.name,error_message:e.message,stack_trace:e.stack?.substring(0,2e3),component:t,chart_type:n.chart_type,timestamp:Date.now(),metadata:{...n,auto_tracked:!0}}}static systemError(e,t,n={}){return this.validateRequired(t,"component"),this.validateRequired(e,"error"),{error_name:e.name,error_message:e.message,stack_trace:e.stack?.substring(0,2e3),component:t,timestamp:Date.now(),metadata:{...n,auto_tracked:!0,system_level:!0}}}static validateRequired(e,t){if(e==null||e==="")throw new Error(`Required field '${t}' is missing or empty in error event`)}};I();var qt="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";var On=class h{constructor(e){this.isOpen=!1;this.clickOutsideHandler=null;this.eventBusUnsubscribe=null;this.eventBusUnsubscribeOpen=null;this.config=e;let{width:t="120px",zIndex:n=10001}=e;if(this.wrapper=document.createElement("div"),this.wrapper.className="cb-combobox-wrapper",this.wrapper.style.width=t,this.wrapper.style.fontFamily=qt,this.dropdown=document.createElement("div"),this.dropdown.className="cb-combobox-dropdown",this.dropdown.style.zIndex=String(n),this.dropdown.style.fontFamily=qt,this.isCustomMode()){let r=this.getCustomConfig();r.positioning==="fixed"&&r.anchorElement&&this.setupFixedPositioning(r.anchorElement)}this.setupBaseEventListeners(),this.setupEventBusListeners()}static{this.activeDropdown=null}static{this.DROPDOWN_STYLES=`
|
|
52
52
|
/* ComboBox Styles */
|
|
53
53
|
.cb-combobox-wrapper {
|
|
@@ -47,7 +47,7 @@ var PF=Object.create;var dv=Object.defineProperty;var IF=Object.getOwnPropertyDe
|
|
|
47
47
|
pointer-events: none;
|
|
48
48
|
font-size: 72px;
|
|
49
49
|
white-space: nowrap;
|
|
50
|
-
`,document.body.appendChild(t),this.warmupContainer=t,t}async warmUpFontsBlocking(e){let t=[...new Set(e.filter(i=>typeof i=="string").map(i=>i.trim()).filter(i=>i.length>0).filter(i=>!this.isSystemFont(i)))];if(t.length===0)return;if(this.loadGoogleFonts(t),document.readyState==="loading"||!document.body){await this.ensureFontsReady(t);return}let n=this.getWarmupContainer(),r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,;:!?";t.forEach(i=>{let a=`cb-font-warmup-${i.replace(/[^a-z0-9]+/gi,"-").toLowerCase()}`;if(!n.querySelector(`[data-font-warmup-id="${a}"]`)){let o=document.createElement("span");o.dataset.fontWarmupId=a,o.style.fontFamily=`"${i}"`,o.textContent=r,n.appendChild(o);let l=document.createElement("span");l.dataset.fontWarmupId=`${a}-bold`,l.style.fontFamily=`"${i}"`,l.style.fontWeight="700",l.textContent=r,n.appendChild(l);let d=document.createElement("span");d.dataset.fontWarmupId=`${a}-italic`,d.style.fontFamily=`"${i}"`,d.style.fontStyle="italic",d.textContent=r,n.appendChild(d)}}),n.offsetHeight,await this.ensureFontsReady(t),await this.markFontsWarmed(t)}loadFont(e){this.loadedFonts.has(e)||this.isSystemFont(e)||this.loadGoogleFonts([e])}ensureFontLoaded(e){this.isSystemFont(e)||this.loadedFonts.has(e)||this.loadGoogleFonts([e])}extractFontsFromChartData(e){let t=new Set;if(!e||typeof e!="object")return t;let n=(r,i=new WeakSet)=>{if(!(r===null||typeof r!="object")&&!i.has(r)){if(i.add(r),Array.isArray(r)){r.forEach(a=>n(a,i));return}if("fontFamily"in r&&typeof r.fontFamily=="string"&&r.fontFamily.trim()){let a=r.fontFamily.trim();this.isSystemFont(a)||t.add(a)}if("labelFontFamily"in r&&typeof r.labelFontFamily=="string"&&r.labelFontFamily.trim()){let a=r.labelFontFamily.trim();this.isSystemFont(a)||t.add(a)}for(let a in r)if(Object.prototype.hasOwnProperty.call(r,a))try{n(r[a],i)}catch{}}};return n(e),t}loadFontsFromChartData(e,t){if(!e)return;let n=this.extractFontsFromChartData(e);if(n.size===0){t&&t();return}let r=this.getAvailableFonts(),i=new Set(r.map(o=>o.toLowerCase())),a=Array.from(n).filter(o=>{let l=o.toLowerCase();return!(this.loadedFonts.has(o)||i.has(l))});if(a.length===0){console.log("[FontService] All fonts from chart data are already available (in cache/backend)"),t&&this.ensureFontsReady(Array.from(n)).then(()=>t()).catch(()=>t());return}console.log("[FontService] Loading fonts from chart data (not in organization list):",a),this.loadGoogleFonts(a),t&&this.ensureFontsReady(Array.from(n)).then(()=>t()).catch(()=>t())}getUnknownFontsFromChartData(e){if(!e)return[];let t=this.extractFontsFromChartData(e);if(t.size===0)return[];let n=new Set(this.getAvailableFonts().map(r=>r.toLowerCase()));return Array.from(t).filter(r=>this.loadedFonts.has(r)?!1:!n.has(r.toLowerCase()))}prepareFontsForChartData(e){if(!e)return{hasUnknownFonts:!1,readyPromise:Promise.resolve()};let t=this.extractFontsFromChartData(e);if(t.size===0)return{hasUnknownFonts:!1,readyPromise:Promise.resolve()};let n=this.getUnknownFontsFromChartData(e),r=n.length>0;return r&&console.log("[FontService] Blocking initial chart render for unknown fonts:",n),this.loadFontsFromChartData(e),{hasUnknownFonts:r,readyPromise:r?this.warmUpFontsBlocking(Array.from(t)):this.ensureFontsReady(Array.from(t))}}reset(){this.customFonts=[],this.loadedFonts.clear(),this.fontDeclarationPromises.clear(),this.fontReadyPromises.clear(),this.warmedFonts.clear(),this.initialized=!1,this.defaultFont="Arial",this.warmupContainer&&this.warmupContainer.parentNode&&this.warmupContainer.parentNode.removeChild(this.warmupContainer),this.warmupContainer=null,this.defaultFonts=["Arial","Calibri","Helvetica","Verdana","Tahoma","Trebuchet MS","Times New Roman","Courier New"]}},Ct=pv.getInstance()});var fL={};hv(fL,{colorService:()=>Sr,default:()=>WF});var gv,Sr,WF,_s=or(()=>{I();gv=class h{constructor(){this.defaultColors=["#98df8a","#17becf","#2c808c","#98df8a","#e377c2","#7f7f7f","#bcbd22","#17becf","#393b79","#637939","#8c6d31","#843c39","#7b4173","#a55194","#c7c7c7","#ffbb78","#98df8a","#ff9896","#ff7f0e","#2ca02c","#d62728","#9467bd","#8c564b","#e377c2","#7f7f7f","#bcbd22","#17becf","#393b79","#637939","#8c6d31","#843c39","#7b4173","#a55194","#c7c7c7","#ffbb78","#98df8a","#ff9896"];this.customColors=[];this.initialized=!1;this.resolveReady=()=>{};this.readyPromise=new Promise(e=>{this.resolveReady=e})}static getInstance(){return h.instance||(h.instance=new h),h.instance}initialize(e){console.log("[ColorService] Initializing with settings:",e),this.setOrganizationColors(e.colorScheme||[])}isInitialized(){return this.initialized}async ready(){return this.readyPromise}getAvailableColors(){let e=[];this.customColors&&this.customColors.length>0&&e.push(...this.customColors),e.push(...this.defaultColors),console.log("[ColorService] getAvailableColors result count:",e.length);let t=new Set;return e.filter(n=>{if(!n)return!1;let r=n.toUpperCase();return t.has(r)?!1:(t.add(r),!0)})}setOrganizationColors(e){this.customColors=Array.isArray(e)?[...e]:[],console.log("[ColorService] Organization colors updated:",this.customColors.length),this.initialized||(this.initialized=!0,this.resolveReady())}getDefaultColors(){return[...this.defaultColors]}getCustomColors(){return[...this.customColors]}hasColor(e){let t=this.getAvailableColors(),n=e.toUpperCase();return t.some(r=>r.toUpperCase()===n)}addCustomColor(e){let t=e.toUpperCase();this.customColors.some(n=>n.toUpperCase()===t)||this.customColors.push(e)}removeCustomColor(e){let t=e.toUpperCase();this.customColors=this.customColors.filter(n=>n.toUpperCase()!==t)}reset(){this.customColors=[],this.initialized=!1,this.defaultColors=["#242424","#484848","#6D6D6D","#919191","#B6B6B6","#DADADA","#FFFFFF","#8B0000","#FF4500","#FFD700","#ADFF2F","#1E90FF","#0000FF","#8B00FF","#FF00FF","#F1E6E6","#FFE6E6","#FFF0E6","#F2FFE6","#E6F3FF","#E6E6FF","#F3E6FF","#FFE6FF","#D9CCCC","#FFCCCC","#FFE1CC","#E6FFCC","#CCE6FF","#CCCCFF","#E6CCFF","#FFCCFF","#B38B8B","#FFB3B3","#FFD9B3","#CCFFB3","#B3CCFF","#B3B3FF","#CCB3FF","#FFB3FF","#806666","#E69999","#FFCC99","#99FF99","#99CCFF","#9999FF","#CC99FF","#FF99FF","#4D3333","#CC6666","#FFB366","#66CC66","#6699FF","#6666FF","#9966FF","#FF66FF"]}},Sr=gv.getInstance(),WF=Sr});function Aa(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(h){let e=Math.random()*16|0;return(h==="x"?e:e&3|8).toString(16)})}var Nh=or(()=>{I()});var co,jg=or(()=>{I();Nh();co=class{constructor(e,t="chart_",n=null){this.platform=e,this.storagePrefix=t,this.recentColorsKey="recent_colors",this.organizationColorsKey="organization_colors",this.presentationColorsKey="presentation_colors",this.maxRecentColors=8,this.chartbuddyUrl=n}setChartbuddyUrl(e){this.chartbuddyUrl=e}isStorageAvailable(){return!!this.platform}getStorageKey(e){return`${this.storagePrefix}${e}`}static generateUUID(){return Aa()}async removeItems(e,t){e.length>0&&this.platform&&(await this.platform.storage.remove(e),console.log(`[Storage] Removed keys: ${e.join(", ")}`)),t&&t()}async remove(e=null,t){if(!this.platform){t&&t();return}let n=await this.platform.storage.get(null),r=[];for(let i in n)(!e||i.startsWith(e))&&r.push(i);r.length>0&&(await this.platform.storage.remove(r),console.log(`[Storage] Removed ${r.length} keys with prefix: ${e||"all"}`)),t&&t()}async removeAllData(e){if(!this.platform){e&&e(new Error("Platform not initialized"));return}try{let t=await this.platform.storage.get(null),n=Object.keys(t);if(n.length===0){e&&e(null,0);return}await this.platform.storage.remove(n),console.log(`[Storage] Successfully removed all ${n.length} items`),e&&e(null,n.length)}catch(t){e&&e(t)}}async clearAll(e){return this.removeAllData(e)}async getOrganizationColors(e){if(!this.platform){console.warn("[Storage] Cannot get organization colors: Platform not initialized"),e([]);return}let n=(await this.platform.storage.get([this.organizationColorsKey]))[this.organizationColorsKey]||[];console.log(`[Storage] Retrieved ${n.length} organization colors from storage`),e(n)}async getDefaultColors(){return this.platform?(await this.platform.storage.get([this.organizationColorsKey]))[this.organizationColorsKey]||[]:[]}async setOrganizationColors(e,t){if(!Array.isArray(e)||!this.platform){console.warn("[Storage] Cannot set organization colors: Invalid input or platform not initialized"),t&&t();return}console.log(`[Storage] Persisting ${e.length} organization colors to storage`),await this.platform.storage.set({[this.organizationColorsKey]:e}),t&&t()}async clearOrganizationColors(e){if(!this.platform){e&&e();return}await this.platform.storage.remove([this.organizationColorsKey]),e&&e()}async getPresentationColors(e,t){if(!e||!this.platform){t([]);return}let n=`${this.presentationColorsKey}_${e}`,r=await this.platform.storage.get([n]);t(r[n]||[])}async setPresentationColors(e,t,n){if(!e||!Array.isArray(t)||!this.platform){n&&n();return}let r=`${this.presentationColorsKey}_${e}`;await this.platform.storage.set({[r]:t}),n&&n()}async getRecentColors(e){if(!this.platform){e([]);return}let t=await this.platform.storage.get([this.recentColorsKey]);e(t[this.recentColorsKey]||[])}async addRecentColor(e,t){let n=this.normalizeColorToHex(e);if(!n||!this.platform){t&&t([]);return}this.getRecentColors(async r=>{r=r.filter(i=>i!==n),r.unshift(n),r=r.slice(0,this.maxRecentColors),this.platform&&await this.platform.storage.set({[this.recentColorsKey]:r}),t&&t(r)})}async clearRecentColors(e){this.platform&&await this.platform.storage.remove([this.recentColorsKey]),e&&e()}static googleRgbToHex(e){if(!e)return null;let t=Math.round((e.red||0)*255),n=Math.round((e.green||0)*255),r=Math.round((e.blue||0)*255);return`#${t.toString(16).padStart(2,"0")}${n.toString(16).padStart(2,"0")}${r.toString(16).padStart(2,"0")}`}normalizeColorToHex(e){if(!e||typeof e!="string")return null;let t=e.trim();if(t.startsWith("#")){let r=t.toUpperCase();return r.length===4&&(r="#"+r[1]+r[1]+r[2]+r[2]+r[3]+r[3]),/^#[0-9A-F]{6}$/.test(r)?r:null}if(/^[0-9A-Fa-f]{6}$/.test(t))return"#"+t.toUpperCase();let n=t.match(/^rgba?\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*[\d.]+)?\s*\)$/i);if(n){let r=Math.min(255,Math.max(0,parseInt(n[1],10))),i=Math.min(255,Math.max(0,parseInt(n[2],10))),a=Math.min(255,Math.max(0,parseInt(n[3],10)));return"#"+r.toString(16).padStart(2,"0").toUpperCase()+i.toString(16).padStart(2,"0").toUpperCase()+a.toString(16).padStart(2,"0").toUpperCase()}return null}async saveLastOpenedChartId(e){await this.platform.storage.set({lastOpenedChartId:e})}async getLastOpenedChartId(e){let t=await this.platform.storage.get(["lastOpenedChartId"]);e(t.lastOpenedChartId||null)}async getTemplates(){if(!this.chartbuddyUrl)return[];try{let t=(await this.platform.storage.get(["token"])).token;if(!t)return[];let n=await fetch(`${this.chartbuddyUrl}/api/chart-templates`,{method:"GET",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"}});if(n.ok){let r=await n.json();return Array.isArray(r)?r:r?.data&&Array.isArray(r.data)?r.data:[]}}catch(e){console.error("[Storage] Failed to fetch templates:",e)}return[]}}});var Mi,ho,bc=or(()=>{I();Mi="1.7.52",ho="chart-buddy"});var mv,bv,yv,Vh,pL=or(()=>{I();jg();bc();mv=class{async get(e){return new Promise(t=>{chrome.storage.local.get(e,n=>{t(n)})})}async set(e){return new Promise(t=>{chrome.storage.local.set(e,()=>{t()})})}async remove(e){return new Promise(t=>{chrome.storage.local.remove(e,()=>{t()})})}async clear(){return new Promise(e=>{chrome.storage.local.clear(()=>{e()})})}},bv=class{getURL(e){return chrome.runtime.getURL(e)}getVersion(){return Mi}getAppName(){return ho}isDevelopmentBuild(){return!1}getManifest(){return chrome.runtime.getManifest()}async sendMessage(e){return new Promise((t,n)=>{chrome.runtime.sendMessage(e,r=>{chrome.runtime.lastError?n(chrome.runtime.lastError):t(r)})})}},yv=class{detect(){let e=window.location.href;return e.includes("canva.com")?"Canva":e.includes("docs.google.com/presentation")?"GSlides":e.includes("docs.google.com/spreadsheets")||e.includes("sheets.google.com")?"GSheets":e.includes("notion.com")||e.includes("notion.so")?"Notion":e.includes("figma.com")?"Figma":e.includes("miro.com")?"Miro":e.includes("powerbi.com")?"PowerBI":e.includes("onedrive.live.com")||e.includes("microsoft365.com")?"PowerPoint":"WebApp"}getPresentationId(){let t=window.location.href.match(/\/presentation\/d\/([a-zA-Z0-9-_]+)/);return t?t[1]:null}},Vh=class{constructor(){this.type="extension";this.storage=new mv;this.runtime=new bv;this.host=new yv;this.chartBuddyStorage=new co(this)}};typeof window<"u"&&(window.ChromeExtensionProvider=Vh)});var xv,vv,wv,Os,Sv=or(()=>{I();jg();bc();xv=class{constructor(){this.prefix="cb_"}async get(e){let t={},n=[];return typeof e=="string"?n=[e]:Array.isArray(e)?n=e:e&&typeof e=="object"&&(n=Object.keys(e),Object.assign(t,e)),n.forEach(r=>{let i=localStorage.getItem(this.prefix+r);if(i!==null)try{t[r]=JSON.parse(i)}catch{t[r]=i}}),t}async set(e){Object.entries(e).forEach(([t,n])=>{localStorage.setItem(this.prefix+t,JSON.stringify(n))})}async remove(e){(Array.isArray(e)?e:[e]).forEach(n=>localStorage.removeItem(this.prefix+n))}async clear(){Object.keys(localStorage).forEach(e=>{e.startsWith(this.prefix)&&localStorage.removeItem(e)})}},vv=class{getURL(e){return e}getVersion(){return Mi}getAppName(){return ho}isDevelopmentBuild(){return!1}getManifest(){return{version:Mi,name:ho,_sys_ctx:this.isDevelopmentBuild()?"d8n3x5q1":"kz6p9m2v"}}async sendMessage(e){return console.log("[WebApp] Mock sendMessage:",e),null}},wv=class{detect(){return"WebApp"}getPresentationId(){return"webapp-mock-presentation-id"}},Os=class{constructor(){this.type="webapp";this.storage=new xv;this.runtime=new vv;this.host=new wv;this.chartBuddyStorage=new co(this)}};typeof window<"u"&&(window.WebAppProvider=Os)});function yc(){if(typeof window>"u")return!1;let h=window;return typeof h.__TAURI__<"u"||typeof h.__TAURI_INTERNALS__<"u"?!0:typeof navigator<"u"&&/tauri/i.test(navigator.userAgent)}var Cv,kv,Av,Xg,zh=or(()=>{I();jg();bc();Cv=class{constructor(){this.prefix="cb_";this.map=new Map}storageKey(e){return`${this.prefix}${e}`}async get(e){let t={},n=[];return typeof e=="string"?n=[e]:Array.isArray(e)?n=e:e&&typeof e=="object"&&(n=Object.keys(e),Object.assign(t,e)),n.forEach(r=>{let i=this.map.get(this.storageKey(r));if(i!==void 0)try{t[r]=JSON.parse(i)}catch{t[r]=i}}),t}async set(e){Object.entries(e).forEach(([t,n])=>{this.map.set(this.storageKey(t),JSON.stringify(n))})}async remove(e){(Array.isArray(e)?e:[e]).forEach(n=>this.map.delete(this.storageKey(n)))}async clear(){let e=[];this.map.forEach((t,n)=>{n.startsWith(this.prefix)&&e.push(n)}),e.forEach(t=>this.map.delete(t))}},kv=class{getURL(e){return e}getVersion(){return Mi}getAppName(){return ho}isDevelopmentBuild(){return!1}getManifest(){return{version:Mi,name:ho,_sys_ctx:this.isDevelopmentBuild()?"d8n3x5q1":"kz6p9m2v"}}async sendMessage(e){return console.log("[Tauri] sendMessage (no-op):",e),null}},Av=class{detect(){return"Tauri"}getPresentationId(){return"tauri-desktop"}},Xg=class{constructor(){this.type="tauri";this.storage=new Cv;this.runtime=new kv;this.host=new Av;this.chartBuddyStorage=new co(this)}}});var _r,Mv,Hh=or(()=>{I();pL();Sv();zh();_r=class{static setPlatform(e){this.instance=e}static getPlatform(){let e=yc();return e&&this.instance!==void 0&&this.instance.type!=="tauri"&&(this.instance=void 0),this.instance?this.instance:e?(this.instance=new Xg,this.instance):(typeof chrome<"u"&&chrome.runtime&&typeof chrome.runtime.getURL=="function"&&!!chrome.runtime.id?this.instance=new Vh:this.instance=new Os,this.instance)}},Mv=_r.getPlatform()});var XF,Dv,Ei,tm,kL=or(()=>{I();XF=["Arial","Calibri","Helvetica","Verdana","Tahoma","Trebuchet MS","Times New Roman","Courier New"],Dv={isExpired:!1,isActive:!0,daysRemaining:null,expiresAt:null},Ei={uploadMethod:"google-drive",featureFlags:{},canManageFeatureFlags:!1,organizationSettings:{colorScheme:["#3B82F6","#10B981","#F59E0B","#9fa90f"],fonts:XF,customFonts:[],defaultFont:"Arial"},trialStatus:Dv},tm={production:"https://chartbuddy.io",acceptance:"https://cb-acc.xyz",current:"production"}});function _v(h){if(h.fonts!==void 0){if(!Array.isArray(h.fonts))return console.warn("[FontCacheManager] Invalid fonts: expected array, got",typeof h.fonts),!1;if(!h.fonts.every(e=>typeof e=="string"&&e.trim().length>0))return console.warn("[FontCacheManager] Invalid fonts: contains non-string or empty values"),!1}if(h.customFonts!==void 0){if(!Array.isArray(h.customFonts))return console.warn("[FontCacheManager] Invalid customFonts: expected array, got",typeof h.customFonts),!1;if(!h.customFonts.every(e=>typeof e=="string"&&e.trim().length>0))return console.warn("[FontCacheManager] Invalid customFonts: contains non-string or empty values"),!1}return h.useDefaultFonts!==void 0&&typeof h.useDefaultFonts!="boolean"?(console.warn("[FontCacheManager] Invalid useDefaultFonts: expected boolean, got",typeof h.useDefaultFonts),!1):!0}var nm,Fs,Ov=or(()=>{I();Hh();nm=class h{static{this.STORAGE_KEY="chartbuddy_fonts_cache"}static{this.CACHE_VERSION="1.0"}constructor(){}static getInstance(){return h.instance||(h.instance=new h),h.instance}async getCachedFonts(){try{let t=(await _r.getPlatform().storage.get([h.STORAGE_KEY]))[h.STORAGE_KEY];if(!t)return null;if(typeof t!="object"||t===null)return console.warn("[FontCacheManager] Invalid cache data type, clearing"),await this.clearCache(),null;if(t.version!==h.CACHE_VERSION)return console.log("[FontCacheManager] Cache version mismatch, invalidating"),await this.clearCache(),null;let n={fonts:t.fonts,customFonts:t.customFonts,defaultFont:t.defaultFont,useDefaultFonts:t.useDefaultFonts};return _v(n)?(console.log("[FontCacheManager] Loaded fonts from cache:",{defaultFont:t.defaultFont,fonts:t.fonts?.length??0,customFonts:t.customFonts?.length??0,cachedAt:new Date(t.cachedAt).toISOString()}),n):(console.warn("[FontCacheManager] Cached data validation failed, clearing cache"),await this.clearCache(),null)}catch(e){return console.warn("[FontCacheManager] Failed to get cached fonts:",e),null}}async saveFontsToCache(e){if(!_v(e))throw new Error("[FontCacheManager] Invalid font settings, cannot save to cache");try{let t={fonts:e.fonts,customFonts:e.customFonts,defaultFont:e.defaultFont,useDefaultFonts:e.useDefaultFonts,cachedAt:Date.now(),version:h.CACHE_VERSION},r=JSON.stringify(t).length,i=100*1024;r>i&&(console.warn(`[FontCacheManager] Cache size (${r} bytes) exceeds limit (${i} bytes), clearing old cache`),await this.clearCache()),await _r.getPlatform().storage.set({[h.STORAGE_KEY]:t})}catch(t){throw console.error("[FontCacheManager] Failed to save fonts to cache:",t),t}}async validateAndSyncFonts(e){if(!_v(e))return console.warn("[FontCacheManager] Invalid backend font settings, using cached data"),{hasChanges:!1,fonts:await this.getCachedFonts()??{fonts:[],customFonts:[],defaultFont:"Arial",useDefaultFonts:!0}};let t=null;try{console.log("[FontCacheManager] Validating fonts against cache..."),t=await this.getCachedFonts();let n=this.fontsHaveChanged(t,e);return n&&await this.saveFontsToCache(e),{hasChanges:n,fonts:e}}catch(n){return console.error("[FontCacheManager] Error validating fonts:",n),{hasChanges:!1,fonts:t??{fonts:[],customFonts:[],defaultFont:"Arial",useDefaultFonts:!0}}}}fontsHaveChanged(e,t){if(!e)return!0;let n=(r,i)=>!r&&!i?!0:!r||!i||r.length!==i.length?!1:r.every((a,o)=>a===i[o]);return!n(e.fonts,t.fonts)||!n(e.customFonts,t.customFonts)||e.defaultFont!==t.defaultFont||e.useDefaultFonts!==t.useDefaultFonts}async clearCache(){try{await _r.getPlatform().storage.remove([h.STORAGE_KEY]),console.log("[FontCacheManager] Cache cleared")}catch(e){console.warn("[FontCacheManager] Failed to clear cache:",e)}}},Fs=nm.getInstance()});var ML={};hv(ML,{CHARTBUDDY_CONFIG_UPDATED_EVENT:()=>AL,ConfigManager:()=>pt,getConfigManager:()=>Or});function Or(){return pt.getInstance()}var AL,pt,Kn=or(()=>{I();kL();Hh();Ai();Ov();_s();AL="chartbuddy:config-updated",pt=class h{constructor(){this.debugEnabled=!1;this.debugAxisBinding=!0;this.loadingPromise=void 0;this.fontPreloadPromise=void 0;this.onLoadCallbacks=[];if(this.config={chartbuddyUrl:this.detectEnvironmentUrl(),bootOptions:{...Ei},environment:{...tm},loaded:!1,loadedAt:void 0},this.config.environment.current=this.detectEnvironment(),this.debugEnabled=this.computeDebugEnabled(this.config.chartbuddyUrl),typeof window<"u"&&window.localStorage)try{window.localStorage.getItem("CHARTBUDDY_DEBUG_MODE")==="true"&&(this.debugEnabled=!0),window.localStorage.getItem("CHARTBUDDY_DEBUG_AXIS_BINDING")==="false"&&(this.debugAxisBinding=!1)}catch{}}static{this.instance=void 0}computeDebugEnabled(e){let t=e.includes("cb-acc.xyz")||e.includes("stag"),n=e.includes("localhost")||e.includes("127.0.0.1"),r=_r.getPlatform().runtime.isDevelopmentBuild();return t||n||r}static getInstance(){return h.instance===void 0&&(h.instance=new h),h.instance}isDebugEnabled(){return this.debugEnabled}isDebugAxisBindingEnabled(){return this.debugAxisBinding}isWaterfallSegmentedBarsEnabled(){return!0}isChartOrientationEnabled(){return!0}isBarMekkoEnabled(){return this.config?.bootOptions?.featureFlags?.barMekko===!0}isDevelopment(){let e=this.config.chartbuddyUrl;return e.includes("localhost")||e.includes("127.0.0.1")}isAcceptance(){return this.config.chartbuddyUrl.includes("cb-acc.xyz")}isProduction(){return!this.isDevelopment()&&!this.isAcceptance()}setDebugMode(e){this.debugEnabled=e}setDebugAxisBindingMode(e){this.debugAxisBinding=e}detectEnvironmentUrl(){return tm.production}detectEnvironment(){return this.config.chartbuddyUrl.includes("cb-acc.xyz")?"acceptance":"production"}getConfig(){return{...this.config}}getChartbuddyUrl(){return this.config.chartbuddyUrl}getBootOptions(){return{...this.config.bootOptions}}getEnvironment(){return{...this.config.environment}}getTrialStatus(){return{...this.config.bootOptions.trialStatus}}isTrialExpired(){return this.config.bootOptions.trialStatus.isExpired}isLoaded(){return this.config.loaded}onLoad(e){this.config.loaded?e():this.onLoadCallbacks.push(e)}setChartbuddyUrl(e){this.config.chartbuddyUrl=e,this.config.environment.current=this.detectEnvironment(),this.debugEnabled=this.computeDebugEnabled(e)}async loadConfig(){if(this.loadingPromise)return this.loadingPromise;if(this.config.loaded&&this.config.loadedAt&&Date.now()-this.config.loadedAt<3e5){console.log("[ConfigManager] Config already loaded recently, skipping reload");return}this.loadingPromise=this.loadConfigInternal();try{await this.loadingPromise}finally{this.loadingPromise=void 0}}async preloadFontSettings(){if(this.fontPreloadPromise)return this.fontPreloadPromise;this.fontPreloadPromise=this.preloadFontSettingsInternal();try{await this.fontPreloadPromise}finally{this.fontPreloadPromise=void 0}}async loadConfigInternal(){try{if(_r.getPlatform().type==="webapp"){console.log("[ConfigManager] Standalone mode (WebApp): using local defaults"),this.config.bootOptions={...Ei},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks();return}console.log("[ConfigManager] Loading configuration from backend...");let t=await this.getAuthToken();if(!t){console.warn("[ConfigManager] No authentication token available, using defaults"),Fs.clearCache().catch(r=>{console.warn("[ConfigManager] Failed to clear font cache on auth failure:",r)}),this.config.bootOptions={...Ei},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks();return}let n=await this.fetchAuthenticatedJson("/api/user/boot-settings",t);if(n.ok){let r=await n.json(),i=r.uploadMethod??Ei.uploadMethod,a=r.featureFlags??Ei.featureFlags,o=r.canManageFeatureFlags??Ei.canManageFeatureFlags,l=r.organizationSettings??Ei.organizationSettings,d=r.trialStatus??Dv;this.config.bootOptions={uploadMethod:i,featureFlags:a,canManageFeatureFlags:o,organizationSettings:l,trialStatus:d},console.log("[ConfigManager] Organization Settings received:",{colorSchemeCount:l.colorScheme?.length||0,fontCount:l.fonts?.length||0}),this.config.loaded=!0,this.config.loadedAt=Date.now(),console.log("[ConfigManager] \u2705 Configuration loaded successfully:",{uploadMethod:this.config.bootOptions.uploadMethod,loadedAt:new Date(this.config.loadedAt).toISOString()}),await this.initializeFontService(),this.initializeColorService();let u={fonts:l.fonts??[],customFonts:l.customFonts??[],defaultFont:l.defaultFont??"Noto Sans"};this.validateFontCache(u).catch(g=>{console.warn("[ConfigManager] Background font validation failed:",g)}),this.triggerOnLoadCallbacks()}else console.warn(`[ConfigManager] Failed to fetch boot settings (HTTP ${n.status}), using defaults`),(n.status===401||n.status===403)&&Fs.clearCache().catch(r=>{console.warn("[ConfigManager] Failed to clear font cache on auth failure:",r)}),this.config.bootOptions={...Ei},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks()}catch(e){console.error("[ConfigManager] Error loading configuration:",e),console.log("[ConfigManager] Using default configuration"),this.config.bootOptions={...Ei},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks()}}async preloadFontSettingsInternal(){try{let e=await this.getAuthToken();if(!e)return;let t=await this.fetchAuthenticatedJson("/api/user/font-settings",e);if(!t.ok){(t.status===401||t.status===403)&&Fs.clearCache().catch(r=>{console.warn("[ConfigManager] Failed to clear font cache on preload auth failure:",r)});return}let n=await t.json();Ct.isInitialized()?Ct.reinitialize(n):Ct.primeEarly(n)}catch(e){console.warn("[ConfigManager] Font preload failed:",e)}}triggerOnLoadCallbacks(){console.log(`[ConfigManager] Triggering ${this.onLoadCallbacks.length} onLoad callbacks`),this.onLoadCallbacks.forEach(e=>{try{e()}catch(t){console.error("[ConfigManager] Error in onLoad callback:",t)}}),this.onLoadCallbacks=[],typeof window<"u"&&window.dispatchEvent(new CustomEvent(AL,{detail:{bootOptions:this.getBootOptions(),loadedAt:this.config.loadedAt}}))}async initializeFontService(){if(Ct.isInitialized()){console.log("[ConfigManager] FontService already initialized, skipping");return}try{let e=await Fs.getCachedFonts();if(e){Ct.initialize(e);return}let t=this.config.bootOptions.organizationSettings,n={fonts:t.fonts??[],customFonts:t.customFonts??[],defaultFont:t.defaultFont??"Noto Sans"};Ct.initialize(n)}catch(e){console.warn("[ConfigManager] Failed to initialize FontService:",e)}}initializeColorService(){try{let t=this.config.bootOptions.organizationSettings.colorScheme||[];Sr.initialize({colorScheme:t});let n=_r.getPlatform();n&&n.chartBuddyStorage&&n.chartBuddyStorage.setOrganizationColors(t).then(()=>console.log("[ConfigManager] Organization colors persisted to storage")).catch(r=>console.warn("[ConfigManager] Failed to persist organization colors:",r)),console.log("[ConfigManager] ColorService initialized")}catch(e){console.warn("[ConfigManager] Failed to initialize ColorService:",e)}}async validateFontCache(e){try{let t=await Fs.validateAndSyncFonts(e);t.hasChanges?(console.log("[ConfigManager] Font settings changed, updating"),Ct.reinitialize(t.fonts)):console.log("[ConfigManager] Font settings unchanged, keeping current initialization")}catch(t){console.warn("[ConfigManager] Font validation failed:",t)}}async getAuthToken(){return(await this.getChromeStorage(["token"])).token}fetchAuthenticatedJson(e,t){return fetch(`${this.config.chartbuddyUrl}${e}`,{method:"GET",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"}})}async getChromeStorage(e){try{let t=await _r.getPlatform().storage.get(e),n={};for(let r of e)n[r]=t[r];return n}catch(t){return console.warn("[ConfigManager] Failed to get chrome storage:",t),{}}}async reloadConfig(){this.config.loaded=!1,this.config.loadedAt=void 0,await this.loadConfig()}reset(){this.config={chartbuddyUrl:this.detectEnvironmentUrl(),bootOptions:{...Ei},environment:{...tm},loaded:!1,loadedAt:void 0},this.config.environment.current=this.detectEnvironment(),this.loadingPromise=void 0,this.fontPreloadPromise=void 0}}});var Xv=$F((Yv,jv)=>{I();(h=>{let e=(()=>{let _=0;return{escape:function(Y){return Y.replace(/([.*+?^${}()|[\]/\\])/g,"\\$1")},isDataUrl:function(Y){return Y.search(/^(data:)/)!==-1},canvasToBlob:function(Y){return Y.toBlob?new Promise(function(J){Y.toBlob(J)}):(J=>new Promise(function(te){var ae=g(J.toDataURL().split(",")[1]),re=ae.length,le=new Uint8Array(re);for(let ye=0;ye<re;ye++)le[ye]=ae.charCodeAt(ye);te(new Blob([le],{type:"image/png"}))}))(Y)},resolveUrl:function(Y,J){var te=document.implementation.createHTMLDocument(),ae=te.createElement("base"),re=(te.head.appendChild(ae),te.createElement("a"));return te.body.appendChild(re),ae.href=J,re.href=Y,re.href},getAndEncode:function(Y){let J=l.impl.urlCache.find(function(te){return te.url===Y});return J||(J={url:Y,promise:null},l.impl.urlCache.push(J)),J.promise===null&&(l.impl.options.cacheBust&&(Y+=(/\?/.test(Y)?"&":"?")+new Date().getTime()),J.promise=new Promise(function(te){let ae=new XMLHttpRequest;function re(Q){console.error(Q),te("")}function le(){var Q=l.impl.options.imagePlaceholder;Q?te(Q):re("Status:"+ae.status+" while fetching resource: "+Y)}if(ae.timeout=l.impl.options.httpTimeout,ae.onerror=le,ae.ontimeout=le,ae.onloadend=function(){if(ae.readyState===XMLHttpRequest.DONE){var Q=ae.status;if(Q===0&&Y.toLowerCase().startsWith("file://")||200<=Q&&Q<=300&&ae.response!==null){Q=ae.response,Q instanceof Blob||re("Expected response to be a Blob, but got: "+typeof Q);let de=new FileReader;de.onloadend=function(){var me=de.result;te(me)};try{de.readAsDataURL(Q)}catch(me){re("Failed to read the response as Data URL: "+me.toString())}}else le()}},0<l.impl.options.useCredentialsFilters.length&&(l.impl.options.useCredentials=0<l.impl.options.useCredentialsFilters.filter(Q=>0<=Y.search(Q)).length),l.impl.options.useCredentials&&(ae.withCredentials=!0),l.impl.options.corsImg&&Y.indexOf("http")===0&&Y.indexOf(window.location.origin)===-1){var ye=(l.impl.options.corsImg.method||"GET").toUpperCase()==="POST"?"POST":"GET";ae.open(ye,(l.impl.options.corsImg.url||"").replace("#{cors}",Y),!0);let Q=!1,de=l.impl.options.corsImg.headers||{},me=(Object.keys(de).forEach(function(Se){de[Se].indexOf("application/json")!==-1&&(Q=!0),ae.setRequestHeader(Se,de[Se])}),(Se=>{try{return JSON.parse(JSON.stringify(Se))}catch(Ce){re("corsImg.data is missing or invalid:"+Ce.toString())}})(l.impl.options.corsImg.data||""));Object.keys(me).forEach(function(Se){typeof me[Se]=="string"&&(me[Se]=me[Se].replace("#{cors}",Y))}),ae.responseType="blob",ae.send(Q?JSON.stringify(me):me)}else ae.open("GET",Y,!0),ae.responseType="blob",ae.send()})),J.promise},uid:function(){return"u"+("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)+_++},asArray:function(Y){var J=[],te=Y.length;for(let ae=0;ae<te;ae++)J.push(Y[ae]);return J},escapeXhtml:function(Y){return Y.replace(/%/g,"%25").replace(/#/g,"%23").replace(/\n/g,"%0A")},makeImage:function(Y){return Y!=="data:,"?new Promise(function(J,te){let ae=document.createElementNS("http://www.w3.org/2000/svg","svg"),re=new Image;l.impl.options.useCredentials&&(re.crossOrigin="use-credentials"),re.onload=function(){document.body.removeChild(ae),window&&window.requestAnimationFrame?window.requestAnimationFrame(function(){J(re)}):J(re)},re.onerror=le=>{document.body.removeChild(ae),te(le)},ae.appendChild(re),re.src=Y,document.body.appendChild(ae)}):Promise.resolve()},width:function(Y){var J=U(Y,"width");if(!isNaN(J))return J;var J=U(Y,"border-left-width"),te=U(Y,"border-right-width");return Y.scrollWidth+J+te},height:function(Y){var J=U(Y,"height");if(!isNaN(J))return J;var J=U(Y,"border-top-width"),te=U(Y,"border-bottom-width");return Y.scrollHeight+J+te},getWindow:P,isElement:q,isElementHostForOpenShadowRoot:function(Y){return q(Y)&&Y.shadowRoot!==null},isShadowRoot:$,isInShadowRoot:V,isHTMLElement:function(Y){return Y instanceof P(Y).HTMLElement},isHTMLCanvasElement:function(Y){return Y instanceof P(Y).HTMLCanvasElement},isHTMLInputElement:function(Y){return Y instanceof P(Y).HTMLInputElement},isHTMLImageElement:function(Y){return Y instanceof P(Y).HTMLImageElement},isHTMLLinkElement:function(Y){return Y instanceof P(Y).HTMLLinkElement},isHTMLScriptElement:function(Y){return Y instanceof P(Y).HTMLScriptElement},isHTMLStyleElement:function(Y){return Y instanceof P(Y).HTMLStyleElement},isHTMLTextAreaElement:function(Y){return Y instanceof P(Y).HTMLTextAreaElement},isShadowSlotElement:function(Y){return V(Y)&&Y instanceof P(Y).HTMLSlotElement},isSVGElement:function(Y){return Y instanceof P(Y).SVGElement},isSVGRectElement:function(Y){return Y instanceof P(Y).SVGRectElement},isDimensionMissing:function(Y){return isNaN(Y)||Y<=0}};function P(Y){return Y=Y?Y.ownerDocument:void 0,(Y?Y.defaultView:void 0)||window||h}function $(Y){return Y instanceof P(Y).ShadowRoot}function V(Y){return Y!=null&&Y.getRootNode!==void 0&&$(Y.getRootNode())}function q(Y){return Y instanceof P(Y).Element}function U(Y,J){if(Y.nodeType===d){let te=u(Y).getPropertyValue(J);if(te.slice(-2)==="px")return te=te.slice(0,-2),parseFloat(te)}return NaN}})(),t=(()=>{let _=/url\(\s*(["']?)((?:\\.|[^\\)])+)\1\s*\)/gm;return{inlineAll:function(U,Y,J){return P(U)?Promise.resolve(U).then($).then(function(te){let ae=Promise.resolve(U);return te.forEach(function(re){ae=ae.then(function(le){return q(le,re,Y,J)})}),ae}):Promise.resolve(U)},shouldProcess:P,impl:{readUrls:$,inline:q,urlAsRegex:V}};function P(U){return U.search(_)!==-1}function $(U){for(var Y,J=[];(Y=_.exec(U))!==null;)J.push(Y[2]);return J.filter(function(te){return!e.isDataUrl(te)})}function V(U){return new RegExp(`url\\((["']?)(${e.escape(U)})\\1\\)`,"gm")}function q(U,Y,J,te){return Promise.resolve(Y).then(function(ae){return J?e.resolveUrl(ae,J):ae}).then(te||e.getAndEncode).then(function(ae){var re=V(Y);return U.replace(re,`url($1${ae}$1)`)})}})(),n={resolveAll:function(){return r().then(function(_){return Promise.all(_.map(function(P){return P.resolve()}))}).then(function(_){return _.join(`
|
|
50
|
+
`,document.body.appendChild(t),this.warmupContainer=t,t}async warmUpFontsBlocking(e){let t=[...new Set(e.filter(i=>typeof i=="string").map(i=>i.trim()).filter(i=>i.length>0).filter(i=>!this.isSystemFont(i)))];if(t.length===0)return;if(this.loadGoogleFonts(t),document.readyState==="loading"||!document.body){await this.ensureFontsReady(t);return}let n=this.getWarmupContainer(),r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,;:!?";t.forEach(i=>{let a=`cb-font-warmup-${i.replace(/[^a-z0-9]+/gi,"-").toLowerCase()}`;if(!n.querySelector(`[data-font-warmup-id="${a}"]`)){let o=document.createElement("span");o.dataset.fontWarmupId=a,o.style.fontFamily=`"${i}"`,o.textContent=r,n.appendChild(o);let l=document.createElement("span");l.dataset.fontWarmupId=`${a}-bold`,l.style.fontFamily=`"${i}"`,l.style.fontWeight="700",l.textContent=r,n.appendChild(l);let d=document.createElement("span");d.dataset.fontWarmupId=`${a}-italic`,d.style.fontFamily=`"${i}"`,d.style.fontStyle="italic",d.textContent=r,n.appendChild(d)}}),n.offsetHeight,await this.ensureFontsReady(t),await this.markFontsWarmed(t)}loadFont(e){this.loadedFonts.has(e)||this.isSystemFont(e)||this.loadGoogleFonts([e])}ensureFontLoaded(e){this.isSystemFont(e)||this.loadedFonts.has(e)||this.loadGoogleFonts([e])}extractFontsFromChartData(e){let t=new Set;if(!e||typeof e!="object")return t;let n=(r,i=new WeakSet)=>{if(!(r===null||typeof r!="object")&&!i.has(r)){if(i.add(r),Array.isArray(r)){r.forEach(a=>n(a,i));return}if("fontFamily"in r&&typeof r.fontFamily=="string"&&r.fontFamily.trim()){let a=r.fontFamily.trim();this.isSystemFont(a)||t.add(a)}if("labelFontFamily"in r&&typeof r.labelFontFamily=="string"&&r.labelFontFamily.trim()){let a=r.labelFontFamily.trim();this.isSystemFont(a)||t.add(a)}for(let a in r)if(Object.prototype.hasOwnProperty.call(r,a))try{n(r[a],i)}catch{}}};return n(e),t}loadFontsFromChartData(e,t){if(!e)return;let n=this.extractFontsFromChartData(e);if(n.size===0){t&&t();return}let r=this.getAvailableFonts(),i=new Set(r.map(o=>o.toLowerCase())),a=Array.from(n).filter(o=>{let l=o.toLowerCase();return!(this.loadedFonts.has(o)||i.has(l))});if(a.length===0){console.log("[FontService] All fonts from chart data are already available (in cache/backend)"),t&&this.ensureFontsReady(Array.from(n)).then(()=>t()).catch(()=>t());return}console.log("[FontService] Loading fonts from chart data (not in organization list):",a),this.loadGoogleFonts(a),t&&this.ensureFontsReady(Array.from(n)).then(()=>t()).catch(()=>t())}getUnknownFontsFromChartData(e){if(!e)return[];let t=this.extractFontsFromChartData(e);if(t.size===0)return[];let n=new Set(this.getAvailableFonts().map(r=>r.toLowerCase()));return Array.from(t).filter(r=>this.loadedFonts.has(r)?!1:!n.has(r.toLowerCase()))}prepareFontsForChartData(e){if(!e)return{hasUnknownFonts:!1,readyPromise:Promise.resolve()};let t=this.extractFontsFromChartData(e);if(t.size===0)return{hasUnknownFonts:!1,readyPromise:Promise.resolve()};let n=this.getUnknownFontsFromChartData(e),r=n.length>0;return r&&console.log("[FontService] Blocking initial chart render for unknown fonts:",n),this.loadFontsFromChartData(e),{hasUnknownFonts:r,readyPromise:r?this.warmUpFontsBlocking(Array.from(t)):this.ensureFontsReady(Array.from(t))}}reset(){this.customFonts=[],this.loadedFonts.clear(),this.fontDeclarationPromises.clear(),this.fontReadyPromises.clear(),this.warmedFonts.clear(),this.initialized=!1,this.defaultFont="Arial",this.warmupContainer&&this.warmupContainer.parentNode&&this.warmupContainer.parentNode.removeChild(this.warmupContainer),this.warmupContainer=null,this.defaultFonts=["Arial","Calibri","Helvetica","Verdana","Tahoma","Trebuchet MS","Times New Roman","Courier New"]}},Ct=pv.getInstance()});var fL={};hv(fL,{colorService:()=>Sr,default:()=>WF});var gv,Sr,WF,_s=or(()=>{I();gv=class h{constructor(){this.defaultColors=["#98df8a","#17becf","#2c808c","#98df8a","#e377c2","#7f7f7f","#bcbd22","#17becf","#393b79","#637939","#8c6d31","#843c39","#7b4173","#a55194","#c7c7c7","#ffbb78","#98df8a","#ff9896","#ff7f0e","#2ca02c","#d62728","#9467bd","#8c564b","#e377c2","#7f7f7f","#bcbd22","#17becf","#393b79","#637939","#8c6d31","#843c39","#7b4173","#a55194","#c7c7c7","#ffbb78","#98df8a","#ff9896"];this.customColors=[];this.initialized=!1;this.resolveReady=()=>{};this.readyPromise=new Promise(e=>{this.resolveReady=e})}static getInstance(){return h.instance||(h.instance=new h),h.instance}initialize(e){console.log("[ColorService] Initializing with settings:",e),this.setOrganizationColors(e.colorScheme||[])}isInitialized(){return this.initialized}async ready(){return this.readyPromise}getAvailableColors(){let e=[];this.customColors&&this.customColors.length>0&&e.push(...this.customColors),e.push(...this.defaultColors),console.log("[ColorService] getAvailableColors result count:",e.length);let t=new Set;return e.filter(n=>{if(!n)return!1;let r=n.toUpperCase();return t.has(r)?!1:(t.add(r),!0)})}setOrganizationColors(e){this.customColors=Array.isArray(e)?[...e]:[],console.log("[ColorService] Organization colors updated:",this.customColors.length),this.initialized||(this.initialized=!0,this.resolveReady())}getDefaultColors(){return[...this.defaultColors]}getCustomColors(){return[...this.customColors]}hasColor(e){let t=this.getAvailableColors(),n=e.toUpperCase();return t.some(r=>r.toUpperCase()===n)}addCustomColor(e){let t=e.toUpperCase();this.customColors.some(n=>n.toUpperCase()===t)||this.customColors.push(e)}removeCustomColor(e){let t=e.toUpperCase();this.customColors=this.customColors.filter(n=>n.toUpperCase()!==t)}reset(){this.customColors=[],this.initialized=!1,this.defaultColors=["#242424","#484848","#6D6D6D","#919191","#B6B6B6","#DADADA","#FFFFFF","#8B0000","#FF4500","#FFD700","#ADFF2F","#1E90FF","#0000FF","#8B00FF","#FF00FF","#F1E6E6","#FFE6E6","#FFF0E6","#F2FFE6","#E6F3FF","#E6E6FF","#F3E6FF","#FFE6FF","#D9CCCC","#FFCCCC","#FFE1CC","#E6FFCC","#CCE6FF","#CCCCFF","#E6CCFF","#FFCCFF","#B38B8B","#FFB3B3","#FFD9B3","#CCFFB3","#B3CCFF","#B3B3FF","#CCB3FF","#FFB3FF","#806666","#E69999","#FFCC99","#99FF99","#99CCFF","#9999FF","#CC99FF","#FF99FF","#4D3333","#CC6666","#FFB366","#66CC66","#6699FF","#6666FF","#9966FF","#FF66FF"]}},Sr=gv.getInstance(),WF=Sr});function Aa(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(h){let e=Math.random()*16|0;return(h==="x"?e:e&3|8).toString(16)})}var Nh=or(()=>{I()});var co,jg=or(()=>{I();Nh();co=class{constructor(e,t="chart_",n=null){this.platform=e,this.storagePrefix=t,this.recentColorsKey="recent_colors",this.organizationColorsKey="organization_colors",this.presentationColorsKey="presentation_colors",this.maxRecentColors=8,this.chartbuddyUrl=n}setChartbuddyUrl(e){this.chartbuddyUrl=e}isStorageAvailable(){return!!this.platform}getStorageKey(e){return`${this.storagePrefix}${e}`}static generateUUID(){return Aa()}async removeItems(e,t){e.length>0&&this.platform&&(await this.platform.storage.remove(e),console.log(`[Storage] Removed keys: ${e.join(", ")}`)),t&&t()}async remove(e=null,t){if(!this.platform){t&&t();return}let n=await this.platform.storage.get(null),r=[];for(let i in n)(!e||i.startsWith(e))&&r.push(i);r.length>0&&(await this.platform.storage.remove(r),console.log(`[Storage] Removed ${r.length} keys with prefix: ${e||"all"}`)),t&&t()}async removeAllData(e){if(!this.platform){e&&e(new Error("Platform not initialized"));return}try{let t=await this.platform.storage.get(null),n=Object.keys(t);if(n.length===0){e&&e(null,0);return}await this.platform.storage.remove(n),console.log(`[Storage] Successfully removed all ${n.length} items`),e&&e(null,n.length)}catch(t){e&&e(t)}}async clearAll(e){return this.removeAllData(e)}async getOrganizationColors(e){if(!this.platform){console.warn("[Storage] Cannot get organization colors: Platform not initialized"),e([]);return}let n=(await this.platform.storage.get([this.organizationColorsKey]))[this.organizationColorsKey]||[];console.log(`[Storage] Retrieved ${n.length} organization colors from storage`),e(n)}async getDefaultColors(){return this.platform?(await this.platform.storage.get([this.organizationColorsKey]))[this.organizationColorsKey]||[]:[]}async setOrganizationColors(e,t){if(!Array.isArray(e)||!this.platform){console.warn("[Storage] Cannot set organization colors: Invalid input or platform not initialized"),t&&t();return}console.log(`[Storage] Persisting ${e.length} organization colors to storage`),await this.platform.storage.set({[this.organizationColorsKey]:e}),t&&t()}async clearOrganizationColors(e){if(!this.platform){e&&e();return}await this.platform.storage.remove([this.organizationColorsKey]),e&&e()}async getPresentationColors(e,t){if(!e||!this.platform){t([]);return}let n=`${this.presentationColorsKey}_${e}`,r=await this.platform.storage.get([n]);t(r[n]||[])}async setPresentationColors(e,t,n){if(!e||!Array.isArray(t)||!this.platform){n&&n();return}let r=`${this.presentationColorsKey}_${e}`;await this.platform.storage.set({[r]:t}),n&&n()}async getRecentColors(e){if(!this.platform){e([]);return}let t=await this.platform.storage.get([this.recentColorsKey]);e(t[this.recentColorsKey]||[])}async addRecentColor(e,t){let n=this.normalizeColorToHex(e);if(!n||!this.platform){t&&t([]);return}this.getRecentColors(async r=>{r=r.filter(i=>i!==n),r.unshift(n),r=r.slice(0,this.maxRecentColors),this.platform&&await this.platform.storage.set({[this.recentColorsKey]:r}),t&&t(r)})}async clearRecentColors(e){this.platform&&await this.platform.storage.remove([this.recentColorsKey]),e&&e()}static googleRgbToHex(e){if(!e)return null;let t=Math.round((e.red||0)*255),n=Math.round((e.green||0)*255),r=Math.round((e.blue||0)*255);return`#${t.toString(16).padStart(2,"0")}${n.toString(16).padStart(2,"0")}${r.toString(16).padStart(2,"0")}`}normalizeColorToHex(e){if(!e||typeof e!="string")return null;let t=e.trim();if(t.startsWith("#")){let r=t.toUpperCase();return r.length===4&&(r="#"+r[1]+r[1]+r[2]+r[2]+r[3]+r[3]),/^#[0-9A-F]{6}$/.test(r)?r:null}if(/^[0-9A-Fa-f]{6}$/.test(t))return"#"+t.toUpperCase();let n=t.match(/^rgba?\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*[\d.]+)?\s*\)$/i);if(n){let r=Math.min(255,Math.max(0,parseInt(n[1],10))),i=Math.min(255,Math.max(0,parseInt(n[2],10))),a=Math.min(255,Math.max(0,parseInt(n[3],10)));return"#"+r.toString(16).padStart(2,"0").toUpperCase()+i.toString(16).padStart(2,"0").toUpperCase()+a.toString(16).padStart(2,"0").toUpperCase()}return null}async saveLastOpenedChartId(e){await this.platform.storage.set({lastOpenedChartId:e})}async getLastOpenedChartId(e){let t=await this.platform.storage.get(["lastOpenedChartId"]);e(t.lastOpenedChartId||null)}async getTemplates(){if(!this.chartbuddyUrl)return[];try{let t=(await this.platform.storage.get(["token"])).token;if(!t)return[];let n=await fetch(`${this.chartbuddyUrl}/api/chart-templates`,{method:"GET",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"}});if(n.ok){let r=await n.json();return Array.isArray(r)?r:r?.data&&Array.isArray(r.data)?r.data:[]}}catch(e){console.error("[Storage] Failed to fetch templates:",e)}return[]}}});var Mi,ho,bc=or(()=>{I();Mi="1.7.53",ho="chart-buddy"});var mv,bv,yv,Vh,pL=or(()=>{I();jg();bc();mv=class{async get(e){return new Promise(t=>{chrome.storage.local.get(e,n=>{t(n)})})}async set(e){return new Promise(t=>{chrome.storage.local.set(e,()=>{t()})})}async remove(e){return new Promise(t=>{chrome.storage.local.remove(e,()=>{t()})})}async clear(){return new Promise(e=>{chrome.storage.local.clear(()=>{e()})})}},bv=class{getURL(e){return chrome.runtime.getURL(e)}getVersion(){return Mi}getAppName(){return ho}isDevelopmentBuild(){return!1}getManifest(){return chrome.runtime.getManifest()}async sendMessage(e){return new Promise((t,n)=>{chrome.runtime.sendMessage(e,r=>{chrome.runtime.lastError?n(chrome.runtime.lastError):t(r)})})}},yv=class{detect(){let e=window.location.href;return e.includes("canva.com")?"Canva":e.includes("docs.google.com/presentation")?"GSlides":e.includes("docs.google.com/spreadsheets")||e.includes("sheets.google.com")?"GSheets":e.includes("notion.com")||e.includes("notion.so")?"Notion":e.includes("figma.com")?"Figma":e.includes("miro.com")?"Miro":e.includes("powerbi.com")?"PowerBI":e.includes("onedrive.live.com")||e.includes("microsoft365.com")?"PowerPoint":"WebApp"}getPresentationId(){let t=window.location.href.match(/\/presentation\/d\/([a-zA-Z0-9-_]+)/);return t?t[1]:null}},Vh=class{constructor(){this.type="extension";this.storage=new mv;this.runtime=new bv;this.host=new yv;this.chartBuddyStorage=new co(this)}};typeof window<"u"&&(window.ChromeExtensionProvider=Vh)});var xv,vv,wv,Os,Sv=or(()=>{I();jg();bc();xv=class{constructor(){this.prefix="cb_"}async get(e){let t={},n=[];return typeof e=="string"?n=[e]:Array.isArray(e)?n=e:e&&typeof e=="object"&&(n=Object.keys(e),Object.assign(t,e)),n.forEach(r=>{let i=localStorage.getItem(this.prefix+r);if(i!==null)try{t[r]=JSON.parse(i)}catch{t[r]=i}}),t}async set(e){Object.entries(e).forEach(([t,n])=>{localStorage.setItem(this.prefix+t,JSON.stringify(n))})}async remove(e){(Array.isArray(e)?e:[e]).forEach(n=>localStorage.removeItem(this.prefix+n))}async clear(){Object.keys(localStorage).forEach(e=>{e.startsWith(this.prefix)&&localStorage.removeItem(e)})}},vv=class{getURL(e){return e}getVersion(){return Mi}getAppName(){return ho}isDevelopmentBuild(){return!1}getManifest(){return{version:Mi,name:ho,_sys_ctx:this.isDevelopmentBuild()?"d8n3x5q1":"kz6p9m2v"}}async sendMessage(e){return console.log("[WebApp] Mock sendMessage:",e),null}},wv=class{detect(){return"WebApp"}getPresentationId(){return"webapp-mock-presentation-id"}},Os=class{constructor(){this.type="webapp";this.storage=new xv;this.runtime=new vv;this.host=new wv;this.chartBuddyStorage=new co(this)}};typeof window<"u"&&(window.WebAppProvider=Os)});function yc(){if(typeof window>"u")return!1;let h=window;return typeof h.__TAURI__<"u"||typeof h.__TAURI_INTERNALS__<"u"?!0:typeof navigator<"u"&&/tauri/i.test(navigator.userAgent)}var Cv,kv,Av,Xg,zh=or(()=>{I();jg();bc();Cv=class{constructor(){this.prefix="cb_";this.map=new Map}storageKey(e){return`${this.prefix}${e}`}async get(e){let t={},n=[];return typeof e=="string"?n=[e]:Array.isArray(e)?n=e:e&&typeof e=="object"&&(n=Object.keys(e),Object.assign(t,e)),n.forEach(r=>{let i=this.map.get(this.storageKey(r));if(i!==void 0)try{t[r]=JSON.parse(i)}catch{t[r]=i}}),t}async set(e){Object.entries(e).forEach(([t,n])=>{this.map.set(this.storageKey(t),JSON.stringify(n))})}async remove(e){(Array.isArray(e)?e:[e]).forEach(n=>this.map.delete(this.storageKey(n)))}async clear(){let e=[];this.map.forEach((t,n)=>{n.startsWith(this.prefix)&&e.push(n)}),e.forEach(t=>this.map.delete(t))}},kv=class{getURL(e){return e}getVersion(){return Mi}getAppName(){return ho}isDevelopmentBuild(){return!1}getManifest(){return{version:Mi,name:ho,_sys_ctx:this.isDevelopmentBuild()?"d8n3x5q1":"kz6p9m2v"}}async sendMessage(e){return console.log("[Tauri] sendMessage (no-op):",e),null}},Av=class{detect(){return"Tauri"}getPresentationId(){return"tauri-desktop"}},Xg=class{constructor(){this.type="tauri";this.storage=new Cv;this.runtime=new kv;this.host=new Av;this.chartBuddyStorage=new co(this)}}});var _r,Mv,Hh=or(()=>{I();pL();Sv();zh();_r=class{static setPlatform(e){this.instance=e}static getPlatform(){let e=yc();return e&&this.instance!==void 0&&this.instance.type!=="tauri"&&(this.instance=void 0),this.instance?this.instance:e?(this.instance=new Xg,this.instance):(typeof chrome<"u"&&chrome.runtime&&typeof chrome.runtime.getURL=="function"&&!!chrome.runtime.id?this.instance=new Vh:this.instance=new Os,this.instance)}},Mv=_r.getPlatform()});var XF,Dv,Ei,tm,kL=or(()=>{I();XF=["Arial","Calibri","Helvetica","Verdana","Tahoma","Trebuchet MS","Times New Roman","Courier New"],Dv={isExpired:!1,isActive:!0,daysRemaining:null,expiresAt:null},Ei={uploadMethod:"google-drive",featureFlags:{},canManageFeatureFlags:!1,organizationSettings:{colorScheme:["#3B82F6","#10B981","#F59E0B","#9fa90f"],fonts:XF,customFonts:[],defaultFont:"Arial"},trialStatus:Dv},tm={production:"https://chartbuddy.io",acceptance:"https://cb-acc.xyz",current:"production"}});function _v(h){if(h.fonts!==void 0){if(!Array.isArray(h.fonts))return console.warn("[FontCacheManager] Invalid fonts: expected array, got",typeof h.fonts),!1;if(!h.fonts.every(e=>typeof e=="string"&&e.trim().length>0))return console.warn("[FontCacheManager] Invalid fonts: contains non-string or empty values"),!1}if(h.customFonts!==void 0){if(!Array.isArray(h.customFonts))return console.warn("[FontCacheManager] Invalid customFonts: expected array, got",typeof h.customFonts),!1;if(!h.customFonts.every(e=>typeof e=="string"&&e.trim().length>0))return console.warn("[FontCacheManager] Invalid customFonts: contains non-string or empty values"),!1}return h.useDefaultFonts!==void 0&&typeof h.useDefaultFonts!="boolean"?(console.warn("[FontCacheManager] Invalid useDefaultFonts: expected boolean, got",typeof h.useDefaultFonts),!1):!0}var nm,Fs,Ov=or(()=>{I();Hh();nm=class h{static{this.STORAGE_KEY="chartbuddy_fonts_cache"}static{this.CACHE_VERSION="1.0"}constructor(){}static getInstance(){return h.instance||(h.instance=new h),h.instance}async getCachedFonts(){try{let t=(await _r.getPlatform().storage.get([h.STORAGE_KEY]))[h.STORAGE_KEY];if(!t)return null;if(typeof t!="object"||t===null)return console.warn("[FontCacheManager] Invalid cache data type, clearing"),await this.clearCache(),null;if(t.version!==h.CACHE_VERSION)return console.log("[FontCacheManager] Cache version mismatch, invalidating"),await this.clearCache(),null;let n={fonts:t.fonts,customFonts:t.customFonts,defaultFont:t.defaultFont,useDefaultFonts:t.useDefaultFonts};return _v(n)?(console.log("[FontCacheManager] Loaded fonts from cache:",{defaultFont:t.defaultFont,fonts:t.fonts?.length??0,customFonts:t.customFonts?.length??0,cachedAt:new Date(t.cachedAt).toISOString()}),n):(console.warn("[FontCacheManager] Cached data validation failed, clearing cache"),await this.clearCache(),null)}catch(e){return console.warn("[FontCacheManager] Failed to get cached fonts:",e),null}}async saveFontsToCache(e){if(!_v(e))throw new Error("[FontCacheManager] Invalid font settings, cannot save to cache");try{let t={fonts:e.fonts,customFonts:e.customFonts,defaultFont:e.defaultFont,useDefaultFonts:e.useDefaultFonts,cachedAt:Date.now(),version:h.CACHE_VERSION},r=JSON.stringify(t).length,i=100*1024;r>i&&(console.warn(`[FontCacheManager] Cache size (${r} bytes) exceeds limit (${i} bytes), clearing old cache`),await this.clearCache()),await _r.getPlatform().storage.set({[h.STORAGE_KEY]:t})}catch(t){throw console.error("[FontCacheManager] Failed to save fonts to cache:",t),t}}async validateAndSyncFonts(e){if(!_v(e))return console.warn("[FontCacheManager] Invalid backend font settings, using cached data"),{hasChanges:!1,fonts:await this.getCachedFonts()??{fonts:[],customFonts:[],defaultFont:"Arial",useDefaultFonts:!0}};let t=null;try{console.log("[FontCacheManager] Validating fonts against cache..."),t=await this.getCachedFonts();let n=this.fontsHaveChanged(t,e);return n&&await this.saveFontsToCache(e),{hasChanges:n,fonts:e}}catch(n){return console.error("[FontCacheManager] Error validating fonts:",n),{hasChanges:!1,fonts:t??{fonts:[],customFonts:[],defaultFont:"Arial",useDefaultFonts:!0}}}}fontsHaveChanged(e,t){if(!e)return!0;let n=(r,i)=>!r&&!i?!0:!r||!i||r.length!==i.length?!1:r.every((a,o)=>a===i[o]);return!n(e.fonts,t.fonts)||!n(e.customFonts,t.customFonts)||e.defaultFont!==t.defaultFont||e.useDefaultFonts!==t.useDefaultFonts}async clearCache(){try{await _r.getPlatform().storage.remove([h.STORAGE_KEY]),console.log("[FontCacheManager] Cache cleared")}catch(e){console.warn("[FontCacheManager] Failed to clear cache:",e)}}},Fs=nm.getInstance()});var ML={};hv(ML,{CHARTBUDDY_CONFIG_UPDATED_EVENT:()=>AL,ConfigManager:()=>pt,getConfigManager:()=>Or});function Or(){return pt.getInstance()}var AL,pt,Kn=or(()=>{I();kL();Hh();Ai();Ov();_s();AL="chartbuddy:config-updated",pt=class h{constructor(){this.debugEnabled=!1;this.debugAxisBinding=!0;this.loadingPromise=void 0;this.fontPreloadPromise=void 0;this.onLoadCallbacks=[];if(this.config={chartbuddyUrl:this.detectEnvironmentUrl(),bootOptions:{...Ei},environment:{...tm},loaded:!1,loadedAt:void 0},this.config.environment.current=this.detectEnvironment(),this.debugEnabled=this.computeDebugEnabled(this.config.chartbuddyUrl),typeof window<"u"&&window.localStorage)try{window.localStorage.getItem("CHARTBUDDY_DEBUG_MODE")==="true"&&(this.debugEnabled=!0),window.localStorage.getItem("CHARTBUDDY_DEBUG_AXIS_BINDING")==="false"&&(this.debugAxisBinding=!1)}catch{}}static{this.instance=void 0}computeDebugEnabled(e){let t=e.includes("cb-acc.xyz")||e.includes("stag"),n=e.includes("localhost")||e.includes("127.0.0.1"),r=_r.getPlatform().runtime.isDevelopmentBuild();return t||n||r}static getInstance(){return h.instance===void 0&&(h.instance=new h),h.instance}isDebugEnabled(){return this.debugEnabled}isDebugAxisBindingEnabled(){return this.debugAxisBinding}isWaterfallSegmentedBarsEnabled(){return!0}isChartOrientationEnabled(){return!0}isBarMekkoEnabled(){return this.config?.bootOptions?.featureFlags?.barMekko===!0}isDevelopment(){let e=this.config.chartbuddyUrl;return e.includes("localhost")||e.includes("127.0.0.1")}isAcceptance(){return this.config.chartbuddyUrl.includes("cb-acc.xyz")}isProduction(){return!this.isDevelopment()&&!this.isAcceptance()}setDebugMode(e){this.debugEnabled=e}setDebugAxisBindingMode(e){this.debugAxisBinding=e}detectEnvironmentUrl(){return tm.production}detectEnvironment(){return this.config.chartbuddyUrl.includes("cb-acc.xyz")?"acceptance":"production"}getConfig(){return{...this.config}}getChartbuddyUrl(){return this.config.chartbuddyUrl}getBootOptions(){return{...this.config.bootOptions}}getEnvironment(){return{...this.config.environment}}getTrialStatus(){return{...this.config.bootOptions.trialStatus}}isTrialExpired(){return this.config.bootOptions.trialStatus.isExpired}isLoaded(){return this.config.loaded}onLoad(e){this.config.loaded?e():this.onLoadCallbacks.push(e)}setChartbuddyUrl(e){this.config.chartbuddyUrl=e,this.config.environment.current=this.detectEnvironment(),this.debugEnabled=this.computeDebugEnabled(e)}async loadConfig(){if(this.loadingPromise)return this.loadingPromise;if(this.config.loaded&&this.config.loadedAt&&Date.now()-this.config.loadedAt<3e5){console.log("[ConfigManager] Config already loaded recently, skipping reload");return}this.loadingPromise=this.loadConfigInternal();try{await this.loadingPromise}finally{this.loadingPromise=void 0}}async preloadFontSettings(){if(this.fontPreloadPromise)return this.fontPreloadPromise;this.fontPreloadPromise=this.preloadFontSettingsInternal();try{await this.fontPreloadPromise}finally{this.fontPreloadPromise=void 0}}async loadConfigInternal(){try{if(_r.getPlatform().type==="webapp"){console.log("[ConfigManager] Standalone mode (WebApp): using local defaults"),this.config.bootOptions={...Ei},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks();return}console.log("[ConfigManager] Loading configuration from backend...");let t=await this.getAuthToken();if(!t){console.warn("[ConfigManager] No authentication token available, using defaults"),Fs.clearCache().catch(r=>{console.warn("[ConfigManager] Failed to clear font cache on auth failure:",r)}),this.config.bootOptions={...Ei},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks();return}let n=await this.fetchAuthenticatedJson("/api/user/boot-settings",t);if(n.ok){let r=await n.json(),i=r.uploadMethod??Ei.uploadMethod,a=r.featureFlags??Ei.featureFlags,o=r.canManageFeatureFlags??Ei.canManageFeatureFlags,l=r.organizationSettings??Ei.organizationSettings,d=r.trialStatus??Dv;this.config.bootOptions={uploadMethod:i,featureFlags:a,canManageFeatureFlags:o,organizationSettings:l,trialStatus:d},console.log("[ConfigManager] Organization Settings received:",{colorSchemeCount:l.colorScheme?.length||0,fontCount:l.fonts?.length||0}),this.config.loaded=!0,this.config.loadedAt=Date.now(),console.log("[ConfigManager] \u2705 Configuration loaded successfully:",{uploadMethod:this.config.bootOptions.uploadMethod,loadedAt:new Date(this.config.loadedAt).toISOString()}),await this.initializeFontService(),this.initializeColorService();let u={fonts:l.fonts??[],customFonts:l.customFonts??[],defaultFont:l.defaultFont??"Noto Sans"};this.validateFontCache(u).catch(g=>{console.warn("[ConfigManager] Background font validation failed:",g)}),this.triggerOnLoadCallbacks()}else console.warn(`[ConfigManager] Failed to fetch boot settings (HTTP ${n.status}), using defaults`),(n.status===401||n.status===403)&&Fs.clearCache().catch(r=>{console.warn("[ConfigManager] Failed to clear font cache on auth failure:",r)}),this.config.bootOptions={...Ei},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks()}catch(e){console.error("[ConfigManager] Error loading configuration:",e),console.log("[ConfigManager] Using default configuration"),this.config.bootOptions={...Ei},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks()}}async preloadFontSettingsInternal(){try{let e=await this.getAuthToken();if(!e)return;let t=await this.fetchAuthenticatedJson("/api/user/font-settings",e);if(!t.ok){(t.status===401||t.status===403)&&Fs.clearCache().catch(r=>{console.warn("[ConfigManager] Failed to clear font cache on preload auth failure:",r)});return}let n=await t.json();Ct.isInitialized()?Ct.reinitialize(n):Ct.primeEarly(n)}catch(e){console.warn("[ConfigManager] Font preload failed:",e)}}triggerOnLoadCallbacks(){console.log(`[ConfigManager] Triggering ${this.onLoadCallbacks.length} onLoad callbacks`),this.onLoadCallbacks.forEach(e=>{try{e()}catch(t){console.error("[ConfigManager] Error in onLoad callback:",t)}}),this.onLoadCallbacks=[],typeof window<"u"&&window.dispatchEvent(new CustomEvent(AL,{detail:{bootOptions:this.getBootOptions(),loadedAt:this.config.loadedAt}}))}async initializeFontService(){if(Ct.isInitialized()){console.log("[ConfigManager] FontService already initialized, skipping");return}try{let e=await Fs.getCachedFonts();if(e){Ct.initialize(e);return}let t=this.config.bootOptions.organizationSettings,n={fonts:t.fonts??[],customFonts:t.customFonts??[],defaultFont:t.defaultFont??"Noto Sans"};Ct.initialize(n)}catch(e){console.warn("[ConfigManager] Failed to initialize FontService:",e)}}initializeColorService(){try{let t=this.config.bootOptions.organizationSettings.colorScheme||[];Sr.initialize({colorScheme:t});let n=_r.getPlatform();n&&n.chartBuddyStorage&&n.chartBuddyStorage.setOrganizationColors(t).then(()=>console.log("[ConfigManager] Organization colors persisted to storage")).catch(r=>console.warn("[ConfigManager] Failed to persist organization colors:",r)),console.log("[ConfigManager] ColorService initialized")}catch(e){console.warn("[ConfigManager] Failed to initialize ColorService:",e)}}async validateFontCache(e){try{let t=await Fs.validateAndSyncFonts(e);t.hasChanges?(console.log("[ConfigManager] Font settings changed, updating"),Ct.reinitialize(t.fonts)):console.log("[ConfigManager] Font settings unchanged, keeping current initialization")}catch(t){console.warn("[ConfigManager] Font validation failed:",t)}}async getAuthToken(){return(await this.getChromeStorage(["token"])).token}fetchAuthenticatedJson(e,t){return fetch(`${this.config.chartbuddyUrl}${e}`,{method:"GET",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"}})}async getChromeStorage(e){try{let t=await _r.getPlatform().storage.get(e),n={};for(let r of e)n[r]=t[r];return n}catch(t){return console.warn("[ConfigManager] Failed to get chrome storage:",t),{}}}async reloadConfig(){this.config.loaded=!1,this.config.loadedAt=void 0,await this.loadConfig()}reset(){this.config={chartbuddyUrl:this.detectEnvironmentUrl(),bootOptions:{...Ei},environment:{...tm},loaded:!1,loadedAt:void 0},this.config.environment.current=this.detectEnvironment(),this.loadingPromise=void 0,this.fontPreloadPromise=void 0}}});var Xv=$F((Yv,jv)=>{I();(h=>{let e=(()=>{let _=0;return{escape:function(Y){return Y.replace(/([.*+?^${}()|[\]/\\])/g,"\\$1")},isDataUrl:function(Y){return Y.search(/^(data:)/)!==-1},canvasToBlob:function(Y){return Y.toBlob?new Promise(function(J){Y.toBlob(J)}):(J=>new Promise(function(te){var ae=g(J.toDataURL().split(",")[1]),re=ae.length,le=new Uint8Array(re);for(let ye=0;ye<re;ye++)le[ye]=ae.charCodeAt(ye);te(new Blob([le],{type:"image/png"}))}))(Y)},resolveUrl:function(Y,J){var te=document.implementation.createHTMLDocument(),ae=te.createElement("base"),re=(te.head.appendChild(ae),te.createElement("a"));return te.body.appendChild(re),ae.href=J,re.href=Y,re.href},getAndEncode:function(Y){let J=l.impl.urlCache.find(function(te){return te.url===Y});return J||(J={url:Y,promise:null},l.impl.urlCache.push(J)),J.promise===null&&(l.impl.options.cacheBust&&(Y+=(/\?/.test(Y)?"&":"?")+new Date().getTime()),J.promise=new Promise(function(te){let ae=new XMLHttpRequest;function re(Q){console.error(Q),te("")}function le(){var Q=l.impl.options.imagePlaceholder;Q?te(Q):re("Status:"+ae.status+" while fetching resource: "+Y)}if(ae.timeout=l.impl.options.httpTimeout,ae.onerror=le,ae.ontimeout=le,ae.onloadend=function(){if(ae.readyState===XMLHttpRequest.DONE){var Q=ae.status;if(Q===0&&Y.toLowerCase().startsWith("file://")||200<=Q&&Q<=300&&ae.response!==null){Q=ae.response,Q instanceof Blob||re("Expected response to be a Blob, but got: "+typeof Q);let de=new FileReader;de.onloadend=function(){var me=de.result;te(me)};try{de.readAsDataURL(Q)}catch(me){re("Failed to read the response as Data URL: "+me.toString())}}else le()}},0<l.impl.options.useCredentialsFilters.length&&(l.impl.options.useCredentials=0<l.impl.options.useCredentialsFilters.filter(Q=>0<=Y.search(Q)).length),l.impl.options.useCredentials&&(ae.withCredentials=!0),l.impl.options.corsImg&&Y.indexOf("http")===0&&Y.indexOf(window.location.origin)===-1){var ye=(l.impl.options.corsImg.method||"GET").toUpperCase()==="POST"?"POST":"GET";ae.open(ye,(l.impl.options.corsImg.url||"").replace("#{cors}",Y),!0);let Q=!1,de=l.impl.options.corsImg.headers||{},me=(Object.keys(de).forEach(function(Se){de[Se].indexOf("application/json")!==-1&&(Q=!0),ae.setRequestHeader(Se,de[Se])}),(Se=>{try{return JSON.parse(JSON.stringify(Se))}catch(Ce){re("corsImg.data is missing or invalid:"+Ce.toString())}})(l.impl.options.corsImg.data||""));Object.keys(me).forEach(function(Se){typeof me[Se]=="string"&&(me[Se]=me[Se].replace("#{cors}",Y))}),ae.responseType="blob",ae.send(Q?JSON.stringify(me):me)}else ae.open("GET",Y,!0),ae.responseType="blob",ae.send()})),J.promise},uid:function(){return"u"+("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)+_++},asArray:function(Y){var J=[],te=Y.length;for(let ae=0;ae<te;ae++)J.push(Y[ae]);return J},escapeXhtml:function(Y){return Y.replace(/%/g,"%25").replace(/#/g,"%23").replace(/\n/g,"%0A")},makeImage:function(Y){return Y!=="data:,"?new Promise(function(J,te){let ae=document.createElementNS("http://www.w3.org/2000/svg","svg"),re=new Image;l.impl.options.useCredentials&&(re.crossOrigin="use-credentials"),re.onload=function(){document.body.removeChild(ae),window&&window.requestAnimationFrame?window.requestAnimationFrame(function(){J(re)}):J(re)},re.onerror=le=>{document.body.removeChild(ae),te(le)},ae.appendChild(re),re.src=Y,document.body.appendChild(ae)}):Promise.resolve()},width:function(Y){var J=U(Y,"width");if(!isNaN(J))return J;var J=U(Y,"border-left-width"),te=U(Y,"border-right-width");return Y.scrollWidth+J+te},height:function(Y){var J=U(Y,"height");if(!isNaN(J))return J;var J=U(Y,"border-top-width"),te=U(Y,"border-bottom-width");return Y.scrollHeight+J+te},getWindow:P,isElement:q,isElementHostForOpenShadowRoot:function(Y){return q(Y)&&Y.shadowRoot!==null},isShadowRoot:$,isInShadowRoot:V,isHTMLElement:function(Y){return Y instanceof P(Y).HTMLElement},isHTMLCanvasElement:function(Y){return Y instanceof P(Y).HTMLCanvasElement},isHTMLInputElement:function(Y){return Y instanceof P(Y).HTMLInputElement},isHTMLImageElement:function(Y){return Y instanceof P(Y).HTMLImageElement},isHTMLLinkElement:function(Y){return Y instanceof P(Y).HTMLLinkElement},isHTMLScriptElement:function(Y){return Y instanceof P(Y).HTMLScriptElement},isHTMLStyleElement:function(Y){return Y instanceof P(Y).HTMLStyleElement},isHTMLTextAreaElement:function(Y){return Y instanceof P(Y).HTMLTextAreaElement},isShadowSlotElement:function(Y){return V(Y)&&Y instanceof P(Y).HTMLSlotElement},isSVGElement:function(Y){return Y instanceof P(Y).SVGElement},isSVGRectElement:function(Y){return Y instanceof P(Y).SVGRectElement},isDimensionMissing:function(Y){return isNaN(Y)||Y<=0}};function P(Y){return Y=Y?Y.ownerDocument:void 0,(Y?Y.defaultView:void 0)||window||h}function $(Y){return Y instanceof P(Y).ShadowRoot}function V(Y){return Y!=null&&Y.getRootNode!==void 0&&$(Y.getRootNode())}function q(Y){return Y instanceof P(Y).Element}function U(Y,J){if(Y.nodeType===d){let te=u(Y).getPropertyValue(J);if(te.slice(-2)==="px")return te=te.slice(0,-2),parseFloat(te)}return NaN}})(),t=(()=>{let _=/url\(\s*(["']?)((?:\\.|[^\\)])+)\1\s*\)/gm;return{inlineAll:function(U,Y,J){return P(U)?Promise.resolve(U).then($).then(function(te){let ae=Promise.resolve(U);return te.forEach(function(re){ae=ae.then(function(le){return q(le,re,Y,J)})}),ae}):Promise.resolve(U)},shouldProcess:P,impl:{readUrls:$,inline:q,urlAsRegex:V}};function P(U){return U.search(_)!==-1}function $(U){for(var Y,J=[];(Y=_.exec(U))!==null;)J.push(Y[2]);return J.filter(function(te){return!e.isDataUrl(te)})}function V(U){return new RegExp(`url\\((["']?)(${e.escape(U)})\\1\\)`,"gm")}function q(U,Y,J,te){return Promise.resolve(Y).then(function(ae){return J?e.resolveUrl(ae,J):ae}).then(te||e.getAndEncode).then(function(ae){var re=V(Y);return U.replace(re,`url($1${ae}$1)`)})}})(),n={resolveAll:function(){return r().then(function(_){return Promise.all(_.map(function(P){return P.resolve()}))}).then(function(_){return _.join(`
|
|
51
51
|
`)})},impl:{readAll:r}};function r(){return Promise.resolve(e.asArray(document.styleSheets)).then(function(P){let $=[];return P.forEach(function(V){var q=Object.getPrototypeOf(V);if(Object.prototype.hasOwnProperty.call(q,"cssRules"))try{e.asArray(V.cssRules||[]).forEach($.push.bind($))}catch(U){console.error("domtoimage: Error while reading CSS rules from: "+V.href,U.toString())}}),$}).then(function(P){return P.filter(function($){return $.type===CSSRule.FONT_FACE_RULE}).filter(function($){return t.shouldProcess($.style.getPropertyValue("src"))})}).then(function(P){return P.map(_)});function _(P){return{resolve:function(){var $=(P.parentStyleSheet||{}).href;return t.inlineAll(P.cssText,$)},src:function(){return P.style.getPropertyValue("src")}}}}let i={inlineAll:function _(P){if(!e.isElement(P))return Promise.resolve(P);return $(P).then(function(){return e.isHTMLImageElement(P)?a(P).inline():Promise.all(e.asArray(P.childNodes).map(function(V){return _(V)}))});function $(V){let q=["background","background-image"],U=q.map(function(Y){let J=V.style.getPropertyValue(Y),te=V.style.getPropertyPriority(Y);return J?t.inlineAll(J).then(function(ae){V.style.setProperty(Y,ae,te)}):Promise.resolve()});return Promise.all(U).then(function(){return V})}},impl:{newImage:a}};function a(_){return{inline:function(P){return e.isDataUrl(_.src)?Promise.resolve():Promise.resolve(_.src).then(P||e.getAndEncode).then(function($){return new Promise(function(V){_.onload=V,_.onerror=V,_.src=$})})}}}let o={copyDefaultStyles:!0,imagePlaceholder:void 0,cacheBust:!1,useCredentials:!1,useCredentialsFilters:[],httpTimeout:3e4,styleCaching:"strict",corsImg:void 0,adjustClonedNode:void 0,filterStyles:void 0},l={toSvg:m,toPng:function(_,P){return y(_,P).then(function($){return $.toDataURL()})},toJpeg:function(_,P){return y(_,P).then(function($){return $.toDataURL("image/jpeg",(P?P.quality:void 0)||1)})},toBlob:function(_,P){return y(_,P).then(e.canvasToBlob)},toPixelData:function(_,P){return y(_,P).then(function($){return $.getContext("2d").getImageData(0,0,e.width(_),e.height(_)).data})},toCanvas:y,impl:{fontFaces:n,images:i,util:e,inliner:t,urlCache:[],options:{},copyOptions:function(_){_.copyDefaultStyles===void 0?l.impl.options.copyDefaultStyles=o.copyDefaultStyles:l.impl.options.copyDefaultStyles=_.copyDefaultStyles,l.impl.options.imagePlaceholder=(_.imagePlaceholder===void 0?o:_).imagePlaceholder,l.impl.options.cacheBust=(_.cacheBust===void 0?o:_).cacheBust,l.impl.options.corsImg=(_.corsImg===void 0?o:_).corsImg,l.impl.options.useCredentials=(_.useCredentials===void 0?o:_).useCredentials,l.impl.options.useCredentialsFilters=(_.useCredentialsFilters===void 0?o:_).useCredentialsFilters,l.impl.options.httpTimeout=(_.httpTimeout===void 0?o:_).httpTimeout,l.impl.options.styleCaching=(_.styleCaching===void 0?o:_).styleCaching}}},d=(typeof Yv=="object"&&typeof jv=="object"?jv.exports=l:h.domtoimage=l,(Node===void 0?void 0:Node.ELEMENT_NODE)||1),u=(h===void 0?void 0:h.getComputedStyle)||(window===void 0?void 0:window.getComputedStyle)||globalThis.getComputedStyle,g=(h===void 0?void 0:h.atob)||(window===void 0?void 0:window.atob)||globalThis.atob;function m(_,P){let $=l.impl.util.getWindow(_),V=(P=P||{},l.impl.copyOptions(P),[]);return Promise.resolve(_).then(function(q){if(q.nodeType===d)return q;var U=q,Y=document.createElement("span");return U.replaceWith(Y),Y.append(q),V.push({child:U,wrapper:Y}),Y}).then(function(q){return(function U(Y,J,te,ae){let re=J.filter;if(Y===v||e.isHTMLScriptElement(Y)||e.isHTMLStyleElement(Y)||e.isHTMLLinkElement(Y)||te!==null&&re&&!re(Y))return Promise.resolve();return Promise.resolve(Y).then(le).then(ye).then(function(Ce){return me(Ce,de(Y))}).then(Q).then(function(Ce){return Se(Ce,Y)});function le(Ce){return e.isHTMLCanvasElement(Ce)?e.makeImage(Ce.toDataURL()):Ce.cloneNode(!1)}function ye(Ce){return J.adjustClonedNode&&J.adjustClonedNode(Y,Ce,!1),Promise.resolve(Ce)}function Q(Ce){return J.adjustClonedNode&&J.adjustClonedNode(Y,Ce,!0),Promise.resolve(Ce)}function de(Ce){return e.isElementHostForOpenShadowRoot(Ce)?Ce.shadowRoot:Ce}function me(Ce,_e){let Ee=at(_e),Ue=Promise.resolve();if(Ee.length!==0){let Re=u(Ie(_e));e.asArray(Ee).forEach(function(bt){Ue=Ue.then(function(){return U(bt,J,Re,ae).then(function(it){it&&Ce.appendChild(it)})})})}return Ue.then(function(){return Ce});function Ie(Re){return e.isShadowRoot(Re)?Re.host:Re}function at(Re){if(e.isShadowSlotElement(Re)){let bt=Re.assignedNodes();if(bt&&0<bt.length)return bt}return Re.childNodes}}function Se(Ce,_e){return!e.isElement(Ce)||e.isShadowSlotElement(_e)?Promise.resolve(Ce):Promise.resolve().then(Ue).then(Ie).then(at).then(Re).then(Ee).then(function(){return Ce});function Ee(){e.isHTMLImageElement(Ce)&&(Ce.removeAttribute("loading"),_e.srcset||_e.sizes)&&(Ce.removeAttribute("srcset"),Ce.removeAttribute("sizes"),Ce.src=_e.currentSrc||_e.src)}function Ue(){function bt(We,Xe){Xe.font=We.font,Xe.fontFamily=We.fontFamily,Xe.fontFeatureSettings=We.fontFeatureSettings,Xe.fontKerning=We.fontKerning,Xe.fontSize=We.fontSize,Xe.fontStretch=We.fontStretch,Xe.fontStyle=We.fontStyle,Xe.fontVariant=We.fontVariant,Xe.fontVariantCaps=We.fontVariantCaps,Xe.fontVariantEastAsian=We.fontVariantEastAsian,Xe.fontVariantLigatures=We.fontVariantLigatures,Xe.fontVariantNumeric=We.fontVariantNumeric,Xe.fontVariationSettings=We.fontVariationSettings,Xe.fontWeight=We.fontWeight}function it(We,Xe){let St=u(We);St.cssText?(Xe.style.cssText=St.cssText,bt(St,Xe.style)):(L(J,We,St,te,Xe),te===null&&(["inset-block","inset-block-start","inset-block-end"].forEach(Ne=>Xe.style.removeProperty(Ne)),["left","right","top","bottom"].forEach(Ne=>{Xe.style.getPropertyValue(Ne)&&Xe.style.setProperty(Ne,"0px")})))}it(_e,Ce)}function Ie(){let bt=e.uid();function it(We){let Xe=u(_e,We),St=Xe.getPropertyValue("content");if(St!==""&&St!=="none"){let Ot=function(){let Xt=`.${bt}:`+We,tn=(Xe.cssText?qe:st)();return document.createTextNode(Xt+`{${tn}}`);function qe(){return`${Xe.cssText} content: ${St};`}function st(){return e.asArray(Xe).map(Et).join("; ")+";";function Et(Tt){let Oe=Xe.getPropertyValue(Tt),He=Xe.getPropertyPriority(Tt)?" !important":"";return Tt+": "+Oe+He}}};var Ne=Ot;let Ft=Ce.getAttribute("class")||"",Vt=(Ce.setAttribute("class",Ft+" "+bt),document.createElement("style"));Vt.appendChild(Ot()),Ce.appendChild(Vt)}}[":before",":after"].forEach(function(We){it(We)})}function at(){e.isHTMLTextAreaElement(_e)&&(Ce.innerHTML=_e.value),e.isHTMLInputElement(_e)&&Ce.setAttribute("value",_e.value)}function Re(){e.isSVGElement(Ce)&&(Ce.setAttribute("xmlns","http://www.w3.org/2000/svg"),e.isSVGRectElement(Ce))&&["width","height"].forEach(function(bt){let it=Ce.getAttribute(bt);it&&Ce.style.setProperty(bt,it)})}}})(q,P,null,$)}).then(P.disableEmbedFonts?Promise.resolve(_):w).then(P.disableInlineImages?Promise.resolve(_):S).then(function(q){P.bgcolor&&(q.style.backgroundColor=P.bgcolor),P.width&&(q.style.width=P.width+"px"),P.height&&(q.style.height=P.height+"px"),P.style&&Object.keys(P.style).forEach(function(Y){q.style[Y]=P.style[Y]});let U=null;return typeof P.onclone=="function"&&(U=P.onclone(q)),Promise.resolve(U).then(function(){return q})}).then(function(q){let U=P.width||e.width(_),Y=P.height||e.height(_);return Promise.resolve(q).then(function(J){return J.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),new XMLSerializer().serializeToString(J)}).then(e.escapeXhtml).then(function(J){var te=(e.isDimensionMissing(U)?' width="100%"':` width="${U}"`)+(e.isDimensionMissing(Y)?' height="100%"':` height="${Y}"`);return`<svg xmlns="http://www.w3.org/2000/svg"${(e.isDimensionMissing(U)?"":` width="${U}"`)+(e.isDimensionMissing(Y)?"":` height="${Y}"`)}><foreignObject${te}>${J}</foreignObject></svg>`}).then(function(J){return"data:image/svg+xml;charset=utf-8,"+J})}).then(function(q){for(;0<V.length;){var U=V.pop();U.wrapper.replaceWith(U.child)}return q}).then(function(q){return l.impl.urlCache=[],v&&(document.body.removeChild(v),v=null),E&&clearTimeout(E),E=setTimeout(()=>{E=null,T={}},2e4),q})}function y(_,P){return m(_,P=P||{}).then(e.makeImage).then(function($){var V=typeof P.scale!="number"?1:P.scale,q=((Y,J)=>{let te=P.width||e.width(Y),ae=P.height||e.height(Y);return e.isDimensionMissing(te)&&(te=e.isDimensionMissing(ae)?300:2*ae),e.isDimensionMissing(ae)&&(ae=te/2),(Y=document.createElement("canvas")).width=te*J,Y.height=ae*J,P.bgcolor&&((J=Y.getContext("2d")).fillStyle=P.bgcolor,J.fillRect(0,0,Y.width,Y.height)),Y})(_,V),U=q.getContext("2d");return U.msImageSmoothingEnabled=!1,U.imageSmoothingEnabled=!1,$&&(U.scale(V,V),U.drawImage($,0,0)),q})}let v=null;function w(_){return n.resolveAll().then(function(P){var $;return P!==""&&($=document.createElement("style"),_.appendChild($),$.appendChild(document.createTextNode(P))),_})}function S(_){return i.inlineAll(_).then(function(){return _})}function L(_,P,$,V,q){let U=l.impl.options.copyDefaultStyles?((J,te)=>{var ae,re=(Q=>(J.styleCaching!=="relaxed"?Q:Q.filter((de,me,Se)=>me===0||me===Se.length-1)).join(">"))(te=(Q=>{var de=[];do if(Q.nodeType===d){var me=Q.tagName;if(de.push(me),D.includes(me))break}while(Q=Q.parentNode);return de})(te));{if(T[re])return T[re];te=((Q,de)=>{let me=Q.body;do{var Se=de.pop(),Se=Q.createElement(Se);me.appendChild(Se),me=Se}while(0<de.length);return me.textContent="\u200B",me})((ae=(()=>{if(v)return v.contentWindow;de=document.characterSet||"UTF-8",Q=(Q=document.doctype)?(`<!DOCTYPE ${Ue(Q.name)} ${Ue(Q.publicId)} `+Ue(Q.systemId)).trim()+">":"",(v=document.createElement("iframe")).id="domtoimage-sandbox-"+e.uid(),v.style.top="-9999px",v.style.visibility="hidden",v.style.position="fixed",document.body.appendChild(v);var Q,de,me=v,Se="domtoimage-sandbox";try{return me.contentWindow.document.write(Q+`<html><head><meta charset='${de}'><title>${Se}</title></head><body></body></html>`),me.contentWindow}catch{}var Ce=document.createElement("meta");Ce.setAttribute("charset",de);try{var _e=document.implementation.createHTMLDocument(Se),Ee=(_e.head.appendChild(Ce),Q+_e.documentElement.outerHTML);return me.setAttribute("srcdoc",Ee),me.contentWindow}catch{}return me.contentDocument.head.appendChild(Ce),me.contentDocument.title=Se,me.contentWindow;function Ue(Ie){var at;return Ie?((at=document.createElement("div")).innerText=Ie,at.innerHTML):""}})()).document,te),ae=((Q,de)=>{let me={},Se=Q.getComputedStyle(de);return e.asArray(Se).forEach(function(Ce){me[Ce]=Ce==="width"||Ce==="height"?"auto":Se.getPropertyValue(Ce)}),me})(ae,te);var le=te;do{var ye=le.parentElement;ye!==null&&ye.removeChild(le),le=ye}while(le&&le.tagName!=="BODY");return T[re]=ae}})(_,P):{},Y=q.style;e.asArray($).forEach(function(J){var te,ae,re,le;_.filterStyles&&!_.filterStyles(P,J)||(ae=$.getPropertyValue(J),re=U[J],te=V?V.getPropertyValue(J):void 0,Y.getPropertyValue(J))||(ae!==re||V&&ae!==te)&&(re=$.getPropertyPriority(J),te=Y,ae=ae,re=re,le=0<=["background-clip"].indexOf(J=J),re?(te.setProperty(J,ae,re),le&&te.setProperty("-webkit-"+J,ae,re)):(te.setProperty(J,ae),le&&te.setProperty("-webkit-"+J,ae)))})}let E=null,T={},D=["ADDRESS","ARTICLE","ASIDE","BLOCKQUOTE","DETAILS","DIALOG","DD","DIV","DL","DT","FIELDSET","FIGCAPTION","FIGURE","FOOTER","FORM","H1","H2","H3","H4","H5","H6","HEADER","HGROUP","HR","LI","MAIN","NAV","OL","P","PRE","SECTION","SVG","TABLE","UL","math","svg","BODY","HEAD","HTML"]})(Yv)});I();I();var Ug=typeof window<"u"?window:globalThis;Ug.__CHARTBUDDY_NO_AUTOBOOT__=!0;Ug.__CHARTBUDDY_ARTIFACT__=!0;Ug.ChartLabelPlacementWorkerUrl=null;Ug.ChartLabelPlacementWasm=null;I();I();I();var ta=window;ta.chrome=ta.chrome||{};ta.chrome.runtime=ta.chrome.runtime||{getURL:h=>h,getManifest:()=>({version:"1.0.0-webapp",name:"Chartbuddy Web"}),sendMessage:h=>(console.log("[WebApp] Mock sendMessage:",h),Promise.resolve(null)),onMessage:{addListener:()=>{}}};ta.chrome.storage=ta.chrome.storage||{local:{get:(h,e)=>{let t=Promise.resolve({});return e&&t.then(e),t},set:(h,e)=>{let t=Promise.resolve();return e&&t.then(e),t},remove:(h,e)=>{let t=Promise.resolve();return e&&t.then(e),t},clear:h=>{let e=Promise.resolve();return h&&e.then(h),e}}};ta.ContextMenuTS||(ta.ContextMenuTS={showAt:()=>{console.log("[WebApp] ContextMenu.showAt suppressed in widget")},close:()=>{},destroy:()=>{}});ta.window.ContextMenuTS=ta.ContextMenuTS;console.log("\u{1F310} WebApp Globals Initialized");I();var VF='.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}',uL="src/ts/shared/css/tippy.css";if(typeof document<"u"&&!document.querySelector('style[data-cb-embed-css="'+uL+'"]')){let h=document.createElement("style");h.setAttribute("data-cb-embed-css",uL),h.textContent=VF,document.head.appendChild(h)}Ai();_s();I();Hh();I();var xc=class{showChartSelectionModal(){console.warn("[NullUIProvider] ChartSelectionModal not available in this build")}showTrialExpiredModal(){console.warn("[NullUIProvider] TrialExpiredModal not available in this build")}showSaveTemplateModal(){console.warn("[NullUIProvider] SaveTemplateModal not available in this build")}showGoogleSheetsConnectionModal(){console.warn("[NullUIProvider] GoogleSheetsConnectionModal not available in this build")}showDeleteConfirmationModal(){console.warn("[NullUIProvider] DeleteConfirmationModal not available in this build")}showInviteModal(){console.warn("[NullUIProvider] InviteModal not available in this build")}removeGoogleSheetsConnection(){console.warn("[NullUIProvider] removeGoogleSheetsConnection not available in this build")}showSeriesOptionsDropdown(){console.warn("[NullUIProvider] SeriesOptionsDropdown not available in this build")}showWaterfallColumnDropdown(){console.warn("[NullUIProvider] WaterfallColumnDropdown not available in this build")}reset(){}};var Kg=null;function gL(h={}){let e=h.platform||_r.getPlatform(),t=h.ui||new xc,n=h.chartbuddyUrl||"https://chartbuddy-app.com";return{platform:e,ui:t,chartbuddyUrl:n}}function GF(h){return Kg=h,h}function mL(h={}){return GF(gL(h))}function Ma(){return Kg||(Kg=gL()),Kg}Hh();Sv();I();I();I();I();I();var yt=class h{static{this.globalInstance=null}constructor(e){this.listeners=new Map,this.debugMode=e?.debug??!1}static global(){return h.globalInstance||(h.globalInstance=new h({debug:!1})),h.globalInstance}static resetGlobal(){h.globalInstance=null}on(e,t){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),()=>{this.off(e,t)}}once(e,t){let n=r=>{this.off(e,n),t(r)};return this.on(e,n)}emit(e,t){let n=this.listeners.get(e);if(this.debugMode&&console.log(`[EventBus] Emitting "${e}"`,t),!n)return;Array.from(n).forEach(i=>{try{i(t)}catch(a){console.error(`[EventBus] Error in listener for "${e}":`,a)}})}off(e,t){let n=this.listeners.get(e);n&&(t?(n.delete(t),n.size===0&&this.listeners.delete(e)):this.listeners.delete(e))}clear(){this.listeners.clear()}listenerCount(e){let t=this.listeners.get(e);return t?t.size:0}eventNames(){return Array.from(this.listeners.keys())}removeListeners(e){e.forEach(t=>{this.listeners.delete(t)})}};I();var sr={CREATED:"chart.created",TYPE_CHANGED:"chart.type_changed",DELETED:"chart.deleted",SAVED:"chart.saved",DOWNLOADED:"chart.downloaded",OPENED:"chart.opened",CD_CHANGED:"chart.cd_changed"};var na={CLOSE_ALL_DROPDOWNS:"ui.close_all_dropdowns",DROPDOWN_OPENING:"ui.dropdown_opening"};var Wr={OPERATION_FAILED:"error.operation_failed",UI_INTERACTION_FAILED:"error.ui_interaction_failed",SYSTEM_ERROR:"error.system_error"};I();function qg(h){if(!h||typeof h.closest!="function")return null;let e=h.closest("[data-cb-instance]");if(e){let r=e.getAttribute("data-cb-instance");if(r)return r}let n=h.closest('svg[id^="chart-svg-"]')?.id;return n&&n.startsWith("chart-svg-")?n.slice(10):null}function Ps(h,e){let t=h?.instanceId??null;return!t||!e?!0:t===e}I();I();I();I();var vc={clusteredBar:{label:"Clustered Bar",description:"Side-by-side bars comparing series within each category.",optionBag:"bar",family:"bar",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"clustered-bar"},stackedBar:{label:"Stacked Bar",description:"Bars stacked to show composition and category totals.",optionBag:"bar",family:"bar",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"stacked-bar"},stackedBar100:{label:"100% Stacked Bar",description:"Stacked bars normalized to 100% to compare mix, not size.",optionBag:"bar",family:"bar",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"stacked-bar"},line:{label:"Line Chart",description:"Trends over an ordered domain, one line per series.",optionBag:"line",family:"line",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"line"},area:{label:"Area Chart",description:"Filled lines showing magnitude over an ordered domain.",optionBag:"area",family:"area",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"area"},area100:{label:"100% Area Chart",description:"Area chart normalized to 100% to show changing mix.",optionBag:"area",family:"area",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"area"},pie:{label:"Pie Chart",description:"Share of a single total across categories.",optionBag:"pie",family:"pie",seriesLayout:"categoryValue",minRows:2,minCols:2,status:"stable",docsSlug:"pie"},scatter:{label:"Scatter Plot",description:"Points positioned by two metrics, optionally sized and grouped.",optionBag:"scatter",family:"scatter",seriesLayout:"pointRows",minRows:2,minCols:3,status:"stable",docsSlug:"scatter"},waterfall:{label:"Waterfall",description:"Running total showing how contributions bridge two values.",optionBag:"waterfall",family:"waterfall",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"waterfall"},mekko:{label:"Marimekko",description:"Variable-width stacked bars where both axes are percentages.",optionBag:"mekko",family:"mekko",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"mekko"},barMekko:{label:"Bar Mekko",description:"Bars whose width encodes one metric and height another; first data row sets widths.",optionBag:"barMekko",family:"mekko",seriesLayout:"widthRowThenHeightRows",minRows:3,minCols:2,status:"beta",docsSlug:"mekko"},combo:{label:"Combo Chart",description:"Mixed bar and line series on shared or dual axes.",optionBag:"combo",family:"combo",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"combo"}},Wh={bubble:"scatter",donut:"pie"},UF=[],bL={},Lv=Object.keys(vc).sort(),yL=Object.keys(Wh).sort(),Jg=[...Lv,...yL].sort(),YF=yL.filter(h=>!UF.includes(h)),dN=[...Lv,...YF].sort(),Zg="clusteredBar";function xL(h){return typeof h=="string"&&Object.prototype.hasOwnProperty.call(vc,h)}function Tv(h){return typeof h=="string"&&Object.prototype.hasOwnProperty.call(Wh,h)}function Qg(h){return xL(h)||Tv(h)}function Is(h){return Tv(h)?Wh[h]:h}function Ev(h,e){let t=new Array(e.length+1),n=new Array(e.length+1);for(let r=0;r<=e.length;r++)t[r]=r;for(let r=1;r<=h.length;r++){n[0]=r;for(let i=1;i<=e.length;i++){let a=h[r-1]===e[i-1]?0:1;n[i]=Math.min(t[i]+1,n[i-1]+1,t[i-1]+a)}for(let i=0;i<=e.length;i++)t[i]=n[i]}return t[e.length]}function vL(h){let e=h.toLowerCase(),t=null,n=1/0;for(let i of Jg){let a=Ev(e,i.toLowerCase());a<n&&(n=a,t=i)}let r=Math.max(2,Math.floor(e.length/3));return n<=r?t:null}function wL(h,e){return xL(h)?h:Tv(h)?Wh[h]:(typeof h=="string"&&h.length>0&&e?.(h),Zg)}function SL(h){if(!h||typeof h!="object")return h;let e=h;if(typeof e.chartType=="string"){let t=Is(e.chartType);t!==e.chartType&&(e.chartType=t)}for(let[t,n]of Object.entries(bL))e[t]!=null&&(e[n]==null&&(e[n]=e[t]),delete e[t]);return h}var jF=["bar","column","gantt","unknown"];function wc(h){return Qg(h)||jF.includes(h)}var uo=class{static createChart(e,t,n){return this.validateChartType(t),this.validateRequired(e,"chartId"),this.validateRequired(n,"source"),{chartId:e,chartType:t,timestamp:Date.now(),data:{source:n}}}static deleteChart(e,t,n){return this.validateChartType(t),this.validateRequired(e,"chartId"),this.validateRequired(n,"source"),{chartId:e,chartType:t,timestamp:Date.now(),data:{source:n}}}static changeChartType(e,t,n){return this.validateChartType(t),this.validateChartType(n),this.validateRequired(e,"chartId"),{chartId:e,chartType:n,timestamp:Date.now(),data:{oldChartType:t,newChartType:n}}}static downloadChart(e,t){return this.validateChartType(t),this.validateRequired(e,"chartId"),{chartId:e,chartType:t,timestamp:Date.now(),data:{}}}static openChart(e,t,n,r){return this.validateRequired(e,"chartId"),this.validateRequired(t,"source"),this.validateRequired(n,"action"),this.validateRequired(r,"trigger"),{chartId:e,chartType:"unknown",timestamp:Date.now(),data:{source:t,action:n,trigger:r}}}static saveChart(e,t,n){return this.validateChartType(t),this.validateRequired(e,"chartId"),{chartId:e,chartType:t,timestamp:Date.now(),data:{performance:n}}}static validateChartType(e){if(!wc(e))throw new Error(`Invalid chart type: ${e}. Must be one of: bar, line, pie, scatter, area, column, donut, waterfall, mekko, barMekko, clusteredBar, stackedBar, stackedBar100, bubble, unknown`)}static validateRequired(e,t){if(e==null||e==="")throw new Error(`Required field '${t}' is missing or empty`)}};I();I();var Cr=class{static operationFailed(e,t,n,r={}){if(this.validateRequired(t,"operation"),this.validateRequired(n,"component"),this.validateRequired(e,"error"),r.chart_type&&!wc(r.chart_type))throw new Error(`Invalid chart_type in error metadata: ${r.chart_type}`);return{error_name:e.name,error_message:e.message,stack_trace:e.stack?.substring(0,2e3),component:n,operation:t,chart_type:r.chart_type,timestamp:Date.now(),metadata:{...r,auto_tracked:!0}}}static uiInteractionFailed(e,t,n={}){if(this.validateRequired(t,"component"),this.validateRequired(e,"error"),n.chart_type&&!wc(n.chart_type))throw new Error(`Invalid chart_type in error metadata: ${n.chart_type}`);return{error_name:e.name,error_message:e.message,stack_trace:e.stack?.substring(0,2e3),component:t,chart_type:n.chart_type,timestamp:Date.now(),metadata:{...n,auto_tracked:!0}}}static systemError(e,t,n={}){return this.validateRequired(t,"component"),this.validateRequired(e,"error"),{error_name:e.name,error_message:e.message,stack_trace:e.stack?.substring(0,2e3),component:t,timestamp:Date.now(),metadata:{...n,auto_tracked:!0,system_level:!0}}}static validateRequired(e,t){if(e==null||e==="")throw new Error(`Required field '${t}' is missing or empty in error event`)}};I();var qt="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";var On=class h{constructor(e){this.isOpen=!1;this.clickOutsideHandler=null;this.eventBusUnsubscribe=null;this.eventBusUnsubscribeOpen=null;this.config=e;let{width:t="120px",zIndex:n=10001}=e;if(this.wrapper=document.createElement("div"),this.wrapper.className="cb-combobox-wrapper",this.wrapper.style.width=t,this.wrapper.style.fontFamily=qt,this.dropdown=document.createElement("div"),this.dropdown.className="cb-combobox-dropdown",this.dropdown.style.zIndex=String(n),this.dropdown.style.fontFamily=qt,this.isCustomMode()){let r=this.getCustomConfig();r.positioning==="fixed"&&r.anchorElement&&this.setupFixedPositioning(r.anchorElement)}this.setupBaseEventListeners(),this.setupEventBusListeners()}static{this.activeDropdown=null}static{this.DROPDOWN_STYLES=`
|
|
52
52
|
/* ComboBox Styles */
|
|
53
53
|
.cb-combobox-wrapper {
|
package/llms.txt
CHANGED
|
@@ -145,6 +145,20 @@ Angular / Svelte / Solid / plain HTML — custom element, no peer dependency:
|
|
|
145
145
|
set `.chartData` as a PROPERTY; events are CustomEvents (ready/change/mode/error)
|
|
146
146
|
All bindings mount once, patch on chartData change, and destroy on unmount.
|
|
147
147
|
|
|
148
|
+
NO BUNDLER? The react/vue subpaths import `react` / `vue` as bare specifiers, so a
|
|
149
|
+
plain HTML page needs an import map mapping BOTH the framework AND the subpath
|
|
150
|
+
(subpaths need the explicit file, e.g. `.../@chartbuddy.io/embed/react.mjs`):
|
|
151
|
+
```html
|
|
152
|
+
<script type="importmap">{"imports":{
|
|
153
|
+
"react":"https://esm.sh/react@19",
|
|
154
|
+
"react-dom/client":"https://esm.sh/react-dom@19/client",
|
|
155
|
+
"@chartbuddy.io/embed/react":"https://unpkg.com/@chartbuddy.io/embed/react.mjs"
|
|
156
|
+
}}</script>
|
|
157
|
+
```
|
|
158
|
+
Then use React.createElement (no JSX — there is no build step).
|
|
159
|
+
For a standalone artifact, prefer plain `new Insight()` or the custom element:
|
|
160
|
+
neither needs an import map or a framework.
|
|
161
|
+
|
|
148
162
|
## Agent observation (round-trip / visual QA)
|
|
149
163
|
|
|
150
164
|
Browsers cannot rewrite the HTML file. Agents (Cursor, Claude, CI) can —
|
|
@@ -221,6 +235,14 @@ Aliases: `bubble`→`scatter`, `donut`→`pie`.
|
|
|
221
235
|
Beta: `barMekko`.
|
|
222
236
|
CHARTBUDDY:GENERATED-CHART-TYPES:END
|
|
223
237
|
|
|
238
|
+
Aliases are input-only and SEED DEFAULTS — they are not just renames:
|
|
239
|
+
chartType: 'donut' → pie with pie.innerRadiusRatio 0.5 (a real hole)
|
|
240
|
+
chartType: 'pie' → pie with pie.innerRadiusRatio 0 (a full pie)
|
|
241
|
+
chartType: 'bubble' → scatter with a larger point diameter
|
|
242
|
+
For a donut just pass `chartType: 'donut'`; do NOT also set innerRadiusRatio
|
|
243
|
+
unless you want a different hole size. getChartData() reports the CANONICAL type
|
|
244
|
+
(a donut round-trips as `pie` + innerRadiusRatio 0.5 — that is correct, not loss).
|
|
245
|
+
|
|
224
246
|
### Validation (read this before generating a config)
|
|
225
247
|
|
|
226
248
|
`new Insight({ chartData })` and `setChartData()` / `setData()` / `update()`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chartbuddy.io/embed",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.53",
|
|
4
4
|
"description": "Embed ChartBuddy Insights via new Insight() — default view-only with hover ball (Download/Drag to slide/Edit; Done exits edit); editable:true for the full editor. Claude/Visualizer: import from this package (unpkg → readable API stub → single-file). Read llms.txt. Spreadsheet not included.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./chartbuddy-embed.api.mjs",
|
package/webapp-entry.js
CHANGED
|
@@ -6,7 +6,7 @@ var ChartBuddyWebApp=(()=>{var Jg=Object.create;var xd=Object.defineProperty;var
|
|
|
6
6
|
pointer-events: none;
|
|
7
7
|
font-size: 72px;
|
|
8
8
|
white-space: nowrap;
|
|
9
|
-
`,document.body.appendChild(t),this.warmupContainer=t,t}async warmUpFontsBlocking(e){let t=[...new Set(e.filter(i=>typeof i=="string").map(i=>i.trim()).filter(i=>i.length>0).filter(i=>!this.isSystemFont(i)))];if(t.length===0)return;if(this.loadGoogleFonts(t),document.readyState==="loading"||!document.body){await this.ensureFontsReady(t);return}let r=this.getWarmupContainer(),n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,;:!?";t.forEach(i=>{let a=`cb-font-warmup-${i.replace(/[^a-z0-9]+/gi,"-").toLowerCase()}`;if(!r.querySelector(`[data-font-warmup-id="${a}"]`)){let s=document.createElement("span");s.dataset.fontWarmupId=a,s.style.fontFamily=`"${i}"`,s.textContent=n,r.appendChild(s);let o=document.createElement("span");o.dataset.fontWarmupId=`${a}-bold`,o.style.fontFamily=`"${i}"`,o.style.fontWeight="700",o.textContent=n,r.appendChild(o);let l=document.createElement("span");l.dataset.fontWarmupId=`${a}-italic`,l.style.fontFamily=`"${i}"`,l.style.fontStyle="italic",l.textContent=n,r.appendChild(l)}}),r.offsetHeight,await this.ensureFontsReady(t),await this.markFontsWarmed(t)}loadFont(e){this.loadedFonts.has(e)||this.isSystemFont(e)||this.loadGoogleFonts([e])}ensureFontLoaded(e){this.isSystemFont(e)||this.loadedFonts.has(e)||this.loadGoogleFonts([e])}extractFontsFromChartData(e){let t=new Set;if(!e||typeof e!="object")return t;let r=(n,i=new WeakSet)=>{if(!(n===null||typeof n!="object")&&!i.has(n)){if(i.add(n),Array.isArray(n)){n.forEach(a=>r(a,i));return}if("fontFamily"in n&&typeof n.fontFamily=="string"&&n.fontFamily.trim()){let a=n.fontFamily.trim();this.isSystemFont(a)||t.add(a)}if("labelFontFamily"in n&&typeof n.labelFontFamily=="string"&&n.labelFontFamily.trim()){let a=n.labelFontFamily.trim();this.isSystemFont(a)||t.add(a)}for(let a in n)if(Object.prototype.hasOwnProperty.call(n,a))try{r(n[a],i)}catch{}}};return r(e),t}loadFontsFromChartData(e,t){if(!e)return;let r=this.extractFontsFromChartData(e);if(r.size===0){t&&t();return}let n=this.getAvailableFonts(),i=new Set(n.map(s=>s.toLowerCase())),a=Array.from(r).filter(s=>{let o=s.toLowerCase();return!(this.loadedFonts.has(s)||i.has(o))});if(a.length===0){console.log("[FontService] All fonts from chart data are already available (in cache/backend)"),t&&this.ensureFontsReady(Array.from(r)).then(()=>t()).catch(()=>t());return}console.log("[FontService] Loading fonts from chart data (not in organization list):",a),this.loadGoogleFonts(a),t&&this.ensureFontsReady(Array.from(r)).then(()=>t()).catch(()=>t())}getUnknownFontsFromChartData(e){if(!e)return[];let t=this.extractFontsFromChartData(e);if(t.size===0)return[];let r=new Set(this.getAvailableFonts().map(n=>n.toLowerCase()));return Array.from(t).filter(n=>this.loadedFonts.has(n)?!1:!r.has(n.toLowerCase()))}prepareFontsForChartData(e){if(!e)return{hasUnknownFonts:!1,readyPromise:Promise.resolve()};let t=this.extractFontsFromChartData(e);if(t.size===0)return{hasUnknownFonts:!1,readyPromise:Promise.resolve()};let r=this.getUnknownFontsFromChartData(e),n=r.length>0;return n&&console.log("[FontService] Blocking initial chart render for unknown fonts:",r),this.loadFontsFromChartData(e),{hasUnknownFonts:n,readyPromise:n?this.warmUpFontsBlocking(Array.from(t)):this.ensureFontsReady(Array.from(t))}}reset(){this.customFonts=[],this.loadedFonts.clear(),this.fontDeclarationPromises.clear(),this.fontReadyPromises.clear(),this.warmedFonts.clear(),this.initialized=!1,this.defaultFont="Arial",this.warmupContainer&&this.warmupContainer.parentNode&&this.warmupContainer.parentNode.removeChild(this.warmupContainer),this.warmupContainer=null,this.defaultFonts=["Arial","Calibri","Helvetica","Verdana","Tahoma","Trebuchet MS","Times New Roman","Courier New"]}},ce=wd.getInstance()});var Cu={};vd(Cu,{colorService:()=>mt,default:()=>sm});var Sd,mt,sm,En=It(()=>{Sd=class c{constructor(){this.defaultColors=["#98df8a","#17becf","#2c808c","#98df8a","#e377c2","#7f7f7f","#bcbd22","#17becf","#393b79","#637939","#8c6d31","#843c39","#7b4173","#a55194","#c7c7c7","#ffbb78","#98df8a","#ff9896","#ff7f0e","#2ca02c","#d62728","#9467bd","#8c564b","#e377c2","#7f7f7f","#bcbd22","#17becf","#393b79","#637939","#8c6d31","#843c39","#7b4173","#a55194","#c7c7c7","#ffbb78","#98df8a","#ff9896"];this.customColors=[];this.initialized=!1;this.resolveReady=()=>{};this.readyPromise=new Promise(e=>{this.resolveReady=e})}static getInstance(){return c.instance||(c.instance=new c),c.instance}initialize(e){console.log("[ColorService] Initializing with settings:",e),this.setOrganizationColors(e.colorScheme||[])}isInitialized(){return this.initialized}async ready(){return this.readyPromise}getAvailableColors(){let e=[];this.customColors&&this.customColors.length>0&&e.push(...this.customColors),e.push(...this.defaultColors),console.log("[ColorService] getAvailableColors result count:",e.length);let t=new Set;return e.filter(r=>{if(!r)return!1;let n=r.toUpperCase();return t.has(n)?!1:(t.add(n),!0)})}setOrganizationColors(e){this.customColors=Array.isArray(e)?[...e]:[],console.log("[ColorService] Organization colors updated:",this.customColors.length),this.initialized||(this.initialized=!0,this.resolveReady())}getDefaultColors(){return[...this.defaultColors]}getCustomColors(){return[...this.customColors]}hasColor(e){let t=this.getAvailableColors(),r=e.toUpperCase();return t.some(n=>n.toUpperCase()===r)}addCustomColor(e){let t=e.toUpperCase();this.customColors.some(r=>r.toUpperCase()===t)||this.customColors.push(e)}removeCustomColor(e){let t=e.toUpperCase();this.customColors=this.customColors.filter(r=>r.toUpperCase()!==t)}reset(){this.customColors=[],this.initialized=!1,this.defaultColors=["#242424","#484848","#6D6D6D","#919191","#B6B6B6","#DADADA","#FFFFFF","#8B0000","#FF4500","#FFD700","#ADFF2F","#1E90FF","#0000FF","#8B00FF","#FF00FF","#F1E6E6","#FFE6E6","#FFF0E6","#F2FFE6","#E6F3FF","#E6E6FF","#F3E6FF","#FFE6FF","#D9CCCC","#FFCCCC","#FFE1CC","#E6FFCC","#CCE6FF","#CCCCFF","#E6CCFF","#FFCCFF","#B38B8B","#FFB3B3","#FFD9B3","#CCFFB3","#B3CCFF","#B3B3FF","#CCB3FF","#FFB3FF","#806666","#E69999","#FFCC99","#99FF99","#99CCFF","#9999FF","#CC99FF","#FF99FF","#4D3333","#CC6666","#FFB366","#66CC66","#6699FF","#6666FF","#9966FF","#FF66FF"]}},mt=Sd.getInstance(),sm=mt});function Ar(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(c){let e=Math.random()*16|0;return(c==="x"?e:e&3|8).toString(16)})}var Ha=It(()=>{});var $r,_o=It(()=>{Ha();$r=class{constructor(e,t="chart_",r=null){this.platform=e,this.storagePrefix=t,this.recentColorsKey="recent_colors",this.organizationColorsKey="organization_colors",this.presentationColorsKey="presentation_colors",this.maxRecentColors=8,this.chartbuddyUrl=r}setChartbuddyUrl(e){this.chartbuddyUrl=e}isStorageAvailable(){return!!this.platform}getStorageKey(e){return`${this.storagePrefix}${e}`}static generateUUID(){return Ar()}async removeItems(e,t){e.length>0&&this.platform&&(await this.platform.storage.remove(e),console.log(`[Storage] Removed keys: ${e.join(", ")}`)),t&&t()}async remove(e=null,t){if(!this.platform){t&&t();return}let r=await this.platform.storage.get(null),n=[];for(let i in r)(!e||i.startsWith(e))&&n.push(i);n.length>0&&(await this.platform.storage.remove(n),console.log(`[Storage] Removed ${n.length} keys with prefix: ${e||"all"}`)),t&&t()}async removeAllData(e){if(!this.platform){e&&e(new Error("Platform not initialized"));return}try{let t=await this.platform.storage.get(null),r=Object.keys(t);if(r.length===0){e&&e(null,0);return}await this.platform.storage.remove(r),console.log(`[Storage] Successfully removed all ${r.length} items`),e&&e(null,r.length)}catch(t){e&&e(t)}}async clearAll(e){return this.removeAllData(e)}async getOrganizationColors(e){if(!this.platform){console.warn("[Storage] Cannot get organization colors: Platform not initialized"),e([]);return}let r=(await this.platform.storage.get([this.organizationColorsKey]))[this.organizationColorsKey]||[];console.log(`[Storage] Retrieved ${r.length} organization colors from storage`),e(r)}async getDefaultColors(){return this.platform?(await this.platform.storage.get([this.organizationColorsKey]))[this.organizationColorsKey]||[]:[]}async setOrganizationColors(e,t){if(!Array.isArray(e)||!this.platform){console.warn("[Storage] Cannot set organization colors: Invalid input or platform not initialized"),t&&t();return}console.log(`[Storage] Persisting ${e.length} organization colors to storage`),await this.platform.storage.set({[this.organizationColorsKey]:e}),t&&t()}async clearOrganizationColors(e){if(!this.platform){e&&e();return}await this.platform.storage.remove([this.organizationColorsKey]),e&&e()}async getPresentationColors(e,t){if(!e||!this.platform){t([]);return}let r=`${this.presentationColorsKey}_${e}`,n=await this.platform.storage.get([r]);t(n[r]||[])}async setPresentationColors(e,t,r){if(!e||!Array.isArray(t)||!this.platform){r&&r();return}let n=`${this.presentationColorsKey}_${e}`;await this.platform.storage.set({[n]:t}),r&&r()}async getRecentColors(e){if(!this.platform){e([]);return}let t=await this.platform.storage.get([this.recentColorsKey]);e(t[this.recentColorsKey]||[])}async addRecentColor(e,t){let r=this.normalizeColorToHex(e);if(!r||!this.platform){t&&t([]);return}this.getRecentColors(async n=>{n=n.filter(i=>i!==r),n.unshift(r),n=n.slice(0,this.maxRecentColors),this.platform&&await this.platform.storage.set({[this.recentColorsKey]:n}),t&&t(n)})}async clearRecentColors(e){this.platform&&await this.platform.storage.remove([this.recentColorsKey]),e&&e()}static googleRgbToHex(e){if(!e)return null;let t=Math.round((e.red||0)*255),r=Math.round((e.green||0)*255),n=Math.round((e.blue||0)*255);return`#${t.toString(16).padStart(2,"0")}${r.toString(16).padStart(2,"0")}${n.toString(16).padStart(2,"0")}`}normalizeColorToHex(e){if(!e||typeof e!="string")return null;let t=e.trim();if(t.startsWith("#")){let n=t.toUpperCase();return n.length===4&&(n="#"+n[1]+n[1]+n[2]+n[2]+n[3]+n[3]),/^#[0-9A-F]{6}$/.test(n)?n:null}if(/^[0-9A-Fa-f]{6}$/.test(t))return"#"+t.toUpperCase();let r=t.match(/^rgba?\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*[\d.]+)?\s*\)$/i);if(r){let n=Math.min(255,Math.max(0,parseInt(r[1],10))),i=Math.min(255,Math.max(0,parseInt(r[2],10))),a=Math.min(255,Math.max(0,parseInt(r[3],10)));return"#"+n.toString(16).padStart(2,"0").toUpperCase()+i.toString(16).padStart(2,"0").toUpperCase()+a.toString(16).padStart(2,"0").toUpperCase()}return null}async saveLastOpenedChartId(e){await this.platform.storage.set({lastOpenedChartId:e})}async getLastOpenedChartId(e){let t=await this.platform.storage.get(["lastOpenedChartId"]);e(t.lastOpenedChartId||null)}async getTemplates(){if(!this.chartbuddyUrl)return[];try{let t=(await this.platform.storage.get(["token"])).token;if(!t)return[];let r=await fetch(`${this.chartbuddyUrl}/api/chart-templates`,{method:"GET",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"}});if(r.ok){let n=await r.json();return Array.isArray(n)?n:n?.data&&Array.isArray(n.data)?n.data:[]}}catch(e){console.error("[Storage] Failed to fetch templates:",e)}return[]}}});var Nr,Vr,$o=It(()=>{Nr="1.7.52",Vr="chart-buddy"});var Cd,kd,Ad,Wa,ku=It(()=>{_o();$o();Cd=class{async get(e){return new Promise(t=>{chrome.storage.local.get(e,r=>{t(r)})})}async set(e){return new Promise(t=>{chrome.storage.local.set(e,()=>{t()})})}async remove(e){return new Promise(t=>{chrome.storage.local.remove(e,()=>{t()})})}async clear(){return new Promise(e=>{chrome.storage.local.clear(()=>{e()})})}},kd=class{getURL(e){return chrome.runtime.getURL(e)}getVersion(){return Nr}getAppName(){return Vr}isDevelopmentBuild(){return!1}getManifest(){return chrome.runtime.getManifest()}async sendMessage(e){return new Promise((t,r)=>{chrome.runtime.sendMessage(e,n=>{chrome.runtime.lastError?r(chrome.runtime.lastError):t(n)})})}},Ad=class{detect(){let e=window.location.href;return e.includes("canva.com")?"Canva":e.includes("docs.google.com/presentation")?"GSlides":e.includes("docs.google.com/spreadsheets")||e.includes("sheets.google.com")?"GSheets":e.includes("notion.com")||e.includes("notion.so")?"Notion":e.includes("figma.com")?"Figma":e.includes("miro.com")?"Miro":e.includes("powerbi.com")?"PowerBI":e.includes("onedrive.live.com")||e.includes("microsoft365.com")?"PowerPoint":"WebApp"}getPresentationId(){let t=window.location.href.match(/\/presentation\/d\/([a-zA-Z0-9-_]+)/);return t?t[1]:null}},Wa=class{constructor(){this.type="extension";this.storage=new Cd;this.runtime=new kd;this.host=new Ad;this.chartBuddyStorage=new $r(this)}};typeof window<"u"&&(window.ChromeExtensionProvider=Wa)});var Ld,Md,Td,On,Dd=It(()=>{_o();$o();Ld=class{constructor(){this.prefix="cb_"}async get(e){let t={},r=[];return typeof e=="string"?r=[e]:Array.isArray(e)?r=e:e&&typeof e=="object"&&(r=Object.keys(e),Object.assign(t,e)),r.forEach(n=>{let i=localStorage.getItem(this.prefix+n);if(i!==null)try{t[n]=JSON.parse(i)}catch{t[n]=i}}),t}async set(e){Object.entries(e).forEach(([t,r])=>{localStorage.setItem(this.prefix+t,JSON.stringify(r))})}async remove(e){(Array.isArray(e)?e:[e]).forEach(r=>localStorage.removeItem(this.prefix+r))}async clear(){Object.keys(localStorage).forEach(e=>{e.startsWith(this.prefix)&&localStorage.removeItem(e)})}},Md=class{getURL(e){return e}getVersion(){return Nr}getAppName(){return Vr}isDevelopmentBuild(){return!1}getManifest(){return{version:Nr,name:Vr,_sys_ctx:this.isDevelopmentBuild()?"d8n3x5q1":"kz6p9m2v"}}async sendMessage(e){return console.log("[WebApp] Mock sendMessage:",e),null}},Td=class{detect(){return"WebApp"}getPresentationId(){return"webapp-mock-presentation-id"}},On=class{constructor(){this.type="webapp";this.storage=new Ld;this.runtime=new Md;this.host=new Td;this.chartBuddyStorage=new $r(this)}};typeof window<"u"&&(window.WebAppProvider=On)});function Li(){if(typeof window>"u")return!1;let c=window;return typeof c.__TAURI__<"u"||typeof c.__TAURI_INTERNALS__<"u"?!0:typeof navigator<"u"&&/tauri/i.test(navigator.userAgent)}var Ed,Od,Pd,No,Ga=It(()=>{_o();$o();Ed=class{constructor(){this.prefix="cb_";this.map=new Map}storageKey(e){return`${this.prefix}${e}`}async get(e){let t={},r=[];return typeof e=="string"?r=[e]:Array.isArray(e)?r=e:e&&typeof e=="object"&&(r=Object.keys(e),Object.assign(t,e)),r.forEach(n=>{let i=this.map.get(this.storageKey(n));if(i!==void 0)try{t[n]=JSON.parse(i)}catch{t[n]=i}}),t}async set(e){Object.entries(e).forEach(([t,r])=>{this.map.set(this.storageKey(t),JSON.stringify(r))})}async remove(e){(Array.isArray(e)?e:[e]).forEach(r=>this.map.delete(this.storageKey(r)))}async clear(){let e=[];this.map.forEach((t,r)=>{r.startsWith(this.prefix)&&e.push(r)}),e.forEach(t=>this.map.delete(t))}},Od=class{getURL(e){return e}getVersion(){return Nr}getAppName(){return Vr}isDevelopmentBuild(){return!1}getManifest(){return{version:Nr,name:Vr,_sys_ctx:this.isDevelopmentBuild()?"d8n3x5q1":"kz6p9m2v"}}async sendMessage(e){return console.log("[Tauri] sendMessage (no-op):",e),null}},Pd=class{detect(){return"Tauri"}getPresentationId(){return"tauri-desktop"}},No=class{constructor(){this.type="tauri";this.storage=new Ed;this.runtime=new Od;this.host=new Pd;this.chartBuddyStorage=new $r(this)}}});var kt,Id,Ua=It(()=>{ku();Dd();Ga();kt=class{static setPlatform(e){this.instance=e}static getPlatform(){let e=Li();return e&&this.instance!==void 0&&this.instance.type!=="tauri"&&(this.instance=void 0),this.instance?this.instance:e?(this.instance=new No,this.instance):(typeof chrome<"u"&&chrome.runtime&&typeof chrome.runtime.getURL=="function"&&!!chrome.runtime.id?this.instance=new Wa:this.instance=new On,this.instance)}},Id=kt.getPlatform()});var hm,_d,er,Yo,Ru=It(()=>{hm=["Arial","Calibri","Helvetica","Verdana","Tahoma","Trebuchet MS","Times New Roman","Courier New"],_d={isExpired:!1,isActive:!0,daysRemaining:null,expiresAt:null},er={uploadMethod:"google-drive",featureFlags:{},canManageFeatureFlags:!1,organizationSettings:{colorScheme:["#3B82F6","#10B981","#F59E0B","#9fa90f"],fonts:hm,customFonts:[],defaultFont:"Arial"},trialStatus:_d},Yo={production:"https://chartbuddy.io",acceptance:"https://cb-acc.xyz",current:"production"}});function $d(c){if(c.fonts!==void 0){if(!Array.isArray(c.fonts))return console.warn("[FontCacheManager] Invalid fonts: expected array, got",typeof c.fonts),!1;if(!c.fonts.every(e=>typeof e=="string"&&e.trim().length>0))return console.warn("[FontCacheManager] Invalid fonts: contains non-string or empty values"),!1}if(c.customFonts!==void 0){if(!Array.isArray(c.customFonts))return console.warn("[FontCacheManager] Invalid customFonts: expected array, got",typeof c.customFonts),!1;if(!c.customFonts.every(e=>typeof e=="string"&&e.trim().length>0))return console.warn("[FontCacheManager] Invalid customFonts: contains non-string or empty values"),!1}return c.useDefaultFonts!==void 0&&typeof c.useDefaultFonts!="boolean"?(console.warn("[FontCacheManager] Invalid useDefaultFonts: expected boolean, got",typeof c.useDefaultFonts),!1):!0}var jo,Fn,Nd=It(()=>{Ua();jo=class c{static{this.STORAGE_KEY="chartbuddy_fonts_cache"}static{this.CACHE_VERSION="1.0"}constructor(){}static getInstance(){return c.instance||(c.instance=new c),c.instance}async getCachedFonts(){try{let t=(await kt.getPlatform().storage.get([c.STORAGE_KEY]))[c.STORAGE_KEY];if(!t)return null;if(typeof t!="object"||t===null)return console.warn("[FontCacheManager] Invalid cache data type, clearing"),await this.clearCache(),null;if(t.version!==c.CACHE_VERSION)return console.log("[FontCacheManager] Cache version mismatch, invalidating"),await this.clearCache(),null;let r={fonts:t.fonts,customFonts:t.customFonts,defaultFont:t.defaultFont,useDefaultFonts:t.useDefaultFonts};return $d(r)?(console.log("[FontCacheManager] Loaded fonts from cache:",{defaultFont:t.defaultFont,fonts:t.fonts?.length??0,customFonts:t.customFonts?.length??0,cachedAt:new Date(t.cachedAt).toISOString()}),r):(console.warn("[FontCacheManager] Cached data validation failed, clearing cache"),await this.clearCache(),null)}catch(e){return console.warn("[FontCacheManager] Failed to get cached fonts:",e),null}}async saveFontsToCache(e){if(!$d(e))throw new Error("[FontCacheManager] Invalid font settings, cannot save to cache");try{let t={fonts:e.fonts,customFonts:e.customFonts,defaultFont:e.defaultFont,useDefaultFonts:e.useDefaultFonts,cachedAt:Date.now(),version:c.CACHE_VERSION},n=JSON.stringify(t).length,i=100*1024;n>i&&(console.warn(`[FontCacheManager] Cache size (${n} bytes) exceeds limit (${i} bytes), clearing old cache`),await this.clearCache()),await kt.getPlatform().storage.set({[c.STORAGE_KEY]:t})}catch(t){throw console.error("[FontCacheManager] Failed to save fonts to cache:",t),t}}async validateAndSyncFonts(e){if(!$d(e))return console.warn("[FontCacheManager] Invalid backend font settings, using cached data"),{hasChanges:!1,fonts:await this.getCachedFonts()??{fonts:[],customFonts:[],defaultFont:"Arial",useDefaultFonts:!0}};let t=null;try{console.log("[FontCacheManager] Validating fonts against cache..."),t=await this.getCachedFonts();let r=this.fontsHaveChanged(t,e);return r&&await this.saveFontsToCache(e),{hasChanges:r,fonts:e}}catch(r){return console.error("[FontCacheManager] Error validating fonts:",r),{hasChanges:!1,fonts:t??{fonts:[],customFonts:[],defaultFont:"Arial",useDefaultFonts:!0}}}}fontsHaveChanged(e,t){if(!e)return!0;let r=(n,i)=>!n&&!i?!0:!n||!i||n.length!==i.length?!1:n.every((a,s)=>a===i[s]);return!r(e.fonts,t.fonts)||!r(e.customFonts,t.customFonts)||e.defaultFont!==t.defaultFont||e.useDefaultFonts!==t.useDefaultFonts}async clearCache(){try{await kt.getPlatform().storage.remove([c.STORAGE_KEY]),console.log("[FontCacheManager] Cache cleared")}catch(e){console.warn("[FontCacheManager] Failed to clear cache:",e)}}},Fn=jo.getInstance()});var Bu={};vd(Bu,{CHARTBUDDY_CONFIG_UPDATED_EVENT:()=>Fu,ConfigManager:()=>ne,getConfigManager:()=>At});function At(){return ne.getInstance()}var Fu,ne,st=It(()=>{Ru();Ua();Jt();Nd();En();Fu="chartbuddy:config-updated",ne=class c{constructor(){this.debugEnabled=!1;this.debugAxisBinding=!0;this.loadingPromise=void 0;this.fontPreloadPromise=void 0;this.onLoadCallbacks=[];if(this.config={chartbuddyUrl:this.detectEnvironmentUrl(),bootOptions:{...er},environment:{...Yo},loaded:!1,loadedAt:void 0},this.config.environment.current=this.detectEnvironment(),this.debugEnabled=this.computeDebugEnabled(this.config.chartbuddyUrl),typeof window<"u"&&window.localStorage)try{window.localStorage.getItem("CHARTBUDDY_DEBUG_MODE")==="true"&&(this.debugEnabled=!0),window.localStorage.getItem("CHARTBUDDY_DEBUG_AXIS_BINDING")==="false"&&(this.debugAxisBinding=!1)}catch{}}static{this.instance=void 0}computeDebugEnabled(e){let t=e.includes("cb-acc.xyz")||e.includes("stag"),r=e.includes("localhost")||e.includes("127.0.0.1"),n=kt.getPlatform().runtime.isDevelopmentBuild();return t||r||n}static getInstance(){return c.instance===void 0&&(c.instance=new c),c.instance}isDebugEnabled(){return this.debugEnabled}isDebugAxisBindingEnabled(){return this.debugAxisBinding}isWaterfallSegmentedBarsEnabled(){return!0}isChartOrientationEnabled(){return!0}isBarMekkoEnabled(){return this.config?.bootOptions?.featureFlags?.barMekko===!0}isDevelopment(){let e=this.config.chartbuddyUrl;return e.includes("localhost")||e.includes("127.0.0.1")}isAcceptance(){return this.config.chartbuddyUrl.includes("cb-acc.xyz")}isProduction(){return!this.isDevelopment()&&!this.isAcceptance()}setDebugMode(e){this.debugEnabled=e}setDebugAxisBindingMode(e){this.debugAxisBinding=e}detectEnvironmentUrl(){return Yo.production}detectEnvironment(){return this.config.chartbuddyUrl.includes("cb-acc.xyz")?"acceptance":"production"}getConfig(){return{...this.config}}getChartbuddyUrl(){return this.config.chartbuddyUrl}getBootOptions(){return{...this.config.bootOptions}}getEnvironment(){return{...this.config.environment}}getTrialStatus(){return{...this.config.bootOptions.trialStatus}}isTrialExpired(){return this.config.bootOptions.trialStatus.isExpired}isLoaded(){return this.config.loaded}onLoad(e){this.config.loaded?e():this.onLoadCallbacks.push(e)}setChartbuddyUrl(e){this.config.chartbuddyUrl=e,this.config.environment.current=this.detectEnvironment(),this.debugEnabled=this.computeDebugEnabled(e)}async loadConfig(){if(this.loadingPromise)return this.loadingPromise;if(this.config.loaded&&this.config.loadedAt&&Date.now()-this.config.loadedAt<3e5){console.log("[ConfigManager] Config already loaded recently, skipping reload");return}this.loadingPromise=this.loadConfigInternal();try{await this.loadingPromise}finally{this.loadingPromise=void 0}}async preloadFontSettings(){if(this.fontPreloadPromise)return this.fontPreloadPromise;this.fontPreloadPromise=this.preloadFontSettingsInternal();try{await this.fontPreloadPromise}finally{this.fontPreloadPromise=void 0}}async loadConfigInternal(){try{if(kt.getPlatform().type==="webapp"){console.log("[ConfigManager] Standalone mode (WebApp): using local defaults"),this.config.bootOptions={...er},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks();return}console.log("[ConfigManager] Loading configuration from backend...");let t=await this.getAuthToken();if(!t){console.warn("[ConfigManager] No authentication token available, using defaults"),Fn.clearCache().catch(n=>{console.warn("[ConfigManager] Failed to clear font cache on auth failure:",n)}),this.config.bootOptions={...er},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks();return}let r=await this.fetchAuthenticatedJson("/api/user/boot-settings",t);if(r.ok){let n=await r.json(),i=n.uploadMethod??er.uploadMethod,a=n.featureFlags??er.featureFlags,s=n.canManageFeatureFlags??er.canManageFeatureFlags,o=n.organizationSettings??er.organizationSettings,l=n.trialStatus??_d;this.config.bootOptions={uploadMethod:i,featureFlags:a,canManageFeatureFlags:s,organizationSettings:o,trialStatus:l},console.log("[ConfigManager] Organization Settings received:",{colorSchemeCount:o.colorScheme?.length||0,fontCount:o.fonts?.length||0}),this.config.loaded=!0,this.config.loadedAt=Date.now(),console.log("[ConfigManager] \u2705 Configuration loaded successfully:",{uploadMethod:this.config.bootOptions.uploadMethod,loadedAt:new Date(this.config.loadedAt).toISOString()}),await this.initializeFontService(),this.initializeColorService();let d={fonts:o.fonts??[],customFonts:o.customFonts??[],defaultFont:o.defaultFont??"Noto Sans"};this.validateFontCache(d).catch(h=>{console.warn("[ConfigManager] Background font validation failed:",h)}),this.triggerOnLoadCallbacks()}else console.warn(`[ConfigManager] Failed to fetch boot settings (HTTP ${r.status}), using defaults`),(r.status===401||r.status===403)&&Fn.clearCache().catch(n=>{console.warn("[ConfigManager] Failed to clear font cache on auth failure:",n)}),this.config.bootOptions={...er},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks()}catch(e){console.error("[ConfigManager] Error loading configuration:",e),console.log("[ConfigManager] Using default configuration"),this.config.bootOptions={...er},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks()}}async preloadFontSettingsInternal(){try{let e=await this.getAuthToken();if(!e)return;let t=await this.fetchAuthenticatedJson("/api/user/font-settings",e);if(!t.ok){(t.status===401||t.status===403)&&Fn.clearCache().catch(n=>{console.warn("[ConfigManager] Failed to clear font cache on preload auth failure:",n)});return}let r=await t.json();ce.isInitialized()?ce.reinitialize(r):ce.primeEarly(r)}catch(e){console.warn("[ConfigManager] Font preload failed:",e)}}triggerOnLoadCallbacks(){console.log(`[ConfigManager] Triggering ${this.onLoadCallbacks.length} onLoad callbacks`),this.onLoadCallbacks.forEach(e=>{try{e()}catch(t){console.error("[ConfigManager] Error in onLoad callback:",t)}}),this.onLoadCallbacks=[],typeof window<"u"&&window.dispatchEvent(new CustomEvent(Fu,{detail:{bootOptions:this.getBootOptions(),loadedAt:this.config.loadedAt}}))}async initializeFontService(){if(ce.isInitialized()){console.log("[ConfigManager] FontService already initialized, skipping");return}try{let e=await Fn.getCachedFonts();if(e){ce.initialize(e);return}let t=this.config.bootOptions.organizationSettings,r={fonts:t.fonts??[],customFonts:t.customFonts??[],defaultFont:t.defaultFont??"Noto Sans"};ce.initialize(r)}catch(e){console.warn("[ConfigManager] Failed to initialize FontService:",e)}}initializeColorService(){try{let t=this.config.bootOptions.organizationSettings.colorScheme||[];mt.initialize({colorScheme:t});let r=kt.getPlatform();r&&r.chartBuddyStorage&&r.chartBuddyStorage.setOrganizationColors(t).then(()=>console.log("[ConfigManager] Organization colors persisted to storage")).catch(n=>console.warn("[ConfigManager] Failed to persist organization colors:",n)),console.log("[ConfigManager] ColorService initialized")}catch(e){console.warn("[ConfigManager] Failed to initialize ColorService:",e)}}async validateFontCache(e){try{let t=await Fn.validateAndSyncFonts(e);t.hasChanges?(console.log("[ConfigManager] Font settings changed, updating"),ce.reinitialize(t.fonts)):console.log("[ConfigManager] Font settings unchanged, keeping current initialization")}catch(t){console.warn("[ConfigManager] Font validation failed:",t)}}async getAuthToken(){return(await this.getChromeStorage(["token"])).token}fetchAuthenticatedJson(e,t){return fetch(`${this.config.chartbuddyUrl}${e}`,{method:"GET",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"}})}async getChromeStorage(e){try{let t=await kt.getPlatform().storage.get(e),r={};for(let n of e)r[n]=t[n];return r}catch(t){return console.warn("[ConfigManager] Failed to get chrome storage:",t),{}}}async reloadConfig(){this.config.loaded=!1,this.config.loadedAt=void 0,await this.loadConfig()}reset(){this.config={chartbuddyUrl:this.detectEnvironmentUrl(),bootOptions:{...er},environment:{...Yo},loaded:!1,loadedAt:void 0},this.config.environment.current=this.detectEnvironment(),this.loadingPromise=void 0,this.fontPreloadPromise=void 0}}});var th=rm((Qd,eh)=>{(c=>{let e=(()=>{let w=0;return{escape:function(L){return L.replace(/([.*+?^${}()|[\]/\\])/g,"\\$1")},isDataUrl:function(L){return L.search(/^(data:)/)!==-1},canvasToBlob:function(L){return L.toBlob?new Promise(function(T){L.toBlob(T)}):(T=>new Promise(function(E){var P=h(T.toDataURL().split(",")[1]),O=P.length,R=new Uint8Array(O);for(let _=0;_<O;_++)R[_]=P.charCodeAt(_);E(new Blob([R],{type:"image/png"}))}))(L)},resolveUrl:function(L,T){var E=document.implementation.createHTMLDocument(),P=E.createElement("base"),O=(E.head.appendChild(P),E.createElement("a"));return E.body.appendChild(O),P.href=T,O.href=L,O.href},getAndEncode:function(L){let T=o.impl.urlCache.find(function(E){return E.url===L});return T||(T={url:L,promise:null},o.impl.urlCache.push(T)),T.promise===null&&(o.impl.options.cacheBust&&(L+=(/\?/.test(L)?"&":"?")+new Date().getTime()),T.promise=new Promise(function(E){let P=new XMLHttpRequest;function O(D){console.error(D),E("")}function R(){var D=o.impl.options.imagePlaceholder;D?E(D):O("Status:"+P.status+" while fetching resource: "+L)}if(P.timeout=o.impl.options.httpTimeout,P.onerror=R,P.ontimeout=R,P.onloadend=function(){if(P.readyState===XMLHttpRequest.DONE){var D=P.status;if(D===0&&L.toLowerCase().startsWith("file://")||200<=D&&D<=300&&P.response!==null){D=P.response,D instanceof Blob||O("Expected response to be a Blob, but got: "+typeof D);let F=new FileReader;F.onloadend=function(){var B=F.result;E(B)};try{F.readAsDataURL(D)}catch(B){O("Failed to read the response as Data URL: "+B.toString())}}else R()}},0<o.impl.options.useCredentialsFilters.length&&(o.impl.options.useCredentials=0<o.impl.options.useCredentialsFilters.filter(D=>0<=L.search(D)).length),o.impl.options.useCredentials&&(P.withCredentials=!0),o.impl.options.corsImg&&L.indexOf("http")===0&&L.indexOf(window.location.origin)===-1){var _=(o.impl.options.corsImg.method||"GET").toUpperCase()==="POST"?"POST":"GET";P.open(_,(o.impl.options.corsImg.url||"").replace("#{cors}",L),!0);let D=!1,F=o.impl.options.corsImg.headers||{},B=(Object.keys(F).forEach(function($){F[$].indexOf("application/json")!==-1&&(D=!0),P.setRequestHeader($,F[$])}),($=>{try{return JSON.parse(JSON.stringify($))}catch(N){O("corsImg.data is missing or invalid:"+N.toString())}})(o.impl.options.corsImg.data||""));Object.keys(B).forEach(function($){typeof B[$]=="string"&&(B[$]=B[$].replace("#{cors}",L))}),P.responseType="blob",P.send(D?JSON.stringify(B):B)}else P.open("GET",L,!0),P.responseType="blob",P.send()})),T.promise},uid:function(){return"u"+("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)+w++},asArray:function(L){var T=[],E=L.length;for(let P=0;P<E;P++)T.push(L[P]);return T},escapeXhtml:function(L){return L.replace(/%/g,"%25").replace(/#/g,"%23").replace(/\n/g,"%0A")},makeImage:function(L){return L!=="data:,"?new Promise(function(T,E){let P=document.createElementNS("http://www.w3.org/2000/svg","svg"),O=new Image;o.impl.options.useCredentials&&(O.crossOrigin="use-credentials"),O.onload=function(){document.body.removeChild(P),window&&window.requestAnimationFrame?window.requestAnimationFrame(function(){T(O)}):T(O)},O.onerror=R=>{document.body.removeChild(P),E(R)},P.appendChild(O),O.src=L,document.body.appendChild(P)}):Promise.resolve()},width:function(L){var T=A(L,"width");if(!isNaN(T))return T;var T=A(L,"border-left-width"),E=A(L,"border-right-width");return L.scrollWidth+T+E},height:function(L){var T=A(L,"height");if(!isNaN(T))return T;var T=A(L,"border-top-width"),E=A(L,"border-bottom-width");return L.scrollHeight+T+E},getWindow:S,isElement:M,isElementHostForOpenShadowRoot:function(L){return M(L)&&L.shadowRoot!==null},isShadowRoot:C,isInShadowRoot:k,isHTMLElement:function(L){return L instanceof S(L).HTMLElement},isHTMLCanvasElement:function(L){return L instanceof S(L).HTMLCanvasElement},isHTMLInputElement:function(L){return L instanceof S(L).HTMLInputElement},isHTMLImageElement:function(L){return L instanceof S(L).HTMLImageElement},isHTMLLinkElement:function(L){return L instanceof S(L).HTMLLinkElement},isHTMLScriptElement:function(L){return L instanceof S(L).HTMLScriptElement},isHTMLStyleElement:function(L){return L instanceof S(L).HTMLStyleElement},isHTMLTextAreaElement:function(L){return L instanceof S(L).HTMLTextAreaElement},isShadowSlotElement:function(L){return k(L)&&L instanceof S(L).HTMLSlotElement},isSVGElement:function(L){return L instanceof S(L).SVGElement},isSVGRectElement:function(L){return L instanceof S(L).SVGRectElement},isDimensionMissing:function(L){return isNaN(L)||L<=0}};function S(L){return L=L?L.ownerDocument:void 0,(L?L.defaultView:void 0)||window||c}function C(L){return L instanceof S(L).ShadowRoot}function k(L){return L!=null&&L.getRootNode!==void 0&&C(L.getRootNode())}function M(L){return L instanceof S(L).Element}function A(L,T){if(L.nodeType===l){let E=d(L).getPropertyValue(T);if(E.slice(-2)==="px")return E=E.slice(0,-2),parseFloat(E)}return NaN}})(),t=(()=>{let w=/url\(\s*(["']?)((?:\\.|[^\\)])+)\1\s*\)/gm;return{inlineAll:function(A,L,T){return S(A)?Promise.resolve(A).then(C).then(function(E){let P=Promise.resolve(A);return E.forEach(function(O){P=P.then(function(R){return M(R,O,L,T)})}),P}):Promise.resolve(A)},shouldProcess:S,impl:{readUrls:C,inline:M,urlAsRegex:k}};function S(A){return A.search(w)!==-1}function C(A){for(var L,T=[];(L=w.exec(A))!==null;)T.push(L[2]);return T.filter(function(E){return!e.isDataUrl(E)})}function k(A){return new RegExp(`url\\((["']?)(${e.escape(A)})\\1\\)`,"gm")}function M(A,L,T,E){return Promise.resolve(L).then(function(P){return T?e.resolveUrl(P,T):P}).then(E||e.getAndEncode).then(function(P){var O=k(L);return A.replace(O,`url($1${P}$1)`)})}})(),r={resolveAll:function(){return n().then(function(w){return Promise.all(w.map(function(S){return S.resolve()}))}).then(function(w){return w.join(`
|
|
9
|
+
`,document.body.appendChild(t),this.warmupContainer=t,t}async warmUpFontsBlocking(e){let t=[...new Set(e.filter(i=>typeof i=="string").map(i=>i.trim()).filter(i=>i.length>0).filter(i=>!this.isSystemFont(i)))];if(t.length===0)return;if(this.loadGoogleFonts(t),document.readyState==="loading"||!document.body){await this.ensureFontsReady(t);return}let r=this.getWarmupContainer(),n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,;:!?";t.forEach(i=>{let a=`cb-font-warmup-${i.replace(/[^a-z0-9]+/gi,"-").toLowerCase()}`;if(!r.querySelector(`[data-font-warmup-id="${a}"]`)){let s=document.createElement("span");s.dataset.fontWarmupId=a,s.style.fontFamily=`"${i}"`,s.textContent=n,r.appendChild(s);let o=document.createElement("span");o.dataset.fontWarmupId=`${a}-bold`,o.style.fontFamily=`"${i}"`,o.style.fontWeight="700",o.textContent=n,r.appendChild(o);let l=document.createElement("span");l.dataset.fontWarmupId=`${a}-italic`,l.style.fontFamily=`"${i}"`,l.style.fontStyle="italic",l.textContent=n,r.appendChild(l)}}),r.offsetHeight,await this.ensureFontsReady(t),await this.markFontsWarmed(t)}loadFont(e){this.loadedFonts.has(e)||this.isSystemFont(e)||this.loadGoogleFonts([e])}ensureFontLoaded(e){this.isSystemFont(e)||this.loadedFonts.has(e)||this.loadGoogleFonts([e])}extractFontsFromChartData(e){let t=new Set;if(!e||typeof e!="object")return t;let r=(n,i=new WeakSet)=>{if(!(n===null||typeof n!="object")&&!i.has(n)){if(i.add(n),Array.isArray(n)){n.forEach(a=>r(a,i));return}if("fontFamily"in n&&typeof n.fontFamily=="string"&&n.fontFamily.trim()){let a=n.fontFamily.trim();this.isSystemFont(a)||t.add(a)}if("labelFontFamily"in n&&typeof n.labelFontFamily=="string"&&n.labelFontFamily.trim()){let a=n.labelFontFamily.trim();this.isSystemFont(a)||t.add(a)}for(let a in n)if(Object.prototype.hasOwnProperty.call(n,a))try{r(n[a],i)}catch{}}};return r(e),t}loadFontsFromChartData(e,t){if(!e)return;let r=this.extractFontsFromChartData(e);if(r.size===0){t&&t();return}let n=this.getAvailableFonts(),i=new Set(n.map(s=>s.toLowerCase())),a=Array.from(r).filter(s=>{let o=s.toLowerCase();return!(this.loadedFonts.has(s)||i.has(o))});if(a.length===0){console.log("[FontService] All fonts from chart data are already available (in cache/backend)"),t&&this.ensureFontsReady(Array.from(r)).then(()=>t()).catch(()=>t());return}console.log("[FontService] Loading fonts from chart data (not in organization list):",a),this.loadGoogleFonts(a),t&&this.ensureFontsReady(Array.from(r)).then(()=>t()).catch(()=>t())}getUnknownFontsFromChartData(e){if(!e)return[];let t=this.extractFontsFromChartData(e);if(t.size===0)return[];let r=new Set(this.getAvailableFonts().map(n=>n.toLowerCase()));return Array.from(t).filter(n=>this.loadedFonts.has(n)?!1:!r.has(n.toLowerCase()))}prepareFontsForChartData(e){if(!e)return{hasUnknownFonts:!1,readyPromise:Promise.resolve()};let t=this.extractFontsFromChartData(e);if(t.size===0)return{hasUnknownFonts:!1,readyPromise:Promise.resolve()};let r=this.getUnknownFontsFromChartData(e),n=r.length>0;return n&&console.log("[FontService] Blocking initial chart render for unknown fonts:",r),this.loadFontsFromChartData(e),{hasUnknownFonts:n,readyPromise:n?this.warmUpFontsBlocking(Array.from(t)):this.ensureFontsReady(Array.from(t))}}reset(){this.customFonts=[],this.loadedFonts.clear(),this.fontDeclarationPromises.clear(),this.fontReadyPromises.clear(),this.warmedFonts.clear(),this.initialized=!1,this.defaultFont="Arial",this.warmupContainer&&this.warmupContainer.parentNode&&this.warmupContainer.parentNode.removeChild(this.warmupContainer),this.warmupContainer=null,this.defaultFonts=["Arial","Calibri","Helvetica","Verdana","Tahoma","Trebuchet MS","Times New Roman","Courier New"]}},ce=wd.getInstance()});var Cu={};vd(Cu,{colorService:()=>mt,default:()=>sm});var Sd,mt,sm,En=It(()=>{Sd=class c{constructor(){this.defaultColors=["#98df8a","#17becf","#2c808c","#98df8a","#e377c2","#7f7f7f","#bcbd22","#17becf","#393b79","#637939","#8c6d31","#843c39","#7b4173","#a55194","#c7c7c7","#ffbb78","#98df8a","#ff9896","#ff7f0e","#2ca02c","#d62728","#9467bd","#8c564b","#e377c2","#7f7f7f","#bcbd22","#17becf","#393b79","#637939","#8c6d31","#843c39","#7b4173","#a55194","#c7c7c7","#ffbb78","#98df8a","#ff9896"];this.customColors=[];this.initialized=!1;this.resolveReady=()=>{};this.readyPromise=new Promise(e=>{this.resolveReady=e})}static getInstance(){return c.instance||(c.instance=new c),c.instance}initialize(e){console.log("[ColorService] Initializing with settings:",e),this.setOrganizationColors(e.colorScheme||[])}isInitialized(){return this.initialized}async ready(){return this.readyPromise}getAvailableColors(){let e=[];this.customColors&&this.customColors.length>0&&e.push(...this.customColors),e.push(...this.defaultColors),console.log("[ColorService] getAvailableColors result count:",e.length);let t=new Set;return e.filter(r=>{if(!r)return!1;let n=r.toUpperCase();return t.has(n)?!1:(t.add(n),!0)})}setOrganizationColors(e){this.customColors=Array.isArray(e)?[...e]:[],console.log("[ColorService] Organization colors updated:",this.customColors.length),this.initialized||(this.initialized=!0,this.resolveReady())}getDefaultColors(){return[...this.defaultColors]}getCustomColors(){return[...this.customColors]}hasColor(e){let t=this.getAvailableColors(),r=e.toUpperCase();return t.some(n=>n.toUpperCase()===r)}addCustomColor(e){let t=e.toUpperCase();this.customColors.some(r=>r.toUpperCase()===t)||this.customColors.push(e)}removeCustomColor(e){let t=e.toUpperCase();this.customColors=this.customColors.filter(r=>r.toUpperCase()!==t)}reset(){this.customColors=[],this.initialized=!1,this.defaultColors=["#242424","#484848","#6D6D6D","#919191","#B6B6B6","#DADADA","#FFFFFF","#8B0000","#FF4500","#FFD700","#ADFF2F","#1E90FF","#0000FF","#8B00FF","#FF00FF","#F1E6E6","#FFE6E6","#FFF0E6","#F2FFE6","#E6F3FF","#E6E6FF","#F3E6FF","#FFE6FF","#D9CCCC","#FFCCCC","#FFE1CC","#E6FFCC","#CCE6FF","#CCCCFF","#E6CCFF","#FFCCFF","#B38B8B","#FFB3B3","#FFD9B3","#CCFFB3","#B3CCFF","#B3B3FF","#CCB3FF","#FFB3FF","#806666","#E69999","#FFCC99","#99FF99","#99CCFF","#9999FF","#CC99FF","#FF99FF","#4D3333","#CC6666","#FFB366","#66CC66","#6699FF","#6666FF","#9966FF","#FF66FF"]}},mt=Sd.getInstance(),sm=mt});function Ar(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(c){let e=Math.random()*16|0;return(c==="x"?e:e&3|8).toString(16)})}var Ha=It(()=>{});var $r,_o=It(()=>{Ha();$r=class{constructor(e,t="chart_",r=null){this.platform=e,this.storagePrefix=t,this.recentColorsKey="recent_colors",this.organizationColorsKey="organization_colors",this.presentationColorsKey="presentation_colors",this.maxRecentColors=8,this.chartbuddyUrl=r}setChartbuddyUrl(e){this.chartbuddyUrl=e}isStorageAvailable(){return!!this.platform}getStorageKey(e){return`${this.storagePrefix}${e}`}static generateUUID(){return Ar()}async removeItems(e,t){e.length>0&&this.platform&&(await this.platform.storage.remove(e),console.log(`[Storage] Removed keys: ${e.join(", ")}`)),t&&t()}async remove(e=null,t){if(!this.platform){t&&t();return}let r=await this.platform.storage.get(null),n=[];for(let i in r)(!e||i.startsWith(e))&&n.push(i);n.length>0&&(await this.platform.storage.remove(n),console.log(`[Storage] Removed ${n.length} keys with prefix: ${e||"all"}`)),t&&t()}async removeAllData(e){if(!this.platform){e&&e(new Error("Platform not initialized"));return}try{let t=await this.platform.storage.get(null),r=Object.keys(t);if(r.length===0){e&&e(null,0);return}await this.platform.storage.remove(r),console.log(`[Storage] Successfully removed all ${r.length} items`),e&&e(null,r.length)}catch(t){e&&e(t)}}async clearAll(e){return this.removeAllData(e)}async getOrganizationColors(e){if(!this.platform){console.warn("[Storage] Cannot get organization colors: Platform not initialized"),e([]);return}let r=(await this.platform.storage.get([this.organizationColorsKey]))[this.organizationColorsKey]||[];console.log(`[Storage] Retrieved ${r.length} organization colors from storage`),e(r)}async getDefaultColors(){return this.platform?(await this.platform.storage.get([this.organizationColorsKey]))[this.organizationColorsKey]||[]:[]}async setOrganizationColors(e,t){if(!Array.isArray(e)||!this.platform){console.warn("[Storage] Cannot set organization colors: Invalid input or platform not initialized"),t&&t();return}console.log(`[Storage] Persisting ${e.length} organization colors to storage`),await this.platform.storage.set({[this.organizationColorsKey]:e}),t&&t()}async clearOrganizationColors(e){if(!this.platform){e&&e();return}await this.platform.storage.remove([this.organizationColorsKey]),e&&e()}async getPresentationColors(e,t){if(!e||!this.platform){t([]);return}let r=`${this.presentationColorsKey}_${e}`,n=await this.platform.storage.get([r]);t(n[r]||[])}async setPresentationColors(e,t,r){if(!e||!Array.isArray(t)||!this.platform){r&&r();return}let n=`${this.presentationColorsKey}_${e}`;await this.platform.storage.set({[n]:t}),r&&r()}async getRecentColors(e){if(!this.platform){e([]);return}let t=await this.platform.storage.get([this.recentColorsKey]);e(t[this.recentColorsKey]||[])}async addRecentColor(e,t){let r=this.normalizeColorToHex(e);if(!r||!this.platform){t&&t([]);return}this.getRecentColors(async n=>{n=n.filter(i=>i!==r),n.unshift(r),n=n.slice(0,this.maxRecentColors),this.platform&&await this.platform.storage.set({[this.recentColorsKey]:n}),t&&t(n)})}async clearRecentColors(e){this.platform&&await this.platform.storage.remove([this.recentColorsKey]),e&&e()}static googleRgbToHex(e){if(!e)return null;let t=Math.round((e.red||0)*255),r=Math.round((e.green||0)*255),n=Math.round((e.blue||0)*255);return`#${t.toString(16).padStart(2,"0")}${r.toString(16).padStart(2,"0")}${n.toString(16).padStart(2,"0")}`}normalizeColorToHex(e){if(!e||typeof e!="string")return null;let t=e.trim();if(t.startsWith("#")){let n=t.toUpperCase();return n.length===4&&(n="#"+n[1]+n[1]+n[2]+n[2]+n[3]+n[3]),/^#[0-9A-F]{6}$/.test(n)?n:null}if(/^[0-9A-Fa-f]{6}$/.test(t))return"#"+t.toUpperCase();let r=t.match(/^rgba?\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*[\d.]+)?\s*\)$/i);if(r){let n=Math.min(255,Math.max(0,parseInt(r[1],10))),i=Math.min(255,Math.max(0,parseInt(r[2],10))),a=Math.min(255,Math.max(0,parseInt(r[3],10)));return"#"+n.toString(16).padStart(2,"0").toUpperCase()+i.toString(16).padStart(2,"0").toUpperCase()+a.toString(16).padStart(2,"0").toUpperCase()}return null}async saveLastOpenedChartId(e){await this.platform.storage.set({lastOpenedChartId:e})}async getLastOpenedChartId(e){let t=await this.platform.storage.get(["lastOpenedChartId"]);e(t.lastOpenedChartId||null)}async getTemplates(){if(!this.chartbuddyUrl)return[];try{let t=(await this.platform.storage.get(["token"])).token;if(!t)return[];let r=await fetch(`${this.chartbuddyUrl}/api/chart-templates`,{method:"GET",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"}});if(r.ok){let n=await r.json();return Array.isArray(n)?n:n?.data&&Array.isArray(n.data)?n.data:[]}}catch(e){console.error("[Storage] Failed to fetch templates:",e)}return[]}}});var Nr,Vr,$o=It(()=>{Nr="1.7.53",Vr="chart-buddy"});var Cd,kd,Ad,Wa,ku=It(()=>{_o();$o();Cd=class{async get(e){return new Promise(t=>{chrome.storage.local.get(e,r=>{t(r)})})}async set(e){return new Promise(t=>{chrome.storage.local.set(e,()=>{t()})})}async remove(e){return new Promise(t=>{chrome.storage.local.remove(e,()=>{t()})})}async clear(){return new Promise(e=>{chrome.storage.local.clear(()=>{e()})})}},kd=class{getURL(e){return chrome.runtime.getURL(e)}getVersion(){return Nr}getAppName(){return Vr}isDevelopmentBuild(){return!1}getManifest(){return chrome.runtime.getManifest()}async sendMessage(e){return new Promise((t,r)=>{chrome.runtime.sendMessage(e,n=>{chrome.runtime.lastError?r(chrome.runtime.lastError):t(n)})})}},Ad=class{detect(){let e=window.location.href;return e.includes("canva.com")?"Canva":e.includes("docs.google.com/presentation")?"GSlides":e.includes("docs.google.com/spreadsheets")||e.includes("sheets.google.com")?"GSheets":e.includes("notion.com")||e.includes("notion.so")?"Notion":e.includes("figma.com")?"Figma":e.includes("miro.com")?"Miro":e.includes("powerbi.com")?"PowerBI":e.includes("onedrive.live.com")||e.includes("microsoft365.com")?"PowerPoint":"WebApp"}getPresentationId(){let t=window.location.href.match(/\/presentation\/d\/([a-zA-Z0-9-_]+)/);return t?t[1]:null}},Wa=class{constructor(){this.type="extension";this.storage=new Cd;this.runtime=new kd;this.host=new Ad;this.chartBuddyStorage=new $r(this)}};typeof window<"u"&&(window.ChromeExtensionProvider=Wa)});var Ld,Md,Td,On,Dd=It(()=>{_o();$o();Ld=class{constructor(){this.prefix="cb_"}async get(e){let t={},r=[];return typeof e=="string"?r=[e]:Array.isArray(e)?r=e:e&&typeof e=="object"&&(r=Object.keys(e),Object.assign(t,e)),r.forEach(n=>{let i=localStorage.getItem(this.prefix+n);if(i!==null)try{t[n]=JSON.parse(i)}catch{t[n]=i}}),t}async set(e){Object.entries(e).forEach(([t,r])=>{localStorage.setItem(this.prefix+t,JSON.stringify(r))})}async remove(e){(Array.isArray(e)?e:[e]).forEach(r=>localStorage.removeItem(this.prefix+r))}async clear(){Object.keys(localStorage).forEach(e=>{e.startsWith(this.prefix)&&localStorage.removeItem(e)})}},Md=class{getURL(e){return e}getVersion(){return Nr}getAppName(){return Vr}isDevelopmentBuild(){return!1}getManifest(){return{version:Nr,name:Vr,_sys_ctx:this.isDevelopmentBuild()?"d8n3x5q1":"kz6p9m2v"}}async sendMessage(e){return console.log("[WebApp] Mock sendMessage:",e),null}},Td=class{detect(){return"WebApp"}getPresentationId(){return"webapp-mock-presentation-id"}},On=class{constructor(){this.type="webapp";this.storage=new Ld;this.runtime=new Md;this.host=new Td;this.chartBuddyStorage=new $r(this)}};typeof window<"u"&&(window.WebAppProvider=On)});function Li(){if(typeof window>"u")return!1;let c=window;return typeof c.__TAURI__<"u"||typeof c.__TAURI_INTERNALS__<"u"?!0:typeof navigator<"u"&&/tauri/i.test(navigator.userAgent)}var Ed,Od,Pd,No,Ga=It(()=>{_o();$o();Ed=class{constructor(){this.prefix="cb_";this.map=new Map}storageKey(e){return`${this.prefix}${e}`}async get(e){let t={},r=[];return typeof e=="string"?r=[e]:Array.isArray(e)?r=e:e&&typeof e=="object"&&(r=Object.keys(e),Object.assign(t,e)),r.forEach(n=>{let i=this.map.get(this.storageKey(n));if(i!==void 0)try{t[n]=JSON.parse(i)}catch{t[n]=i}}),t}async set(e){Object.entries(e).forEach(([t,r])=>{this.map.set(this.storageKey(t),JSON.stringify(r))})}async remove(e){(Array.isArray(e)?e:[e]).forEach(r=>this.map.delete(this.storageKey(r)))}async clear(){let e=[];this.map.forEach((t,r)=>{r.startsWith(this.prefix)&&e.push(r)}),e.forEach(t=>this.map.delete(t))}},Od=class{getURL(e){return e}getVersion(){return Nr}getAppName(){return Vr}isDevelopmentBuild(){return!1}getManifest(){return{version:Nr,name:Vr,_sys_ctx:this.isDevelopmentBuild()?"d8n3x5q1":"kz6p9m2v"}}async sendMessage(e){return console.log("[Tauri] sendMessage (no-op):",e),null}},Pd=class{detect(){return"Tauri"}getPresentationId(){return"tauri-desktop"}},No=class{constructor(){this.type="tauri";this.storage=new Ed;this.runtime=new Od;this.host=new Pd;this.chartBuddyStorage=new $r(this)}}});var kt,Id,Ua=It(()=>{ku();Dd();Ga();kt=class{static setPlatform(e){this.instance=e}static getPlatform(){let e=Li();return e&&this.instance!==void 0&&this.instance.type!=="tauri"&&(this.instance=void 0),this.instance?this.instance:e?(this.instance=new No,this.instance):(typeof chrome<"u"&&chrome.runtime&&typeof chrome.runtime.getURL=="function"&&!!chrome.runtime.id?this.instance=new Wa:this.instance=new On,this.instance)}},Id=kt.getPlatform()});var hm,_d,er,Yo,Ru=It(()=>{hm=["Arial","Calibri","Helvetica","Verdana","Tahoma","Trebuchet MS","Times New Roman","Courier New"],_d={isExpired:!1,isActive:!0,daysRemaining:null,expiresAt:null},er={uploadMethod:"google-drive",featureFlags:{},canManageFeatureFlags:!1,organizationSettings:{colorScheme:["#3B82F6","#10B981","#F59E0B","#9fa90f"],fonts:hm,customFonts:[],defaultFont:"Arial"},trialStatus:_d},Yo={production:"https://chartbuddy.io",acceptance:"https://cb-acc.xyz",current:"production"}});function $d(c){if(c.fonts!==void 0){if(!Array.isArray(c.fonts))return console.warn("[FontCacheManager] Invalid fonts: expected array, got",typeof c.fonts),!1;if(!c.fonts.every(e=>typeof e=="string"&&e.trim().length>0))return console.warn("[FontCacheManager] Invalid fonts: contains non-string or empty values"),!1}if(c.customFonts!==void 0){if(!Array.isArray(c.customFonts))return console.warn("[FontCacheManager] Invalid customFonts: expected array, got",typeof c.customFonts),!1;if(!c.customFonts.every(e=>typeof e=="string"&&e.trim().length>0))return console.warn("[FontCacheManager] Invalid customFonts: contains non-string or empty values"),!1}return c.useDefaultFonts!==void 0&&typeof c.useDefaultFonts!="boolean"?(console.warn("[FontCacheManager] Invalid useDefaultFonts: expected boolean, got",typeof c.useDefaultFonts),!1):!0}var jo,Fn,Nd=It(()=>{Ua();jo=class c{static{this.STORAGE_KEY="chartbuddy_fonts_cache"}static{this.CACHE_VERSION="1.0"}constructor(){}static getInstance(){return c.instance||(c.instance=new c),c.instance}async getCachedFonts(){try{let t=(await kt.getPlatform().storage.get([c.STORAGE_KEY]))[c.STORAGE_KEY];if(!t)return null;if(typeof t!="object"||t===null)return console.warn("[FontCacheManager] Invalid cache data type, clearing"),await this.clearCache(),null;if(t.version!==c.CACHE_VERSION)return console.log("[FontCacheManager] Cache version mismatch, invalidating"),await this.clearCache(),null;let r={fonts:t.fonts,customFonts:t.customFonts,defaultFont:t.defaultFont,useDefaultFonts:t.useDefaultFonts};return $d(r)?(console.log("[FontCacheManager] Loaded fonts from cache:",{defaultFont:t.defaultFont,fonts:t.fonts?.length??0,customFonts:t.customFonts?.length??0,cachedAt:new Date(t.cachedAt).toISOString()}),r):(console.warn("[FontCacheManager] Cached data validation failed, clearing cache"),await this.clearCache(),null)}catch(e){return console.warn("[FontCacheManager] Failed to get cached fonts:",e),null}}async saveFontsToCache(e){if(!$d(e))throw new Error("[FontCacheManager] Invalid font settings, cannot save to cache");try{let t={fonts:e.fonts,customFonts:e.customFonts,defaultFont:e.defaultFont,useDefaultFonts:e.useDefaultFonts,cachedAt:Date.now(),version:c.CACHE_VERSION},n=JSON.stringify(t).length,i=100*1024;n>i&&(console.warn(`[FontCacheManager] Cache size (${n} bytes) exceeds limit (${i} bytes), clearing old cache`),await this.clearCache()),await kt.getPlatform().storage.set({[c.STORAGE_KEY]:t})}catch(t){throw console.error("[FontCacheManager] Failed to save fonts to cache:",t),t}}async validateAndSyncFonts(e){if(!$d(e))return console.warn("[FontCacheManager] Invalid backend font settings, using cached data"),{hasChanges:!1,fonts:await this.getCachedFonts()??{fonts:[],customFonts:[],defaultFont:"Arial",useDefaultFonts:!0}};let t=null;try{console.log("[FontCacheManager] Validating fonts against cache..."),t=await this.getCachedFonts();let r=this.fontsHaveChanged(t,e);return r&&await this.saveFontsToCache(e),{hasChanges:r,fonts:e}}catch(r){return console.error("[FontCacheManager] Error validating fonts:",r),{hasChanges:!1,fonts:t??{fonts:[],customFonts:[],defaultFont:"Arial",useDefaultFonts:!0}}}}fontsHaveChanged(e,t){if(!e)return!0;let r=(n,i)=>!n&&!i?!0:!n||!i||n.length!==i.length?!1:n.every((a,s)=>a===i[s]);return!r(e.fonts,t.fonts)||!r(e.customFonts,t.customFonts)||e.defaultFont!==t.defaultFont||e.useDefaultFonts!==t.useDefaultFonts}async clearCache(){try{await kt.getPlatform().storage.remove([c.STORAGE_KEY]),console.log("[FontCacheManager] Cache cleared")}catch(e){console.warn("[FontCacheManager] Failed to clear cache:",e)}}},Fn=jo.getInstance()});var Bu={};vd(Bu,{CHARTBUDDY_CONFIG_UPDATED_EVENT:()=>Fu,ConfigManager:()=>ne,getConfigManager:()=>At});function At(){return ne.getInstance()}var Fu,ne,st=It(()=>{Ru();Ua();Jt();Nd();En();Fu="chartbuddy:config-updated",ne=class c{constructor(){this.debugEnabled=!1;this.debugAxisBinding=!0;this.loadingPromise=void 0;this.fontPreloadPromise=void 0;this.onLoadCallbacks=[];if(this.config={chartbuddyUrl:this.detectEnvironmentUrl(),bootOptions:{...er},environment:{...Yo},loaded:!1,loadedAt:void 0},this.config.environment.current=this.detectEnvironment(),this.debugEnabled=this.computeDebugEnabled(this.config.chartbuddyUrl),typeof window<"u"&&window.localStorage)try{window.localStorage.getItem("CHARTBUDDY_DEBUG_MODE")==="true"&&(this.debugEnabled=!0),window.localStorage.getItem("CHARTBUDDY_DEBUG_AXIS_BINDING")==="false"&&(this.debugAxisBinding=!1)}catch{}}static{this.instance=void 0}computeDebugEnabled(e){let t=e.includes("cb-acc.xyz")||e.includes("stag"),r=e.includes("localhost")||e.includes("127.0.0.1"),n=kt.getPlatform().runtime.isDevelopmentBuild();return t||r||n}static getInstance(){return c.instance===void 0&&(c.instance=new c),c.instance}isDebugEnabled(){return this.debugEnabled}isDebugAxisBindingEnabled(){return this.debugAxisBinding}isWaterfallSegmentedBarsEnabled(){return!0}isChartOrientationEnabled(){return!0}isBarMekkoEnabled(){return this.config?.bootOptions?.featureFlags?.barMekko===!0}isDevelopment(){let e=this.config.chartbuddyUrl;return e.includes("localhost")||e.includes("127.0.0.1")}isAcceptance(){return this.config.chartbuddyUrl.includes("cb-acc.xyz")}isProduction(){return!this.isDevelopment()&&!this.isAcceptance()}setDebugMode(e){this.debugEnabled=e}setDebugAxisBindingMode(e){this.debugAxisBinding=e}detectEnvironmentUrl(){return Yo.production}detectEnvironment(){return this.config.chartbuddyUrl.includes("cb-acc.xyz")?"acceptance":"production"}getConfig(){return{...this.config}}getChartbuddyUrl(){return this.config.chartbuddyUrl}getBootOptions(){return{...this.config.bootOptions}}getEnvironment(){return{...this.config.environment}}getTrialStatus(){return{...this.config.bootOptions.trialStatus}}isTrialExpired(){return this.config.bootOptions.trialStatus.isExpired}isLoaded(){return this.config.loaded}onLoad(e){this.config.loaded?e():this.onLoadCallbacks.push(e)}setChartbuddyUrl(e){this.config.chartbuddyUrl=e,this.config.environment.current=this.detectEnvironment(),this.debugEnabled=this.computeDebugEnabled(e)}async loadConfig(){if(this.loadingPromise)return this.loadingPromise;if(this.config.loaded&&this.config.loadedAt&&Date.now()-this.config.loadedAt<3e5){console.log("[ConfigManager] Config already loaded recently, skipping reload");return}this.loadingPromise=this.loadConfigInternal();try{await this.loadingPromise}finally{this.loadingPromise=void 0}}async preloadFontSettings(){if(this.fontPreloadPromise)return this.fontPreloadPromise;this.fontPreloadPromise=this.preloadFontSettingsInternal();try{await this.fontPreloadPromise}finally{this.fontPreloadPromise=void 0}}async loadConfigInternal(){try{if(kt.getPlatform().type==="webapp"){console.log("[ConfigManager] Standalone mode (WebApp): using local defaults"),this.config.bootOptions={...er},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks();return}console.log("[ConfigManager] Loading configuration from backend...");let t=await this.getAuthToken();if(!t){console.warn("[ConfigManager] No authentication token available, using defaults"),Fn.clearCache().catch(n=>{console.warn("[ConfigManager] Failed to clear font cache on auth failure:",n)}),this.config.bootOptions={...er},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks();return}let r=await this.fetchAuthenticatedJson("/api/user/boot-settings",t);if(r.ok){let n=await r.json(),i=n.uploadMethod??er.uploadMethod,a=n.featureFlags??er.featureFlags,s=n.canManageFeatureFlags??er.canManageFeatureFlags,o=n.organizationSettings??er.organizationSettings,l=n.trialStatus??_d;this.config.bootOptions={uploadMethod:i,featureFlags:a,canManageFeatureFlags:s,organizationSettings:o,trialStatus:l},console.log("[ConfigManager] Organization Settings received:",{colorSchemeCount:o.colorScheme?.length||0,fontCount:o.fonts?.length||0}),this.config.loaded=!0,this.config.loadedAt=Date.now(),console.log("[ConfigManager] \u2705 Configuration loaded successfully:",{uploadMethod:this.config.bootOptions.uploadMethod,loadedAt:new Date(this.config.loadedAt).toISOString()}),await this.initializeFontService(),this.initializeColorService();let d={fonts:o.fonts??[],customFonts:o.customFonts??[],defaultFont:o.defaultFont??"Noto Sans"};this.validateFontCache(d).catch(h=>{console.warn("[ConfigManager] Background font validation failed:",h)}),this.triggerOnLoadCallbacks()}else console.warn(`[ConfigManager] Failed to fetch boot settings (HTTP ${r.status}), using defaults`),(r.status===401||r.status===403)&&Fn.clearCache().catch(n=>{console.warn("[ConfigManager] Failed to clear font cache on auth failure:",n)}),this.config.bootOptions={...er},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks()}catch(e){console.error("[ConfigManager] Error loading configuration:",e),console.log("[ConfigManager] Using default configuration"),this.config.bootOptions={...er},this.config.loaded=!0,this.config.loadedAt=Date.now(),await this.initializeFontService(),this.initializeColorService(),this.triggerOnLoadCallbacks()}}async preloadFontSettingsInternal(){try{let e=await this.getAuthToken();if(!e)return;let t=await this.fetchAuthenticatedJson("/api/user/font-settings",e);if(!t.ok){(t.status===401||t.status===403)&&Fn.clearCache().catch(n=>{console.warn("[ConfigManager] Failed to clear font cache on preload auth failure:",n)});return}let r=await t.json();ce.isInitialized()?ce.reinitialize(r):ce.primeEarly(r)}catch(e){console.warn("[ConfigManager] Font preload failed:",e)}}triggerOnLoadCallbacks(){console.log(`[ConfigManager] Triggering ${this.onLoadCallbacks.length} onLoad callbacks`),this.onLoadCallbacks.forEach(e=>{try{e()}catch(t){console.error("[ConfigManager] Error in onLoad callback:",t)}}),this.onLoadCallbacks=[],typeof window<"u"&&window.dispatchEvent(new CustomEvent(Fu,{detail:{bootOptions:this.getBootOptions(),loadedAt:this.config.loadedAt}}))}async initializeFontService(){if(ce.isInitialized()){console.log("[ConfigManager] FontService already initialized, skipping");return}try{let e=await Fn.getCachedFonts();if(e){ce.initialize(e);return}let t=this.config.bootOptions.organizationSettings,r={fonts:t.fonts??[],customFonts:t.customFonts??[],defaultFont:t.defaultFont??"Noto Sans"};ce.initialize(r)}catch(e){console.warn("[ConfigManager] Failed to initialize FontService:",e)}}initializeColorService(){try{let t=this.config.bootOptions.organizationSettings.colorScheme||[];mt.initialize({colorScheme:t});let r=kt.getPlatform();r&&r.chartBuddyStorage&&r.chartBuddyStorage.setOrganizationColors(t).then(()=>console.log("[ConfigManager] Organization colors persisted to storage")).catch(n=>console.warn("[ConfigManager] Failed to persist organization colors:",n)),console.log("[ConfigManager] ColorService initialized")}catch(e){console.warn("[ConfigManager] Failed to initialize ColorService:",e)}}async validateFontCache(e){try{let t=await Fn.validateAndSyncFonts(e);t.hasChanges?(console.log("[ConfigManager] Font settings changed, updating"),ce.reinitialize(t.fonts)):console.log("[ConfigManager] Font settings unchanged, keeping current initialization")}catch(t){console.warn("[ConfigManager] Font validation failed:",t)}}async getAuthToken(){return(await this.getChromeStorage(["token"])).token}fetchAuthenticatedJson(e,t){return fetch(`${this.config.chartbuddyUrl}${e}`,{method:"GET",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"}})}async getChromeStorage(e){try{let t=await kt.getPlatform().storage.get(e),r={};for(let n of e)r[n]=t[n];return r}catch(t){return console.warn("[ConfigManager] Failed to get chrome storage:",t),{}}}async reloadConfig(){this.config.loaded=!1,this.config.loadedAt=void 0,await this.loadConfig()}reset(){this.config={chartbuddyUrl:this.detectEnvironmentUrl(),bootOptions:{...er},environment:{...Yo},loaded:!1,loadedAt:void 0},this.config.environment.current=this.detectEnvironment(),this.loadingPromise=void 0,this.fontPreloadPromise=void 0}}});var th=rm((Qd,eh)=>{(c=>{let e=(()=>{let w=0;return{escape:function(L){return L.replace(/([.*+?^${}()|[\]/\\])/g,"\\$1")},isDataUrl:function(L){return L.search(/^(data:)/)!==-1},canvasToBlob:function(L){return L.toBlob?new Promise(function(T){L.toBlob(T)}):(T=>new Promise(function(E){var P=h(T.toDataURL().split(",")[1]),O=P.length,R=new Uint8Array(O);for(let _=0;_<O;_++)R[_]=P.charCodeAt(_);E(new Blob([R],{type:"image/png"}))}))(L)},resolveUrl:function(L,T){var E=document.implementation.createHTMLDocument(),P=E.createElement("base"),O=(E.head.appendChild(P),E.createElement("a"));return E.body.appendChild(O),P.href=T,O.href=L,O.href},getAndEncode:function(L){let T=o.impl.urlCache.find(function(E){return E.url===L});return T||(T={url:L,promise:null},o.impl.urlCache.push(T)),T.promise===null&&(o.impl.options.cacheBust&&(L+=(/\?/.test(L)?"&":"?")+new Date().getTime()),T.promise=new Promise(function(E){let P=new XMLHttpRequest;function O(D){console.error(D),E("")}function R(){var D=o.impl.options.imagePlaceholder;D?E(D):O("Status:"+P.status+" while fetching resource: "+L)}if(P.timeout=o.impl.options.httpTimeout,P.onerror=R,P.ontimeout=R,P.onloadend=function(){if(P.readyState===XMLHttpRequest.DONE){var D=P.status;if(D===0&&L.toLowerCase().startsWith("file://")||200<=D&&D<=300&&P.response!==null){D=P.response,D instanceof Blob||O("Expected response to be a Blob, but got: "+typeof D);let F=new FileReader;F.onloadend=function(){var B=F.result;E(B)};try{F.readAsDataURL(D)}catch(B){O("Failed to read the response as Data URL: "+B.toString())}}else R()}},0<o.impl.options.useCredentialsFilters.length&&(o.impl.options.useCredentials=0<o.impl.options.useCredentialsFilters.filter(D=>0<=L.search(D)).length),o.impl.options.useCredentials&&(P.withCredentials=!0),o.impl.options.corsImg&&L.indexOf("http")===0&&L.indexOf(window.location.origin)===-1){var _=(o.impl.options.corsImg.method||"GET").toUpperCase()==="POST"?"POST":"GET";P.open(_,(o.impl.options.corsImg.url||"").replace("#{cors}",L),!0);let D=!1,F=o.impl.options.corsImg.headers||{},B=(Object.keys(F).forEach(function($){F[$].indexOf("application/json")!==-1&&(D=!0),P.setRequestHeader($,F[$])}),($=>{try{return JSON.parse(JSON.stringify($))}catch(N){O("corsImg.data is missing or invalid:"+N.toString())}})(o.impl.options.corsImg.data||""));Object.keys(B).forEach(function($){typeof B[$]=="string"&&(B[$]=B[$].replace("#{cors}",L))}),P.responseType="blob",P.send(D?JSON.stringify(B):B)}else P.open("GET",L,!0),P.responseType="blob",P.send()})),T.promise},uid:function(){return"u"+("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)+w++},asArray:function(L){var T=[],E=L.length;for(let P=0;P<E;P++)T.push(L[P]);return T},escapeXhtml:function(L){return L.replace(/%/g,"%25").replace(/#/g,"%23").replace(/\n/g,"%0A")},makeImage:function(L){return L!=="data:,"?new Promise(function(T,E){let P=document.createElementNS("http://www.w3.org/2000/svg","svg"),O=new Image;o.impl.options.useCredentials&&(O.crossOrigin="use-credentials"),O.onload=function(){document.body.removeChild(P),window&&window.requestAnimationFrame?window.requestAnimationFrame(function(){T(O)}):T(O)},O.onerror=R=>{document.body.removeChild(P),E(R)},P.appendChild(O),O.src=L,document.body.appendChild(P)}):Promise.resolve()},width:function(L){var T=A(L,"width");if(!isNaN(T))return T;var T=A(L,"border-left-width"),E=A(L,"border-right-width");return L.scrollWidth+T+E},height:function(L){var T=A(L,"height");if(!isNaN(T))return T;var T=A(L,"border-top-width"),E=A(L,"border-bottom-width");return L.scrollHeight+T+E},getWindow:S,isElement:M,isElementHostForOpenShadowRoot:function(L){return M(L)&&L.shadowRoot!==null},isShadowRoot:C,isInShadowRoot:k,isHTMLElement:function(L){return L instanceof S(L).HTMLElement},isHTMLCanvasElement:function(L){return L instanceof S(L).HTMLCanvasElement},isHTMLInputElement:function(L){return L instanceof S(L).HTMLInputElement},isHTMLImageElement:function(L){return L instanceof S(L).HTMLImageElement},isHTMLLinkElement:function(L){return L instanceof S(L).HTMLLinkElement},isHTMLScriptElement:function(L){return L instanceof S(L).HTMLScriptElement},isHTMLStyleElement:function(L){return L instanceof S(L).HTMLStyleElement},isHTMLTextAreaElement:function(L){return L instanceof S(L).HTMLTextAreaElement},isShadowSlotElement:function(L){return k(L)&&L instanceof S(L).HTMLSlotElement},isSVGElement:function(L){return L instanceof S(L).SVGElement},isSVGRectElement:function(L){return L instanceof S(L).SVGRectElement},isDimensionMissing:function(L){return isNaN(L)||L<=0}};function S(L){return L=L?L.ownerDocument:void 0,(L?L.defaultView:void 0)||window||c}function C(L){return L instanceof S(L).ShadowRoot}function k(L){return L!=null&&L.getRootNode!==void 0&&C(L.getRootNode())}function M(L){return L instanceof S(L).Element}function A(L,T){if(L.nodeType===l){let E=d(L).getPropertyValue(T);if(E.slice(-2)==="px")return E=E.slice(0,-2),parseFloat(E)}return NaN}})(),t=(()=>{let w=/url\(\s*(["']?)((?:\\.|[^\\)])+)\1\s*\)/gm;return{inlineAll:function(A,L,T){return S(A)?Promise.resolve(A).then(C).then(function(E){let P=Promise.resolve(A);return E.forEach(function(O){P=P.then(function(R){return M(R,O,L,T)})}),P}):Promise.resolve(A)},shouldProcess:S,impl:{readUrls:C,inline:M,urlAsRegex:k}};function S(A){return A.search(w)!==-1}function C(A){for(var L,T=[];(L=w.exec(A))!==null;)T.push(L[2]);return T.filter(function(E){return!e.isDataUrl(E)})}function k(A){return new RegExp(`url\\((["']?)(${e.escape(A)})\\1\\)`,"gm")}function M(A,L,T,E){return Promise.resolve(L).then(function(P){return T?e.resolveUrl(P,T):P}).then(E||e.getAndEncode).then(function(P){var O=k(L);return A.replace(O,`url($1${P}$1)`)})}})(),r={resolveAll:function(){return n().then(function(w){return Promise.all(w.map(function(S){return S.resolve()}))}).then(function(w){return w.join(`
|
|
10
10
|
`)})},impl:{readAll:n}};function n(){return Promise.resolve(e.asArray(document.styleSheets)).then(function(S){let C=[];return S.forEach(function(k){var M=Object.getPrototypeOf(k);if(Object.prototype.hasOwnProperty.call(M,"cssRules"))try{e.asArray(k.cssRules||[]).forEach(C.push.bind(C))}catch(A){console.error("domtoimage: Error while reading CSS rules from: "+k.href,A.toString())}}),C}).then(function(S){return S.filter(function(C){return C.type===CSSRule.FONT_FACE_RULE}).filter(function(C){return t.shouldProcess(C.style.getPropertyValue("src"))})}).then(function(S){return S.map(w)});function w(S){return{resolve:function(){var C=(S.parentStyleSheet||{}).href;return t.inlineAll(S.cssText,C)},src:function(){return S.style.getPropertyValue("src")}}}}let i={inlineAll:function w(S){if(!e.isElement(S))return Promise.resolve(S);return C(S).then(function(){return e.isHTMLImageElement(S)?a(S).inline():Promise.all(e.asArray(S.childNodes).map(function(k){return w(k)}))});function C(k){let M=["background","background-image"],A=M.map(function(L){let T=k.style.getPropertyValue(L),E=k.style.getPropertyPriority(L);return T?t.inlineAll(T).then(function(P){k.style.setProperty(L,P,E)}):Promise.resolve()});return Promise.all(A).then(function(){return k})}},impl:{newImage:a}};function a(w){return{inline:function(S){return e.isDataUrl(w.src)?Promise.resolve():Promise.resolve(w.src).then(S||e.getAndEncode).then(function(C){return new Promise(function(k){w.onload=k,w.onerror=k,w.src=C})})}}}let s={copyDefaultStyles:!0,imagePlaceholder:void 0,cacheBust:!1,useCredentials:!1,useCredentialsFilters:[],httpTimeout:3e4,styleCaching:"strict",corsImg:void 0,adjustClonedNode:void 0,filterStyles:void 0},o={toSvg:u,toPng:function(w,S){return f(w,S).then(function(C){return C.toDataURL()})},toJpeg:function(w,S){return f(w,S).then(function(C){return C.toDataURL("image/jpeg",(S?S.quality:void 0)||1)})},toBlob:function(w,S){return f(w,S).then(e.canvasToBlob)},toPixelData:function(w,S){return f(w,S).then(function(C){return C.getContext("2d").getImageData(0,0,e.width(w),e.height(w)).data})},toCanvas:f,impl:{fontFaces:r,images:i,util:e,inliner:t,urlCache:[],options:{},copyOptions:function(w){w.copyDefaultStyles===void 0?o.impl.options.copyDefaultStyles=s.copyDefaultStyles:o.impl.options.copyDefaultStyles=w.copyDefaultStyles,o.impl.options.imagePlaceholder=(w.imagePlaceholder===void 0?s:w).imagePlaceholder,o.impl.options.cacheBust=(w.cacheBust===void 0?s:w).cacheBust,o.impl.options.corsImg=(w.corsImg===void 0?s:w).corsImg,o.impl.options.useCredentials=(w.useCredentials===void 0?s:w).useCredentials,o.impl.options.useCredentialsFilters=(w.useCredentialsFilters===void 0?s:w).useCredentialsFilters,o.impl.options.httpTimeout=(w.httpTimeout===void 0?s:w).httpTimeout,o.impl.options.styleCaching=(w.styleCaching===void 0?s:w).styleCaching}}},l=(typeof Qd=="object"&&typeof eh=="object"?eh.exports=o:c.domtoimage=o,(Node===void 0?void 0:Node.ELEMENT_NODE)||1),d=(c===void 0?void 0:c.getComputedStyle)||(window===void 0?void 0:window.getComputedStyle)||globalThis.getComputedStyle,h=(c===void 0?void 0:c.atob)||(window===void 0?void 0:window.atob)||globalThis.atob;function u(w,S){let C=o.impl.util.getWindow(w),k=(S=S||{},o.impl.copyOptions(S),[]);return Promise.resolve(w).then(function(M){if(M.nodeType===l)return M;var A=M,L=document.createElement("span");return A.replaceWith(L),L.append(M),k.push({child:A,wrapper:L}),L}).then(function(M){return(function A(L,T,E,P){let O=T.filter;if(L===p||e.isHTMLScriptElement(L)||e.isHTMLStyleElement(L)||e.isHTMLLinkElement(L)||E!==null&&O&&!O(L))return Promise.resolve();return Promise.resolve(L).then(R).then(_).then(function(N){return B(N,F(L))}).then(D).then(function(N){return $(N,L)});function R(N){return e.isHTMLCanvasElement(N)?e.makeImage(N.toDataURL()):N.cloneNode(!1)}function _(N){return T.adjustClonedNode&&T.adjustClonedNode(L,N,!1),Promise.resolve(N)}function D(N){return T.adjustClonedNode&&T.adjustClonedNode(L,N,!0),Promise.resolve(N)}function F(N){return e.isElementHostForOpenShadowRoot(N)?N.shadowRoot:N}function B(N,z){let W=le(z),K=Promise.resolve();if(W.length!==0){let U=d(G(z));e.asArray(W).forEach(function(he){K=K.then(function(){return A(he,T,U,P).then(function(oe){oe&&N.appendChild(oe)})})})}return K.then(function(){return N});function G(U){return e.isShadowRoot(U)?U.host:U}function le(U){if(e.isShadowSlotElement(U)){let he=U.assignedNodes();if(he&&0<he.length)return he}return U.childNodes}}function $(N,z){return!e.isElement(N)||e.isShadowSlotElement(z)?Promise.resolve(N):Promise.resolve().then(K).then(G).then(le).then(U).then(W).then(function(){return N});function W(){e.isHTMLImageElement(N)&&(N.removeAttribute("loading"),z.srcset||z.sizes)&&(N.removeAttribute("srcset"),N.removeAttribute("sizes"),N.src=z.currentSrc||z.src)}function K(){function he(j,J){J.font=j.font,J.fontFamily=j.fontFamily,J.fontFeatureSettings=j.fontFeatureSettings,J.fontKerning=j.fontKerning,J.fontSize=j.fontSize,J.fontStretch=j.fontStretch,J.fontStyle=j.fontStyle,J.fontVariant=j.fontVariant,J.fontVariantCaps=j.fontVariantCaps,J.fontVariantEastAsian=j.fontVariantEastAsian,J.fontVariantLigatures=j.fontVariantLigatures,J.fontVariantNumeric=j.fontVariantNumeric,J.fontVariationSettings=j.fontVariationSettings,J.fontWeight=j.fontWeight}function oe(j,J){let me=d(j);me.cssText?(J.style.cssText=me.cssText,he(me,J.style)):(b(T,j,me,E,J),E===null&&(["inset-block","inset-block-start","inset-block-end"].forEach(Y=>J.style.removeProperty(Y)),["left","right","top","bottom"].forEach(Y=>{J.style.getPropertyValue(Y)&&J.style.setProperty(Y,"0px")})))}oe(z,N)}function G(){let he=e.uid();function oe(j){let J=d(z,j),me=J.getPropertyValue("content");if(me!==""&&me!=="none"){let Ee=function(){let Ne=`.${he}:`+j,nt=(J.cssText?Z:fe)();return document.createTextNode(Ne+`{${nt}}`);function Z(){return`${J.cssText} content: ${me};`}function fe(){return e.asArray(J).map(Ae).join("; ")+";";function Ae(Ce){let se=J.getPropertyValue(Ce),Ge=J.getPropertyPriority(Ce)?" !important":"";return Ce+": "+se+Ge}}};var Y=Ee;let $e=N.getAttribute("class")||"",We=(N.setAttribute("class",$e+" "+he),document.createElement("style"));We.appendChild(Ee()),N.appendChild(We)}}[":before",":after"].forEach(function(j){oe(j)})}function le(){e.isHTMLTextAreaElement(z)&&(N.innerHTML=z.value),e.isHTMLInputElement(z)&&N.setAttribute("value",z.value)}function U(){e.isSVGElement(N)&&(N.setAttribute("xmlns","http://www.w3.org/2000/svg"),e.isSVGRectElement(N))&&["width","height"].forEach(function(he){let oe=N.getAttribute(he);oe&&N.style.setProperty(he,oe)})}}})(M,S,null,C)}).then(S.disableEmbedFonts?Promise.resolve(w):g).then(S.disableInlineImages?Promise.resolve(w):m).then(function(M){S.bgcolor&&(M.style.backgroundColor=S.bgcolor),S.width&&(M.style.width=S.width+"px"),S.height&&(M.style.height=S.height+"px"),S.style&&Object.keys(S.style).forEach(function(L){M.style[L]=S.style[L]});let A=null;return typeof S.onclone=="function"&&(A=S.onclone(M)),Promise.resolve(A).then(function(){return M})}).then(function(M){let A=S.width||e.width(w),L=S.height||e.height(w);return Promise.resolve(M).then(function(T){return T.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),new XMLSerializer().serializeToString(T)}).then(e.escapeXhtml).then(function(T){var E=(e.isDimensionMissing(A)?' width="100%"':` width="${A}"`)+(e.isDimensionMissing(L)?' height="100%"':` height="${L}"`);return`<svg xmlns="http://www.w3.org/2000/svg"${(e.isDimensionMissing(A)?"":` width="${A}"`)+(e.isDimensionMissing(L)?"":` height="${L}"`)}><foreignObject${E}>${T}</foreignObject></svg>`}).then(function(T){return"data:image/svg+xml;charset=utf-8,"+T})}).then(function(M){for(;0<k.length;){var A=k.pop();A.wrapper.replaceWith(A.child)}return M}).then(function(M){return o.impl.urlCache=[],p&&(document.body.removeChild(p),p=null),x&&clearTimeout(x),x=setTimeout(()=>{x=null,y={}},2e4),M})}function f(w,S){return u(w,S=S||{}).then(e.makeImage).then(function(C){var k=typeof S.scale!="number"?1:S.scale,M=((L,T)=>{let E=S.width||e.width(L),P=S.height||e.height(L);return e.isDimensionMissing(E)&&(E=e.isDimensionMissing(P)?300:2*P),e.isDimensionMissing(P)&&(P=E/2),(L=document.createElement("canvas")).width=E*T,L.height=P*T,S.bgcolor&&((T=L.getContext("2d")).fillStyle=S.bgcolor,T.fillRect(0,0,L.width,L.height)),L})(w,k),A=M.getContext("2d");return A.msImageSmoothingEnabled=!1,A.imageSmoothingEnabled=!1,C&&(A.scale(k,k),A.drawImage(C,0,0)),M})}let p=null;function g(w){return r.resolveAll().then(function(S){var C;return S!==""&&(C=document.createElement("style"),w.appendChild(C),C.appendChild(document.createTextNode(S))),w})}function m(w){return i.inlineAll(w).then(function(){return w})}function b(w,S,C,k,M){let A=o.impl.options.copyDefaultStyles?((T,E)=>{var P,O=(D=>(T.styleCaching!=="relaxed"?D:D.filter((F,B,$)=>B===0||B===$.length-1)).join(">"))(E=(D=>{var F=[];do if(D.nodeType===l){var B=D.tagName;if(F.push(B),v.includes(B))break}while(D=D.parentNode);return F})(E));{if(y[O])return y[O];E=((D,F)=>{let B=D.body;do{var $=F.pop(),$=D.createElement($);B.appendChild($),B=$}while(0<F.length);return B.textContent="\u200B",B})((P=(()=>{if(p)return p.contentWindow;F=document.characterSet||"UTF-8",D=(D=document.doctype)?(`<!DOCTYPE ${K(D.name)} ${K(D.publicId)} `+K(D.systemId)).trim()+">":"",(p=document.createElement("iframe")).id="domtoimage-sandbox-"+e.uid(),p.style.top="-9999px",p.style.visibility="hidden",p.style.position="fixed",document.body.appendChild(p);var D,F,B=p,$="domtoimage-sandbox";try{return B.contentWindow.document.write(D+`<html><head><meta charset='${F}'><title>${$}</title></head><body></body></html>`),B.contentWindow}catch{}var N=document.createElement("meta");N.setAttribute("charset",F);try{var z=document.implementation.createHTMLDocument($),W=(z.head.appendChild(N),D+z.documentElement.outerHTML);return B.setAttribute("srcdoc",W),B.contentWindow}catch{}return B.contentDocument.head.appendChild(N),B.contentDocument.title=$,B.contentWindow;function K(G){var le;return G?((le=document.createElement("div")).innerText=G,le.innerHTML):""}})()).document,E),P=((D,F)=>{let B={},$=D.getComputedStyle(F);return e.asArray($).forEach(function(N){B[N]=N==="width"||N==="height"?"auto":$.getPropertyValue(N)}),B})(P,E);var R=E;do{var _=R.parentElement;_!==null&&_.removeChild(R),R=_}while(R&&R.tagName!=="BODY");return y[O]=P}})(w,S):{},L=M.style;e.asArray(C).forEach(function(T){var E,P,O,R;w.filterStyles&&!w.filterStyles(S,T)||(P=C.getPropertyValue(T),O=A[T],E=k?k.getPropertyValue(T):void 0,L.getPropertyValue(T))||(P!==O||k&&P!==E)&&(O=C.getPropertyPriority(T),E=L,P=P,O=O,R=0<=["background-clip"].indexOf(T=T),O?(E.setProperty(T,P,O),R&&E.setProperty("-webkit-"+T,P,O)):(E.setProperty(T,P),R&&E.setProperty("-webkit-"+T,P)))})}let x=null,y={},v=["ADDRESS","ARTICLE","ASIDE","BLOCKQUOTE","DETAILS","DIALOG","DD","DIV","DL","DT","FIELDSET","FIGCAPTION","FIGURE","FOOTER","FORM","H1","H2","H3","H4","H5","H6","HEADER","HGROUP","HR","LI","MAIN","NAV","OL","P","PRE","SECTION","SVG","TABLE","UL","math","svg","BODY","HEAD","HTML"]})(Qd)});var dr=window;dr.chrome=dr.chrome||{};dr.chrome.runtime=dr.chrome.runtime||{getURL:c=>c,getManifest:()=>({version:"1.0.0-webapp",name:"Chartbuddy Web"}),sendMessage:c=>(console.log("[WebApp] Mock sendMessage:",c),Promise.resolve(null)),onMessage:{addListener:()=>{}}};dr.chrome.storage=dr.chrome.storage||{local:{get:(c,e)=>{let t=Promise.resolve({});return e&&t.then(e),t},set:(c,e)=>{let t=Promise.resolve();return e&&t.then(e),t},remove:(c,e)=>{let t=Promise.resolve();return e&&t.then(e),t},clear:c=>{let e=Promise.resolve();return c&&e.then(c),e}}};dr.ContextMenuTS||(dr.ContextMenuTS={showAt:()=>{console.log("[WebApp] ContextMenu.showAt suppressed in widget")},close:()=>{},destroy:()=>{}});dr.window.ContextMenuTS=dr.ContextMenuTS;console.log("\u{1F310} WebApp Globals Initialized");Jt();En();Ua();var Mi=class{showChartSelectionModal(){console.warn("[NullUIProvider] ChartSelectionModal not available in this build")}showTrialExpiredModal(){console.warn("[NullUIProvider] TrialExpiredModal not available in this build")}showSaveTemplateModal(){console.warn("[NullUIProvider] SaveTemplateModal not available in this build")}showGoogleSheetsConnectionModal(){console.warn("[NullUIProvider] GoogleSheetsConnectionModal not available in this build")}showDeleteConfirmationModal(){console.warn("[NullUIProvider] DeleteConfirmationModal not available in this build")}showInviteModal(){console.warn("[NullUIProvider] InviteModal not available in this build")}removeGoogleSheetsConnection(){console.warn("[NullUIProvider] removeGoogleSheetsConnection not available in this build")}showSeriesOptionsDropdown(){console.warn("[NullUIProvider] SeriesOptionsDropdown not available in this build")}showWaterfallColumnDropdown(){console.warn("[NullUIProvider] WaterfallColumnDropdown not available in this build")}reset(){}};var Vo=null;function Au(c={}){let e=c.platform||kt.getPlatform(),t=c.ui||new Mi,r=c.chartbuddyUrl||"https://chartbuddy-app.com";return{platform:e,ui:t,chartbuddyUrl:r}}function om(c){return Vo=c,c}function Lu(c={}){return om(Au(c))}function Lr(){return Vo||(Vo=Au()),Vo}Ua();Dd();var de=class c{static{this.globalInstance=null}constructor(e){this.listeners=new Map,this.debugMode=e?.debug??!1}static global(){return c.globalInstance||(c.globalInstance=new c({debug:!1})),c.globalInstance}static resetGlobal(){c.globalInstance=null}on(e,t){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),()=>{this.off(e,t)}}once(e,t){let r=n=>{this.off(e,r),t(n)};return this.on(e,r)}emit(e,t){let r=this.listeners.get(e);if(this.debugMode&&console.log(`[EventBus] Emitting "${e}"`,t),!r)return;Array.from(r).forEach(i=>{try{i(t)}catch(a){console.error(`[EventBus] Error in listener for "${e}":`,a)}})}off(e,t){let r=this.listeners.get(e);r&&(t?(r.delete(t),r.size===0&&this.listeners.delete(e)):this.listeners.delete(e))}clear(){this.listeners.clear()}listenerCount(e){let t=this.listeners.get(e);return t?t.size:0}eventNames(){return Array.from(this.listeners.keys())}removeListeners(e){e.forEach(t=>{this.listeners.delete(t)})}};var Rt={CREATED:"chart.created",TYPE_CHANGED:"chart.type_changed",DELETED:"chart.deleted",SAVED:"chart.saved",DOWNLOADED:"chart.downloaded",OPENED:"chart.opened",CD_CHANGED:"chart.cd_changed"};var hr={CLOSE_ALL_DROPDOWNS:"ui.close_all_dropdowns",DROPDOWN_OPENING:"ui.dropdown_opening"};var Ft={OPERATION_FAILED:"error.operation_failed",UI_INTERACTION_FAILED:"error.ui_interaction_failed",SYSTEM_ERROR:"error.system_error"};function zo(c){if(!c||typeof c.closest!="function")return null;let e=c.closest("[data-cb-instance]");if(e){let n=e.getAttribute("data-cb-instance");if(n)return n}let r=c.closest('svg[id^="chart-svg-"]')?.id;return r&&r.startsWith("chart-svg-")?r.slice(10):null}function Pn(c,e){let t=c?.instanceId??null;return!t||!e?!0:t===e}var Ti={clusteredBar:{label:"Clustered Bar",description:"Side-by-side bars comparing series within each category.",optionBag:"bar",family:"bar",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"clustered-bar"},stackedBar:{label:"Stacked Bar",description:"Bars stacked to show composition and category totals.",optionBag:"bar",family:"bar",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"stacked-bar"},stackedBar100:{label:"100% Stacked Bar",description:"Stacked bars normalized to 100% to compare mix, not size.",optionBag:"bar",family:"bar",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"stacked-bar"},line:{label:"Line Chart",description:"Trends over an ordered domain, one line per series.",optionBag:"line",family:"line",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"line"},area:{label:"Area Chart",description:"Filled lines showing magnitude over an ordered domain.",optionBag:"area",family:"area",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"area"},area100:{label:"100% Area Chart",description:"Area chart normalized to 100% to show changing mix.",optionBag:"area",family:"area",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"area"},pie:{label:"Pie Chart",description:"Share of a single total across categories.",optionBag:"pie",family:"pie",seriesLayout:"categoryValue",minRows:2,minCols:2,status:"stable",docsSlug:"pie"},scatter:{label:"Scatter Plot",description:"Points positioned by two metrics, optionally sized and grouped.",optionBag:"scatter",family:"scatter",seriesLayout:"pointRows",minRows:2,minCols:3,status:"stable",docsSlug:"scatter"},waterfall:{label:"Waterfall",description:"Running total showing how contributions bridge two values.",optionBag:"waterfall",family:"waterfall",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"waterfall"},mekko:{label:"Marimekko",description:"Variable-width stacked bars where both axes are percentages.",optionBag:"mekko",family:"mekko",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"mekko"},barMekko:{label:"Bar Mekko",description:"Bars whose width encodes one metric and height another; first data row sets widths.",optionBag:"barMekko",family:"mekko",seriesLayout:"widthRowThenHeightRows",minRows:3,minCols:2,status:"beta",docsSlug:"mekko"},combo:{label:"Combo Chart",description:"Mixed bar and line series on shared or dual axes.",optionBag:"combo",family:"combo",seriesLayout:"seriesRows",minRows:2,minCols:2,status:"stable",docsSlug:"combo"}},Ya={bubble:"scatter",donut:"pie"},lm=[],Mu={},Rd=Object.keys(Ti).sort(),Tu=Object.keys(Ya).sort(),Ho=[...Rd,...Tu].sort(),cm=Tu.filter(c=>!lm.includes(c)),Tv=[...Rd,...cm].sort(),Wo="clusteredBar";function Du(c){return typeof c=="string"&&Object.prototype.hasOwnProperty.call(Ti,c)}function Fd(c){return typeof c=="string"&&Object.prototype.hasOwnProperty.call(Ya,c)}function Go(c){return Du(c)||Fd(c)}function In(c){return Fd(c)?Ya[c]:c}function Bd(c,e){let t=new Array(e.length+1),r=new Array(e.length+1);for(let n=0;n<=e.length;n++)t[n]=n;for(let n=1;n<=c.length;n++){r[0]=n;for(let i=1;i<=e.length;i++){let a=c[n-1]===e[i-1]?0:1;r[i]=Math.min(t[i]+1,r[i-1]+1,t[i-1]+a)}for(let i=0;i<=e.length;i++)t[i]=r[i]}return t[e.length]}function Eu(c){let e=c.toLowerCase(),t=null,r=1/0;for(let i of Ho){let a=Bd(e,i.toLowerCase());a<r&&(r=a,t=i)}let n=Math.max(2,Math.floor(e.length/3));return r<=n?t:null}function Ou(c,e){return Du(c)?c:Fd(c)?Ya[c]:(typeof c=="string"&&c.length>0&&e?.(c),Wo)}function Pu(c){if(!c||typeof c!="object")return c;let e=c;if(typeof e.chartType=="string"){let t=In(e.chartType);t!==e.chartType&&(e.chartType=t)}for(let[t,r]of Object.entries(Mu))e[t]!=null&&(e[r]==null&&(e[r]=e[t]),delete e[t]);return c}var dm=["bar","column","gantt","unknown"];function Di(c){return Go(c)||dm.includes(c)}var zr=class{static createChart(e,t,r){return this.validateChartType(t),this.validateRequired(e,"chartId"),this.validateRequired(r,"source"),{chartId:e,chartType:t,timestamp:Date.now(),data:{source:r}}}static deleteChart(e,t,r){return this.validateChartType(t),this.validateRequired(e,"chartId"),this.validateRequired(r,"source"),{chartId:e,chartType:t,timestamp:Date.now(),data:{source:r}}}static changeChartType(e,t,r){return this.validateChartType(t),this.validateChartType(r),this.validateRequired(e,"chartId"),{chartId:e,chartType:r,timestamp:Date.now(),data:{oldChartType:t,newChartType:r}}}static downloadChart(e,t){return this.validateChartType(t),this.validateRequired(e,"chartId"),{chartId:e,chartType:t,timestamp:Date.now(),data:{}}}static openChart(e,t,r,n){return this.validateRequired(e,"chartId"),this.validateRequired(t,"source"),this.validateRequired(r,"action"),this.validateRequired(n,"trigger"),{chartId:e,chartType:"unknown",timestamp:Date.now(),data:{source:t,action:r,trigger:n}}}static saveChart(e,t,r){return this.validateChartType(t),this.validateRequired(e,"chartId"),{chartId:e,chartType:t,timestamp:Date.now(),data:{performance:r}}}static validateChartType(e){if(!Di(e))throw new Error(`Invalid chart type: ${e}. Must be one of: bar, line, pie, scatter, area, column, donut, waterfall, mekko, barMekko, clusteredBar, stackedBar, stackedBar100, bubble, unknown`)}static validateRequired(e,t){if(e==null||e==="")throw new Error(`Required field '${t}' is missing or empty`)}};var bt=class{static operationFailed(e,t,r,n={}){if(this.validateRequired(t,"operation"),this.validateRequired(r,"component"),this.validateRequired(e,"error"),n.chart_type&&!Di(n.chart_type))throw new Error(`Invalid chart_type in error metadata: ${n.chart_type}`);return{error_name:e.name,error_message:e.message,stack_trace:e.stack?.substring(0,2e3),component:r,operation:t,chart_type:n.chart_type,timestamp:Date.now(),metadata:{...n,auto_tracked:!0}}}static uiInteractionFailed(e,t,r={}){if(this.validateRequired(t,"component"),this.validateRequired(e,"error"),r.chart_type&&!Di(r.chart_type))throw new Error(`Invalid chart_type in error metadata: ${r.chart_type}`);return{error_name:e.name,error_message:e.message,stack_trace:e.stack?.substring(0,2e3),component:t,chart_type:r.chart_type,timestamp:Date.now(),metadata:{...r,auto_tracked:!0}}}static systemError(e,t,r={}){return this.validateRequired(t,"component"),this.validateRequired(e,"error"),{error_name:e.name,error_message:e.message,stack_trace:e.stack?.substring(0,2e3),component:t,timestamp:Date.now(),metadata:{...r,auto_tracked:!0,system_level:!0}}}static validateRequired(e,t){if(e==null||e==="")throw new Error(`Required field '${t}' is missing or empty in error event`)}};var Le="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";var je=class c{constructor(e){this.isOpen=!1;this.clickOutsideHandler=null;this.eventBusUnsubscribe=null;this.eventBusUnsubscribeOpen=null;this.config=e;let{width:t="120px",zIndex:r=10001}=e;if(this.wrapper=document.createElement("div"),this.wrapper.className="cb-combobox-wrapper",this.wrapper.style.width=t,this.wrapper.style.fontFamily=Le,this.dropdown=document.createElement("div"),this.dropdown.className="cb-combobox-dropdown",this.dropdown.style.zIndex=String(r),this.dropdown.style.fontFamily=Le,this.isCustomMode()){let n=this.getCustomConfig();n.positioning==="fixed"&&n.anchorElement&&this.setupFixedPositioning(n.anchorElement)}this.setupBaseEventListeners(),this.setupEventBusListeners()}static{this.activeDropdown=null}static{this.DROPDOWN_STYLES=`
|
|
11
11
|
/* ComboBox Styles */
|
|
12
12
|
.cb-combobox-wrapper {
|