html-in-pptx-out 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- const e=require(`./converter-BXOql-G5.cjs`);let t=require(`fs/promises`),n=require(`path`);function r(t){let n=`${e.a.dim}[html-in-pptx-out]${e.a.reset}`;return{error:()=>{console.error(`${n} ${e.a.red}Error:${e.a.reset}\n${t}`)},info:()=>{console.log(`${n} ${t}`)},success:()=>{console.log(`${n} ${e.a.green}${t}${e.a.reset}`)}}}async function i(){let i=process.argv.slice(2),a=[],o=`.slide`;for(let e=0;e<i.length;e++)i[e]===`--selector`&&e+1<i.length?(o=i[e+1],e++):i[e].startsWith(`--`)||a.push(i[e]);a.length<2&&(r(`Usage: html-in-pptx-out <input.html> <output.pptx> [--selector <selector>]`).error(),process.exit(1));let[s,c]=a,l=(0,n.resolve)(s),u=(0,n.resolve)(c),d=await(0,t.readFile)(l,`utf-8`),f=new e.t({selector:o});await f.load(d).convert();let p=await f.export({format:`pptx`,filename:u});await(0,t.writeFile)(u,Buffer.from(p)),r(`exported: ${u}`).success()}i().catch(e=>{console.error(e.message),process.exit(1)});
2
+ const e=require(`./converter-BQuv6GPK.cjs`);let t=require(`fs/promises`),n=require(`path`);function r(t){let n=`${e.a.dim}[html-in-pptx-out]${e.a.reset}`;return{error:()=>{console.error(`${n} ${e.a.red}Error:${e.a.reset}\n${t}`)},info:()=>{console.log(`${n} ${t}`)},success:()=>{console.log(`${n} ${e.a.green}${t}${e.a.reset}`)}}}async function i(){let i=process.argv.slice(2),a=[],o=`.slide`;for(let e=0;e<i.length;e++)i[e]===`--selector`&&e+1<i.length?(o=i[e+1],e++):i[e].startsWith(`--`)||a.push(i[e]);a.length<2&&(r(`Usage: html-in-pptx-out <input.html> <output.pptx> [--selector <selector>]`).error(),process.exit(1));let[s,c]=a,l=(0,n.resolve)(s),u=(0,n.resolve)(c),d=await(0,t.readFile)(l,`utf-8`),f=new e.t({selector:o});await f.load(d).convert();let p=await f.export({format:`pptx`,filename:u});await(0,t.writeFile)(u,Buffer.from(p)),r(`exported: ${u}`).success()}i().catch(e=>{console.error(e.message),process.exit(1)});
package/dist/cli.mjs CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import{a as e,t}from"./converter-DzUDHivU.mjs";import{readFile as n,writeFile as r}from"fs/promises";import{resolve as i}from"path";function a(t){let n=`${e.dim}[html-in-pptx-out]${e.reset}`;return{error:()=>{console.error(`${n} ${e.red}Error:${e.reset}\n${t}`)},info:()=>{console.log(`${n} ${t}`)},success:()=>{console.log(`${n} ${e.green}${t}${e.reset}`)}}}async function o(){let e=process.argv.slice(2),o=[],s=`.slide`;for(let t=0;t<e.length;t++)e[t]===`--selector`&&t+1<e.length?(s=e[t+1],t++):e[t].startsWith(`--`)||o.push(e[t]);o.length<2&&(a(`Usage: html-in-pptx-out <input.html> <output.pptx> [--selector <selector>]`).error(),process.exit(1));let[c,l]=o,u=i(c),d=i(l),f=await n(u,`utf-8`),p=new t({selector:s});await p.load(f).convert();let m=await p.export({format:`pptx`,filename:d});await r(d,Buffer.from(m)),a(`exported: ${d}`).success()}o().catch(e=>{console.error(e.message),process.exit(1)});export{};
2
+ import{a as e,t}from"./converter-DRGQShsh.mjs";import{readFile as n,writeFile as r}from"fs/promises";import{resolve as i}from"path";function a(t){let n=`${e.dim}[html-in-pptx-out]${e.reset}`;return{error:()=>{console.error(`${n} ${e.red}Error:${e.reset}\n${t}`)},info:()=>{console.log(`${n} ${t}`)},success:()=>{console.log(`${n} ${e.green}${t}${e.reset}`)}}}async function o(){let e=process.argv.slice(2),o=[],s=`.slide`;for(let t=0;t<e.length;t++)e[t]===`--selector`&&t+1<e.length?(s=e[t+1],t++):e[t].startsWith(`--`)||o.push(e[t]);o.length<2&&(a(`Usage: html-in-pptx-out <input.html> <output.pptx> [--selector <selector>]`).error(),process.exit(1));let[c,l]=o,u=i(c),d=i(l),f=await n(u,`utf-8`),p=new t({selector:s});await p.load(f).convert();let m=await p.export({format:`pptx`,filename:d});await r(d,Buffer.from(m)),a(`exported: ${d}`).success()}o().catch(e=>{console.error(e.message),process.exit(1)});export{};
3
3
  //# sourceMappingURL=cli.mjs.map
@@ -0,0 +1,4 @@
1
+ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`pptxgenjs`);c=s(c);var l=class{plugins=[];context={presentation:void 0,metadata:{},state:new Map};register(e){if(this.plugins.some(t=>t.name===e.name))throw Error(`Plugin "${e.name}" is already registered`);this.plugins.push(e)}unregister(e){let t=this.plugins.findIndex(t=>t.name===e);t!==-1&&this.plugins.splice(t,1)}getPlugins(){return[...this.plugins]}setPresentation(e){this.context.presentation=e}async executeBeforeParse(e,t){let n=e;for(let e of this.plugins)e.beforeParse&&(n=await e.beforeParse(n,t,this.context));return n}async executeOnParse(e,t){for(let n of this.plugins){if(!n.handles||!n.onParse||!new Set(n.handles).has(t.elementType))continue;let r=await n.onParse(e,t,this.context);if(r)return r}return null}async executeOnSlide(e){let t=e;for(let e of this.plugins)e.onSlide&&(t=await e.onSlide(t,this.context));return t}async executeAfterGenerate(e,t){for(let n of this.plugins)n.afterGenerate&&await n.afterGenerate(e,t,this.context)}},u=class extends Error{constructor(e){super(`Assertion failed: ${e}`),this.name=`AssertionError`}};function d(e,t){if(!e)throw new u(t)}function f(e,t){if(e==null)throw new u(t)}const p=e=>e.split(`,`).map(e=>e.trim().replace(/^["']|["']$/g,``).trim()).filter(e=>e!=null).join(`, `),m=e=>{if(!e||e===`transparent`)return``;let t=e.trim().replace(/^#/,``);if(/^[0-9a-fA-F]{3}$/.test(t))return t[0]+t[0]+t[1]+t[1]+t[2]+t[2];if(/^[0-9a-fA-F]{6}$/.test(t))return t;let n=e.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);if(n){let[,e,t,r]=n;return[e,t,r].map(e=>parseInt(e,10).toString(16).padStart(2,`0`)).join(``)}return``},h=e=>{let t=parseInt(e,10);if(!isNaN(t))return String(t);if(e===`bold`||e===`bolder`)return`700`;if(e===`lighter`)return`300`;if(e===`normal`)return`400`},g=e=>{if(e===`italic`)return`italic`;if(e===`oblique`)return`oblique`;if(e===`normal`)return`normal`},ee=e=>{if(e===`left`||e===`start`)return`left`;if(e===`center`)return`center`;if(e===`right`||e===`end`)return`right`;if(e===`justify`)return`justify`},te=e=>{if(e===`top`)return`top`;if(e===`middle`)return`middle`;if(e===`bottom`)return`bottom`},_=e=>({fontFamily:p(e.fontFamily)||V.FONT_FAMILY,fontSize:parseFloat(e.fontSize)||void 0,fontWeight:h(e.fontWeight),fontStyle:g(e.fontStyle),letterSpacing:parseFloat(e.letterSpacing)||void 0,lineHeight:parseFloat(e.lineHeight)||void 0,color:m(e.color)||void 0,underline:e.textDecorationLine?.includes(`underline`)||!1,strikethrough:e.textDecorationLine?.includes(`line-through`)||!1,textAlign:ee(e.textAlign),verticalAlign:te(e.verticalAlign)}),ne=e=>({top:parseFloat(e.paddingTop)||0,right:parseFloat(e.paddingRight)||0,bottom:parseFloat(e.paddingBottom)||0,left:parseFloat(e.paddingLeft)||0}),v=e=>{let t=e.transform;if(!t||t===`none`)return;let n=t.match(/rotate\(([-\d.]+)/);if(n)return parseFloat(n[1])||void 0;let r=t.match(/matrix\(([^)]+)\)/);if(r){let e=r[1].split(`,`).map(e=>parseFloat(e.trim()));if(e.length>=2){let t=e[0],n=e[1],r=Math.atan2(n,t)*(180/Math.PI);return Math.abs(r)<.01?void 0:r}}},y=e=>{let t=parseFloat(e.opacity);return t===1?void 0:t||void 0},b=e=>parseInt(e.zIndex,10)||void 0,x=(e,t)=>({left:e.left-t.left,top:e.top-t.top}),S=(e,t=1)=>({width:e.width*t,height:e.height}),re=new Set([`h1`,`h2`,`h3`,`h4`,`h5`,`h6`,`p`,`span`,`div`,`a`,`li`,`label`,`strong`,`em`,`b`,`u`,`s`,`small`,`mark`]),ie=new Set([`img`,`picture`,`svg`]),ae=new Set([`table`]),oe=new Set([`td`,`th`,`tr`,`thead`,`tbody`,`tfoot`,`caption`,`colgroup`,`col`]),se=(e,t=window)=>{let n=[],r=e.tagName.toLowerCase();if(ae.has(r))return n.push(`table`),n;if(oe.has(r))return n;if(e.id.toLowerCase().includes(`chart`)&&n.push(`chart`),ie.has(r))return n.push(`image`),n;if(r===`hr`)return n.push(`line`),n;if(T(e))return n.push(`icon`),n;let i=t.getComputedStyle(e);return ce(i)&&n.push(`shape`),w(i)&&n.push(`line`),re.has(r)&&ue(e)&&n.push(`text`),n},ce=e=>{let t=e.backgroundColor!==`transparent`&&e.backgroundColor!==`rgba(0, 0, 0, 0)`,n=e.backgroundImage!==`none`&&e.backgroundImage!==``,r=parseFloat(e.borderWidth)>0&&e.borderColor!==`transparent`&&e.borderColor!==`rgba(0, 0, 0, 0)`,i=e.boxShadow!==`none`&&e.boxShadow!==``,a=parseFloat(e.borderRadius)>0;return t||n||r||i||a},C=e=>{let t=e.toLowerCase();return re.has(e)?/^h[1-6]$/.test(t)?t:t===`p`?`p`:`body`:null},le=(e,t)=>{let n=parseFloat(e.borderRadius)||0,{width:r,height:i}=t;return n>=Math.min(r,i)/2*.9&&Math.abs(r-i)<2?`ellipse`:n>0?`roundRect`:`rect`},ue=e=>{for(let t of e.childNodes)if(t.nodeType===Node.TEXT_NODE&&t.textContent&&t.textContent.trim().length>0)return!0;return!1},w=e=>{let t=parseFloat(e.borderLeftWidth)||0,n=parseFloat(e.borderRightWidth)||0,r=parseFloat(e.borderTopWidth)||0,i=parseFloat(e.borderBottomWidth)||0,a=[{side:`left`,width:t},{side:`right`,width:n},{side:`top`,width:r},{side:`bottom`,width:i}].filter(e=>e.width>0);return a.length===1?a[0].side:null},T=e=>e.tagName.toLowerCase()===`i`?Array.from(e.classList).some(e=>e.startsWith(`fa-`)&&e!==`fa`):!1,E=e=>{let t=[];for(let n of e.childNodes){if(n.nodeType===Node.TEXT_NODE){let e=n.textContent?.replace(/\s+/g,` `)||``;e.trim().length>0&&t.push({content:e})}if(n.nodeType===Node.ELEMENT_NODE){let e=n,r=e.tagName.toLowerCase();if(r===`br`){t.push({content:`
2
+ `});continue}let i=e.className||``,a=e.ownerDocument.defaultView.getComputedStyle(e),o=E(e);if(!C(r))continue;let s={content:e.textContent||``,tagName:r,className:i,typography:_(a),children:o.length>0?o:void 0};r===`a`&&(s.href=e.getAttribute(`href`)||void 0),t.push(s)}}return t},de=e=>{let t=``,n=e=>{if(e.nodeType===Node.TEXT_NODE){t+=e.textContent||``;return}if(e.nodeType===Node.ELEMENT_NODE){let r=e.tagName.toLowerCase();if(r===`br`){t+=`
3
+ `;return}for(let t of e.childNodes)n(t);(r===`p`||r===`div`)&&e.nextSibling&&(t+=`
4
+ `)}};for(let t of e.childNodes)n(t);return t.trim()},fe=(e,t)=>{let n=e.querySelectorAll(`i`),r=0;for(let e of n)if(T(e)){let t=e.getBoundingClientRect().width,n=e.ownerDocument.defaultView.getComputedStyle(e),i=parseFloat(n.marginRight)||0;r+=t+i}return new DOMRect(t.left+r,t.top,t.width-r,t.height)},D={name:`core:text`,handles:[`text`],onParse:(e,t)=>{let{computedStyle:n,boundingRect:r,tagName:i,slideElement:a}=t,o=e.textContent?.trim();if(!o)return null;let s=C(i);if(!s)return null;let c=a.getBoundingClientRect(),l=fe(e,r),u=x(l,c),d=S(l,He),f=E(e);return{type:`text`,id:crypto.randomUUID(),content:o,runs:f.length>0?f:void 0,position:u,dimensions:d,typography:_(n),textType:s,padding:ne(n),zIndex:b(n),rotation:v(n),opacity:y(n)}}},O=e=>{let t=e.match(/rgba\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*([\d.]+)\s*\)/);if(t){let e=parseFloat(t[1]);if(e<1)return e}},k=e=>{let t=[],n=/(rgba?\([^)]+\)|#[0-9a-fA-F]{3,6}|\w+)\s*([\d.]+%)?/g,r,i=0;for(;(r=n.exec(e))!==null;){let[,e,n]=r,a=m(e);if(!a)continue;let o=0;o=n?parseFloat(n)/100:i===0?0:1;let s=O(e);t.push({color:a,position:o,opacity:s}),i++}return t},pe=e=>{let t=e.match(/(\d+)deg/);if(t)return parseInt(t[1],10);for(let[t,n]of Object.entries({"to top":0,"to right":90,"to bottom":180,"to left":270,"to top right":45,"to bottom right":135,"to bottom left":225,"to top left":315}))if(e.includes(t))return n;return 180},A=e=>{let t=e.backgroundImage;if(t&&t!==`none`){if(t.includes(`linear-gradient`)){let e=k(t);if(e.length>=2)return{type:`gradient`,gradientType:`linear`,angle:pe(t),stops:e}}if(t.includes(`radial-gradient`)){let e=k(t);if(e.length>=2)return{type:`gradient`,gradientType:`radial`,stops:e}}}let n=e.backgroundColor;if(!n||n===`transparent`||n===`rgba(0, 0, 0, 0)`)return;let r=m(n);if(r)return{type:`solid`,color:r,opacity:O(n)}},me=e=>{let t=parseFloat(e.borderWidth)||0;if(t===0)return;let n=e.borderColor,r=m(n);if(!r)return;let i=e.borderStyle,a=`solid`;i===`dashed`?a=`dashed`:i===`dotted`&&(a=`dotted`);let o,s=n.match(/rgba?\([^)]+,\s*([\d.]+)\)/);if(s){let e=parseFloat(s[1]);e<1&&(o=e)}return{color:r,width:t,style:a,opacity:o}},he=e=>{let t=parseFloat(e.borderRadius)||0;if(t!==0)return t},ge={name:`core:shape`,handles:[`shape`],onParse:(e,t)=>{let{computedStyle:n,boundingRect:r,slideElement:i}=t,a=i.getBoundingClientRect();return{type:`shape`,id:crypto.randomUUID(),shapeType:le(n,r),position:x(r,a),dimensions:S(r),fill:A(n),stroke:me(n),borderRadius:he(n),zIndex:b(n),rotation:v(n),opacity:y(n)}}},_e=(e,t)=>{let n=1,r=`rgb(0,0,0)`,i=`solid`;t===`left`?(n=parseFloat(e.borderLeftWidth)||1,r=e.borderLeftColor||`rgb(0,0,0)`,i=e.borderLeftStyle||`solid`):t===`right`?(n=parseFloat(e.borderRightWidth)||1,r=e.borderRightColor||`rgb(0,0,0)`,i=e.borderRightStyle||`solid`):t===`top`?(n=parseFloat(e.borderTopWidth)||1,r=e.borderTopColor||`rgb(0,0,0)`,i=e.borderTopStyle||`solid`):(n=parseFloat(e.borderBottomWidth)||1,r=e.borderBottomColor||`rgb(0,0,0)`,i=e.borderBottomStyle||`solid`);let a=m(r)||`000000`,o=`solid`;i===`dashed`?o=`dashed`:i===`dotted`&&(o=`dotted`);let s,c=r.match(/rgba\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*([\d.]+)\s*\)/);if(c){let e=parseFloat(c[1]);e<1&&(s=e)}return{color:a,width:n,style:o,opacity:s}},ve=(e,t,n)=>{let r=e.left-t.left,i=e.top-t.top,a=r+e.width,o=i+e.height;return n===`left`?{start:{left:r,top:i},end:{left:r,top:o}}:n===`right`?{start:{left:a,top:i},end:{left:a,top:o}}:n===`top`?{start:{left:r,top:i},end:{left:a,top:i}}:{start:{left:r,top:o},end:{left:a,top:o}}},ye={name:`core:line`,handles:[`line`],onParse:(e,t)=>{let{computedStyle:n,boundingRect:r,tagName:i,slideElement:a}=t,o=a.getBoundingClientRect(),s,c,l;if(i===`hr`){let e=r.left-o.left,t=r.top-o.top,i=e+r.width;c={left:e,top:t},l={left:i,top:t};let a=parseFloat(n.borderTopWidth)||1;s={color:m(n.borderTopColor||`rgb(0,0,0)`)||`000000`,width:a,style:`solid`}}else{let e=w(n);if(!e)return null;let t=ve(r,o,e);c=t.start,l=t.end,s=_e(n,e)}return{type:`line`,id:crypto.randomUUID(),start:c,end:l,stroke:s,zIndex:b(n),rotation:v(n),opacity:y(n)}}},j=(e,t,n)=>{if(t===0)return;let r=m(e);if(!r)return;let i=`solid`;n===`dashed`?i=`dashed`:n===`dotted`&&(i=`dotted`);let a=O(e);return{color:r,width:t,style:i,opacity:a}},be=e=>{let t=parseFloat(e.borderTopWidth)||0,n=parseFloat(e.borderRightWidth)||0,r=parseFloat(e.borderBottomWidth)||0,i=parseFloat(e.borderLeftWidth)||0;if(!(t>0||n>0||r>0||i>0))return;let a={};return t>0&&(a.top=j(e.borderTopColor,t,e.borderTopStyle)),n>0&&(a.right=j(e.borderRightColor,n,e.borderRightStyle)),r>0&&(a.bottom=j(e.borderBottomColor,r,e.borderBottomStyle)),i>0&&(a.left=j(e.borderLeftColor,i,e.borderLeftStyle)),a},xe=e=>{let t=e.ownerDocument,n=t.defaultView.getComputedStyle(e),r=A(n),i=be(n),a=e.parentElement;if(a){let e=t.defaultView.getComputedStyle(a);r||=A(e),i||=be(e)}let o=E(e),s={id:crypto.randomUUID(),text:de(e),runs:o.length>0?o:void 0,typography:_(n),fill:r,border:i};return e.colSpan>1&&(s.colspan=e.colSpan),e.rowSpan>1&&(s.rowspan=e.rowSpan),s},Se=e=>{let t=[],n=e.querySelectorAll(`tr`);for(let e of n){let n=[],r=e.querySelectorAll(`th, td`);for(let e of r)n.push(xe(e));n.length>0&&t.push(n)}return t},Ce=e=>{let t=e.querySelector(`tr`);if(!t)return[];let n=t.querySelectorAll(`th, td`);if(n.length===0)return[];let r=[];for(let e of n){let t=e.getBoundingClientRect().width;r.push(t)}return r},M={name:`core:table`,handles:[`table`],onParse:(e,t)=>{let{boundingRect:n,slideElement:r}=t,i=e,a=r.getBoundingClientRect(),o=Se(i);if(o.length===0)return null;let s=i.querySelector(`thead`)!==null,c=i.querySelector(`th`)!==null,l=Ce(i);return{type:`table`,id:crypto.randomUUID(),position:x(n,a),dimensions:S(n),rows:o,colWidths:l.length>0?l:void 0,headerRow:s||c}}},we=e=>{if(!e||typeof e!=`object`)return`unknown`;let t=e;return Array.isArray(t.data)&&t.data.length>0&&t.data[0]&&typeof t.data[0]==`object`&&`type`in t.data[0]?`plotly`:`unknown`},Te=e=>{let t=new Map;return e.querySelectorAll(`script[type="application/json"][data-chart-id]`).forEach(n=>{let r=n.getAttribute(`data-chart-id`),i=n.getAttribute(`data-chart-type`);if(!(!r||!i)&&e.getElementById(r))try{let e=JSON.parse(n.textContent||`{}`),a=e;if(!(Array.isArray(a.data)&&a.data.length>0&&a.data[0]&&typeof a.data[0]==`object`&&`type`in a.data[0]))return;let o=we(e),s=a.data[0].type;t.set(r,{chartId:r,chartType:s||i,config:e,sourceLibrary:o})}catch{return}}),t},N=e=>Array.isArray(e)?e.map(e=>e==null?``:String(e)):[],P=e=>Array.isArray(e)?e.map(e=>{let t=Number(e);return isNaN(t)?0:t}):[],Ee=e=>{for(let t of e){if(t.labels&&Array.isArray(t.labels))return N(t.labels);if(t.orientation===`h`&&t.y&&Array.isArray(t.y))return N(t.y);if(t.x&&Array.isArray(t.x))return N(t.x)}return[]},De=e=>{if(e.marker?.color&&typeof e.marker.color==`string`)return e.marker.color;if(e.line?.color&&typeof e.line.color==`string`)return e.line.color},Oe=e=>{if(e.marker?.colors&&Array.isArray(e.marker.colors))return e.marker.colors;if(e.marker?.color&&Array.isArray(e.marker.color))return e.marker.color},ke=e=>{if(e.title){if(typeof e.title==`string`)return e.title;if(typeof e.title==`object`&&e.title.text)return e.title.text}},Ae=e=>{if(e.title){if(typeof e.title==`string`)return 11;if(typeof e.title==`object`&&e.title.font)return e.title.font.size}},F=e=>{if(!(!e||!e.title)){if(typeof e.title==`string`)return e.title;if(typeof e.title==`object`&&e.title.text)return e.title.text}},je=e=>{let t=e.data||[],n=e.layout||{};if(t.length===0)throw Error(`No traces found in config.data`);let r=t[0],i=G[(r?.type||`bar`).toLowerCase()]||`bar`,a=Ee(t),o=t.map(e=>{let t={name:e.name||`Series`,values:[],color:De(e),colors:Oe(e)},n=e.type||`bar`;return t.chartType=G[n.toLowerCase()]||n,e.values?t.values=P(e.values):e.orientation===`h`&&e.x?t.values=P(e.x):e.y&&(t.values=P(e.y)),e.yaxis===`y2`?t.yAxis=`y2`:e.yaxis===`y3`&&(t.yAxis=`y3`),t}),s={title:ke(n),titleFontSize:Ae(n),showLegend:n.showlegend!==!1,xAxisTitle:F(n.xaxis),yAxisTitle:F(n.yaxis),margin:n.margin};return n.yaxis2&&(s.hasSecondaryAxis=!0,s.yAxis2Title=F(n.yaxis2)),(t.some(e=>e.text&&Array.isArray(e.text)&&e.text.length>0)||r.textinfo)&&(s.showDataLabels=!0),i===`bar`&&(s.orientation=r.orientation===`h`?`horizontal`:`vertical`,n.barmode===`stack`?(s.barGrouping=`stacked`,s.barmode=`stack`):n.barmode===`group`?(s.barGrouping=`clustered`,s.barmode=`group`):n.barmode===`relative`&&(s.barGrouping=`percentStacked`,s.barmode=`relative`),r.textposition&&(s.dataLabelPosition=r.textposition)),i===`pie`&&(r.hole!==void 0&&(s.hole=r.hole),r.textinfo&&(s.dataLabelFormat=r.textinfo),r.textposition&&(s.dataLabelPosition=r.textposition)),n.font&&(s.font={family:n.font.family,size:n.font.size}),{chartType:i,series:o,labels:a,options:s}},I={name:`core:chart-plotly`,handles:[`chart`],beforeParse:(e,t,n)=>{let r=Te(new DOMParser().parseFromString(e,`text/html`));if(r.size===0)return e;let i={extractedCharts:r,chartBoundsMap:new Map};return n.state.set(I.name,i),e},onParse:(e,t,n)=>{let r=n.state.get(I.name);if(!r||r.extractedCharts.size===0)return null;let i=e.ownerDocument,{slideIndex:a,slideElement:o}=t,s=o.getBoundingClientRect();return r.extractedCharts.forEach((e,t)=>{if(r.chartBoundsMap.has(t))return;let n=i.getElementById(t);if(!n||!o.contains(n))return;let c=n.getBoundingClientRect();r.chartBoundsMap.set(t,{left:c.left-s.left,top:c.top-s.top,width:c.width,height:c.height,slideIndex:a})}),null},onSlide:(e,t)=>{let n=t.state.get(I.name);if(!n||n.extractedCharts.size===0||n.chartBoundsMap.size===0)return e;let{extractedCharts:r,chartBoundsMap:i}=n,a=new Set,o=[];r.forEach((t,n)=>{let r=i.get(n);if(!r||r.slideIndex!==e.order)return;let s=-1,c=1/0;if(e.elements.forEach((e,t)=>{if(e.type!==`image`||a.has(t))return;let n=Math.sqrt((e.position.left-r.left)**2+(e.position.top-r.top)**2);n<c&&(c=n,s=t)}),s!==-1){let n;try{if(t.sourceLibrary===`plotly`)n=je(t.config);else return}catch{return}let i=e.elements[s],c=i.position.left,l=i.position.top,u=c+i.dimensions.width,d=l+i.dimensions.height;e.elements.forEach((e,t)=>{if(e.type!==`image`)return;let n=e,r=n.position.left,i=n.position.top,o=r+n.dimensions.width,s=i+n.dimensions.height;r>=c&&i>=l&&o<=u&&s<=d&&a.add(t)});let f={type:`chart`,originalType:`image`,id:crypto.randomUUID(),position:{left:r.left,top:r.top},dimensions:{width:r.width,height:r.height},data:n,sourceLibrary:t.sourceLibrary};o.push(f)}});let s=e.elements.filter((e,t)=>!a.has(t));return{...e,elements:[...s,...o]}}},Me=e=>{let t=e.tagName.toLowerCase();if(t===`img`)return e.src||``;if(t===`svg`){let t=new XMLSerializer().serializeToString(e);return`data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(t)))}`}if(t===`picture`){let t=e.querySelector(`img`);if(t)return t.src||``}return``},Ne=e=>{let t=e.tagName.toLowerCase();if(t===`img`)return e.alt||void 0;if(t===`svg`){let t=e.querySelector(`title`);if(t)return t.textContent||void 0}},L={name:`core:image`,handles:[`image`],onParse:(e,t)=>{let{computedStyle:n,boundingRect:r,slideElement:i}=t,a=i.getBoundingClientRect(),o=Me(e);return o?{type:`image`,id:crypto.randomUUID(),src:o,alt:Ne(e),position:x(r,a),dimensions:S(r),zIndex:b(n),rotation:v(n),opacity:y(n)}:null}},R=new Map,z=new Map,Pe=e=>e.includes(`fab`)||e.includes(`fa-brands`)?`brands`:e.includes(`far`)||e.includes(`fa-regular`)?`regular`:`solid`,Fe=new Set([`fa-solid`,`fa-regular`,`fa-brands`,`fa-light`,`fa-thin`,`fa-duotone`]),Ie=e=>e.find(e=>e.startsWith(`fa-`)&&e!==`fa`&&!Fe.has(e))||null,Le=async(e,t)=>{let n=e.replace(`fa-`,``),r=We[n]||n,i=r===n?[n]:[r,n],a=t===`solid`?[`solid`]:[t,`solid`];for(let e of i)for(let t of a){let n=[`https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.0.0/svgs/${t}/${e}.svg`,`https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@7.0.0/svgs/${t}/${e}.svg`];for(let e of n)try{let t=await fetch(e);if(!t.ok)continue;let n=await t.text(),r=new DOMParser().parseFromString(n,`image/svg+xml`).querySelector(`svg`);if(!r)continue;let i=r.getAttribute(`viewBox`)||`0 0 512 512`,a=Array.from(r.querySelectorAll(`path`)).map(e=>e.getAttribute(`d`)).filter(Boolean).join(` `);if(!a)continue;return{viewBox:i,path:a}}catch{continue}}return null},Re=async(e,t)=>{let n=`${t}:${e}`;if(R.has(n))return R.get(n);if(z.has(n))return z.get(n);let r=Le(e,t).then(e=>(e&&R.set(n,e),e)).finally(()=>{z.delete(n)});return z.set(n,r),r},ze=(e,t)=>{let n=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="${e.viewBox}"><path fill="#${t}" d="${e.path}"/></svg>`;return`data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(n)))}`},B={name:`core:icon-fontawesome`,handles:[`icon`],onParse:async(e,t)=>{let{computedStyle:n,boundingRect:r,slideElement:i}=t,a=Array.from(e.classList),o=Ie(a);if(!o)return null;let s=await Re(o,Pe(a));if(!s)return null;let c=ze(s,m(n.color)||`000000`),l=i.getBoundingClientRect(),u=s.viewBox.split(` `).map(Number),d=(u[2]||512)/(u[3]||512),f=r.width,p=r.height,h=p*d,g=f/d;return h<=f?f=h:p=g,{type:`image`,originalType:`icon`,id:crypto.randomUUID(),src:c,alt:o,position:x(r,l),dimensions:{width:f,height:p},zIndex:b(n),rotation:v(n),opacity:y(n)}}},Be={reset:`\x1B[0m`,red:`\x1B[31m`,green:`\x1B[32m`,yellow:`\x1B[33m`,dim:`\x1B[2m`},V={SLIDE_SELECTOR:`.slide`,SLIDE_WIDTH:992,SLIDE_HEIGHT:558,FONT_FAMILY:``,CHART_FONT_SIZE:9},H={DPI:96,PPTX_PIXELS_TO_INCHES:73.7,RADIUS_MULTIPLIER:.75},U={solid:`solid`,dashed:`dash`,dotted:`sysDot`},Ve={100:`Thin`,200:`ExtraLight`,300:`Light`,400:``,500:`Medium`,600:`SemiBold`,700:`Bold`,800:`ExtraBold`,900:`Black`},W=[D,ge,ye,M,L,B,I],He=1.03,G={pie:`pie`,bar:`bar`,line:`line`,scatter:`scatter`,area:`area`,doughnut:`doughnut`,radar:`radar`,bubble:`bubble`},Ue={pie:`pie`,bar:`bar`,line:`line`,scatter:`line`,area:`area`,doughnut:`doughnut`,radar:`radar`,bubble:`bubble`},We={"check-circle":`circle-check`,"times-circle":`circle-xmark`,"exclamation-circle":`circle-exclamation`,"exclamation-triangle":`triangle-exclamation`,"shield-alt":`shield`,search:`magnifying-glass`,times:`xmark`,bars:`bars`,cog:`gear`,trash:`trash-can`,edit:`pen-to-square`,"external-link-alt":`arrow-up-right-from-square`,"arrow-alt-circle-down":`circle-down`,"arrow-alt-circle-up":`circle-up`,"arrow-alt-circle-left":`circle-left`,"arrow-alt-circle-right":`circle-right`,"sign-in-alt":`right-to-bracket`,"sign-out-alt":`right-from-bracket`,percentage:`percent`};var Ge=class{config;pluginManager;presentation=null;source=null;parser;serializer;constructor(e){f(e.parser,`Parser strategy is required`),f(e.serializer,`Serializer strategy is required`),this.config={...e,selector:e.selector||`.slide`,dimensions:e.dimensions||{width:V.SLIDE_WIDTH,height:V.SLIDE_HEIGHT}},this.parser=e.parser,this.serializer=e.serializer,this.pluginManager=new l,this.serializer.setPluginManager&&this.serializer.setPluginManager(this.pluginManager);let t=e.plugins?.core??[],n=e.plugins?.extensions??[];t.forEach(e=>this.use(e)),n.forEach(e=>this.use(e))}use(e){return this.pluginManager.register(e),this}load(e){return typeof e==`string`?this.source=e:this.source=e.content,this}async convert(){f(this.source,`No HTML source loaded. Call load() first.`),this.config.debug&&console.group(`[html-in-pptx-out] convert`);let e={selector:this.config.selector,dimensions:this.config.dimensions},t=await this.pluginManager.executeBeforeParse(this.source,e),{elements:n,cleanup:r}=await this.parser.parse(t,e);this.config.debug&&console.log(`before: executeOnParse`,{elements:n});let i=new Map;for(let{slideIndex:e,element:t,parseContext:r}of n){let n=await this.pluginManager.executeOnParse(t,r);n&&(i.has(e)||i.set(e,[]),i.get(e).push(n))}this.config.debug&&console.log(`after: executeOnParse`,{slides:i}),r();let a=[],o=Array.from(i.keys()).sort((e,t)=>e-t);for(let e of o){let t={id:crypto.randomUUID(),order:e,elements:i.get(e)||[]};a.push(t)}this.presentation={slides:a,metadata:{createdAt:new Date,plugins:this.pluginManager.getPlugins().map(e=>e.name)},viewport:this.config.dimensions};for(let e=0;e<this.presentation.slides.length;e++)this.presentation.slides[e]=await this.pluginManager.executeOnSlide(this.presentation.slides[e]);return this.pluginManager.setPresentation(this.presentation),this.config.debug&&(console.log(`after: executeOnSlide`,{presentation:this.presentation}),console.groupEnd()),this}async export(e){return f(this.presentation,`No presentation to export. Call convert() first.`),await this.serializer.serialize(this.presentation,e)}async exportImages(e){throw Error(`Not implemented`)}getPresentation(){return f(this.presentation,`No presentation available. Call convert() first.`),this.presentation}};const Ke=(e,t)=>new Promise((n,r)=>{let i=document.createElement(`iframe`);i.style.position=`fixed`,i.style.left=`-9999px`,i.style.top=`-9999px`,i.style.width=`${t.width}px`,i.style.height=`${t.height}px`,i.style.opacity=`0`,i.style.pointerEvents=`none`,i.style.zIndex=`-1`,i.setAttribute(`aria-hidden`,`true`);let a=()=>{i.removeEventListener(`load`,a);let e=i.contentDocument;if(!e){r(Error(`Failed to access iframe document`));return}let t=()=>{e.readyState===`complete`?requestAnimationFrame(()=>n(i)):setTimeout(t,10)};t()};i.addEventListener(`load`,a),i.onerror=()=>r(Error(`Failed to load iframe`)),i.srcdoc=e,document.body.appendChild(i)}),qe=e=>{e.remove()};var Je=class{async parse(e,t){let n=await Ke(e,t.dimensions),r=n.contentDocument.querySelectorAll(t.selector),i=[];for(let e=0;e<r.length;e++){let t=r[e],a=t.querySelectorAll(`*`),o=[t,...Array.from(a)],s=new Set;for(let r of o){let a=!1,o=r.parentElement;for(;o&&o!==t;){if(s.has(o)){a=!0;break}o=o.parentElement}if(a)continue;let c=se(r,n.contentWindow);if(c.length===0)continue;let l=n.contentWindow.getComputedStyle(r),u=r.getBoundingClientRect(),d=r.tagName.toLowerCase();for(let n of c){(n===`table`||n===`text`)&&s.add(r);let a={elementType:n,tagName:d,computedStyle:l,boundingRect:u,slideIndex:e,slideElement:t};i.push({slideIndex:e,element:r,parseContext:a})}}}return{elements:i,cleanup:()=>qe(n)}}};const K=e=>e/H.DPI,q=e=>e/H.DPI*72,J=(e,t)=>{let n=e.left/t.width*100,r=e.top/t.height*100;return{x:`${n}%`,y:`${r}%`}},Y=(e,t)=>{let n=e.width/t.width*100,r=e.height/t.height*100;return{w:`${n}%`,h:`${r}%`}},Ye=e=>({x:K(e.left),y:K(e.top)}),Xe=e=>({w:K(e.width),h:K(e.height)}),X=e=>{let t={};return e.fontFamily&&(t.fontFace=e.fontFamily.split(`,`)[0].trim()),e.fontSize&&(t.fontSize=q(e.fontSize)),e.color&&(t.color=e.color.toUpperCase()),e.fontWeight&&(parseInt(e.fontWeight,10)||400)>400&&(t.bold=!0),(e.fontStyle===`italic`||e.fontStyle===`oblique`)&&(t.italic=!0),e.underline&&(t.underline={style:`sng`}),e.strikethrough&&(t.strike=`sngStrike`),t},Z=e=>{let t=[];for(let n of e)if(n.children&&n.children.length>0){let e=Z(n.children);for(let r of e){let e={...r.options};if(n.typography){let t=X(n.typography);Object.assign(e,t,r.options)}n.href&&(e.hyperlink={url:n.href}),t.push({text:r.text,options:e})}}else{let e={};n.typography&&Object.assign(e,X(n.typography)),n.href&&(e.hyperlink={url:n.href}),t.push({text:n.content,options:e})}return t},Ze=(e,t,n)=>{let r=J(t.position,n),i=Y(t.dimensions,n),a={x:r.x,y:r.y,w:i.w,h:i.h,lineSpacingMultiple:1,valign:`top`,align:`left`,isTextBox:!0,wrap:!0,shrinkText:!1};if(t.typography){let e=t.typography,n=X(e);Object.assign(a,n),e.textAlign&&(a.align=e.textAlign),e.verticalAlign&&(a.valign=e.verticalAlign),e.letterSpacing&&(a.charSpacing=e.letterSpacing)}if(t.padding&&(a.margin=[q(t.padding.top),q(t.padding.right),q(t.padding.bottom),q(t.padding.left)]),t.rotation&&(a.rotate=t.rotation),t.opacity!==void 0&&t.opacity<1&&(a.transparency=Math.round((1-t.opacity)*100)),t.runs&&t.runs.length>0){let n=Z(t.runs);e.addText(n,a)}else e.addText(t.content,a)},Qe=e=>e,$e=e=>U[e.style]||`solid`,et=(e,t,n)=>{let r=J(t.position,n),i=Y(t.dimensions,n),a=Qe(t.shapeType)||c.default.ShapeType.rect,o={x:r.x,y:r.y,w:i.w,h:i.h};if(t.fill){let e={};if(t.fill.type===`solid`)e.color=t.fill.color.toUpperCase(),t.fill.opacity!==void 0&&t.fill.opacity<1&&(e.transparency=Math.round((1-t.fill.opacity)*100));else if(t.fill.type===`gradient`){let n=t.fill.stops[0];n&&(e.color=n.color.toUpperCase(),n.opacity!==void 0&&n.opacity<1&&(e.transparency=Math.round((1-n.opacity)*100)))}e.color&&(o.fill=e)}if(t.stroke){let e={color:t.stroke.color.toUpperCase(),width:t.stroke.width,dashType:$e(t.stroke)};t.stroke.opacity!==void 0&&(e.transparency=Math.round((1-t.stroke.opacity)*100)),o.line=e}if(t.rotation&&(o.rotate=t.rotation),t.borderRadius&&t.shapeType===`roundRect`){let e=Math.min(t.dimensions.width,t.dimensions.height);o.rectRadius=Math.min(t.borderRadius/e,1)}if(t.shadow){let e=t.shadow.offset.x,n=t.shadow.offset.y,r=Math.sqrt(e**2+n**2),i=(Math.atan2(n,e)*180/Math.PI%360+360)%360;o.shadow={type:t.shadow.type,color:t.shadow.color.toUpperCase(),blur:q(t.shadow.blur),offset:q(r),angle:i,opacity:t.shadow.opacity??1}}e.addShape(a,o)},tt=e=>U[e.style]||`solid`,nt=(e,t,n)=>{let r=t.start.left/n.width*100,i=t.start.top/n.height*100,a=t.end.left/n.width*100,o=t.end.top/n.height*100,s=Math.abs(a-r),c=Math.abs(o-i),l={color:t.stroke.color.toUpperCase(),width:t.stroke.width,dashType:tt(t.stroke)};t.stroke.opacity!==void 0&&(l.transparency=Math.round((1-t.stroke.opacity)*100));let u={x:`${Math.min(r,a)}%`,y:`${Math.min(i,o)}%`,w:`${s||.1}%`,h:`${c||.1}%`,line:l},d=t.end.left<t.start.left,f=t.end.top<t.start.top;d&&(u.flipH=!0),f&&(u.flipV=!0),e.addShape(`line`,u)},rt=(e,t,n)=>{let r=J(t.position,n),i=Y(t.dimensions,n),a={x:r.x,y:r.y,w:i.w,h:i.h};t.src.startsWith(`data:`)?a.data=t.src:a.path=t.src,t.alt&&(a.altText=t.alt),t.rotation&&(a.rotate=t.rotation),t.opacity!==void 0&&t.opacity<1&&(a.transparency=Math.round((1-t.opacity)*100)),t.fit&&(a.sizing={type:{contain:`contain`,cover:`cover`,stretch:`crop`}[t.fit]||`contain`,w:t.dimensions.width,h:t.dimensions.height}),e.addImage(a)},it=(e,t)=>{let n=e.split(`,`)[0].trim();if(!t)return n;let r=Ve[parseInt(t,10)||400];return!r||r===``?n:`${n} ${r}`},at=(e,t,n)=>{let r=J(t.position,n),i=Y(t.dimensions,n),a=t.rows.map(e=>e.map(e=>{let t={text:e.runs&&e.runs.length>0?Z(e.runs):e.text};if(e.colspan&&(t.options={...t.options,colspan:e.colspan}),e.rowspan&&(t.options={...t.options,rowspan:e.rowspan}),e.typography){let n=e.typography,r=n.fontWeight&&parseInt(n.fontWeight,10)||400;t.options={...t.options,fontFace:n.fontFamily?it(n.fontFamily,n.fontWeight):void 0,fontSize:n.fontSize?q(n.fontSize):void 0,color:n.color?n.color.toUpperCase():void 0,bold:r>400,italic:n.fontStyle===`italic`||n.fontStyle===`oblique`,underline:n.underline?{style:`sng`}:void 0,align:n.textAlign,valign:n.verticalAlign}}if(e.fill){if(e.fill.type===`solid`){let n={color:e.fill.color.toUpperCase()};e.fill.opacity!==void 0&&e.fill.opacity<1&&(n.transparency=Math.round((1-e.fill.opacity)*100)),t.options={...t.options,fill:n}}else if(e.fill.type===`gradient`){let n=e.fill.stops[0];n&&(t.options={...t.options,fill:{color:n.color.toUpperCase()}})}}if(e.border){let n=[`top`,`right`,`bottom`,`left`],r=[];for(let t of n){let n=e.border[t];if(n){let e=`solid`;(n.style===`dashed`||n.style===`dotted`)&&(e=`dash`),r.push({color:n.color.toUpperCase(),pt:n.width,type:e})}else r.push({type:`none`})}let i=r;t.options={...t.options,border:i}}return t})),o={x:r.x,y:r.y,w:i.w,h:i.h};t.colWidths&&t.colWidths.length>0&&(o.colW=t.colWidths.map(e=>K(e))),t.cellMinHeight&&(o.rowH=q(t.cellMinHeight)/72),t.headerRow&&(o.autoPageHeaderRows=1),e.addTable(a,o)},ot=e=>{for(let t of e)if(!(!t.values||!Array.isArray(t.values))){for(let e of t.values)if(typeof e==`number`&&!Number.isInteger(e)){let e=0;for(let n of t.values)if(typeof n==`number`&&!Number.isInteger(n)){let t=n.toString().split(`.`)[1]?.length||0;e=Math.max(e,Math.min(t,2))}return e===1?`#,##0.0`:`#,##0.00`}}return`#,##0`},st=e=>Ue[e]||`bar`,Q=e=>{let t=e.data.chartType;return t===`pie`&&e.data.options?.hole!==void 0&&e.data.options.hole>0?`doughnut`:Ue[t]||`bar`},ct=e=>{let t=Ye(e.position),n=Xe(e.dimensions),r=e.data,i={type:r.chartType,series:r.series,labels:r.labels,options:r.options},a=i.series.map(e=>({name:e.name,labels:i.labels,values:e.values,color:m(e.color||``)})),o={x:t.x,y:t.y,w:n.w,h:n.h,title:i.options?.title,showTitle:!!i.options?.title,titleFontSize:i.options?.titleFontSize||V.CHART_FONT_SIZE,showLegend:i.options?.showLegend!==!1,legendPos:`t`,legendFontSize:V.CHART_FONT_SIZE,showLabel:i.options?.showDataLabels===!0,dataLabelFontSize:V.CHART_FONT_SIZE};if(i.options?.showDataLabels===!0)if(i.type===`bar`){o.showValue=!0;let e=ot(i.series);e&&(o.dataLabelFormatCode=e)}else i.type===`pie`&&(o.showPercent=!0);i.type===`pie`&&(o.dataLabelPosition=`outEnd`);let s=[];if(i.series.some(e=>e.colors&&e.colors.length>0)){let e=i.series.find(e=>e.colors&&e.colors.length>0);e?.colors&&s.push(...e.colors)}else i.series.forEach(e=>{e.color&&s.push(e.color)});if(s.length>0&&(o.chartColors=s.map(e=>m(e)).filter(e=>e!==void 0)),i.options?.xAxisTitle&&(o.catAxisTitle=i.options.xAxisTitle,o.showCatAxisTitle=!0,o.catAxisTitleFontSize=V.CHART_FONT_SIZE),i.options?.yAxisTitle&&(o.valAxisTitle=i.options.yAxisTitle,o.showValAxisTitle=!0,o.valAxisTitleFontSize=V.CHART_FONT_SIZE),o.catAxisLabelFontSize=V.CHART_FONT_SIZE,o.valAxisLabelFontSize=V.CHART_FONT_SIZE,o.catGridLine={style:`none`},o.valGridLine={style:`solid`,size:1,color:`D9D9D9`},i.options?.hole!==void 0&&i.options.hole>0&&(o.holeSize=Math.round(i.options.hole*100)),i.options?.orientation===`horizontal`?o.barDir=`bar`:(i.options?.orientation===`vertical`||i.type===`bar`)&&(o.barDir=`col`),i.options?.barGrouping&&(o.barGrouping=i.options.barGrouping),i.options?.hasSecondaryAxis){let t=new Map,n=new Map;if(i.series.forEach((e,r)=>{let o=e.chartType||i.type,s=a[r];e.yAxis===`y2`?(n.has(o)||n.set(o,[]),n.get(o).push(s)):(t.has(o)||t.set(o,[]),t.get(o).push(s))}),n.size===0)return{data:a,options:o,chartTypeKey:Q(e)};let r=[];return t.forEach((e,t)=>{r.push({typeKey:st(t),data:e,options:{}})}),n.forEach((e,t)=>{let n=t===`line`||t===`area`;r.push({typeKey:st(t),data:e,options:{secondaryValAxis:!0,secondaryCatAxis:!0,...n?{showValue:!0,dataLabelPosition:`t`}:{}}})}),{data:null,options:{x:o.x,y:o.y,w:o.w,h:o.h,title:o.title,showTitle:o.showTitle,titleFontSize:o.titleFontSize,showLegend:o.showLegend,legendPos:`t`,legendFontSize:V.CHART_FONT_SIZE,chartColors:o.chartColors,dataLabelFormatCode:o.dataLabelFormatCode,dataLabelFontSize:V.CHART_FONT_SIZE,valAxes:[{valAxisTitle:i.options.yAxisTitle||``,showValAxisTitle:!!i.options.yAxisTitle,valAxisTitleFontSize:V.CHART_FONT_SIZE,valAxisLabelFontSize:V.CHART_FONT_SIZE,valGridLine:{style:`solid`,size:1,color:`D9D9D9`}},{valAxisTitle:i.options.yAxis2Title||``,showValAxisTitle:!1,valAxisTitleFontSize:V.CHART_FONT_SIZE,valAxisLabelFontSize:V.CHART_FONT_SIZE,valGridLine:{style:`none`}}],catAxes:[{catAxisTitle:i.options.xAxisTitle||``,showCatAxisTitle:!!i.options.xAxisTitle,catAxisTitleFontSize:V.CHART_FONT_SIZE,catAxisLabelFontSize:V.CHART_FONT_SIZE,catGridLine:{style:`none`}},{catAxisLabelFontSize:V.CHART_FONT_SIZE,catAxisHidden:!0,catGridLine:{style:`none`}}]},chartTypesForCombo:r,chartTypeKey:Q(e)}}return{data:a,options:o,chartTypeKey:Q(e)}},lt=(e,t)=>{let{data:n,options:r,chartTypesForCombo:i,chartTypeKey:a}=ct(t);if(t.data.options?.hasSecondaryAxis&&i){let t=i.map(e=>({type:e.typeKey,data:e.data,options:e.options||{}}));e.addChart(t,r)}else{let t=a;if(!t||!n)return;e.addChart(t,n,r)}};var $=class{pluginManager=null;setPluginManager(e){this.pluginManager=e}async serialize(e,t){d(e.slides.length>0,`No slides to export. Check selector or create a slide to export`);let n=new c.default,r=K(e.viewport.width),i=K(e.viewport.height);n.defineLayout({name:`custom`,width:r,height:i}),n.layout=`custom`,e.metadata.title&&(n.title=e.metadata.title),e.metadata.author&&(n.author=e.metadata.author),e.metadata.subject&&(n.subject=e.metadata.subject);for(let t of e.slides){let r=n.addSlide();for(let n of t.elements)switch(n.type){case`text`:Ze(r,n,e.viewport);break;case`image`:rt(r,n,e.viewport);break;case`shape`:et(r,n,e.viewport);break;case`table`:at(r,n,e.viewport);break;case`chart`:lt(r,n);break;case`line`:nt(r,n,e.viewport);break}}return this.pluginManager&&await this.pluginManager.executeAfterGenerate(n,e),await n.write({outputType:`arraybuffer`})}},ut=class extends Ge{constructor(e={}){super({selector:e.selector||V.SLIDE_SELECTOR,dimensions:e.dimensions||{width:V.SLIDE_WIDTH,height:V.SLIDE_HEIGHT},plugins:{core:e.plugins?.core??W,extensions:e.plugins?.extensions??[]},parser:e.parser||new Je,serializer:e.serializer||new $,debug:e.debug})}};Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return Be}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return B}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return M}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return ye}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return Ge}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return L}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return D}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return $}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return V}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return ge}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return Je}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return W}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return ut}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return I}});
@@ -0,0 +1,5 @@
1
+ import e from"pptxgenjs";var t=class{plugins=[];context={presentation:void 0,metadata:{},state:new Map};register(e){if(this.plugins.some(t=>t.name===e.name))throw Error(`Plugin "${e.name}" is already registered`);this.plugins.push(e)}unregister(e){let t=this.plugins.findIndex(t=>t.name===e);t!==-1&&this.plugins.splice(t,1)}getPlugins(){return[...this.plugins]}setPresentation(e){this.context.presentation=e}async executeBeforeParse(e,t){let n=e;for(let e of this.plugins)e.beforeParse&&(n=await e.beforeParse(n,t,this.context));return n}async executeOnParse(e,t){for(let n of this.plugins){if(!n.handles||!n.onParse||!new Set(n.handles).has(t.elementType))continue;let r=await n.onParse(e,t,this.context);if(r)return r}return null}async executeOnSlide(e){let t=e;for(let e of this.plugins)e.onSlide&&(t=await e.onSlide(t,this.context));return t}async executeAfterGenerate(e,t){for(let n of this.plugins)n.afterGenerate&&await n.afterGenerate(e,t,this.context)}},n=class extends Error{constructor(e){super(`Assertion failed: ${e}`),this.name=`AssertionError`}};function r(e,t){if(!e)throw new n(t)}function i(e,t){if(e==null)throw new n(t)}const a=e=>e.split(`,`).map(e=>e.trim().replace(/^["']|["']$/g,``).trim()).filter(e=>e!=null).join(`, `),o=e=>{if(!e||e===`transparent`)return``;let t=e.trim().replace(/^#/,``);if(/^[0-9a-fA-F]{3}$/.test(t))return t[0]+t[0]+t[1]+t[1]+t[2]+t[2];if(/^[0-9a-fA-F]{6}$/.test(t))return t;let n=e.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);if(n){let[,e,t,r]=n;return[e,t,r].map(e=>parseInt(e,10).toString(16).padStart(2,`0`)).join(``)}return``},s=e=>{let t=parseInt(e,10);if(!isNaN(t))return String(t);if(e===`bold`||e===`bolder`)return`700`;if(e===`lighter`)return`300`;if(e===`normal`)return`400`},c=e=>{if(e===`italic`)return`italic`;if(e===`oblique`)return`oblique`;if(e===`normal`)return`normal`},l=e=>{if(e===`left`||e===`start`)return`left`;if(e===`center`)return`center`;if(e===`right`||e===`end`)return`right`;if(e===`justify`)return`justify`},u=e=>{if(e===`top`)return`top`;if(e===`middle`)return`middle`;if(e===`bottom`)return`bottom`},d=e=>({fontFamily:a(e.fontFamily)||z.FONT_FAMILY,fontSize:parseFloat(e.fontSize)||void 0,fontWeight:s(e.fontWeight),fontStyle:c(e.fontStyle),letterSpacing:parseFloat(e.letterSpacing)||void 0,lineHeight:parseFloat(e.lineHeight)||void 0,color:o(e.color)||void 0,underline:e.textDecorationLine?.includes(`underline`)||!1,strikethrough:e.textDecorationLine?.includes(`line-through`)||!1,textAlign:l(e.textAlign),verticalAlign:u(e.verticalAlign)}),f=e=>({top:parseFloat(e.paddingTop)||0,right:parseFloat(e.paddingRight)||0,bottom:parseFloat(e.paddingBottom)||0,left:parseFloat(e.paddingLeft)||0}),p=e=>{let t=e.transform;if(!t||t===`none`)return;let n=t.match(/rotate\(([-\d.]+)/);if(n)return parseFloat(n[1])||void 0;let r=t.match(/matrix\(([^)]+)\)/);if(r){let e=r[1].split(`,`).map(e=>parseFloat(e.trim()));if(e.length>=2){let t=e[0],n=e[1],r=Math.atan2(n,t)*(180/Math.PI);return Math.abs(r)<.01?void 0:r}}},m=e=>{let t=parseFloat(e.opacity);return t===1?void 0:t||void 0},h=e=>parseInt(e.zIndex,10)||void 0,g=(e,t)=>({left:e.left-t.left,top:e.top-t.top}),_=(e,t=1)=>({width:e.width*t,height:e.height}),v=new Set([`h1`,`h2`,`h3`,`h4`,`h5`,`h6`,`p`,`span`,`div`,`a`,`li`,`label`,`strong`,`em`,`b`,`u`,`s`,`small`,`mark`]),y=new Set([`img`,`picture`,`svg`]),b=new Set([`table`]),ee=new Set([`td`,`th`,`tr`,`thead`,`tbody`,`tfoot`,`caption`,`colgroup`,`col`]),te=(e,t=window)=>{let n=[],r=e.tagName.toLowerCase();if(b.has(r))return n.push(`table`),n;if(ee.has(r))return n;if(e.id.toLowerCase().includes(`chart`)&&n.push(`chart`),y.has(r))return n.push(`image`),n;if(r===`hr`)return n.push(`line`),n;if(C(e))return n.push(`icon`),n;let i=t.getComputedStyle(e);return ne(i)&&n.push(`shape`),S(i)&&n.push(`line`),v.has(r)&&ie(e)&&n.push(`text`),n},ne=e=>{let t=e.backgroundColor!==`transparent`&&e.backgroundColor!==`rgba(0, 0, 0, 0)`,n=e.backgroundImage!==`none`&&e.backgroundImage!==``,r=parseFloat(e.borderWidth)>0&&e.borderColor!==`transparent`&&e.borderColor!==`rgba(0, 0, 0, 0)`,i=e.boxShadow!==`none`&&e.boxShadow!==``,a=parseFloat(e.borderRadius)>0;return t||n||r||i||a},x=e=>{let t=e.toLowerCase();return v.has(e)?/^h[1-6]$/.test(t)?t:t===`p`?`p`:`body`:null},re=(e,t)=>{let n=parseFloat(e.borderRadius)||0,{width:r,height:i}=t;return n>=Math.min(r,i)/2*.9&&Math.abs(r-i)<2?`ellipse`:n>0?`roundRect`:`rect`},ie=e=>{for(let t of e.childNodes)if(t.nodeType===Node.TEXT_NODE&&t.textContent&&t.textContent.trim().length>0)return!0;return!1},S=e=>{let t=parseFloat(e.borderLeftWidth)||0,n=parseFloat(e.borderRightWidth)||0,r=parseFloat(e.borderTopWidth)||0,i=parseFloat(e.borderBottomWidth)||0,a=[{side:`left`,width:t},{side:`right`,width:n},{side:`top`,width:r},{side:`bottom`,width:i}].filter(e=>e.width>0);return a.length===1?a[0].side:null},C=e=>e.tagName.toLowerCase()===`i`?Array.from(e.classList).some(e=>e.startsWith(`fa-`)&&e!==`fa`):!1,w=e=>{let t=[];for(let n of e.childNodes){if(n.nodeType===Node.TEXT_NODE){let e=n.textContent?.replace(/\s+/g,` `)||``;e.trim().length>0&&t.push({content:e})}if(n.nodeType===Node.ELEMENT_NODE){let e=n,r=e.tagName.toLowerCase();if(r===`br`){t.push({content:`
2
+ `});continue}let i=e.className||``,a=e.ownerDocument.defaultView.getComputedStyle(e),o=w(e);if(!x(r))continue;let s={content:e.textContent||``,tagName:r,className:i,typography:d(a),children:o.length>0?o:void 0};r===`a`&&(s.href=e.getAttribute(`href`)||void 0),t.push(s)}}return t},ae=e=>{let t=``,n=e=>{if(e.nodeType===Node.TEXT_NODE){t+=e.textContent||``;return}if(e.nodeType===Node.ELEMENT_NODE){let r=e.tagName.toLowerCase();if(r===`br`){t+=`
3
+ `;return}for(let t of e.childNodes)n(t);(r===`p`||r===`div`)&&e.nextSibling&&(t+=`
4
+ `)}};for(let t of e.childNodes)n(t);return t.trim()},oe=(e,t)=>{let n=e.querySelectorAll(`i`),r=0;for(let e of n)if(C(e)){let t=e.getBoundingClientRect().width,n=e.ownerDocument.defaultView.getComputedStyle(e),i=parseFloat(n.marginRight)||0;r+=t+i}return new DOMRect(t.left+r,t.top,t.width-r,t.height)},T={name:`core:text`,handles:[`text`],onParse:(e,t)=>{let{computedStyle:n,boundingRect:r,tagName:i,slideElement:a}=t,o=e.textContent?.trim();if(!o)return null;let s=x(i);if(!s)return null;let c=a.getBoundingClientRect(),l=oe(e,r),u=g(l,c),v=_(l,Ie),y=w(e);return{type:`text`,id:crypto.randomUUID(),content:o,runs:y.length>0?y:void 0,position:u,dimensions:v,typography:d(n),textType:s,padding:f(n),zIndex:h(n),rotation:p(n),opacity:m(n)}}},E=e=>{let t=e.match(/rgba\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*([\d.]+)\s*\)/);if(t){let e=parseFloat(t[1]);if(e<1)return e}},se=e=>{let t=[],n=/(rgba?\([^)]+\)|#[0-9a-fA-F]{3,6}|\w+)\s*([\d.]+%)?/g,r,i=0;for(;(r=n.exec(e))!==null;){let[,e,n]=r,a=o(e);if(!a)continue;let s=0;s=n?parseFloat(n)/100:i===0?0:1;let c=E(e);t.push({color:a,position:s,opacity:c}),i++}return t},ce=e=>{let t=e.match(/(\d+)deg/);if(t)return parseInt(t[1],10);for(let[t,n]of Object.entries({"to top":0,"to right":90,"to bottom":180,"to left":270,"to top right":45,"to bottom right":135,"to bottom left":225,"to top left":315}))if(e.includes(t))return n;return 180},D=e=>{let t=e.backgroundImage;if(t&&t!==`none`){if(t.includes(`linear-gradient`)){let e=se(t);if(e.length>=2)return{type:`gradient`,gradientType:`linear`,angle:ce(t),stops:e}}if(t.includes(`radial-gradient`)){let e=se(t);if(e.length>=2)return{type:`gradient`,gradientType:`radial`,stops:e}}}let n=e.backgroundColor;if(!n||n===`transparent`||n===`rgba(0, 0, 0, 0)`)return;let r=o(n);if(r)return{type:`solid`,color:r,opacity:E(n)}},le=e=>{let t=parseFloat(e.borderWidth)||0;if(t===0)return;let n=e.borderColor,r=o(n);if(!r)return;let i=e.borderStyle,a=`solid`;i===`dashed`?a=`dashed`:i===`dotted`&&(a=`dotted`);let s,c=n.match(/rgba?\([^)]+,\s*([\d.]+)\)/);if(c){let e=parseFloat(c[1]);e<1&&(s=e)}return{color:r,width:t,style:a,opacity:s}},ue=e=>{let t=parseFloat(e.borderRadius)||0;if(t!==0)return t},de={name:`core:shape`,handles:[`shape`],onParse:(e,t)=>{let{computedStyle:n,boundingRect:r,slideElement:i}=t,a=i.getBoundingClientRect();return{type:`shape`,id:crypto.randomUUID(),shapeType:re(n,r),position:g(r,a),dimensions:_(r),fill:D(n),stroke:le(n),borderRadius:ue(n),zIndex:h(n),rotation:p(n),opacity:m(n)}}},fe=(e,t)=>{let n=1,r=`rgb(0,0,0)`,i=`solid`;t===`left`?(n=parseFloat(e.borderLeftWidth)||1,r=e.borderLeftColor||`rgb(0,0,0)`,i=e.borderLeftStyle||`solid`):t===`right`?(n=parseFloat(e.borderRightWidth)||1,r=e.borderRightColor||`rgb(0,0,0)`,i=e.borderRightStyle||`solid`):t===`top`?(n=parseFloat(e.borderTopWidth)||1,r=e.borderTopColor||`rgb(0,0,0)`,i=e.borderTopStyle||`solid`):(n=parseFloat(e.borderBottomWidth)||1,r=e.borderBottomColor||`rgb(0,0,0)`,i=e.borderBottomStyle||`solid`);let a=o(r)||`000000`,s=`solid`;i===`dashed`?s=`dashed`:i===`dotted`&&(s=`dotted`);let c,l=r.match(/rgba\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*([\d.]+)\s*\)/);if(l){let e=parseFloat(l[1]);e<1&&(c=e)}return{color:a,width:n,style:s,opacity:c}},pe=(e,t,n)=>{let r=e.left-t.left,i=e.top-t.top,a=r+e.width,o=i+e.height;return n===`left`?{start:{left:r,top:i},end:{left:r,top:o}}:n===`right`?{start:{left:a,top:i},end:{left:a,top:o}}:n===`top`?{start:{left:r,top:i},end:{left:a,top:i}}:{start:{left:r,top:o},end:{left:a,top:o}}},me={name:`core:line`,handles:[`line`],onParse:(e,t)=>{let{computedStyle:n,boundingRect:r,tagName:i,slideElement:a}=t,s=a.getBoundingClientRect(),c,l,u;if(i===`hr`){let e=r.left-s.left,t=r.top-s.top,i=e+r.width;l={left:e,top:t},u={left:i,top:t};let a=parseFloat(n.borderTopWidth)||1;c={color:o(n.borderTopColor||`rgb(0,0,0)`)||`000000`,width:a,style:`solid`}}else{let e=S(n);if(!e)return null;let t=pe(r,s,e);l=t.start,u=t.end,c=fe(n,e)}return{type:`line`,id:crypto.randomUUID(),start:l,end:u,stroke:c,zIndex:h(n),rotation:p(n),opacity:m(n)}}},O=(e,t,n)=>{if(t===0)return;let r=o(e);if(!r)return;let i=`solid`;n===`dashed`?i=`dashed`:n===`dotted`&&(i=`dotted`);let a=E(e);return{color:r,width:t,style:i,opacity:a}},k=e=>{let t=parseFloat(e.borderTopWidth)||0,n=parseFloat(e.borderRightWidth)||0,r=parseFloat(e.borderBottomWidth)||0,i=parseFloat(e.borderLeftWidth)||0;if(!(t>0||n>0||r>0||i>0))return;let a={};return t>0&&(a.top=O(e.borderTopColor,t,e.borderTopStyle)),n>0&&(a.right=O(e.borderRightColor,n,e.borderRightStyle)),r>0&&(a.bottom=O(e.borderBottomColor,r,e.borderBottomStyle)),i>0&&(a.left=O(e.borderLeftColor,i,e.borderLeftStyle)),a},he=e=>{let t=e.ownerDocument,n=t.defaultView.getComputedStyle(e),r=D(n),i=k(n),a=e.parentElement;if(a){let e=t.defaultView.getComputedStyle(a);r||=D(e),i||=k(e)}let o=w(e),s={id:crypto.randomUUID(),text:ae(e),runs:o.length>0?o:void 0,typography:d(n),fill:r,border:i};return e.colSpan>1&&(s.colspan=e.colSpan),e.rowSpan>1&&(s.rowspan=e.rowSpan),s},ge=e=>{let t=[],n=e.querySelectorAll(`tr`);for(let e of n){let n=[],r=e.querySelectorAll(`th, td`);for(let e of r)n.push(he(e));n.length>0&&t.push(n)}return t},_e=e=>{let t=e.querySelector(`tr`);if(!t)return[];let n=t.querySelectorAll(`th, td`);if(n.length===0)return[];let r=[];for(let e of n){let t=e.getBoundingClientRect().width;r.push(t)}return r},A={name:`core:table`,handles:[`table`],onParse:(e,t)=>{let{boundingRect:n,slideElement:r}=t,i=e,a=r.getBoundingClientRect(),o=ge(i);if(o.length===0)return null;let s=i.querySelector(`thead`)!==null,c=i.querySelector(`th`)!==null,l=_e(i);return{type:`table`,id:crypto.randomUUID(),position:g(n,a),dimensions:_(n),rows:o,colWidths:l.length>0?l:void 0,headerRow:s||c}}},ve=e=>{if(!e||typeof e!=`object`)return`unknown`;let t=e;return Array.isArray(t.data)&&t.data.length>0&&t.data[0]&&typeof t.data[0]==`object`&&`type`in t.data[0]?`plotly`:`unknown`},ye=e=>{let t=new Map;return e.querySelectorAll(`script[type="application/json"][data-chart-id]`).forEach(n=>{let r=n.getAttribute(`data-chart-id`),i=n.getAttribute(`data-chart-type`);if(!(!r||!i)&&e.getElementById(r))try{let e=JSON.parse(n.textContent||`{}`),a=e;if(!(Array.isArray(a.data)&&a.data.length>0&&a.data[0]&&typeof a.data[0]==`object`&&`type`in a.data[0]))return;let o=ve(e),s=a.data[0].type;t.set(r,{chartId:r,chartType:s||i,config:e,sourceLibrary:o})}catch{return}}),t},j=e=>Array.isArray(e)?e.map(e=>e==null?``:String(e)):[],M=e=>Array.isArray(e)?e.map(e=>{let t=Number(e);return isNaN(t)?0:t}):[],be=e=>{for(let t of e){if(t.labels&&Array.isArray(t.labels))return j(t.labels);if(t.orientation===`h`&&t.y&&Array.isArray(t.y))return j(t.y);if(t.x&&Array.isArray(t.x))return j(t.x)}return[]},xe=e=>{if(e.marker?.color&&typeof e.marker.color==`string`)return e.marker.color;if(e.line?.color&&typeof e.line.color==`string`)return e.line.color},Se=e=>{if(e.marker?.colors&&Array.isArray(e.marker.colors))return e.marker.colors;if(e.marker?.color&&Array.isArray(e.marker.color))return e.marker.color},Ce=e=>{if(e.title){if(typeof e.title==`string`)return e.title;if(typeof e.title==`object`&&e.title.text)return e.title.text}},we=e=>{if(e.title){if(typeof e.title==`string`)return 11;if(typeof e.title==`object`&&e.title.font)return e.title.font.size}},N=e=>{if(!(!e||!e.title)){if(typeof e.title==`string`)return e.title;if(typeof e.title==`object`&&e.title.text)return e.title.text}},Te=e=>{let t=e.data||[],n=e.layout||{};if(t.length===0)throw Error(`No traces found in config.data`);let r=t[0],i=U[(r?.type||`bar`).toLowerCase()]||`bar`,a=be(t),o=t.map(e=>{let t={name:e.name||`Series`,values:[],color:xe(e),colors:Se(e)},n=e.type||`bar`;return t.chartType=U[n.toLowerCase()]||n,e.values?t.values=M(e.values):e.orientation===`h`&&e.x?t.values=M(e.x):e.y&&(t.values=M(e.y)),e.yaxis===`y2`?t.yAxis=`y2`:e.yaxis===`y3`&&(t.yAxis=`y3`),t}),s={title:Ce(n),titleFontSize:we(n),showLegend:n.showlegend!==!1,xAxisTitle:N(n.xaxis),yAxisTitle:N(n.yaxis),margin:n.margin};return n.yaxis2&&(s.hasSecondaryAxis=!0,s.yAxis2Title=N(n.yaxis2)),(t.some(e=>e.text&&Array.isArray(e.text)&&e.text.length>0)||r.textinfo)&&(s.showDataLabels=!0),i===`bar`&&(s.orientation=r.orientation===`h`?`horizontal`:`vertical`,n.barmode===`stack`?(s.barGrouping=`stacked`,s.barmode=`stack`):n.barmode===`group`?(s.barGrouping=`clustered`,s.barmode=`group`):n.barmode===`relative`&&(s.barGrouping=`percentStacked`,s.barmode=`relative`),r.textposition&&(s.dataLabelPosition=r.textposition)),i===`pie`&&(r.hole!==void 0&&(s.hole=r.hole),r.textinfo&&(s.dataLabelFormat=r.textinfo),r.textposition&&(s.dataLabelPosition=r.textposition)),n.font&&(s.font={family:n.font.family,size:n.font.size}),{chartType:i,series:o,labels:a,options:s}},P={name:`core:chart-plotly`,handles:[`chart`],beforeParse:(e,t,n)=>{let r=ye(new DOMParser().parseFromString(e,`text/html`));if(r.size===0)return e;let i={extractedCharts:r,chartBoundsMap:new Map};return n.state.set(P.name,i),e},onParse:(e,t,n)=>{let r=n.state.get(P.name);if(!r||r.extractedCharts.size===0)return null;let i=e.ownerDocument,{slideIndex:a,slideElement:o}=t,s=o.getBoundingClientRect();return r.extractedCharts.forEach((e,t)=>{if(r.chartBoundsMap.has(t))return;let n=i.getElementById(t);if(!n||!o.contains(n))return;let c=n.getBoundingClientRect();r.chartBoundsMap.set(t,{left:c.left-s.left,top:c.top-s.top,width:c.width,height:c.height,slideIndex:a})}),null},onSlide:(e,t)=>{let n=t.state.get(P.name);if(!n||n.extractedCharts.size===0||n.chartBoundsMap.size===0)return e;let{extractedCharts:r,chartBoundsMap:i}=n,a=new Set,o=[];r.forEach((t,n)=>{let r=i.get(n);if(!r||r.slideIndex!==e.order)return;let s=-1,c=1/0;if(e.elements.forEach((e,t)=>{if(e.type!==`image`||a.has(t))return;let n=Math.sqrt((e.position.left-r.left)**2+(e.position.top-r.top)**2);n<c&&(c=n,s=t)}),s!==-1){let n;try{if(t.sourceLibrary===`plotly`)n=Te(t.config);else return}catch{return}let i=e.elements[s],c=i.position.left,l=i.position.top,u=c+i.dimensions.width,d=l+i.dimensions.height;e.elements.forEach((e,t)=>{if(e.type!==`image`)return;let n=e,r=n.position.left,i=n.position.top,o=r+n.dimensions.width,s=i+n.dimensions.height;r>=c&&i>=l&&o<=u&&s<=d&&a.add(t)});let f={type:`chart`,originalType:`image`,id:crypto.randomUUID(),position:{left:r.left,top:r.top},dimensions:{width:r.width,height:r.height},data:n,sourceLibrary:t.sourceLibrary};o.push(f)}});let s=e.elements.filter((e,t)=>!a.has(t));return{...e,elements:[...s,...o]}}},Ee=e=>{let t=e.tagName.toLowerCase();if(t===`img`)return e.src||``;if(t===`svg`){let t=new XMLSerializer().serializeToString(e);return`data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(t)))}`}if(t===`picture`){let t=e.querySelector(`img`);if(t)return t.src||``}return``},De=e=>{let t=e.tagName.toLowerCase();if(t===`img`)return e.alt||void 0;if(t===`svg`){let t=e.querySelector(`title`);if(t)return t.textContent||void 0}},F={name:`core:image`,handles:[`image`],onParse:(e,t)=>{let{computedStyle:n,boundingRect:r,slideElement:i}=t,a=i.getBoundingClientRect(),o=Ee(e);return o?{type:`image`,id:crypto.randomUUID(),src:o,alt:De(e),position:g(r,a),dimensions:_(r),zIndex:h(n),rotation:p(n),opacity:m(n)}:null}},I=new Map,L=new Map,Oe=e=>e.includes(`fab`)||e.includes(`fa-brands`)?`brands`:e.includes(`far`)||e.includes(`fa-regular`)?`regular`:`solid`,ke=new Set([`fa-solid`,`fa-regular`,`fa-brands`,`fa-light`,`fa-thin`,`fa-duotone`]),Ae=e=>e.find(e=>e.startsWith(`fa-`)&&e!==`fa`&&!ke.has(e))||null,je=async(e,t)=>{let n=e.replace(`fa-`,``),r=Le[n]||n,i=r===n?[n]:[r,n],a=t===`solid`?[`solid`]:[t,`solid`];for(let e of i)for(let t of a){let n=[`https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.0.0/svgs/${t}/${e}.svg`,`https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@7.0.0/svgs/${t}/${e}.svg`];for(let e of n)try{let t=await fetch(e);if(!t.ok)continue;let n=await t.text(),r=new DOMParser().parseFromString(n,`image/svg+xml`).querySelector(`svg`);if(!r)continue;let i=r.getAttribute(`viewBox`)||`0 0 512 512`,a=Array.from(r.querySelectorAll(`path`)).map(e=>e.getAttribute(`d`)).filter(Boolean).join(` `);if(!a)continue;return{viewBox:i,path:a}}catch{continue}}return null},Me=async(e,t)=>{let n=`${t}:${e}`;if(I.has(n))return I.get(n);if(L.has(n))return L.get(n);let r=je(e,t).then(e=>(e&&I.set(n,e),e)).finally(()=>{L.delete(n)});return L.set(n,r),r},Ne=(e,t)=>{let n=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="${e.viewBox}"><path fill="#${t}" d="${e.path}"/></svg>`;return`data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(n)))}`},R={name:`core:icon-fontawesome`,handles:[`icon`],onParse:async(e,t)=>{let{computedStyle:n,boundingRect:r,slideElement:i}=t,a=Array.from(e.classList),s=Ae(a);if(!s)return null;let c=await Me(s,Oe(a));if(!c)return null;let l=Ne(c,o(n.color)||`000000`),u=i.getBoundingClientRect(),d=c.viewBox.split(` `).map(Number),f=(d[2]||512)/(d[3]||512),_=r.width,v=r.height,y=v*f,b=_/f;return y<=_?_=y:v=b,{type:`image`,originalType:`icon`,id:crypto.randomUUID(),src:l,alt:s,position:g(r,u),dimensions:{width:_,height:v},zIndex:h(n),rotation:p(n),opacity:m(n)}}},Pe={reset:`\x1B[0m`,red:`\x1B[31m`,green:`\x1B[32m`,yellow:`\x1B[33m`,dim:`\x1B[2m`},z={SLIDE_SELECTOR:`.slide`,SLIDE_WIDTH:992,SLIDE_HEIGHT:558,FONT_FAMILY:``,CHART_FONT_SIZE:9},B={DPI:96,PPTX_PIXELS_TO_INCHES:73.7,RADIUS_MULTIPLIER:.75},V={solid:`solid`,dashed:`dash`,dotted:`sysDot`},Fe={100:`Thin`,200:`ExtraLight`,300:`Light`,400:``,500:`Medium`,600:`SemiBold`,700:`Bold`,800:`ExtraBold`,900:`Black`},H=[T,de,me,A,F,R,P],Ie=1.03,U={pie:`pie`,bar:`bar`,line:`line`,scatter:`scatter`,area:`area`,doughnut:`doughnut`,radar:`radar`,bubble:`bubble`},W={pie:`pie`,bar:`bar`,line:`line`,scatter:`line`,area:`area`,doughnut:`doughnut`,radar:`radar`,bubble:`bubble`},Le={"check-circle":`circle-check`,"times-circle":`circle-xmark`,"exclamation-circle":`circle-exclamation`,"exclamation-triangle":`triangle-exclamation`,"shield-alt":`shield`,search:`magnifying-glass`,times:`xmark`,bars:`bars`,cog:`gear`,trash:`trash-can`,edit:`pen-to-square`,"external-link-alt":`arrow-up-right-from-square`,"arrow-alt-circle-down":`circle-down`,"arrow-alt-circle-up":`circle-up`,"arrow-alt-circle-left":`circle-left`,"arrow-alt-circle-right":`circle-right`,"sign-in-alt":`right-to-bracket`,"sign-out-alt":`right-from-bracket`,percentage:`percent`};var G=class{config;pluginManager;presentation=null;source=null;parser;serializer;constructor(e){i(e.parser,`Parser strategy is required`),i(e.serializer,`Serializer strategy is required`),this.config={...e,selector:e.selector||`.slide`,dimensions:e.dimensions||{width:z.SLIDE_WIDTH,height:z.SLIDE_HEIGHT}},this.parser=e.parser,this.serializer=e.serializer,this.pluginManager=new t,this.serializer.setPluginManager&&this.serializer.setPluginManager(this.pluginManager);let n=e.plugins?.core??[],r=e.plugins?.extensions??[];n.forEach(e=>this.use(e)),r.forEach(e=>this.use(e))}use(e){return this.pluginManager.register(e),this}load(e){return typeof e==`string`?this.source=e:this.source=e.content,this}async convert(){i(this.source,`No HTML source loaded. Call load() first.`),this.config.debug&&console.group(`[html-in-pptx-out] convert`);let e={selector:this.config.selector,dimensions:this.config.dimensions},t=await this.pluginManager.executeBeforeParse(this.source,e),{elements:n,cleanup:r}=await this.parser.parse(t,e);this.config.debug&&console.log(`before: executeOnParse`,{elements:n});let a=new Map;for(let{slideIndex:e,element:t,parseContext:r}of n){let n=await this.pluginManager.executeOnParse(t,r);n&&(a.has(e)||a.set(e,[]),a.get(e).push(n))}this.config.debug&&console.log(`after: executeOnParse`,{slides:a}),r();let o=[],s=Array.from(a.keys()).sort((e,t)=>e-t);for(let e of s){let t={id:crypto.randomUUID(),order:e,elements:a.get(e)||[]};o.push(t)}this.presentation={slides:o,metadata:{createdAt:new Date,plugins:this.pluginManager.getPlugins().map(e=>e.name)},viewport:this.config.dimensions};for(let e=0;e<this.presentation.slides.length;e++)this.presentation.slides[e]=await this.pluginManager.executeOnSlide(this.presentation.slides[e]);return this.pluginManager.setPresentation(this.presentation),this.config.debug&&(console.log(`after: executeOnSlide`,{presentation:this.presentation}),console.groupEnd()),this}async export(e){return i(this.presentation,`No presentation to export. Call convert() first.`),await this.serializer.serialize(this.presentation,e)}async exportImages(e){throw Error(`Not implemented`)}getPresentation(){return i(this.presentation,`No presentation available. Call convert() first.`),this.presentation}};const Re=(e,t)=>new Promise((n,r)=>{let i=document.createElement(`iframe`);i.style.position=`fixed`,i.style.left=`-9999px`,i.style.top=`-9999px`,i.style.width=`${t.width}px`,i.style.height=`${t.height}px`,i.style.opacity=`0`,i.style.pointerEvents=`none`,i.style.zIndex=`-1`,i.setAttribute(`aria-hidden`,`true`);let a=()=>{i.removeEventListener(`load`,a);let e=i.contentDocument;if(!e){r(Error(`Failed to access iframe document`));return}let t=()=>{e.readyState===`complete`?requestAnimationFrame(()=>n(i)):setTimeout(t,10)};t()};i.addEventListener(`load`,a),i.onerror=()=>r(Error(`Failed to load iframe`)),i.srcdoc=e,document.body.appendChild(i)}),ze=e=>{e.remove()};var K=class{async parse(e,t){let n=await Re(e,t.dimensions),r=n.contentDocument.querySelectorAll(t.selector),i=[];for(let e=0;e<r.length;e++){let t=r[e],a=t.querySelectorAll(`*`),o=[t,...Array.from(a)],s=new Set;for(let r of o){let a=!1,o=r.parentElement;for(;o&&o!==t;){if(s.has(o)){a=!0;break}o=o.parentElement}if(a)continue;let c=te(r,n.contentWindow);if(c.length===0)continue;let l=n.contentWindow.getComputedStyle(r),u=r.getBoundingClientRect(),d=r.tagName.toLowerCase();for(let n of c){(n===`table`||n===`text`)&&s.add(r);let a={elementType:n,tagName:d,computedStyle:l,boundingRect:u,slideIndex:e,slideElement:t};i.push({slideIndex:e,element:r,parseContext:a})}}}return{elements:i,cleanup:()=>ze(n)}}};const q=e=>e/B.DPI,J=e=>e/B.DPI*72,Y=(e,t)=>{let n=e.left/t.width*100,r=e.top/t.height*100;return{x:`${n}%`,y:`${r}%`}},X=(e,t)=>{let n=e.width/t.width*100,r=e.height/t.height*100;return{w:`${n}%`,h:`${r}%`}},Be=e=>({x:q(e.left),y:q(e.top)}),Ve=e=>({w:q(e.width),h:q(e.height)}),Z=e=>{let t={};return e.fontFamily&&(t.fontFace=e.fontFamily.split(`,`)[0].trim()),e.fontSize&&(t.fontSize=J(e.fontSize)),e.color&&(t.color=e.color.toUpperCase()),e.fontWeight&&(parseInt(e.fontWeight,10)||400)>400&&(t.bold=!0),(e.fontStyle===`italic`||e.fontStyle===`oblique`)&&(t.italic=!0),e.underline&&(t.underline={style:`sng`}),e.strikethrough&&(t.strike=`sngStrike`),t},Q=e=>{let t=[];for(let n of e)if(n.children&&n.children.length>0){let e=Q(n.children);for(let r of e){let e={...r.options};if(n.typography){let t=Z(n.typography);Object.assign(e,t,r.options)}n.href&&(e.hyperlink={url:n.href}),t.push({text:r.text,options:e})}}else{let e={};n.typography&&Object.assign(e,Z(n.typography)),n.href&&(e.hyperlink={url:n.href}),t.push({text:n.content,options:e})}return t},He=(e,t,n)=>{let r=Y(t.position,n),i=X(t.dimensions,n),a={x:r.x,y:r.y,w:i.w,h:i.h,lineSpacingMultiple:1,valign:`top`,align:`left`,isTextBox:!0,wrap:!0,shrinkText:!1};if(t.typography){let e=t.typography,n=Z(e);Object.assign(a,n),e.textAlign&&(a.align=e.textAlign),e.verticalAlign&&(a.valign=e.verticalAlign),e.letterSpacing&&(a.charSpacing=e.letterSpacing)}if(t.padding&&(a.margin=[J(t.padding.top),J(t.padding.right),J(t.padding.bottom),J(t.padding.left)]),t.rotation&&(a.rotate=t.rotation),t.opacity!==void 0&&t.opacity<1&&(a.transparency=Math.round((1-t.opacity)*100)),t.runs&&t.runs.length>0){let n=Q(t.runs);e.addText(n,a)}else e.addText(t.content,a)},Ue=e=>e,We=e=>V[e.style]||`solid`,Ge=(t,n,r)=>{let i=Y(n.position,r),a=X(n.dimensions,r),o=Ue(n.shapeType)||e.ShapeType.rect,s={x:i.x,y:i.y,w:a.w,h:a.h};if(n.fill){let e={};if(n.fill.type===`solid`)e.color=n.fill.color.toUpperCase(),n.fill.opacity!==void 0&&n.fill.opacity<1&&(e.transparency=Math.round((1-n.fill.opacity)*100));else if(n.fill.type===`gradient`){let t=n.fill.stops[0];t&&(e.color=t.color.toUpperCase(),t.opacity!==void 0&&t.opacity<1&&(e.transparency=Math.round((1-t.opacity)*100)))}e.color&&(s.fill=e)}if(n.stroke){let e={color:n.stroke.color.toUpperCase(),width:n.stroke.width,dashType:We(n.stroke)};n.stroke.opacity!==void 0&&(e.transparency=Math.round((1-n.stroke.opacity)*100)),s.line=e}if(n.rotation&&(s.rotate=n.rotation),n.borderRadius&&n.shapeType===`roundRect`){let e=Math.min(n.dimensions.width,n.dimensions.height);s.rectRadius=Math.min(n.borderRadius/e,1)}if(n.shadow){let e=n.shadow.offset.x,t=n.shadow.offset.y,r=Math.sqrt(e**2+t**2),i=(Math.atan2(t,e)*180/Math.PI%360+360)%360;s.shadow={type:n.shadow.type,color:n.shadow.color.toUpperCase(),blur:J(n.shadow.blur),offset:J(r),angle:i,opacity:n.shadow.opacity??1}}t.addShape(o,s)},Ke=e=>V[e.style]||`solid`,qe=(e,t,n)=>{let r=t.start.left/n.width*100,i=t.start.top/n.height*100,a=t.end.left/n.width*100,o=t.end.top/n.height*100,s=Math.abs(a-r),c=Math.abs(o-i),l={color:t.stroke.color.toUpperCase(),width:t.stroke.width,dashType:Ke(t.stroke)};t.stroke.opacity!==void 0&&(l.transparency=Math.round((1-t.stroke.opacity)*100));let u={x:`${Math.min(r,a)}%`,y:`${Math.min(i,o)}%`,w:`${s||.1}%`,h:`${c||.1}%`,line:l},d=t.end.left<t.start.left,f=t.end.top<t.start.top;d&&(u.flipH=!0),f&&(u.flipV=!0),e.addShape(`line`,u)},Je=(e,t,n)=>{let r=Y(t.position,n),i=X(t.dimensions,n),a={x:r.x,y:r.y,w:i.w,h:i.h};t.src.startsWith(`data:`)?a.data=t.src:a.path=t.src,t.alt&&(a.altText=t.alt),t.rotation&&(a.rotate=t.rotation),t.opacity!==void 0&&t.opacity<1&&(a.transparency=Math.round((1-t.opacity)*100)),t.fit&&(a.sizing={type:{contain:`contain`,cover:`cover`,stretch:`crop`}[t.fit]||`contain`,w:t.dimensions.width,h:t.dimensions.height}),e.addImage(a)},Ye=(e,t)=>{let n=e.split(`,`)[0].trim();if(!t)return n;let r=Fe[parseInt(t,10)||400];return!r||r===``?n:`${n} ${r}`},Xe=(e,t,n)=>{let r=Y(t.position,n),i=X(t.dimensions,n),a=t.rows.map(e=>e.map(e=>{let t={text:e.runs&&e.runs.length>0?Q(e.runs):e.text};if(e.colspan&&(t.options={...t.options,colspan:e.colspan}),e.rowspan&&(t.options={...t.options,rowspan:e.rowspan}),e.typography){let n=e.typography,r=n.fontWeight&&parseInt(n.fontWeight,10)||400;t.options={...t.options,fontFace:n.fontFamily?Ye(n.fontFamily,n.fontWeight):void 0,fontSize:n.fontSize?J(n.fontSize):void 0,color:n.color?n.color.toUpperCase():void 0,bold:r>400,italic:n.fontStyle===`italic`||n.fontStyle===`oblique`,underline:n.underline?{style:`sng`}:void 0,align:n.textAlign,valign:n.verticalAlign}}if(e.fill){if(e.fill.type===`solid`){let n={color:e.fill.color.toUpperCase()};e.fill.opacity!==void 0&&e.fill.opacity<1&&(n.transparency=Math.round((1-e.fill.opacity)*100)),t.options={...t.options,fill:n}}else if(e.fill.type===`gradient`){let n=e.fill.stops[0];n&&(t.options={...t.options,fill:{color:n.color.toUpperCase()}})}}if(e.border){let n=[`top`,`right`,`bottom`,`left`],r=[];for(let t of n){let n=e.border[t];if(n){let e=`solid`;(n.style===`dashed`||n.style===`dotted`)&&(e=`dash`),r.push({color:n.color.toUpperCase(),pt:n.width,type:e})}else r.push({type:`none`})}let i=r;t.options={...t.options,border:i}}return t})),o={x:r.x,y:r.y,w:i.w,h:i.h};t.colWidths&&t.colWidths.length>0&&(o.colW=t.colWidths.map(e=>q(e))),t.cellMinHeight&&(o.rowH=J(t.cellMinHeight)/72),t.headerRow&&(o.autoPageHeaderRows=1),e.addTable(a,o)},Ze=e=>{for(let t of e)if(!(!t.values||!Array.isArray(t.values))){for(let e of t.values)if(typeof e==`number`&&!Number.isInteger(e)){let e=0;for(let n of t.values)if(typeof n==`number`&&!Number.isInteger(n)){let t=n.toString().split(`.`)[1]?.length||0;e=Math.max(e,Math.min(t,2))}return e===1?`#,##0.0`:`#,##0.00`}}return`#,##0`},Qe=e=>W[e]||`bar`,$=e=>{let t=e.data.chartType;return t===`pie`&&e.data.options?.hole!==void 0&&e.data.options.hole>0?`doughnut`:W[t]||`bar`},$e=e=>{let t=Be(e.position),n=Ve(e.dimensions),r=e.data,i={type:r.chartType,series:r.series,labels:r.labels,options:r.options},a=i.series.map(e=>({name:e.name,labels:i.labels,values:e.values,color:o(e.color||``)})),s={x:t.x,y:t.y,w:n.w,h:n.h,title:i.options?.title,showTitle:!!i.options?.title,titleFontSize:i.options?.titleFontSize||z.CHART_FONT_SIZE,showLegend:i.options?.showLegend!==!1,legendPos:`t`,legendFontSize:z.CHART_FONT_SIZE,showLabel:i.options?.showDataLabels===!0,dataLabelFontSize:z.CHART_FONT_SIZE};if(i.options?.showDataLabels===!0)if(i.type===`bar`){s.showValue=!0;let e=Ze(i.series);e&&(s.dataLabelFormatCode=e)}else i.type===`pie`&&(s.showPercent=!0);i.type===`pie`&&(s.dataLabelPosition=`outEnd`);let c=[];if(i.series.some(e=>e.colors&&e.colors.length>0)){let e=i.series.find(e=>e.colors&&e.colors.length>0);e?.colors&&c.push(...e.colors)}else i.series.forEach(e=>{e.color&&c.push(e.color)});if(c.length>0&&(s.chartColors=c.map(e=>o(e)).filter(e=>e!==void 0)),i.options?.xAxisTitle&&(s.catAxisTitle=i.options.xAxisTitle,s.showCatAxisTitle=!0,s.catAxisTitleFontSize=z.CHART_FONT_SIZE),i.options?.yAxisTitle&&(s.valAxisTitle=i.options.yAxisTitle,s.showValAxisTitle=!0,s.valAxisTitleFontSize=z.CHART_FONT_SIZE),s.catAxisLabelFontSize=z.CHART_FONT_SIZE,s.valAxisLabelFontSize=z.CHART_FONT_SIZE,s.catGridLine={style:`none`},s.valGridLine={style:`solid`,size:1,color:`D9D9D9`},i.options?.hole!==void 0&&i.options.hole>0&&(s.holeSize=Math.round(i.options.hole*100)),i.options?.orientation===`horizontal`?s.barDir=`bar`:(i.options?.orientation===`vertical`||i.type===`bar`)&&(s.barDir=`col`),i.options?.barGrouping&&(s.barGrouping=i.options.barGrouping),i.options?.hasSecondaryAxis){let t=new Map,n=new Map;if(i.series.forEach((e,r)=>{let o=e.chartType||i.type,s=a[r];e.yAxis===`y2`?(n.has(o)||n.set(o,[]),n.get(o).push(s)):(t.has(o)||t.set(o,[]),t.get(o).push(s))}),n.size===0)return{data:a,options:s,chartTypeKey:$(e)};let r=[];return t.forEach((e,t)=>{r.push({typeKey:Qe(t),data:e,options:{}})}),n.forEach((e,t)=>{let n=t===`line`||t===`area`;r.push({typeKey:Qe(t),data:e,options:{secondaryValAxis:!0,secondaryCatAxis:!0,...n?{showValue:!0,dataLabelPosition:`t`}:{}}})}),{data:null,options:{x:s.x,y:s.y,w:s.w,h:s.h,title:s.title,showTitle:s.showTitle,titleFontSize:s.titleFontSize,showLegend:s.showLegend,legendPos:`t`,legendFontSize:z.CHART_FONT_SIZE,chartColors:s.chartColors,dataLabelFormatCode:s.dataLabelFormatCode,dataLabelFontSize:z.CHART_FONT_SIZE,valAxes:[{valAxisTitle:i.options.yAxisTitle||``,showValAxisTitle:!!i.options.yAxisTitle,valAxisTitleFontSize:z.CHART_FONT_SIZE,valAxisLabelFontSize:z.CHART_FONT_SIZE,valGridLine:{style:`solid`,size:1,color:`D9D9D9`}},{valAxisTitle:i.options.yAxis2Title||``,showValAxisTitle:!1,valAxisTitleFontSize:z.CHART_FONT_SIZE,valAxisLabelFontSize:z.CHART_FONT_SIZE,valGridLine:{style:`none`}}],catAxes:[{catAxisTitle:i.options.xAxisTitle||``,showCatAxisTitle:!!i.options.xAxisTitle,catAxisTitleFontSize:z.CHART_FONT_SIZE,catAxisLabelFontSize:z.CHART_FONT_SIZE,catGridLine:{style:`none`}},{catAxisLabelFontSize:z.CHART_FONT_SIZE,catAxisHidden:!0,catGridLine:{style:`none`}}]},chartTypesForCombo:r,chartTypeKey:$(e)}}return{data:a,options:s,chartTypeKey:$(e)}},et=(e,t)=>{let{data:n,options:r,chartTypesForCombo:i,chartTypeKey:a}=$e(t);if(t.data.options?.hasSecondaryAxis&&i){let t=i.map(e=>({type:e.typeKey,data:e.data,options:e.options||{}}));e.addChart(t,r)}else{let t=a;if(!t||!n)return;e.addChart(t,n,r)}};var tt=class{pluginManager=null;setPluginManager(e){this.pluginManager=e}async serialize(t,n){r(t.slides.length>0,`No slides to export. Check selector or create a slide to export`);let i=new e,a=q(t.viewport.width),o=q(t.viewport.height);i.defineLayout({name:`custom`,width:a,height:o}),i.layout=`custom`,t.metadata.title&&(i.title=t.metadata.title),t.metadata.author&&(i.author=t.metadata.author),t.metadata.subject&&(i.subject=t.metadata.subject);for(let e of t.slides){let n=i.addSlide();for(let r of e.elements)switch(r.type){case`text`:He(n,r,t.viewport);break;case`image`:Je(n,r,t.viewport);break;case`shape`:Ge(n,r,t.viewport);break;case`table`:Xe(n,r,t.viewport);break;case`chart`:et(n,r);break;case`line`:qe(n,r,t.viewport);break}}return this.pluginManager&&await this.pluginManager.executeAfterGenerate(i,t),await i.write({outputType:`arraybuffer`})}},nt=class extends G{constructor(e={}){super({selector:e.selector||z.SLIDE_SELECTOR,dimensions:e.dimensions||{width:z.SLIDE_WIDTH,height:z.SLIDE_HEIGHT},plugins:{core:e.plugins?.core??H,extensions:e.plugins?.extensions??[]},parser:e.parser||new K,serializer:e.serializer||new tt,debug:e.debug})}};export{Pe as a,R as c,A as d,me as f,G as i,F as l,T as m,tt as n,z as o,de as p,K as r,H as s,nt as t,P as u};
5
+ //# sourceMappingURL=converter-DRGQShsh.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"converter-DRGQShsh.mjs","names":["types: ElementType[]","runs: TextRun[]","run: TextRun","textPlugin: Plugin<TextElementDTO>","stops: GradientStop[]","strokeStyle: \"solid\" | \"dashed\" | \"dotted\"","opacity: number | undefined","shapePlugin: Plugin<ShapeElementDTO>","strokeStyle: \"solid\" | \"dashed\" | \"dotted\"","opacity: number | undefined","linePlugin: Plugin<LineElementDTO>","stroke: Stroke","start: Position","end: Position","strokeStyle: \"solid\" | \"dashed\" | \"dotted\"","border: Border","cellDTO: TableCellDTO","rows: TableCellDTO[][]","cells: TableCellDTO[]","widths: number[]","tablePlugin: Plugin<TableElementDTO>","series: ChartSeries[]","seriesData: ChartSeries","options: ChartOptions","plotlyPlugin: Plugin","state: ChartPluginState","chartElements: ChartElementDTO[]","chartDataDTO: ChartData","chartElement: ChartElementDTO","imagePlugin: Plugin<ImageElementDTO>","fontAwesomePlugin: Plugin<ImageElementDTO>","STROKE_DASH_MAP: Record<\n string,\n | \"solid\"\n | \"dash\"\n | \"dashDot\"\n | \"lgDash\"\n | \"lgDashDot\"\n | \"lgDashDotDot\"\n | \"sysDash\"\n | \"sysDot\"\n>","FONT_WEIGHT_SUFFIX_MAP: Record<number, string>","DEFAULT_CORE_PLUGINS: Plugin[]","CHART_TYPE_MAP: Record<string, string>","PPTX_CHART_TYPE_MAP: Record<string, string>","FA5_TO_FA6_NAMES: Record<string, string>","slides: SlideDTO[]","slide: SlideDTO","elements: ParserElement[]","parseContext: ParseContext","props: PptxGenJS.TextPropsOptions","result: Array<{ text: string; options: PptxGenJS.TextPropsOptions }>","options: PptxGenJS.TextPropsOptions","textOptions: PptxGenJS.TextPropsOptions","getStrokeDashType","shapeType: PptxGenJS.ShapeType","shapeOptions: PptxGenJS.ShapeProps","fillProps: PptxGenJS.ShapeFillProps","lineProps: PptxGenJS.ShapeLineProps","lineProps: PptxGenJS.ShapeLineProps","lineOptions: PptxGenJS.ShapeProps","imageOptions: PptxGenJS.ImageProps","rows: PptxGenJS.TableRow[]","cellProps: PptxGenJS.TableCell","fillOptions: { color: string; transparency?: number }","borderArray: PptxGenJS.BorderProps[]","borderType: \"solid\" | \"dash\" | \"none\"","tableOptions: PptxGenJS.TableProps","data: ChartSeries[]","options: PptxGenJS.IChartOpts","allColors: string[]","chartTypesForCombo: ComboChartType[]"],"sources":["../src/lib/plugin-manager.ts","../src/utils/assert.ts","../src/utils/sanitize.ts","../src/lib/extractors/typography.ts","../src/lib/extractors/position.ts","../src/lib/extractors/classifier.ts","../src/lib/extractors/text.ts","../src/plugins/core/text.plugin.ts","../src/lib/extractors/color.ts","../src/lib/extractors/shape.ts","../src/plugins/core/shape.plugin.ts","../src/plugins/core/line.plugin.ts","../src/lib/extractors/stroke.ts","../src/plugins/core/table.plugin.ts","../src/lib/extractors/plotly.ts","../src/plugins/core/plotly.plugin.ts","../src/plugins/core/image.plugin.ts","../src/lib/extractors/fontawesome.ts","../src/plugins/core/fontawesome.plugin.ts","../src/constants.ts","../src/core/base-converter.ts","../src/lib/iframe-renderer.ts","../src/parsers/iframe.ts","../src/utils/units.ts","../src/serializers/elements/text.serializer.ts","../src/serializers/elements/shape.serializer.ts","../src/serializers/elements/line.serializer.ts","../src/serializers/elements/image.serializer.ts","../src/serializers/elements/table.serializer.ts","../src/serializers/elements/plotly.serializer.ts","../src/serializers/pptxgenjs.ts","../src/core/converter.ts"],"sourcesContent":["import type {\n Plugin,\n PluginManagerInterface,\n PluginContext,\n ParseContext,\n} from \"@/types/plugin.types\";\nimport type { SlideDTO, PresentationDTO } from \"@/types/presentation.types\";\nimport type { ParserConfig } from \"@/types/config.types\";\nimport type { ElementDTO } from \"@/types/elements.types\";\nimport type PptxGenJS from \"pptxgenjs\";\n\nexport class PluginManager implements PluginManagerInterface {\n private plugins: Plugin[] = [];\n private context: PluginContext = {\n presentation: undefined,\n metadata: {},\n state: new Map(),\n };\n\n register(plugin: Plugin): void {\n if (this.plugins.some((p) => p.name === plugin.name)) {\n throw new Error(`Plugin \"${plugin.name}\" is already registered`);\n }\n this.plugins.push(plugin);\n }\n\n unregister(name: string): void {\n const index = this.plugins.findIndex((p) => p.name === name);\n if (index !== -1) {\n this.plugins.splice(index, 1);\n }\n }\n\n getPlugins(): Plugin[] {\n return [...this.plugins];\n }\n\n setPresentation(presentation: PresentationDTO): void {\n this.context.presentation = presentation;\n }\n\n async executeBeforeParse(\n html: string,\n config: ParserConfig,\n ): Promise<string> {\n let result = html;\n\n for (const plugin of this.plugins) {\n if (plugin.beforeParse) {\n result = await plugin.beforeParse(result, config, this.context);\n }\n }\n\n return result;\n }\n\n async executeOnParse(\n element: HTMLElement,\n parseContext: ParseContext,\n ): Promise<ElementDTO | null> {\n for (const plugin of this.plugins) {\n if (!plugin.handles || !plugin.onParse) continue;\n\n const handlers = new Set(plugin.handles);\n if (!handlers.has(parseContext.elementType)) continue;\n\n const result = await plugin.onParse(element, parseContext, this.context);\n if (result) return result;\n }\n\n return null;\n }\n\n async executeOnSlide(slide: SlideDTO): Promise<SlideDTO> {\n let result = slide;\n\n for (const plugin of this.plugins) {\n if (plugin.onSlide) {\n result = await plugin.onSlide(result, this.context);\n }\n }\n\n return result;\n }\n\n async executeAfterGenerate(\n pptx: PptxGenJS,\n presentation: PresentationDTO,\n ): Promise<void> {\n for (const plugin of this.plugins) {\n if (plugin.afterGenerate) {\n await plugin.afterGenerate(pptx, presentation, this.context);\n }\n }\n }\n}\n","export class AssertionError extends Error {\n constructor(message: string) {\n super(`Assertion failed: ${message}`);\n this.name = 'AssertionError';\n }\n}\n\nexport function assert(condition: unknown, message: string): asserts condition {\n if (!condition) {\n throw new AssertionError(message);\n }\n}\n\nexport function assertNonNull<T>(\n value: T | null | undefined,\n message: string\n): asserts value is T {\n if (value === null || value === undefined) {\n throw new AssertionError(message);\n }\n}\n","export const sanitizeFontFamily = (fontFamily: string): string => {\n const fonts = fontFamily.split(\",\").map((font) => {\n const f = font\n .trim()\n .replace(/^[\"']|[\"']$/g, \"\")\n .trim();\n\n return f;\n });\n return fonts.filter((font) => font != null).join(\", \");\n};\n\nexport const sanitizeColor = (color: string): string => {\n if (!color || color === \"transparent\") return \"\";\n\n const cleaned = color.trim().replace(/^#/, \"\");\n\n if (/^[0-9a-fA-F]{3}$/.test(cleaned)) {\n return (\n cleaned[0] +\n cleaned[0] +\n cleaned[1] +\n cleaned[1] +\n cleaned[2] +\n cleaned[2]\n );\n }\n\n if (/^[0-9a-fA-F]{6}$/.test(cleaned)) {\n return cleaned;\n }\n\n const rgbMatch = color.match(/rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)/);\n if (rgbMatch) {\n const [, r, g, b] = rgbMatch;\n return [r, g, b]\n .map((v) => parseInt(v, 10).toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n return \"\";\n};\n","import type { Typography, Padding } from \"@/types/base.types\";\nimport { sanitizeFontFamily, sanitizeColor } from \"@/utils/sanitize\";\nimport { DEFAULTS } from \"@/constants\";\n\nexport const parseFontWeight = (value: string): string | undefined => {\n const num = parseInt(value, 10);\n if (!isNaN(num)) return String(num);\n if (value === \"bold\") return \"700\";\n if (value === \"bolder\") return \"700\";\n if (value === \"lighter\") return \"300\";\n if (value === \"normal\") return \"400\";\n return undefined;\n};\n\nexport const parseFontStyle = (\n value: string,\n): Typography[\"fontStyle\"] | undefined => {\n if (value === \"italic\") return \"italic\";\n if (value === \"oblique\") return \"oblique\";\n if (value === \"normal\") return \"normal\";\n return undefined;\n};\n\nexport const parseTextAlign = (\n value: string,\n): Typography[\"textAlign\"] | undefined => {\n if (value === \"left\" || value === \"start\") return \"left\";\n if (value === \"center\") return \"center\";\n if (value === \"right\" || value === \"end\") return \"right\";\n if (value === \"justify\") return \"justify\";\n return undefined;\n};\n\nexport const parseVerticalAlign = (\n value: string,\n): Typography[\"verticalAlign\"] | undefined => {\n if (value === \"top\") return \"top\";\n if (value === \"middle\") return \"middle\";\n if (value === \"bottom\") return \"bottom\";\n return undefined;\n};\n\nexport const extractTypography = (style: CSSStyleDeclaration): Typography => {\n const typography: Typography = {\n fontFamily: sanitizeFontFamily(style.fontFamily) || DEFAULTS.FONT_FAMILY,\n fontSize: parseFloat(style.fontSize) || undefined,\n fontWeight: parseFontWeight(style.fontWeight),\n fontStyle: parseFontStyle(style.fontStyle),\n letterSpacing: parseFloat(style.letterSpacing) || undefined,\n lineHeight: parseFloat(style.lineHeight) || undefined,\n color: sanitizeColor(style.color) || undefined,\n underline: style.textDecorationLine?.includes(\"underline\") || false,\n strikethrough: style.textDecorationLine?.includes(\"line-through\") || false,\n textAlign: parseTextAlign(style.textAlign),\n verticalAlign: parseVerticalAlign(style.verticalAlign),\n };\n\n return typography;\n};\n\nexport const extractPadding = (style: CSSStyleDeclaration): Padding => ({\n top: parseFloat(style.paddingTop) || 0,\n right: parseFloat(style.paddingRight) || 0,\n bottom: parseFloat(style.paddingBottom) || 0,\n left: parseFloat(style.paddingLeft) || 0,\n});\n\nexport const extractRotation = (\n style: CSSStyleDeclaration,\n): number | undefined => {\n const transform = style.transform;\n if (!transform || transform === \"none\") return undefined;\n\n const rotateMatch = transform.match(/rotate\\(([-\\d.]+)/);\n if (rotateMatch) {\n const deg = parseFloat(rotateMatch[1]);\n return deg || undefined;\n }\n\n const matrixMatch = transform.match(/matrix\\(([^)]+)\\)/);\n if (matrixMatch) {\n const values = matrixMatch[1].split(\",\").map((v) => parseFloat(v.trim()));\n if (values.length >= 2) {\n const a = values[0];\n const b = values[1];\n const radians = Math.atan2(b, a);\n const degrees = radians * (180 / Math.PI);\n return Math.abs(degrees) < 0.01 ? undefined : degrees;\n }\n }\n\n return undefined;\n};\n\nexport const extractOpacity = (\n style: CSSStyleDeclaration,\n): number | undefined => {\n const opacity = parseFloat(style.opacity);\n return opacity === 1 ? undefined : opacity || undefined;\n};\n\nexport const extractZIndex = (\n style: CSSStyleDeclaration,\n): number | undefined => {\n return parseInt(style.zIndex, 10) || undefined;\n};\n","import type { Position, Dimensions } from \"@/types/base.types\";\n\nexport const extractRelativePosition = (\n elementRect: DOMRect,\n containerRect: DOMRect,\n): Position => ({\n left: elementRect.left - containerRect.left,\n top: elementRect.top - containerRect.top,\n});\n\nexport const extractDimensions = (\n rect: DOMRect,\n buffer: number = 1,\n): Dimensions => ({\n width: rect.width * buffer,\n height: rect.height,\n});\n","import type { ElementType } from \"@/types/base.types\";\n\nconst TEXT_TAGS = new Set([\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"p\",\n \"span\",\n \"div\",\n \"a\",\n \"li\",\n \"label\",\n \"strong\",\n \"em\",\n \"b\",\n // \"i\",\n \"u\",\n \"s\",\n \"small\",\n \"mark\",\n]);\n\nconst IMAGE_TAGS = new Set([\"img\", \"picture\", \"svg\"]);\nconst TABLE_TAGS = new Set([\"table\"]);\nconst TABLE_INTERNAL_TAGS = new Set([\n \"td\",\n \"th\",\n \"tr\",\n \"thead\",\n \"tbody\",\n \"tfoot\",\n \"caption\",\n \"colgroup\",\n \"col\",\n]);\n\nexport const classifyElement = (\n element: HTMLElement,\n win: Window = window,\n): ElementType[] => {\n const types: ElementType[] = [];\n const tagName = element.tagName.toLowerCase();\n\n if (TABLE_TAGS.has(tagName)) {\n types.push(\"table\");\n return types;\n }\n\n if (TABLE_INTERNAL_TAGS.has(tagName)) {\n return types;\n }\n\n if (element.id.toLowerCase().includes(\"chart\")) {\n types.push(\"chart\");\n }\n\n if (IMAGE_TAGS.has(tagName)) {\n types.push(\"image\");\n return types;\n }\n\n if (tagName === \"hr\") {\n types.push(\"line\");\n return types;\n }\n\n if (classifyIcon(element)) {\n types.push(\"icon\");\n return types;\n }\n\n const style = win.getComputedStyle(element);\n\n const hasVisualStyling = classifyVisualElement(style);\n if (hasVisualStyling) {\n types.push(\"shape\");\n }\n\n const singleBorderSide = hasSingleBorderSide(style);\n if (singleBorderSide) {\n types.push(\"line\");\n }\n\n if (TEXT_TAGS.has(tagName) && hasDirectTextNode(element)) {\n types.push(\"text\");\n }\n\n return types;\n};\n\nconst classifyVisualElement = (style: CSSStyleDeclaration): boolean => {\n const hasBackgroundColor =\n style.backgroundColor !== \"transparent\" &&\n style.backgroundColor !== \"rgba(0, 0, 0, 0)\";\n\n const hasBackgroundImage =\n style.backgroundImage !== \"none\" && style.backgroundImage !== \"\";\n\n const hasBorder =\n parseFloat(style.borderWidth) > 0 &&\n style.borderColor !== \"transparent\" &&\n style.borderColor !== \"rgba(0, 0, 0, 0)\";\n\n const hasShadow = style.boxShadow !== \"none\" && style.boxShadow !== \"\";\n\n const hasBorderRadius = parseFloat(style.borderRadius) > 0;\n\n return (\n hasBackgroundColor ||\n hasBackgroundImage ||\n hasBorder ||\n hasShadow ||\n hasBorderRadius\n );\n};\n\nexport const classifyText = (\n tagName: string,\n): \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"p\" | \"body\" | null => {\n const tag = tagName.toLowerCase();\n if (!TEXT_TAGS.has(tagName)) return null;\n if (/^h[1-6]$/.test(tag))\n return tag as \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\";\n if (tag === \"p\") return \"p\";\n return \"body\";\n};\n\nexport const classifyShape = (\n style: CSSStyleDeclaration,\n boundingRect: DOMRect,\n): \"rect\" | \"ellipse\" | \"roundRect\" => {\n const borderRadius = parseFloat(style.borderRadius) || 0;\n const { width, height } = boundingRect;\n\n const minDimension = Math.min(width, height);\n const maxRadius = minDimension / 2;\n\n if (borderRadius >= maxRadius * 0.9) {\n if (Math.abs(width - height) < 2) {\n return \"ellipse\";\n }\n }\n\n if (borderRadius > 0) {\n return \"roundRect\";\n }\n\n return \"rect\";\n};\n\nconst hasDirectTextNode = (element: HTMLElement): boolean => {\n for (const node of element.childNodes) {\n if (node.nodeType === Node.TEXT_NODE) {\n if (node.textContent && node.textContent.trim().length > 0) {\n return true;\n }\n }\n }\n return false;\n};\n\nexport const hasSingleBorderSide = (\n style: CSSStyleDeclaration,\n): \"left\" | \"right\" | \"top\" | \"bottom\" | null => {\n const leftWidth = parseFloat(style.borderLeftWidth) || 0;\n const rightWidth = parseFloat(style.borderRightWidth) || 0;\n const topWidth = parseFloat(style.borderTopWidth) || 0;\n const bottomWidth = parseFloat(style.borderBottomWidth) || 0;\n\n const sides = [\n { side: \"left\" as const, width: leftWidth },\n { side: \"right\" as const, width: rightWidth },\n { side: \"top\" as const, width: topWidth },\n { side: \"bottom\" as const, width: bottomWidth },\n ];\n\n const activeSides = sides.filter((s) => s.width > 0);\n\n if (activeSides.length === 1) {\n return activeSides[0].side;\n }\n\n return null;\n};\n\nexport const classifyIcon = (element: HTMLElement): boolean => {\n if (element.tagName.toLowerCase() !== \"i\") return false;\n\n const classList = Array.from(element.classList);\n return classList.some((cls) => cls.startsWith(\"fa-\") && cls !== \"fa\");\n};\n","import type { TextRun } from \"@/types/elements.types\";\nimport { extractTypography } from \"./typography\";\nimport { classifyText } from \"./classifier\";\n\nexport const extractRuns = (node: Node): TextRun[] => {\n const runs: TextRun[] = [];\n\n for (const child of node.childNodes) {\n if (child.nodeType === Node.TEXT_NODE) {\n const text = child.textContent?.replace(/\\s+/g, \" \") || \"\";\n if (text.trim().length > 0) {\n runs.push({ content: text });\n }\n }\n\n if (child.nodeType === Node.ELEMENT_NODE) {\n const el = child as HTMLElement;\n const tagName = el.tagName.toLowerCase();\n\n if (tagName === \"br\") {\n runs.push({ content: \"\\n\" });\n continue;\n }\n\n const className = el.className || \"\";\n const doc = el.ownerDocument;\n const style = doc.defaultView!.getComputedStyle(el);\n\n const childRuns = extractRuns(el);\n const textType = classifyText(tagName);\n if (!textType) continue;\n\n const run: TextRun = {\n content: el.textContent || \"\",\n tagName: tagName,\n className: className,\n typography: extractTypography(style),\n children: childRuns.length > 0 ? childRuns : undefined,\n };\n\n if (tagName === \"a\") {\n run.href = el.getAttribute(\"href\") || undefined;\n }\n\n runs.push(run);\n }\n }\n\n return runs;\n};\n\nexport const extractTextContent = (node: Node): string => {\n let text = \"\";\n\n const processNode = (n: Node): void => {\n if (n.nodeType === Node.TEXT_NODE) {\n text += n.textContent || \"\";\n return;\n }\n\n if (n.nodeType === Node.ELEMENT_NODE) {\n const el = n as HTMLElement;\n const tagName = el.tagName.toLowerCase();\n\n if (tagName === \"br\") {\n text += \"\\n\";\n return;\n }\n\n for (const child of n.childNodes) {\n processNode(child);\n }\n\n if (tagName === \"p\" || tagName === \"div\") {\n if (n.nextSibling) {\n text += \"\\n\";\n }\n }\n }\n };\n\n for (const child of node.childNodes) {\n processNode(child);\n }\n\n return text.trim();\n};\n","import type { Plugin } from \"@/types/plugin.types\";\nimport type { TextElementDTO } from \"@/types/elements.types\";\nimport {\n extractTypography,\n extractPadding,\n extractRotation,\n extractOpacity,\n extractZIndex,\n} from \"@/lib/extractors/typography\";\nimport {\n extractRelativePosition,\n extractDimensions,\n} from \"@/lib/extractors/position\";\nimport { classifyText, classifyIcon } from \"@/lib/extractors/classifier\";\nimport { extractRuns } from \"@/lib/extractors/text\";\nimport { COORDINATE_BUFFER } from \"@/constants\";\n\nconst adjustBoundsForInlineIcons = (\n element: HTMLElement,\n rect: DOMRect,\n): DOMRect => {\n const iconElements = element.querySelectorAll<HTMLElement>(\"i\");\n let iconOffset = 0;\n\n for (const icon of iconElements) {\n if (classifyIcon(icon)) {\n const iconRect = icon.getBoundingClientRect();\n const width = iconRect.width;\n\n const style = icon.ownerDocument.defaultView!.getComputedStyle(icon);\n const marginRight = parseFloat(style.marginRight) || 0;\n\n iconOffset += width + marginRight;\n }\n }\n\n return new DOMRect(\n rect.left + iconOffset,\n rect.top,\n rect.width - iconOffset,\n rect.height,\n );\n};\n\nexport const textPlugin: Plugin<TextElementDTO> = {\n name: \"core:text\",\n handles: [\"text\"],\n onParse: (element, parseContext) => {\n const { computedStyle, boundingRect, tagName, slideElement } = parseContext;\n\n const content = element.textContent?.trim();\n if (!content) return null;\n\n const textType = classifyText(tagName);\n if (!textType) return null;\n\n const slideRect = slideElement.getBoundingClientRect();\n\n const adjustedRect = adjustBoundsForInlineIcons(element, boundingRect);\n\n const position = extractRelativePosition(adjustedRect, slideRect);\n const dimensions = extractDimensions(adjustedRect, COORDINATE_BUFFER);\n\n const runs = extractRuns(element);\n\n const textElement: TextElementDTO = {\n type: \"text\",\n id: crypto.randomUUID(),\n content,\n runs: runs.length > 0 ? runs : undefined,\n position: position,\n dimensions: dimensions,\n typography: extractTypography(computedStyle),\n textType,\n padding: extractPadding(computedStyle),\n zIndex: extractZIndex(computedStyle),\n rotation: extractRotation(computedStyle),\n opacity: extractOpacity(computedStyle),\n };\n\n return textElement;\n },\n};\n","import { sanitizeColor } from \"@/utils/sanitize\";\n\nexport const parseColorOpacity = (rgba: string): number | undefined => {\n const rgbaMatch = rgba.match(\n /rgba\\(\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*([\\d.]+)\\s*\\)/,\n );\n\n if (rgbaMatch) {\n const opacity = parseFloat(rgbaMatch[1]);\n if (opacity < 1) {\n return opacity;\n }\n }\n\n return undefined;\n};\n\nexport const parseHex = (hex: string): string | undefined => {\n return sanitizeColor(hex) || undefined;\n};\n\nexport const transformBgColorToSolidFill = (\n bgColor: string,\n): { color: string; opacity?: number } | undefined => {\n if (!bgColor || bgColor === \"transparent\" || bgColor === \"rgba(0, 0, 0, 0)\") {\n return undefined;\n }\n\n const hex = sanitizeColor(bgColor);\n if (!hex) return undefined;\n\n const opacity = parseColorOpacity(bgColor);\n\n return {\n color: hex,\n opacity: opacity,\n };\n};\n","import type {\n Fill,\n Stroke,\n Shadow,\n SolidFill,\n GradientFill,\n GradientStop,\n} from \"@/types/base.types\";\nimport { sanitizeColor } from \"@/utils/sanitize\";\nimport { parseColorOpacity } from \"@/lib/extractors/color\";\n\nconst parseGradientStops = (rgba: string): GradientStop[] => {\n const stops: GradientStop[] = [];\n const colorStopRegex = /(rgba?\\([^)]+\\)|#[0-9a-fA-F]{3,6}|\\w+)\\s*([\\d.]+%)?/g;\n let match;\n let index = 0;\n\n while ((match = colorStopRegex.exec(rgba)) !== null) {\n const [, colorPart, positionPart] = match;\n const hex = sanitizeColor(colorPart);\n if (!hex) continue;\n\n let position = 0;\n if (positionPart) {\n position = parseFloat(positionPart) / 100;\n } else {\n position = index === 0 ? 0 : 1;\n }\n\n const opacity = parseColorOpacity(colorPart);\n stops.push({ color: hex, position, opacity });\n index++;\n }\n\n return stops;\n};\n\nconst parseGradientAngle = (gradient: string): number => {\n const degMatch = gradient.match(/(\\d+)deg/);\n if (degMatch) {\n return parseInt(degMatch[1], 10);\n }\n\n const directionMap: Record<string, number> = {\n \"to top\": 0,\n \"to right\": 90,\n \"to bottom\": 180,\n \"to left\": 270,\n \"to top right\": 45,\n \"to bottom right\": 135,\n \"to bottom left\": 225,\n \"to top left\": 315,\n };\n\n for (const [direction, angle] of Object.entries(directionMap)) {\n if (gradient.includes(direction)) {\n return angle;\n }\n }\n\n return 180;\n};\n\nexport const extractFill = (style: CSSStyleDeclaration): Fill | undefined => {\n const bgImage = style.backgroundImage;\n\n if (bgImage && bgImage !== \"none\") {\n if (bgImage.includes(\"linear-gradient\")) {\n const stops = parseGradientStops(bgImage);\n if (stops.length >= 2) {\n const gradient: GradientFill = {\n type: \"gradient\",\n gradientType: \"linear\",\n angle: parseGradientAngle(bgImage),\n stops,\n };\n return gradient;\n }\n }\n\n if (bgImage.includes(\"radial-gradient\")) {\n const stops = parseGradientStops(bgImage);\n if (stops.length >= 2) {\n const gradient: GradientFill = {\n type: \"gradient\",\n gradientType: \"radial\",\n stops,\n };\n return gradient;\n }\n }\n }\n\n const bgColor = style.backgroundColor;\n if (!bgColor || bgColor === \"transparent\" || bgColor === \"rgba(0, 0, 0, 0)\") {\n return undefined;\n }\n\n const hex = sanitizeColor(bgColor);\n if (!hex) return undefined;\n\n const opacity = parseColorOpacity(bgColor);\n\n const fill: SolidFill = {\n type: \"solid\",\n color: hex,\n opacity: opacity,\n };\n\n return fill;\n};\n\nexport const extractStroke = (\n style: CSSStyleDeclaration,\n): Stroke | undefined => {\n const borderWidth = parseFloat(style.borderWidth) || 0;\n if (borderWidth === 0) return undefined;\n\n const borderColor = style.borderColor;\n const hex = sanitizeColor(borderColor);\n if (!hex) return undefined;\n\n const borderStyle = style.borderStyle;\n let strokeStyle: \"solid\" | \"dashed\" | \"dotted\" = \"solid\";\n if (borderStyle === \"dashed\") strokeStyle = \"dashed\";\n else if (borderStyle === \"dotted\") strokeStyle = \"dotted\";\n\n let opacity: number | undefined;\n const opacityMatch = borderColor.match(/rgba?\\([^)]+,\\s*([\\d.]+)\\)/);\n if (opacityMatch) {\n const extractedOpacity = parseFloat(opacityMatch[1]);\n if (extractedOpacity < 1) {\n opacity = extractedOpacity;\n }\n }\n\n return {\n color: hex,\n width: borderWidth,\n style: strokeStyle,\n opacity: opacity,\n };\n};\n\nexport const extractBorderRadius = (\n style: CSSStyleDeclaration,\n): number | undefined => {\n const radius = parseFloat(style.borderRadius) || 0;\n if (radius === 0) return undefined;\n return radius;\n};\n\nexport const extractShadow = (\n style: CSSStyleDeclaration,\n): Shadow | undefined => {\n const boxShadow = style.boxShadow;\n if (!boxShadow || boxShadow === \"none\") return undefined;\n\n const insetMatch = boxShadow.includes(\"inset\");\n const shadowType: \"outer\" | \"inner\" = insetMatch ? \"inner\" : \"outer\";\n\n const cleanShadow = boxShadow.replace(\"inset\", \"\").trim();\n\n const rgbaMatch = cleanShadow.match(\n /rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*([\\d.]+))?\\)/,\n );\n let color = \"000000\";\n let opacity = 1;\n\n if (rgbaMatch) {\n const [, r, g, b, a] = rgbaMatch;\n color = [r, g, b]\n .map((v) => parseInt(v, 10).toString(16).padStart(2, \"0\"))\n .join(\"\");\n if (a) opacity = parseFloat(a);\n }\n\n const valuesMatch = cleanShadow.match(\n /(?:rgba?\\([^)]+\\)|#[0-9a-fA-F]+|\\w+)\\s+(-?[\\d.]+)px\\s+(-?[\\d.]+)px\\s+([\\d.]+)px/,\n );\n\n if (!valuesMatch) return undefined;\n\n const [, offsetX, offsetY, blur] = valuesMatch;\n\n return {\n type: shadowType,\n color,\n blur: parseFloat(blur),\n offset: {\n x: parseFloat(offsetX),\n y: parseFloat(offsetY),\n },\n opacity: opacity < 1 ? opacity : undefined,\n };\n};\n","import type { Plugin } from \"@/types/plugin.types\";\nimport type { ShapeElementDTO } from \"@/types/elements.types\";\nimport {\n extractFill,\n extractStroke,\n extractBorderRadius,\n} from \"@/lib/extractors/shape\";\nimport {\n extractRotation,\n extractOpacity,\n extractZIndex,\n} from \"@/lib/extractors/typography\";\nimport {\n extractRelativePosition,\n extractDimensions,\n} from \"@/lib/extractors/position\";\nimport { classifyShape } from \"@/lib/extractors/classifier\";\n\nexport const shapePlugin: Plugin<ShapeElementDTO> = {\n name: \"core:shape\",\n handles: [\"shape\"],\n onParse: (_element, parseContext) => {\n const { computedStyle, boundingRect, slideElement } = parseContext;\n\n const slideRect = slideElement.getBoundingClientRect();\n\n const shapeElement: ShapeElementDTO = {\n type: \"shape\",\n id: crypto.randomUUID(),\n shapeType: classifyShape(computedStyle, boundingRect),\n position: extractRelativePosition(boundingRect, slideRect),\n dimensions: extractDimensions(boundingRect),\n fill: extractFill(computedStyle),\n stroke: extractStroke(computedStyle),\n borderRadius: extractBorderRadius(computedStyle),\n zIndex: extractZIndex(computedStyle),\n rotation: extractRotation(computedStyle),\n opacity: extractOpacity(computedStyle),\n };\n\n return shapeElement;\n },\n};\n","import type { Plugin } from \"@/types/plugin.types\";\nimport type { LineElementDTO } from \"@/types/elements.types\";\nimport type { Position, Stroke } from \"@/types/base.types\";\nimport {\n extractRotation,\n extractOpacity,\n extractZIndex,\n} from \"@/lib/extractors/typography\";\nimport { hasSingleBorderSide } from \"@/lib/extractors/classifier\";\nimport { sanitizeColor } from \"@/utils/sanitize\";\n\nconst extractLineStroke = (\n style: CSSStyleDeclaration,\n side: \"left\" | \"right\" | \"top\" | \"bottom\",\n): Stroke => {\n let width = 1;\n let borderColor = \"rgb(0,0,0)\";\n let borderStyle = \"solid\";\n\n if (side === \"left\") {\n width = parseFloat(style.borderLeftWidth) || 1;\n borderColor = style.borderLeftColor || \"rgb(0,0,0)\";\n borderStyle = style.borderLeftStyle || \"solid\";\n } else if (side === \"right\") {\n width = parseFloat(style.borderRightWidth) || 1;\n borderColor = style.borderRightColor || \"rgb(0,0,0)\";\n borderStyle = style.borderRightStyle || \"solid\";\n } else if (side === \"top\") {\n width = parseFloat(style.borderTopWidth) || 1;\n borderColor = style.borderTopColor || \"rgb(0,0,0)\";\n borderStyle = style.borderTopStyle || \"solid\";\n } else {\n width = parseFloat(style.borderBottomWidth) || 1;\n borderColor = style.borderBottomColor || \"rgb(0,0,0)\";\n borderStyle = style.borderBottomStyle || \"solid\";\n }\n\n const hex = sanitizeColor(borderColor) || \"000000\";\n\n let strokeStyle: \"solid\" | \"dashed\" | \"dotted\" = \"solid\";\n if (borderStyle === \"dashed\") strokeStyle = \"dashed\";\n else if (borderStyle === \"dotted\") strokeStyle = \"dotted\";\n\n let opacity: number | undefined;\n const rgbaMatch = borderColor.match(\n /rgba\\(\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*([\\d.]+)\\s*\\)/,\n );\n if (rgbaMatch) {\n const extractedOpacity = parseFloat(rgbaMatch[1]);\n if (extractedOpacity < 1) {\n opacity = extractedOpacity;\n }\n }\n\n return {\n color: hex,\n width: width,\n style: strokeStyle,\n opacity: opacity,\n };\n};\n\nconst calculateLinePositions = (\n boundingRect: DOMRect,\n slideRect: DOMRect,\n side: \"left\" | \"right\" | \"top\" | \"bottom\",\n): { start: Position; end: Position } => {\n const relLeft = boundingRect.left - slideRect.left;\n const relTop = boundingRect.top - slideRect.top;\n const relRight = relLeft + boundingRect.width;\n const relBottom = relTop + boundingRect.height;\n\n if (side === \"left\") {\n return {\n start: { left: relLeft, top: relTop },\n end: { left: relLeft, top: relBottom },\n };\n }\n\n if (side === \"right\") {\n return {\n start: { left: relRight, top: relTop },\n end: { left: relRight, top: relBottom },\n };\n }\n\n if (side === \"top\") {\n return {\n start: { left: relLeft, top: relTop },\n end: { left: relRight, top: relTop },\n };\n }\n\n return {\n start: { left: relLeft, top: relBottom },\n end: { left: relRight, top: relBottom },\n };\n};\n\nexport const linePlugin: Plugin<LineElementDTO> = {\n name: \"core:line\",\n handles: [\"line\"],\n onParse: (_element, parseContext) => {\n const { computedStyle, boundingRect, tagName, slideElement } = parseContext;\n\n const slideRect = slideElement.getBoundingClientRect();\n\n let stroke: Stroke;\n let start: Position;\n let end: Position;\n\n if (tagName === \"hr\") {\n const relLeft = boundingRect.left - slideRect.left;\n const relTop = boundingRect.top - slideRect.top;\n const relRight = relLeft + boundingRect.width;\n\n start = { left: relLeft, top: relTop };\n end = { left: relRight, top: relTop };\n\n const borderWidth = parseFloat(computedStyle.borderTopWidth) || 1;\n const borderColor = computedStyle.borderTopColor || \"rgb(0,0,0)\";\n const hex = sanitizeColor(borderColor) || \"000000\";\n\n stroke = {\n color: hex,\n width: borderWidth,\n style: \"solid\",\n };\n } else {\n const side = hasSingleBorderSide(computedStyle);\n if (!side) return null;\n\n const positions = calculateLinePositions(boundingRect, slideRect, side);\n start = positions.start;\n end = positions.end;\n stroke = extractLineStroke(computedStyle, side);\n }\n\n const lineElement: LineElementDTO = {\n type: \"line\",\n id: crypto.randomUUID(),\n start: start,\n end: end,\n stroke: stroke,\n zIndex: extractZIndex(computedStyle),\n rotation: extractRotation(computedStyle),\n opacity: extractOpacity(computedStyle),\n };\n\n return lineElement;\n },\n};\n","import type { Stroke } from \"@/types/base.types\";\nimport { sanitizeColor } from \"@/utils/sanitize\";\nimport { parseColorOpacity } from \"./color\";\n\nexport const extractStrokeFromBorder = (\n color: string,\n width: number,\n borderStyle: string,\n): Stroke | undefined => {\n if (width === 0) return undefined;\n\n const hex = sanitizeColor(color);\n if (!hex) return undefined;\n\n let strokeStyle: \"solid\" | \"dashed\" | \"dotted\" = \"solid\";\n if (borderStyle === \"dashed\") strokeStyle = \"dashed\";\n else if (borderStyle === \"dotted\") strokeStyle = \"dotted\";\n\n const opacity = parseColorOpacity(color);\n\n return {\n color: hex,\n width: width,\n style: strokeStyle,\n opacity: opacity,\n };\n};\n","import type { Plugin } from \"@/types/plugin.types\";\nimport type { TableElementDTO, TableCellDTO } from \"@/types/elements.types\";\nimport type { Border } from \"@/types/base.types\";\nimport { extractTypography } from \"@/lib/extractors/typography\";\nimport {\n extractRelativePosition,\n extractDimensions,\n} from \"@/lib/extractors/position\";\nimport { extractStrokeFromBorder } from \"@/lib/extractors/stroke\";\nimport { extractFill } from \"@/lib/extractors/shape\";\nimport { extractTextContent, extractRuns } from \"@/lib/extractors/text\";\n\nconst extractCellBorder = (style: CSSStyleDeclaration): Border | undefined => {\n const topWidth = parseFloat(style.borderTopWidth) || 0;\n const rightWidth = parseFloat(style.borderRightWidth) || 0;\n const bottomWidth = parseFloat(style.borderBottomWidth) || 0;\n const leftWidth = parseFloat(style.borderLeftWidth) || 0;\n\n const hasBorder =\n topWidth > 0 || rightWidth > 0 || bottomWidth > 0 || leftWidth > 0;\n if (!hasBorder) return undefined;\n\n const border: Border = {};\n\n if (topWidth > 0) {\n border.top = extractStrokeFromBorder(\n style.borderTopColor,\n topWidth,\n style.borderTopStyle,\n );\n }\n\n if (rightWidth > 0) {\n border.right = extractStrokeFromBorder(\n style.borderRightColor,\n rightWidth,\n style.borderRightStyle,\n );\n }\n\n if (bottomWidth > 0) {\n border.bottom = extractStrokeFromBorder(\n style.borderBottomColor,\n bottomWidth,\n style.borderBottomStyle,\n );\n }\n\n if (leftWidth > 0) {\n border.left = extractStrokeFromBorder(\n style.borderLeftColor,\n leftWidth,\n style.borderLeftStyle,\n );\n }\n\n return border;\n};\n\nconst parseTableCell = (cell: HTMLTableCellElement): TableCellDTO => {\n const doc = cell.ownerDocument;\n const style = doc.defaultView!.getComputedStyle(cell);\n\n let fill = extractFill(style);\n let border = extractCellBorder(style);\n\n const row = cell.parentElement;\n if (row) {\n const rowStyle = doc.defaultView!.getComputedStyle(row);\n if (!fill) {\n fill = extractFill(rowStyle);\n }\n if (!border) {\n border = extractCellBorder(rowStyle);\n }\n }\n\n const runs = extractRuns(cell);\n const cellDTO: TableCellDTO = {\n id: crypto.randomUUID(),\n text: extractTextContent(cell),\n runs: runs.length > 0 ? runs : undefined,\n typography: extractTypography(style),\n fill: fill,\n border: border,\n };\n\n if (cell.colSpan > 1) {\n cellDTO.colspan = cell.colSpan;\n }\n\n if (cell.rowSpan > 1) {\n cellDTO.rowspan = cell.rowSpan;\n }\n\n return cellDTO;\n};\n\nconst parseTableRows = (table: HTMLTableElement): TableCellDTO[][] => {\n const rows: TableCellDTO[][] = [];\n const tableRows = table.querySelectorAll(\"tr\");\n\n for (const row of tableRows) {\n const cells: TableCellDTO[] = [];\n const tableCells = row.querySelectorAll<HTMLTableCellElement>(\"th, td\");\n\n for (const cell of tableCells) {\n cells.push(parseTableCell(cell));\n }\n\n if (cells.length > 0) {\n rows.push(cells);\n }\n }\n\n return rows;\n};\n\nconst extractColumnWidths = (table: HTMLTableElement): number[] => {\n const firstRow = table.querySelector(\"tr\");\n if (!firstRow) return [];\n\n const cells = firstRow.querySelectorAll<HTMLTableCellElement>(\"th, td\");\n if (cells.length === 0) return [];\n\n const widths: number[] = [];\n\n for (const cell of cells) {\n const cellWidth = cell.getBoundingClientRect().width;\n widths.push(cellWidth);\n }\n\n return widths;\n};\n\nexport const tablePlugin: Plugin<TableElementDTO> = {\n name: \"core:table\",\n handles: [\"table\"],\n onParse: (element, parseContext) => {\n const { boundingRect, slideElement } = parseContext;\n\n const table = element as HTMLTableElement;\n const slideRect = slideElement.getBoundingClientRect();\n\n const rows = parseTableRows(table);\n if (rows.length === 0) return null;\n\n const hasHeader = table.querySelector(\"thead\") !== null;\n const firstRowHasHeader = table.querySelector(\"th\") !== null;\n const colWidths = extractColumnWidths(table);\n\n const tableElement: TableElementDTO = {\n type: \"table\",\n id: crypto.randomUUID(),\n position: extractRelativePosition(boundingRect, slideRect),\n dimensions: extractDimensions(boundingRect),\n rows: rows,\n colWidths: colWidths.length > 0 ? colWidths : undefined,\n headerRow: hasHeader || firstRowHasHeader,\n };\n\n return tableElement;\n },\n};\n","import type {\n ExtractedChart,\n SourceLibrary,\n ChartData,\n ChartSeries,\n ChartOptions,\n} from \"@/types/plotly.types\";\nimport { CHART_TYPE_MAP } from \"@/constants\";\n\nexport const detectSourceLibrary = (config: unknown): SourceLibrary => {\n if (!config || typeof config !== \"object\") {\n return \"unknown\";\n }\n\n const configObj = config as Record<string, unknown>;\n\n const hasStandardPlotly = Boolean(\n Array.isArray(configObj.data) &&\n configObj.data.length > 0 &&\n configObj.data[0] &&\n typeof configObj.data[0] === \"object\" &&\n \"type\" in (configObj.data[0] as object),\n );\n\n if (hasStandardPlotly) {\n return \"plotly\";\n }\n\n return \"unknown\";\n};\n\nexport const extractChartsFromHTML = (\n doc: Document,\n): Map<string, ExtractedChart> => {\n const charts = new Map<string, ExtractedChart>();\n\n const chartScripts = doc.querySelectorAll(\n 'script[type=\"application/json\"][data-chart-id]',\n );\n\n chartScripts.forEach((script) => {\n const chartId = script.getAttribute(\"data-chart-id\");\n const chartType = script.getAttribute(\"data-chart-type\");\n\n if (!chartId || !chartType) {\n return;\n }\n\n const chartDiv = doc.getElementById(chartId);\n if (!chartDiv) {\n return;\n }\n\n try {\n const config = JSON.parse(script.textContent || \"{}\");\n\n const configObj = config as Record<string, unknown>;\n const hasStandardPlotly = Boolean(\n Array.isArray(configObj.data) &&\n configObj.data.length > 0 &&\n configObj.data[0] &&\n typeof configObj.data[0] === \"object\" &&\n \"type\" in (configObj.data[0] as object),\n );\n\n if (!hasStandardPlotly) {\n return;\n }\n\n const sourceLibrary = detectSourceLibrary(config);\n const detectedChartType = (configObj.data as Array<{ type?: string }>)[0]\n .type as string;\n\n charts.set(chartId, {\n chartId,\n chartType: detectedChartType || chartType,\n config,\n sourceLibrary,\n });\n } catch {\n return;\n }\n });\n\n return charts;\n};\n\nconst parseLabels = (labels: unknown[]): string[] => {\n if (!Array.isArray(labels)) return [];\n return labels.map((label) => {\n if (label === null || label === undefined) return \"\";\n return String(label);\n });\n};\n\nconst parseValues = (values: unknown[]): number[] => {\n if (!Array.isArray(values)) return [];\n return values.map((value) => {\n const num = Number(value);\n return isNaN(num) ? 0 : num;\n });\n};\n\ninterface PlotlyTrace {\n type?: string;\n name?: string;\n x?: unknown[];\n y?: unknown[];\n labels?: unknown[];\n values?: unknown[];\n orientation?: string;\n yaxis?: string;\n text?: unknown[];\n textinfo?: string;\n textposition?: string;\n hole?: number;\n marker?: {\n color?: string | string[];\n colors?: string[];\n };\n line?: {\n color?: string;\n };\n}\n\ninterface PlotlyLayout {\n title?: string | { text?: string; font?: { size?: number } };\n showlegend?: boolean;\n barmode?: string;\n xaxis?: { title?: string | { text?: string } };\n yaxis?: { title?: string | { text?: string } };\n yaxis2?: { title?: string | { text?: string } };\n font?: { family?: string; size?: number };\n margin?: { t?: number; b?: number; l?: number; r?: number };\n}\n\ninterface PlotlyConfig {\n data: PlotlyTrace[];\n layout?: PlotlyLayout;\n}\n\nconst extractLabelsFromTraces = (traces: PlotlyTrace[]): string[] => {\n for (const trace of traces) {\n if (trace.labels && Array.isArray(trace.labels)) {\n return parseLabels(trace.labels);\n }\n\n if (trace.orientation === \"h\" && trace.y && Array.isArray(trace.y)) {\n return parseLabels(trace.y);\n }\n\n if (trace.x && Array.isArray(trace.x)) {\n return parseLabels(trace.x);\n }\n }\n return [];\n};\n\nconst extractColor = (trace: PlotlyTrace): string | undefined => {\n if (trace.marker?.color && typeof trace.marker.color === \"string\") {\n return trace.marker.color;\n }\n\n if (trace.line?.color && typeof trace.line.color === \"string\") {\n return trace.line.color;\n }\n\n return undefined;\n};\n\nconst extractColors = (trace: PlotlyTrace): string[] | undefined => {\n if (trace.marker?.colors && Array.isArray(trace.marker.colors)) {\n return trace.marker.colors;\n }\n\n if (trace.marker?.color && Array.isArray(trace.marker.color)) {\n return trace.marker.color;\n }\n\n return undefined;\n};\n\nconst extractTitle = (layout: PlotlyLayout): string | undefined => {\n if (!layout.title) return undefined;\n\n if (typeof layout.title === \"string\") {\n return layout.title;\n }\n\n if (typeof layout.title === \"object\" && layout.title.text) {\n return layout.title.text;\n }\n\n return undefined;\n};\n\nconst extractTitleFontSize = (layout: PlotlyLayout): number | undefined => {\n if (!layout.title) return undefined;\n\n if (typeof layout.title === \"string\") {\n return 11;\n }\n\n if (typeof layout.title === \"object\" && layout.title.font) {\n return layout.title.font.size;\n }\n\n return undefined;\n};\n\nconst extractAxisTitle = (axis: PlotlyLayout[\"xaxis\"]): string | undefined => {\n if (!axis || !axis.title) return undefined;\n\n if (typeof axis.title === \"string\") {\n return axis.title;\n }\n\n if (typeof axis.title === \"object\" && axis.title.text) {\n return axis.title.text;\n }\n\n return undefined;\n};\n\nexport const transformPlotlyToChartData = (config: PlotlyConfig): ChartData => {\n const traces = config.data || [];\n const layout = config.layout || {};\n\n if (traces.length === 0) {\n throw new Error(\"No traces found in config.data\");\n }\n\n const firstTrace = traces[0];\n const plotlyType = firstTrace?.type || \"bar\";\n const chartType = CHART_TYPE_MAP[plotlyType.toLowerCase()] || \"bar\";\n\n const labels = extractLabelsFromTraces(traces);\n\n const series: ChartSeries[] = traces.map((trace) => {\n const seriesData: ChartSeries = {\n name: trace.name || \"Series\",\n values: [],\n color: extractColor(trace),\n colors: extractColors(trace),\n };\n\n const traceType = trace.type || \"bar\";\n seriesData.chartType = CHART_TYPE_MAP[traceType.toLowerCase()] || traceType;\n\n if (trace.values) {\n seriesData.values = parseValues(trace.values);\n } else if (trace.orientation === \"h\" && trace.x) {\n seriesData.values = parseValues(trace.x);\n } else if (trace.y) {\n seriesData.values = parseValues(trace.y);\n }\n\n if (trace.yaxis === \"y2\") {\n seriesData.yAxis = \"y2\";\n } else if (trace.yaxis === \"y3\") {\n seriesData.yAxis = \"y3\";\n }\n\n return seriesData;\n });\n\n const options: ChartOptions = {\n title: extractTitle(layout),\n titleFontSize: extractTitleFontSize(layout),\n showLegend: layout.showlegend !== false,\n xAxisTitle: extractAxisTitle(layout.xaxis),\n yAxisTitle: extractAxisTitle(layout.yaxis),\n margin: layout.margin,\n };\n\n if (layout.yaxis2) {\n options.hasSecondaryAxis = true;\n options.yAxis2Title = extractAxisTitle(layout.yaxis2);\n }\n\n const hasTextLabels = traces.some(\n (trace) => trace.text && Array.isArray(trace.text) && trace.text.length > 0,\n );\n if (hasTextLabels || firstTrace.textinfo) {\n options.showDataLabels = true;\n }\n\n if (chartType === \"bar\") {\n options.orientation =\n firstTrace.orientation === \"h\" ? \"horizontal\" : \"vertical\";\n\n if (layout.barmode === \"stack\") {\n options.barGrouping = \"stacked\";\n options.barmode = \"stack\";\n } else if (layout.barmode === \"group\") {\n options.barGrouping = \"clustered\";\n options.barmode = \"group\";\n } else if (layout.barmode === \"relative\") {\n options.barGrouping = \"percentStacked\";\n options.barmode = \"relative\";\n }\n\n if (firstTrace.textposition) {\n options.dataLabelPosition = firstTrace.textposition;\n }\n }\n\n if (chartType === \"pie\") {\n if (firstTrace.hole !== undefined) {\n options.hole = firstTrace.hole;\n }\n\n if (firstTrace.textinfo) {\n options.dataLabelFormat = firstTrace.textinfo;\n }\n\n if (firstTrace.textposition) {\n options.dataLabelPosition = firstTrace.textposition;\n }\n }\n\n if (layout.font) {\n options.font = {\n family: layout.font.family,\n size: layout.font.size,\n };\n }\n\n return {\n chartType,\n series,\n labels,\n options,\n };\n};\n","import type { Plugin } from \"@/types/plugin.types\";\nimport type { ChartData, ExtractedChart } from \"@/types/plotly.types\";\nimport {\n extractChartsFromHTML,\n transformPlotlyToChartData,\n} from \"@/lib/extractors/plotly\";\nimport { ChartElementDTO, ImageElementDTO } from \"@/types/elements.types\";\n\ninterface ChartBounds {\n left: number;\n top: number;\n width: number;\n height: number;\n slideIndex: number;\n}\n\ninterface ChartPluginState {\n extractedCharts: Map<string, ExtractedChart>;\n chartBoundsMap: Map<string, ChartBounds>;\n}\n\nexport const plotlyPlugin: Plugin = {\n name: \"core:chart-plotly\",\n handles: [\"chart\"],\n beforeParse: (html, _config, context) => {\n const parser = new DOMParser();\n const doc = parser.parseFromString(html, \"text/html\");\n\n const extractedCharts = extractChartsFromHTML(doc);\n\n if (extractedCharts.size === 0) {\n return html;\n }\n\n const state: ChartPluginState = {\n extractedCharts,\n chartBoundsMap: new Map(),\n };\n\n context.state.set(plotlyPlugin.name, state);\n\n return html;\n },\n\n onParse: (element, parseContext, pluginContext) => {\n const state = pluginContext.state.get(plotlyPlugin.name) as\n | ChartPluginState\n | undefined;\n\n if (!state || state.extractedCharts.size === 0) return null;\n\n const doc = element.ownerDocument;\n const { slideIndex, slideElement } = parseContext;\n const slideRect = slideElement.getBoundingClientRect();\n\n state.extractedCharts.forEach((_, chartId) => {\n if (state.chartBoundsMap.has(chartId)) return;\n\n const chartDiv = doc.getElementById(chartId);\n if (!chartDiv || !slideElement.contains(chartDiv)) return;\n\n const chartRect = chartDiv.getBoundingClientRect();\n state.chartBoundsMap.set(chartId, {\n left: chartRect.left - slideRect.left,\n top: chartRect.top - slideRect.top,\n width: chartRect.width,\n height: chartRect.height,\n slideIndex,\n });\n });\n\n return null;\n },\n\n onSlide: (slide, context) => {\n const state = context.state.get(plotlyPlugin.name) as\n | ChartPluginState\n | undefined;\n\n if (!state || state.extractedCharts.size === 0) {\n return slide;\n }\n\n if (state.chartBoundsMap.size === 0) {\n return slide;\n }\n\n const { extractedCharts, chartBoundsMap } = state;\n\n const indicesToRemove = new Set<number>();\n const chartElements: ChartElementDTO[] = [];\n\n extractedCharts.forEach((chartData, chartId) => {\n const chartBounds = chartBoundsMap.get(chartId);\n if (!chartBounds || chartBounds.slideIndex !== slide.order) return;\n\n let bestMatchIndex = -1;\n let bestDistance = Infinity;\n\n slide.elements.forEach((el, index) => {\n if (el.type !== \"image\") return;\n if (indicesToRemove.has(index)) return;\n\n const distance = Math.sqrt(\n Math.pow(el.position.left - chartBounds.left, 2) +\n Math.pow(el.position.top - chartBounds.top, 2),\n );\n\n if (distance < bestDistance) {\n bestDistance = distance;\n bestMatchIndex = index;\n }\n });\n\n if (bestMatchIndex !== -1) {\n let chartDataDTO: ChartData;\n try {\n if (chartData.sourceLibrary === \"plotly\") {\n chartDataDTO = transformPlotlyToChartData(\n chartData.config as Parameters<\n typeof transformPlotlyToChartData\n >[0],\n );\n } else {\n return;\n }\n } catch {\n return;\n }\n\n const matchedImage = slide.elements[bestMatchIndex] as ImageElementDTO;\n const matchLeft = matchedImage.position.left;\n const matchTop = matchedImage.position.top;\n const matchRight = matchLeft + matchedImage.dimensions.width;\n const matchBottom = matchTop + matchedImage.dimensions.height;\n\n slide.elements.forEach((el, index) => {\n if (el.type !== \"image\") return;\n\n const img = el as ImageElementDTO;\n const imgLeft = img.position.left;\n const imgTop = img.position.top;\n const imgRight = imgLeft + img.dimensions.width;\n const imgBottom = imgTop + img.dimensions.height;\n\n const isOverlapping =\n imgLeft >= matchLeft &&\n imgTop >= matchTop &&\n imgRight <= matchRight &&\n imgBottom <= matchBottom;\n\n if (isOverlapping) {\n indicesToRemove.add(index);\n }\n });\n\n const chartElement: ChartElementDTO = {\n type: \"chart\",\n originalType: \"image\",\n id: crypto.randomUUID(),\n position: {\n left: chartBounds.left,\n top: chartBounds.top,\n },\n dimensions: {\n width: chartBounds.width,\n height: chartBounds.height,\n },\n data: chartDataDTO,\n sourceLibrary: chartData.sourceLibrary,\n };\n\n chartElements.push(chartElement);\n }\n });\n\n // remove previous elements and will replace with chart element\n const filteredElements = slide.elements.filter(\n (_, index) => !indicesToRemove.has(index),\n );\n\n return {\n ...slide,\n elements: [...filteredElements, ...chartElements],\n };\n },\n};\n","import type { Plugin } from \"@/types/plugin.types\";\nimport type { ImageElementDTO } from \"@/types/elements.types\";\nimport {\n extractRelativePosition,\n extractDimensions,\n} from \"@/lib/extractors/position\";\nimport {\n extractRotation,\n extractOpacity,\n extractZIndex,\n} from \"@/lib/extractors/typography\";\n\nconst extractImageSrc = (element: HTMLElement): string => {\n const tagName = element.tagName.toLowerCase();\n\n if (tagName === \"img\") {\n return (element as HTMLImageElement).src || \"\";\n }\n\n if (tagName === \"svg\") {\n const serializer = new XMLSerializer();\n const svgString = serializer.serializeToString(element);\n const base64 = btoa(unescape(encodeURIComponent(svgString)));\n return `data:image/svg+xml;base64,${base64}`;\n }\n\n if (tagName === \"picture\") {\n const img = element.querySelector(\"img\");\n if (img) {\n return img.src || \"\";\n }\n }\n\n return \"\";\n};\n\nconst extractImageAlt = (element: HTMLElement): string | undefined => {\n const tagName = element.tagName.toLowerCase();\n\n if (tagName === \"img\") {\n return (element as HTMLImageElement).alt || undefined;\n }\n\n if (tagName === \"svg\") {\n const title = element.querySelector(\"title\");\n if (title) {\n return title.textContent || undefined;\n }\n }\n\n return undefined;\n};\n\nexport const imagePlugin: Plugin<ImageElementDTO> = {\n name: \"core:image\",\n handles: [\"image\"],\n onParse: (element, parseContext) => {\n const { computedStyle, boundingRect, slideElement } = parseContext;\n\n const slideRect = slideElement.getBoundingClientRect();\n const src = extractImageSrc(element);\n\n if (!src) return null;\n\n const imageElement: ImageElementDTO = {\n type: \"image\",\n id: crypto.randomUUID(),\n src: src,\n alt: extractImageAlt(element),\n position: extractRelativePosition(boundingRect, slideRect),\n dimensions: extractDimensions(boundingRect),\n zIndex: extractZIndex(computedStyle),\n rotation: extractRotation(computedStyle),\n opacity: extractOpacity(computedStyle),\n };\n\n return imageElement;\n },\n};\n","import { FA5_TO_FA6_NAMES } from \"@/constants\";\n\nexport interface IconSVGData {\n viewBox: string;\n path: string;\n}\n\nconst iconStore = new Map<string, IconSVGData>();\nconst iconFetchPromiseStore = new Map<string, Promise<IconSVGData | null>>();\n\nexport const detectIconVariant = (classList: string[]): string => {\n if (classList.includes(\"fab\") || classList.includes(\"fa-brands\"))\n return \"brands\";\n if (classList.includes(\"far\") || classList.includes(\"fa-regular\"))\n return \"regular\";\n return \"solid\";\n};\n\nconst VARIANT_CLASSES = new Set([\n \"fa-solid\",\n \"fa-regular\",\n \"fa-brands\",\n \"fa-light\",\n \"fa-thin\",\n \"fa-duotone\",\n]);\n\nexport const parseIconClass = (classList: string[]): string | null => {\n return (\n classList.find(\n (cls) =>\n cls.startsWith(\"fa-\") && cls !== \"fa\" && !VARIANT_CLASSES.has(cls),\n ) || null\n );\n};\n\nconst fetchIconFromCDNInternal = async (\n iconClass: string,\n variant: string,\n): Promise<IconSVGData | null> => {\n const iconName = iconClass.replace(\"fa-\", \"\");\n const fa6Name = FA5_TO_FA6_NAMES[iconName] || iconName;\n const iconNames = fa6Name !== iconName ? [fa6Name, iconName] : [iconName];\n const variants = variant === \"solid\" ? [\"solid\"] : [variant, \"solid\"];\n\n for (const name of iconNames) {\n for (const v of variants) {\n const urls = [\n `https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.0.0/svgs/${v}/${name}.svg`,\n `https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@7.0.0/svgs/${v}/${name}.svg`,\n ];\n\n for (const url of urls) {\n try {\n const response = await fetch(url);\n if (!response.ok) continue;\n\n const svgText = await response.text();\n const parser = new DOMParser();\n const doc = parser.parseFromString(svgText, \"image/svg+xml\");\n const svg = doc.querySelector(\"svg\");\n\n if (!svg) continue;\n\n const viewBox = svg.getAttribute(\"viewBox\") || \"0 0 512 512\";\n const paths = Array.from(svg.querySelectorAll(\"path\"))\n .map((p) => p.getAttribute(\"d\"))\n .filter(Boolean)\n .join(\" \");\n\n if (!paths) continue;\n\n return { viewBox, path: paths };\n } catch {\n continue;\n }\n }\n }\n }\n\n return null;\n};\n\nexport const fetchIconFromCDN = async (\n iconClass: string,\n variant: string,\n): Promise<IconSVGData | null> => {\n const cacheKey = `${variant}:${iconClass}`;\n\n if (iconStore.has(cacheKey)) {\n return iconStore.get(cacheKey)!;\n }\n\n if (iconFetchPromiseStore.has(cacheKey)) {\n return iconFetchPromiseStore.get(cacheKey)!;\n }\n\n const fetchPromise = fetchIconFromCDNInternal(iconClass, variant)\n .then((result) => {\n if (result) {\n iconStore.set(cacheKey, result);\n }\n return result;\n })\n .finally(() => {\n iconFetchPromiseStore.delete(cacheKey);\n });\n\n iconFetchPromiseStore.set(cacheKey, fetchPromise);\n return fetchPromise;\n};\n\nexport const createIconSVGDataURI = (\n svgData: IconSVGData,\n color: string,\n): string => {\n const svgString = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"${svgData.viewBox}\"><path fill=\"#${color}\" d=\"${svgData.path}\"/></svg>`;\n const base64 = btoa(unescape(encodeURIComponent(svgString)));\n return `data:image/svg+xml;base64,${base64}`;\n};\n","import type { Plugin } from \"@/types/plugin.types\";\nimport type { ImageElementDTO } from \"@/types/elements.types\";\nimport {\n extractRelativePosition,\n extractDimensions,\n} from \"@/lib/extractors/position\";\nimport {\n extractRotation,\n extractOpacity,\n extractZIndex,\n} from \"@/lib/extractors/typography\";\nimport {\n detectIconVariant,\n parseIconClass,\n fetchIconFromCDN,\n createIconSVGDataURI,\n} from \"@/lib/extractors/fontawesome\";\nimport { sanitizeColor } from \"@/utils/sanitize\";\n\nexport const fontAwesomePlugin: Plugin<ImageElementDTO> = {\n name: \"core:icon-fontawesome\",\n handles: [\"icon\"],\n onParse: async (element, parseContext) => {\n const { computedStyle, boundingRect, slideElement } = parseContext;\n\n const classList = Array.from(element.classList);\n const iconClass = parseIconClass(classList);\n\n if (!iconClass) return null;\n\n const variant = detectIconVariant(classList);\n const svgData = await fetchIconFromCDN(iconClass, variant);\n\n if (!svgData) return null;\n\n const color = sanitizeColor(computedStyle.color) || \"000000\";\n const src = createIconSVGDataURI(svgData, color);\n\n const slideRect = slideElement.getBoundingClientRect();\n\n const viewBoxParts = svgData.viewBox.split(\" \").map(Number);\n const svgWidth = viewBoxParts[2] || 512;\n const svgHeight = viewBoxParts[3] || 512;\n const svgAspectRatio = svgWidth / svgHeight;\n\n let finalWidth = boundingRect.width;\n let finalHeight = boundingRect.height;\n\n const heightBasedWidth = finalHeight * svgAspectRatio;\n const widthBasedHeight = finalWidth / svgAspectRatio;\n\n if (heightBasedWidth <= finalWidth) {\n finalWidth = heightBasedWidth;\n } else {\n finalHeight = widthBasedHeight;\n }\n\n const imageElement: ImageElementDTO = {\n type: \"image\",\n originalType: \"icon\",\n id: crypto.randomUUID(),\n src: src,\n alt: iconClass,\n position: extractRelativePosition(boundingRect, slideRect),\n dimensions: { width: finalWidth, height: finalHeight },\n zIndex: extractZIndex(computedStyle),\n rotation: extractRotation(computedStyle),\n opacity: extractOpacity(computedStyle),\n };\n\n return imageElement;\n },\n};\n","import { Plugin } from \"@/types/plugin.types\";\nimport { textPlugin } from \"@/plugins/core/text.plugin\";\nimport { shapePlugin } from \"@/plugins/core/shape.plugin\";\nimport { linePlugin } from \"@/plugins/core/line.plugin\";\nimport { tablePlugin } from \"@/plugins/core/table.plugin\";\nimport { plotlyPlugin } from \"@/plugins/core/plotly.plugin\";\nimport { imagePlugin } from \"@/plugins/core/image.plugin\";\nimport { fontAwesomePlugin } from \"@/plugins/core/fontawesome.plugin\";\n\nexport const ANSI = {\n reset: \"\\x1b[0m\",\n red: \"\\x1b[31m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n dim: \"\\x1b[2m\",\n} as const;\n\nexport const DEFAULTS = {\n SLIDE_SELECTOR: \".slide\",\n SLIDE_WIDTH: 992,\n SLIDE_HEIGHT: 558,\n FONT_FAMILY: \"\",\n CHART_FONT_SIZE: 9,\n} as const;\n\nexport const SERIALIZER = {\n DPI: 96,\n PPTX_PIXELS_TO_INCHES: 73.7,\n RADIUS_MULTIPLIER: 0.75,\n} as const;\n\nexport const STROKE_DASH_MAP: Record<\n string,\n | \"solid\"\n | \"dash\"\n | \"dashDot\"\n | \"lgDash\"\n | \"lgDashDot\"\n | \"lgDashDotDot\"\n | \"sysDash\"\n | \"sysDot\"\n> = {\n solid: \"solid\",\n dashed: \"dash\",\n dotted: \"sysDot\",\n} as const;\n\nexport const FONT_WEIGHT_SUFFIX_MAP: Record<number, string> = {\n 100: \"Thin\",\n 200: \"ExtraLight\",\n 300: \"Light\",\n 400: \"\",\n 500: \"Medium\",\n 600: \"SemiBold\",\n 700: \"Bold\",\n 800: \"ExtraBold\",\n 900: \"Black\",\n} as const;\n\nexport const DEFAULT_CORE_PLUGINS: Plugin[] = [\n textPlugin,\n shapePlugin,\n linePlugin,\n tablePlugin,\n imagePlugin,\n fontAwesomePlugin,\n plotlyPlugin,\n];\nexport const COORDINATE_BUFFER = 1.03 as const;\n\nexport const CHART_TYPE_MAP: Record<string, string> = {\n pie: \"pie\",\n bar: \"bar\",\n line: \"line\",\n scatter: \"scatter\",\n area: \"area\",\n doughnut: \"doughnut\",\n radar: \"radar\",\n bubble: \"bubble\",\n} as const;\n\nexport const PPTX_CHART_TYPE_MAP: Record<string, string> = {\n pie: \"pie\",\n bar: \"bar\",\n line: \"line\",\n scatter: \"line\",\n area: \"area\",\n doughnut: \"doughnut\",\n radar: \"radar\",\n bubble: \"bubble\",\n} as const;\n\nexport const FA5_TO_FA6_NAMES: Record<string, string> = {\n \"check-circle\": \"circle-check\",\n \"times-circle\": \"circle-xmark\",\n \"exclamation-circle\": \"circle-exclamation\",\n \"exclamation-triangle\": \"triangle-exclamation\",\n \"shield-alt\": \"shield\",\n search: \"magnifying-glass\",\n times: \"xmark\",\n bars: \"bars\",\n cog: \"gear\",\n trash: \"trash-can\",\n edit: \"pen-to-square\",\n \"external-link-alt\": \"arrow-up-right-from-square\",\n \"arrow-alt-circle-down\": \"circle-down\",\n \"arrow-alt-circle-up\": \"circle-up\",\n \"arrow-alt-circle-left\": \"circle-left\",\n \"arrow-alt-circle-right\": \"circle-right\",\n \"sign-in-alt\": \"right-to-bracket\",\n \"sign-out-alt\": \"right-from-bracket\",\n percentage: \"percent\",\n} as const;\n","import type {\n ExportConfig,\n ImageExportConfig,\n HTMLSource,\n ConverterConfig,\n ParserStrategy,\n SerializerStrategy,\n} from \"@/types/config.types\";\nimport type { PresentationDTO, SlideDTO } from \"@/types/presentation.types\";\nimport type { ElementDTO } from \"@/types/elements.types\";\nimport type { Plugin } from \"@/types/plugin.types\";\nimport { PluginManager } from \"@/lib/plugin-manager\";\nimport { assertNonNull } from \"@/utils/assert\";\nimport { DEFAULTS } from \"@/constants\";\n\nexport class BaseConverter {\n protected config: Required<Pick<ConverterConfig, \"selector\" | \"dimensions\">> &\n ConverterConfig;\n protected pluginManager: PluginManager;\n protected presentation: PresentationDTO | null = null;\n protected source: string | null = null;\n protected parser: ParserStrategy;\n protected serializer: SerializerStrategy;\n\n constructor(config: ConverterConfig) {\n assertNonNull(config.parser, \"Parser strategy is required\");\n assertNonNull(config.serializer, \"Serializer strategy is required\");\n\n this.config = {\n ...config,\n selector: config.selector || \".slide\",\n dimensions: config.dimensions || {\n width: DEFAULTS.SLIDE_WIDTH,\n height: DEFAULTS.SLIDE_HEIGHT,\n },\n };\n this.parser = config.parser;\n this.serializer = config.serializer;\n this.pluginManager = new PluginManager();\n\n if (this.serializer.setPluginManager) {\n this.serializer.setPluginManager(this.pluginManager);\n }\n\n const corePlugins = config.plugins?.core ?? [];\n const extensionPlugins = config.plugins?.extensions ?? [];\n\n corePlugins.forEach((plugin) => this.use(plugin));\n extensionPlugins.forEach((plugin) => this.use(plugin));\n }\n\n use(plugin: Plugin): this {\n this.pluginManager.register(plugin);\n return this;\n }\n\n load(input: HTMLSource): this {\n if (typeof input === \"string\") {\n this.source = input;\n } else {\n this.source = input.content;\n }\n return this;\n }\n\n async convert(): Promise<this> {\n assertNonNull(this.source, \"No HTML source loaded. Call load() first.\");\n\n if (this.config.debug) {\n console.group(\"[html-in-pptx-out] convert\");\n }\n const parserConfig = {\n selector: this.config.selector,\n dimensions: this.config.dimensions,\n };\n\n const html = await this.pluginManager.executeBeforeParse(\n this.source,\n parserConfig,\n );\n\n const { elements, cleanup } = await this.parser.parse(html, parserConfig);\n\n if (this.config.debug) {\n console.log(\"before: executeOnParse\", {\n elements,\n });\n }\n\n const slidesMap = new Map<number, ElementDTO[]>();\n\n for (const { slideIndex, element, parseContext } of elements) {\n const dto = await this.pluginManager.executeOnParse(\n element,\n parseContext,\n );\n\n if (dto) {\n if (!slidesMap.has(slideIndex)) {\n slidesMap.set(slideIndex, []);\n }\n slidesMap.get(slideIndex)!.push(dto);\n }\n }\n\n if (this.config.debug) {\n console.log(\"after: executeOnParse\", {\n slides: slidesMap,\n });\n }\n\n cleanup();\n\n const slides: SlideDTO[] = [];\n const slideIndices = Array.from(slidesMap.keys()).sort((a, b) => a - b);\n\n for (const slideIndex of slideIndices) {\n const slide: SlideDTO = {\n id: crypto.randomUUID(),\n order: slideIndex,\n elements: slidesMap.get(slideIndex) || [],\n };\n slides.push(slide);\n }\n\n this.presentation = {\n slides: slides,\n metadata: {\n createdAt: new Date(),\n plugins: this.pluginManager.getPlugins().map((plugin) => plugin.name),\n },\n viewport: this.config.dimensions,\n };\n\n for (let i = 0; i < this.presentation.slides.length; i++) {\n this.presentation.slides[i] = await this.pluginManager.executeOnSlide(\n this.presentation.slides[i],\n );\n }\n\n this.pluginManager.setPresentation(this.presentation);\n\n if (this.config.debug) {\n console.log(\"after: executeOnSlide\", {\n presentation: this.presentation,\n });\n console.groupEnd();\n }\n\n return this;\n }\n\n async export(options: ExportConfig): Promise<ArrayBuffer> {\n assertNonNull(\n this.presentation,\n \"No presentation to export. Call convert() first.\",\n );\n\n const buffer = await this.serializer.serialize(this.presentation, options);\n return buffer;\n }\n\n async exportImages(_options: ImageExportConfig): Promise<void> {\n throw new Error(\"Not implemented\");\n }\n\n getPresentation(): PresentationDTO {\n assertNonNull(\n this.presentation,\n \"No presentation available. Call convert() first.\",\n );\n return this.presentation;\n }\n}\n","import { Dimensions } from \"@/types/base.types\";\n\nexport const createIframe = (\n html: string,\n dimension: Dimensions,\n): Promise<HTMLIFrameElement> => {\n return new Promise((resolve, reject) => {\n const iframe = document.createElement(\"iframe\");\n iframe.style.position = \"fixed\";\n iframe.style.left = \"-9999px\";\n iframe.style.top = \"-9999px\";\n (iframe.style.width = `${dimension.width}px`),\n (iframe.style.height = `${dimension.height}px`);\n iframe.style.opacity = \"0\";\n iframe.style.pointerEvents = \"none\";\n iframe.style.zIndex = \"-1\";\n iframe.setAttribute(\"aria-hidden\", \"true\");\n\n const handleLoad = () => {\n iframe.removeEventListener(\"load\", handleLoad);\n\n const doc = iframe.contentDocument;\n if (!doc) {\n reject(new Error(\"Failed to access iframe document\"));\n return;\n }\n\n const checkReady = () => {\n if (doc.readyState === \"complete\") {\n requestAnimationFrame(() => resolve(iframe));\n } else {\n setTimeout(checkReady, 10);\n }\n };\n\n checkReady();\n };\n\n iframe.addEventListener(\"load\", handleLoad);\n iframe.onerror = () => reject(new Error(\"Failed to load iframe\"));\n iframe.srcdoc = html;\n document.body.appendChild(iframe);\n });\n};\n\nexport const destroyIframe = (iframe: HTMLIFrameElement): void => {\n iframe.remove();\n};\n","import type {\n ParserStrategy,\n ParserConfig,\n ParserResult,\n ParserElement,\n} from \"@/types/config.types\";\nimport type { ParseContext } from \"@/types/plugin.types\";\nimport { createIframe, destroyIframe } from \"@/lib/iframe-renderer\";\nimport { classifyElement } from \"@/lib/extractors/classifier\";\n\nexport class IframeParser implements ParserStrategy {\n async parse(html: string, config: ParserConfig): Promise<ParserResult> {\n const iframe = await createIframe(html, config.dimensions);\n const doc = iframe.contentDocument!;\n const slideElements = doc.querySelectorAll<HTMLElement>(config.selector);\n\n const elements: ParserElement[] = [];\n\n for (let slideIndex = 0; slideIndex < slideElements.length; slideIndex++) {\n const slideElement = slideElements[slideIndex];\n const children = slideElement.querySelectorAll<HTMLElement>(\"*\");\n\n const allElements = [slideElement, ...Array.from(children)];\n\n const consumedElements = new Set<HTMLElement>();\n\n for (const child of allElements) {\n let isConsumed = false;\n let parent = child.parentElement;\n while (parent && parent !== slideElement) {\n if (consumedElements.has(parent)) {\n isConsumed = true;\n break;\n }\n parent = parent.parentElement;\n }\n if (isConsumed) continue;\n\n const elementTypes = classifyElement(child, iframe.contentWindow!);\n if (elementTypes.length === 0) continue;\n\n const computedStyle = iframe.contentWindow!.getComputedStyle(child);\n const boundingRect = child.getBoundingClientRect();\n const tagName = child.tagName.toLowerCase();\n\n for (const elementType of elementTypes) {\n if (elementType === \"table\" || elementType === \"text\") {\n consumedElements.add(child);\n }\n\n const parseContext: ParseContext = {\n elementType: elementType,\n tagName: tagName,\n computedStyle: computedStyle,\n boundingRect: boundingRect,\n slideIndex: slideIndex,\n slideElement: slideElement,\n };\n\n elements.push({\n slideIndex: slideIndex,\n element: child,\n parseContext: parseContext,\n });\n }\n }\n }\n\n return {\n elements,\n cleanup: () => destroyIframe(iframe),\n };\n }\n}\n","import { SERIALIZER } from \"@/constants\";\nimport type { Position, Dimensions } from \"@/types/base.types\";\n\nexport const pxToInches = (px: number): number => {\n return px / SERIALIZER.DPI;\n};\n\nexport const pxToPoints = (px: number): number => {\n return (px / SERIALIZER.DPI) * 72;\n};\n\nexport const positionToPercentage = (\n position: Position,\n viewport: Dimensions,\n): { x: `${number}%`; y: `${number}%` } => {\n const xPercent = (position.left / viewport.width) * 100;\n const yPercent = (position.top / viewport.height) * 100;\n\n return {\n x: `${xPercent}%`,\n y: `${yPercent}%`,\n };\n};\n\nexport const dimensionsToPercentage = (\n dimensions: Dimensions,\n viewport: Dimensions,\n): { w: `${number}%`; h: `${number}%` } => {\n const wPercent = (dimensions.width / viewport.width) * 100;\n const hPercent = (dimensions.height / viewport.height) * 100;\n\n return {\n w: `${wPercent}%`,\n h: `${hPercent}%`,\n };\n};\n\nexport const positionToInches = (\n position: Position,\n): { x: number; y: number } => {\n return {\n x: pxToInches(position.left),\n y: pxToInches(position.top),\n };\n};\n\nexport const dimensionsToInches = (\n dimensions: Dimensions,\n): { w: number; h: number } => {\n return {\n w: pxToInches(dimensions.width),\n h: pxToInches(dimensions.height),\n };\n};\n","import type { TextElementDTO, TextRun } from \"@/types/elements.types\";\nimport type { Dimensions, Typography } from \"@/types/base.types\";\nimport type PptxGenJS from \"pptxgenjs\";\nimport { dimensionsToPercentage } from \"@/utils/units\";\nimport { positionToPercentage } from \"@/utils/units\";\nimport { pxToPoints } from \"@/utils/units\";\n\nexport const transformTypographyToPptxTextProps = (\n typo: Typography,\n): PptxGenJS.TextPropsOptions => {\n const props: PptxGenJS.TextPropsOptions = {};\n\n if (typo.fontFamily) {\n props.fontFace = typo.fontFamily.split(\",\")[0].trim();\n }\n\n if (typo.fontSize) {\n props.fontSize = pxToPoints(typo.fontSize);\n }\n\n if (typo.color) {\n props.color = typo.color.toUpperCase();\n }\n\n if (typo.fontWeight) {\n const weight = parseInt(typo.fontWeight, 10) || 400;\n if (weight > 400) {\n props.bold = true;\n }\n }\n\n if (typo.fontStyle === \"italic\" || typo.fontStyle === \"oblique\") {\n props.italic = true;\n }\n\n if (typo.underline) {\n props.underline = { style: \"sng\" };\n }\n\n if (typo.strikethrough) {\n props.strike = \"sngStrike\";\n }\n\n return props;\n};\n\nexport const flattenRuns = (\n runs: TextRun[],\n): Array<{ text: string; options: PptxGenJS.TextPropsOptions }> => {\n const result: Array<{ text: string; options: PptxGenJS.TextPropsOptions }> =\n [];\n\n for (const run of runs) {\n if (run.children && run.children.length > 0) {\n const childResults = flattenRuns(run.children);\n for (const child of childResults) {\n const aggregatedOptions = { ...child.options };\n\n if (run.typography) {\n const runProps = transformTypographyToPptxTextProps(run.typography);\n Object.assign(aggregatedOptions, runProps, child.options);\n }\n\n if (run.href) {\n aggregatedOptions.hyperlink = { url: run.href };\n }\n\n result.push({ text: child.text, options: aggregatedOptions });\n }\n } else {\n const options: PptxGenJS.TextPropsOptions = {};\n\n if (run.typography) {\n Object.assign(\n options,\n transformTypographyToPptxTextProps(run.typography),\n );\n }\n\n if (run.href) {\n options.hyperlink = { url: run.href };\n }\n\n result.push({ text: run.content, options: options });\n }\n }\n\n return result;\n};\n\nexport const serializeText = (\n slide: PptxGenJS.Slide,\n element: TextElementDTO,\n viewport: Dimensions,\n): void => {\n const pos = positionToPercentage(element.position, viewport);\n const dims = dimensionsToPercentage(element.dimensions, viewport);\n\n const textOptions: PptxGenJS.TextPropsOptions = {\n x: pos.x,\n y: pos.y,\n w: dims.w,\n h: dims.h,\n /*\n * I'm setting lineSpacingMultiple to one bcs its not vertically aligned well idk why\n * Default line height to 1 for accurate vertical positioning.\n * Without this, pptxgenjs uses its own default which is shit\n */\n lineSpacingMultiple: 1,\n valign: \"top\",\n align: \"left\",\n isTextBox: true,\n wrap: true,\n shrinkText: false,\n };\n\n if (element.typography) {\n const typo = element.typography;\n const typoProps = transformTypographyToPptxTextProps(typo);\n Object.assign(textOptions, typoProps);\n\n if (typo.textAlign) {\n textOptions.align = typo.textAlign as\n | \"left\"\n | \"center\"\n | \"right\"\n | \"justify\";\n }\n\n if (typo.verticalAlign) {\n textOptions.valign = typo.verticalAlign as \"top\" | \"middle\" | \"bottom\";\n }\n\n if (typo.letterSpacing) {\n textOptions.charSpacing = typo.letterSpacing;\n }\n }\n\n if (element.padding) {\n textOptions.margin = [\n pxToPoints(element.padding.top),\n pxToPoints(element.padding.right),\n pxToPoints(element.padding.bottom),\n pxToPoints(element.padding.left),\n ];\n }\n\n if (element.rotation) {\n textOptions.rotate = element.rotation;\n }\n\n if (element.opacity !== undefined && element.opacity < 1) {\n textOptions.transparency = Math.round((1 - element.opacity) * 100);\n }\n\n if (element.runs && element.runs.length > 0) {\n const textProps = flattenRuns(element.runs);\n slide.addText(textProps, textOptions);\n } else {\n // if parser does not support runs fallback\n slide.addText(element.content, textOptions);\n }\n};\n","import type { ShapeElementDTO } from \"@/types/elements.types\";\nimport type { Dimensions, Stroke } from \"@/types/base.types\";\nimport PptxGenJS from \"pptxgenjs\";\nimport { dimensionsToPercentage } from \"@/utils/units\";\nimport { positionToPercentage } from \"@/utils/units\";\nimport { pxToPoints } from \"@/utils/units\";\nimport { SERIALIZER, STROKE_DASH_MAP } from \"@/constants\";\n\nconst getShapeType = (\n shape: ShapeElementDTO[\"shapeType\"],\n): PptxGenJS.ShapeType => {\n return shape as PptxGenJS.ShapeType;\n};\n\nconst getStrokeDashType = (\n stroke: Stroke,\n):\n | \"solid\"\n | \"dash\"\n | \"dashDot\"\n | \"lgDash\"\n | \"lgDashDot\"\n | \"lgDashDotDot\"\n | \"sysDash\"\n | \"sysDot\" => {\n return STROKE_DASH_MAP[stroke.style] || \"solid\";\n};\n\nexport const serializeShape = (\n slide: PptxGenJS.Slide,\n element: ShapeElementDTO,\n viewport: Dimensions,\n): void => {\n const pos = positionToPercentage(element.position, viewport);\n const dims = dimensionsToPercentage(element.dimensions, viewport);\n\n const shapeType: PptxGenJS.ShapeType =\n getShapeType(element.shapeType) || PptxGenJS.ShapeType.rect;\n\n const shapeOptions: PptxGenJS.ShapeProps = {\n x: pos.x,\n y: pos.y,\n w: dims.w,\n h: dims.h,\n };\n\n if (element.fill) {\n const fillProps: PptxGenJS.ShapeFillProps = {};\n\n if (element.fill.type === \"solid\") {\n fillProps.color = element.fill.color.toUpperCase();\n\n if (element.fill.opacity !== undefined && element.fill.opacity < 1) {\n const transparencyPercent = Math.round(\n (1 - element.fill.opacity) * 100,\n );\n fillProps.transparency = transparencyPercent;\n }\n } else if (element.fill.type === \"gradient\") {\n const firstStop = element.fill.stops[0];\n if (firstStop) {\n fillProps.color = firstStop.color.toUpperCase();\n\n if (firstStop.opacity !== undefined && firstStop.opacity < 1) {\n fillProps.transparency = Math.round((1 - firstStop.opacity) * 100);\n }\n }\n }\n\n if (fillProps.color) {\n shapeOptions.fill = fillProps;\n }\n }\n\n if (element.stroke) {\n const lineProps: PptxGenJS.ShapeLineProps = {\n color: element.stroke.color.toUpperCase(),\n width: element.stroke.width,\n dashType: getStrokeDashType(element.stroke),\n };\n\n if (element.stroke.opacity !== undefined) {\n lineProps.transparency = Math.round((1 - element.stroke.opacity) * 100);\n }\n\n shapeOptions.line = lineProps;\n }\n\n if (element.rotation) {\n shapeOptions.rotate = element.rotation;\n }\n\n if (element.borderRadius && element.shapeType === \"roundRect\") {\n const minDimension = Math.min(\n element.dimensions.width,\n element.dimensions.height,\n );\n const normalizedRadius = Math.min(element.borderRadius / minDimension, 1);\n shapeOptions.rectRadius = normalizedRadius;\n }\n\n if (element.shadow) {\n const offsetX = element.shadow.offset.x;\n const offsetY = element.shadow.offset.y;\n const offsetDistance = Math.sqrt(offsetX ** 2 + offsetY ** 2);\n\n const angleRadians = Math.atan2(offsetY, offsetX);\n const angleDegrees = (angleRadians * 180) / Math.PI;\n const normalizedAngle = ((angleDegrees % 360) + 360) % 360;\n\n shapeOptions.shadow = {\n type: element.shadow.type,\n color: element.shadow.color.toUpperCase(),\n blur: pxToPoints(element.shadow.blur),\n offset: pxToPoints(offsetDistance),\n angle: normalizedAngle,\n opacity: element.shadow.opacity ?? 1,\n };\n }\n\n slide.addShape(shapeType, shapeOptions);\n};\n","import type { LineElementDTO } from \"@/types/elements.types\";\nimport type { Dimensions, Stroke } from \"@/types/base.types\";\nimport type PptxGenJS from \"pptxgenjs\";\nimport { STROKE_DASH_MAP } from \"@/constants\";\n\nconst getStrokeDashType = (\n stroke: Stroke,\n):\n | \"solid\"\n | \"dash\"\n | \"dashDot\"\n | \"lgDash\"\n | \"lgDashDot\"\n | \"lgDashDotDot\"\n | \"sysDash\"\n | \"sysDot\" => {\n return STROKE_DASH_MAP[stroke.style] || \"solid\";\n};\n\nexport const serializeLine = (\n slide: PptxGenJS.Slide,\n element: LineElementDTO,\n viewport: Dimensions,\n): void => {\n const startXPercent = (element.start.left / viewport.width) * 100;\n const startYPercent = (element.start.top / viewport.height) * 100;\n const endXPercent = (element.end.left / viewport.width) * 100;\n const endYPercent = (element.end.top / viewport.height) * 100;\n\n const width = Math.abs(endXPercent - startXPercent);\n const height = Math.abs(endYPercent - startYPercent);\n\n const lineProps: PptxGenJS.ShapeLineProps = {\n color: element.stroke.color.toUpperCase(),\n width: element.stroke.width,\n dashType: getStrokeDashType(element.stroke),\n };\n\n if (element.stroke.opacity !== undefined) {\n lineProps.transparency = Math.round((1 - element.stroke.opacity) * 100);\n }\n\n const lineOptions: PptxGenJS.ShapeProps = {\n x: `${Math.min(startXPercent, endXPercent)}%`,\n y: `${Math.min(startYPercent, endYPercent)}%`,\n w: `${width || 0.1}%`,\n h: `${height || 0.1}%`,\n line: lineProps,\n };\n\n const flipH = element.end.left < element.start.left;\n const flipV = element.end.top < element.start.top;\n\n if (flipH) {\n lineOptions.flipH = true;\n }\n\n if (flipV) {\n lineOptions.flipV = true;\n }\n\n slide.addShape(\"line\", lineOptions);\n};\n","import type { ImageElementDTO } from \"@/types/elements.types\";\nimport type { Dimensions } from \"@/types/base.types\";\nimport type PptxGenJS from \"pptxgenjs\";\nimport { dimensionsToPercentage } from \"@/utils/units\";\nimport { positionToPercentage } from \"@/utils/units\";\n\nexport const serializeImage = (\n slide: PptxGenJS.Slide,\n element: ImageElementDTO,\n viewport: Dimensions,\n): void => {\n const pos = positionToPercentage(element.position, viewport);\n const dims = dimensionsToPercentage(element.dimensions, viewport);\n\n const imageOptions: PptxGenJS.ImageProps = {\n x: pos.x,\n y: pos.y,\n w: dims.w,\n h: dims.h,\n };\n\n if (element.src.startsWith(\"data:\")) {\n imageOptions.data = element.src;\n } else {\n imageOptions.path = element.src;\n }\n\n if (element.alt) {\n imageOptions.altText = element.alt;\n }\n\n if (element.rotation) {\n imageOptions.rotate = element.rotation;\n }\n\n if (element.opacity !== undefined && element.opacity < 1) {\n imageOptions.transparency = Math.round((1 - element.opacity) * 100);\n }\n\n if (element.fit) {\n const fitMap: Record<string, \"contain\" | \"cover\" | \"crop\"> = {\n contain: \"contain\",\n cover: \"cover\",\n stretch: \"crop\",\n };\n imageOptions.sizing = {\n type: fitMap[element.fit] || \"contain\",\n w: element.dimensions.width,\n h: element.dimensions.height,\n };\n }\n\n slide.addImage(imageOptions);\n};\n","import type { TableElementDTO } from \"@/types/elements.types\";\nimport type { Dimensions } from \"@/types/base.types\";\nimport type PptxGenJS from \"pptxgenjs\";\nimport { dimensionsToPercentage } from \"@/utils/units\";\nimport { positionToPercentage } from \"@/utils/units\";\nimport { pxToPoints } from \"@/utils/units\";\nimport { pxToInches } from \"@/utils/units\";\nimport { FONT_WEIGHT_SUFFIX_MAP } from \"@/constants\";\nimport { flattenRuns } from \"./text.serializer\";\n\nconst getFontFaceWithWeight = (fontFamily: string, fontWeight?: string): string => {\n const baseFontFace = fontFamily.split(\",\")[0].trim();\n if (!fontWeight) return baseFontFace;\n\n const weight = parseInt(fontWeight, 10) || 400;\n const suffix = FONT_WEIGHT_SUFFIX_MAP[weight];\n\n if (!suffix || suffix === \"\") return baseFontFace;\n\n return `${baseFontFace} ${suffix}`;\n};\n\nexport const serializeTable = (\n slide: PptxGenJS.Slide,\n element: TableElementDTO,\n viewport: Dimensions,\n): void => {\n const pos = positionToPercentage(element.position, viewport);\n const dims = dimensionsToPercentage(element.dimensions, viewport);\n\n const rows: PptxGenJS.TableRow[] = element.rows.map((row) =>\n row.map((cell) => {\n const cellProps: PptxGenJS.TableCell = {\n text: cell.runs && cell.runs.length > 0 ? flattenRuns(cell.runs) : cell.text,\n };\n\n if (cell.colspan) {\n cellProps.options = {\n ...cellProps.options,\n colspan: cell.colspan,\n };\n }\n\n if (cell.rowspan) {\n cellProps.options = {\n ...cellProps.options,\n rowspan: cell.rowspan,\n };\n }\n\n if (cell.typography) {\n const typo = cell.typography;\n const weight = typo.fontWeight ? parseInt(typo.fontWeight, 10) || 400 : 400;\n\n cellProps.options = {\n ...cellProps.options,\n fontFace: typo.fontFamily\n ? getFontFaceWithWeight(typo.fontFamily, typo.fontWeight)\n : undefined,\n fontSize: typo.fontSize ? pxToPoints(typo.fontSize) : undefined,\n color: typo.color ? typo.color.toUpperCase() : undefined,\n bold: weight > 400,\n italic: typo.fontStyle === \"italic\" || typo.fontStyle === \"oblique\",\n underline: typo.underline ? { style: \"sng\" } : undefined,\n align: typo.textAlign as \"left\" | \"center\" | \"right\" | undefined,\n valign: typo.verticalAlign as \"top\" | \"middle\" | \"bottom\" | undefined,\n };\n }\n\n if (cell.fill) {\n if (cell.fill.type === \"solid\") {\n const fillOptions: { color: string; transparency?: number } = {\n color: cell.fill.color.toUpperCase(),\n };\n\n if (cell.fill.opacity !== undefined && cell.fill.opacity < 1) {\n fillOptions.transparency = Math.round((1 - cell.fill.opacity) * 100);\n }\n\n cellProps.options = {\n ...cellProps.options,\n fill: fillOptions,\n };\n } else if (cell.fill.type === \"gradient\") {\n const firstStop = cell.fill.stops[0];\n if (firstStop) {\n cellProps.options = {\n ...cellProps.options,\n fill: { color: firstStop.color.toUpperCase() },\n };\n }\n }\n }\n\n if (cell.border) {\n const sides = [\"top\", \"right\", \"bottom\", \"left\"] as const;\n const borderArray: PptxGenJS.BorderProps[] = [];\n\n for (const side of sides) {\n const stroke = cell.border[side];\n if (stroke) {\n let borderType: \"solid\" | \"dash\" | \"none\" = \"solid\";\n if (stroke.style === \"dashed\" || stroke.style === \"dotted\") {\n borderType = \"dash\";\n }\n\n borderArray.push({\n color: stroke.color.toUpperCase(),\n pt: stroke.width,\n type: borderType,\n });\n } else {\n borderArray.push({ type: \"none\" });\n }\n }\n\n const borderOptions = borderArray as [\n PptxGenJS.BorderProps,\n PptxGenJS.BorderProps,\n PptxGenJS.BorderProps,\n PptxGenJS.BorderProps,\n ];\n\n cellProps.options = {\n ...cellProps.options,\n border: borderOptions,\n };\n }\n\n return cellProps;\n }),\n );\n\n const tableOptions: PptxGenJS.TableProps = {\n x: pos.x,\n y: pos.y,\n w: dims.w,\n h: dims.h,\n };\n\n if (element.colWidths && element.colWidths.length > 0) {\n tableOptions.colW = element.colWidths.map((widthPx) => pxToInches(widthPx));\n }\n\n if (element.cellMinHeight) {\n tableOptions.rowH = pxToPoints(element.cellMinHeight) / 72;\n }\n\n if (element.headerRow) {\n tableOptions.autoPageHeaderRows = 1;\n }\n\n slide.addTable(rows, tableOptions);\n};\n","import type { ChartElementDTO, ChartSeries } from \"@/types/elements.types\";\nimport { positionToInches, dimensionsToInches } from \"@/utils/units\";\nimport { DEFAULTS, PPTX_CHART_TYPE_MAP } from \"@/constants\";\nimport PptxGenJS from \"pptxgenjs\";\nimport { sanitizeColor } from \"@/utils/sanitize\";\n\nconst detectDecimalFormat = (\n series: ChartElementDTO[\"data\"][\"series\"],\n): string => {\n for (const s of series) {\n if (!s.values || !Array.isArray(s.values)) continue;\n\n for (const value of s.values) {\n if (typeof value === \"number\" && !Number.isInteger(value)) {\n let maxDecimals = 0;\n for (const v of s.values) {\n if (typeof v === \"number\" && !Number.isInteger(v)) {\n const decimals = v.toString().split(\".\")[1]?.length || 0;\n maxDecimals = Math.max(maxDecimals, Math.min(decimals, 2));\n }\n }\n\n if (maxDecimals === 1) return \"#,##0.0\";\n return \"#,##0.00\";\n }\n }\n }\n\n return \"#,##0\";\n};\n\nconst mapChartTypeToPptxGenJS = (chartType: string): string => {\n return PPTX_CHART_TYPE_MAP[chartType] || \"bar\";\n};\n\nconst getPptxChartTypeKey = (element: ChartElementDTO): string => {\n const chartType = element.data.chartType;\n\n if (\n chartType === \"pie\" &&\n element.data.options?.hole !== undefined &&\n element.data.options.hole > 0\n ) {\n return \"doughnut\";\n }\n\n return PPTX_CHART_TYPE_MAP[chartType] || \"bar\";\n};\n\ninterface ComboChartType {\n typeKey: string;\n data: ChartSeries[];\n options: PptxGenJS.IChartOpts;\n}\n\ninterface TransformedChartData {\n data: ChartSeries[] | null;\n options: PptxGenJS.IChartOpts;\n chartTypesForCombo?: ComboChartType[];\n chartTypeKey: string;\n}\n\nexport const transformChartToPptxGenJS = (\n element: ChartElementDTO,\n): TransformedChartData => {\n const pos = positionToInches(element.position);\n const dims = dimensionsToInches(element.dimensions);\n\n const chartData = element.data;\n const normalized = {\n type: chartData.chartType,\n series: chartData.series,\n labels: chartData.labels,\n options: chartData.options,\n };\n\n const data: ChartSeries[] = normalized.series.map((series) => ({\n name: series.name,\n labels: normalized.labels,\n values: series.values,\n color: sanitizeColor(series.color || \"\"),\n }));\n\n const options: PptxGenJS.IChartOpts = {\n x: pos.x,\n y: pos.y,\n w: dims.w,\n h: dims.h,\n title: normalized.options?.title,\n showTitle: normalized.options?.title ? true : false,\n titleFontSize:\n normalized.options?.titleFontSize || DEFAULTS.CHART_FONT_SIZE,\n showLegend: normalized.options?.showLegend !== false,\n legendPos: \"t\",\n legendFontSize: DEFAULTS.CHART_FONT_SIZE,\n showLabel: normalized.options?.showDataLabels === true,\n dataLabelFontSize: DEFAULTS.CHART_FONT_SIZE,\n };\n\n const showDataLabels = normalized.options?.showDataLabels === true;\n\n if (showDataLabels) {\n if (normalized.type === \"bar\") {\n options.showValue = true;\n const formatCode = detectDecimalFormat(normalized.series);\n if (formatCode) {\n options.dataLabelFormatCode = formatCode;\n }\n } else if (normalized.type === \"pie\") {\n options.showPercent = true;\n }\n }\n\n if (normalized.type === \"pie\") {\n options.dataLabelPosition = \"outEnd\";\n }\n\n const allColors: string[] = [];\n\n const hasColorsArray = normalized.series.some(\n (s) => s.colors && s.colors.length > 0,\n );\n\n if (hasColorsArray) {\n const seriesWithColors = normalized.series.find(\n (s) => s.colors && s.colors.length > 0,\n );\n if (seriesWithColors?.colors) {\n allColors.push(...seriesWithColors.colors);\n }\n } else {\n normalized.series.forEach((series) => {\n if (series.color) {\n allColors.push(series.color);\n }\n });\n }\n\n if (allColors.length > 0) {\n options.chartColors = allColors\n .map((c) => sanitizeColor(c))\n .filter((c): c is string => c !== undefined);\n }\n\n if (normalized.options?.xAxisTitle) {\n options.catAxisTitle = normalized.options.xAxisTitle;\n options.showCatAxisTitle = true;\n options.catAxisTitleFontSize = DEFAULTS.CHART_FONT_SIZE;\n }\n if (normalized.options?.yAxisTitle) {\n options.valAxisTitle = normalized.options.yAxisTitle;\n options.showValAxisTitle = true;\n options.valAxisTitleFontSize = DEFAULTS.CHART_FONT_SIZE;\n }\n\n options.catAxisLabelFontSize = DEFAULTS.CHART_FONT_SIZE;\n options.valAxisLabelFontSize = DEFAULTS.CHART_FONT_SIZE;\n\n options.catGridLine = { style: \"none\" };\n options.valGridLine = { style: \"solid\", size: 1, color: \"D9D9D9\" };\n\n if (normalized.options?.hole !== undefined && normalized.options.hole > 0) {\n options.holeSize = Math.round(normalized.options.hole * 100);\n }\n\n if (normalized.options?.orientation === \"horizontal\") {\n options.barDir = \"bar\";\n } else if (\n normalized.options?.orientation === \"vertical\" ||\n normalized.type === \"bar\"\n ) {\n options.barDir = \"col\";\n }\n\n if (normalized.options?.barGrouping) {\n options.barGrouping = normalized.options.barGrouping;\n }\n\n if (normalized.options?.hasSecondaryAxis) {\n const primaryAxisSeriesMap = new Map<string, ChartSeries[]>();\n const secondaryAxisSeriesMap = new Map<string, ChartSeries[]>();\n\n normalized.series.forEach((series, idx) => {\n const seriesChartType = series.chartType || normalized.type;\n const seriesData = data[idx];\n\n if (series.yAxis === \"y2\") {\n if (!secondaryAxisSeriesMap.has(seriesChartType)) {\n secondaryAxisSeriesMap.set(seriesChartType, []);\n }\n secondaryAxisSeriesMap.get(seriesChartType)!.push(seriesData);\n } else {\n if (!primaryAxisSeriesMap.has(seriesChartType)) {\n primaryAxisSeriesMap.set(seriesChartType, []);\n }\n primaryAxisSeriesMap.get(seriesChartType)!.push(seriesData);\n }\n });\n\n if (secondaryAxisSeriesMap.size === 0) {\n return { data, options, chartTypeKey: getPptxChartTypeKey(element) };\n }\n\n const chartTypesForCombo: ComboChartType[] = [];\n\n primaryAxisSeriesMap.forEach((seriesDataArray, seriesChartType) => {\n chartTypesForCombo.push({\n typeKey: mapChartTypeToPptxGenJS(seriesChartType),\n data: seriesDataArray,\n options: {},\n });\n });\n\n secondaryAxisSeriesMap.forEach((seriesDataArray, seriesChartType) => {\n const isLineChart =\n seriesChartType === \"line\" || seriesChartType === \"area\";\n chartTypesForCombo.push({\n typeKey: mapChartTypeToPptxGenJS(seriesChartType),\n data: seriesDataArray,\n options: {\n secondaryValAxis: true,\n secondaryCatAxis: true,\n ...(isLineChart ? { showValue: true, dataLabelPosition: \"t\" } : {}),\n },\n });\n });\n\n const globalOptions: PptxGenJS.IChartOpts = {\n x: options.x,\n y: options.y,\n w: options.w,\n h: options.h,\n title: options.title,\n showTitle: options.showTitle,\n titleFontSize: options.titleFontSize,\n showLegend: options.showLegend,\n legendPos: \"t\",\n legendFontSize: DEFAULTS.CHART_FONT_SIZE,\n chartColors: options.chartColors,\n dataLabelFormatCode: options.dataLabelFormatCode,\n // dlbs fontsize\n dataLabelFontSize: DEFAULTS.CHART_FONT_SIZE,\n valAxes: [\n {\n valAxisTitle: normalized.options.yAxisTitle || \"\",\n showValAxisTitle: normalized.options.yAxisTitle ? true : false,\n valAxisTitleFontSize: DEFAULTS.CHART_FONT_SIZE,\n valAxisLabelFontSize: DEFAULTS.CHART_FONT_SIZE,\n valGridLine: { style: \"solid\", size: 1, color: \"D9D9D9\" },\n },\n {\n valAxisTitle: normalized.options.yAxis2Title || \"\",\n showValAxisTitle: false,\n valAxisTitleFontSize: DEFAULTS.CHART_FONT_SIZE,\n valAxisLabelFontSize: DEFAULTS.CHART_FONT_SIZE,\n valGridLine: { style: \"none\" },\n },\n ],\n catAxes: [\n {\n catAxisTitle: normalized.options.xAxisTitle || \"\",\n showCatAxisTitle: normalized.options.xAxisTitle ? true : false,\n catAxisTitleFontSize: DEFAULTS.CHART_FONT_SIZE,\n catAxisLabelFontSize: DEFAULTS.CHART_FONT_SIZE,\n catGridLine: { style: \"none\" },\n },\n {\n catAxisLabelFontSize: DEFAULTS.CHART_FONT_SIZE,\n catAxisHidden: true,\n catGridLine: { style: \"none\" },\n },\n ],\n };\n\n return {\n data: null,\n options: globalOptions,\n chartTypesForCombo,\n chartTypeKey: getPptxChartTypeKey(element),\n };\n }\n\n return { data, options, chartTypeKey: getPptxChartTypeKey(element) };\n};\n\nexport const serializeChart = (\n slide: PptxGenJS.Slide,\n element: ChartElementDTO,\n): void => {\n const { data, options, chartTypesForCombo, chartTypeKey } =\n transformChartToPptxGenJS(element);\n\n if (element.data.options?.hasSecondaryAxis && chartTypesForCombo) {\n const comboChartTypes = chartTypesForCombo.map((chartTypeInfo) => ({\n type: chartTypeInfo.typeKey,\n data: chartTypeInfo.data,\n options: chartTypeInfo.options || {},\n }));\n\n slide.addChart(comboChartTypes as any, options as any);\n } else {\n const chartType = chartTypeKey;\n\n if (!chartType || !data) {\n return;\n }\n\n slide.addChart(chartType as any, data as any, options as any);\n }\n};\n","import type { SerializerStrategy, ExportConfig } from \"@/types/config.types\";\nimport type { PresentationDTO } from \"@/types/presentation.types\";\nimport type { PluginManagerInterface } from \"@/types/plugin.types\";\nimport PptxGenJS from \"pptxgenjs\";\nimport { pxToInches } from \"@/utils/units\";\nimport { serializeText } from \"./elements/text.serializer\";\nimport { serializeShape } from \"./elements/shape.serializer\";\nimport { serializeLine } from \"./elements/line.serializer\";\nimport { serializeImage } from \"./elements/image.serializer\";\nimport { serializeTable } from \"./elements/table.serializer\";\nimport { serializeChart } from \"./elements/plotly.serializer\";\nimport { assert } from \"@/utils/assert\";\n\nexport class PptxSerializer implements SerializerStrategy {\n private pluginManager: PluginManagerInterface | null = null;\n\n setPluginManager(pluginManager: PluginManagerInterface): void {\n this.pluginManager = pluginManager;\n }\n\n async serialize(\n presentation: PresentationDTO,\n _options: ExportConfig,\n ): Promise<ArrayBuffer> {\n assert(\n presentation.slides.length > 0,\n \"No slides to export. Check selector or create a slide to export\",\n );\n const pptx = new PptxGenJS();\n\n const widthInches = pxToInches(presentation.viewport.width);\n const heightInches = pxToInches(presentation.viewport.height);\n\n pptx.defineLayout({\n name: \"custom\",\n width: widthInches,\n height: heightInches,\n });\n pptx.layout = \"custom\";\n\n if (presentation.metadata.title) {\n pptx.title = presentation.metadata.title;\n }\n if (presentation.metadata.author) {\n pptx.author = presentation.metadata.author;\n }\n if (presentation.metadata.subject) {\n pptx.subject = presentation.metadata.subject;\n }\n\n for (const slideDTO of presentation.slides) {\n const slide = pptx.addSlide();\n\n for (const element of slideDTO.elements) {\n switch (element.type) {\n case \"text\":\n serializeText(slide, element, presentation.viewport);\n break;\n case \"image\":\n serializeImage(slide, element, presentation.viewport);\n break;\n case \"shape\":\n serializeShape(slide, element, presentation.viewport);\n break;\n case \"table\":\n serializeTable(slide, element, presentation.viewport);\n break;\n case \"chart\":\n serializeChart(slide, element);\n break;\n case \"line\":\n serializeLine(slide, element, presentation.viewport);\n break;\n }\n }\n }\n\n if (this.pluginManager) {\n await this.pluginManager.executeAfterGenerate(pptx, presentation);\n }\n\n const buffer = await pptx.write({ outputType: \"arraybuffer\" });\n return buffer as ArrayBuffer;\n }\n}\n","import type { ConverterConfig } from \"@/types/config.types\";\nimport { BaseConverter } from \"./base-converter\";\nimport { DEFAULT_CORE_PLUGINS, DEFAULTS } from \"@/constants\";\nimport { IframeParser } from \"@/parsers/iframe\";\nimport { PptxSerializer } from \"@/serializers/pptxgenjs\";\n\nexport class HtmlToPptx extends BaseConverter {\n constructor(config: Partial<ConverterConfig> = {}) {\n super({\n selector: config.selector || DEFAULTS.SLIDE_SELECTOR,\n dimensions: config.dimensions || {\n width: DEFAULTS.SLIDE_WIDTH,\n height: DEFAULTS.SLIDE_HEIGHT,\n },\n plugins: {\n core: config.plugins?.core ?? DEFAULT_CORE_PLUGINS,\n extensions: config.plugins?.extensions ?? [],\n },\n parser: config.parser || new IframeParser(),\n serializer: config.serializer || new PptxSerializer(),\n debug: config.debug,\n });\n }\n}\n"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- const e=require(`./converter-BXOql-G5.cjs`);exports.BaseConverter=e.i,exports.DEFAULTS=e.o,exports.DEFAULT_CORE_PLUGINS=e.s,exports.HtmlToPptx=e.t,exports.IframeParser=e.r,exports.PptxSerializer=e.n,exports.fontAwesomePlugin=e.c,exports.imagePlugin=e.l,exports.linePlugin=e.f,exports.plotlyPlugin=e.u,exports.shapePlugin=e.p,exports.tablePlugin=e.d,exports.textPlugin=e.m;
1
+ const e=require(`./converter-BQuv6GPK.cjs`);exports.BaseConverter=e.i,exports.DEFAULTS=e.o,exports.DEFAULT_CORE_PLUGINS=e.s,exports.HtmlToPptx=e.t,exports.IframeParser=e.r,exports.PptxSerializer=e.n,exports.fontAwesomePlugin=e.c,exports.imagePlugin=e.l,exports.linePlugin=e.f,exports.plotlyPlugin=e.u,exports.shapePlugin=e.p,exports.tablePlugin=e.d,exports.textPlugin=e.m;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{c as e,d as t,f as n,i as r,l as i,m as a,n as o,o as s,p as c,r as l,s as u,t as d,u as f}from"./converter-DzUDHivU.mjs";export{r as BaseConverter,s as DEFAULTS,u as DEFAULT_CORE_PLUGINS,d as HtmlToPptx,l as IframeParser,o as PptxSerializer,e as fontAwesomePlugin,i as imagePlugin,n as linePlugin,f as plotlyPlugin,c as shapePlugin,t as tablePlugin,a as textPlugin};
1
+ import{c as e,d as t,f as n,i as r,l as i,m as a,n as o,o as s,p as c,r as l,s as u,t as d,u as f}from"./converter-DRGQShsh.mjs";export{r as BaseConverter,s as DEFAULTS,u as DEFAULT_CORE_PLUGINS,d as HtmlToPptx,l as IframeParser,o as PptxSerializer,e as fontAwesomePlugin,i as imagePlugin,n as linePlugin,f as plotlyPlugin,c as shapePlugin,t as tablePlugin,a as textPlugin};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "html-in-pptx-out",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Convert HTML to PowerPoint presentations with a flexible plugin architecture",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -46,7 +46,7 @@
46
46
  "node": ">=18.0.0"
47
47
  },
48
48
  "peerDependencies": {
49
- "pptxgenjs": "^3.12.0"
49
+ "pptxgenjs": ">=3.12.0"
50
50
  },
51
51
  "peerDependenciesMeta": {
52
52
  "pptxgenjs": {
@@ -54,7 +54,7 @@
54
54
  }
55
55
  },
56
56
  "devDependencies": {
57
- "pptxgenjs": "^3.12.0",
57
+ "pptxgenjs": ">=3.12.0",
58
58
  "@types/jest": "^29.5.12",
59
59
  "@types/node": "^20.11.19",
60
60
  "jest": "^29.7.0",
@@ -1,4 +0,0 @@
1
- var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`pptxgenjs`);c=s(c);var l=class{plugins=[];context={presentation:void 0,metadata:{},state:new Map};register(e){if(this.plugins.some(t=>t.name===e.name))throw Error(`Plugin "${e.name}" is already registered`);this.plugins.push(e)}unregister(e){let t=this.plugins.findIndex(t=>t.name===e);t!==-1&&this.plugins.splice(t,1)}getPlugins(){return[...this.plugins]}setPresentation(e){this.context.presentation=e}async executeBeforeParse(e,t){let n=e;for(let e of this.plugins)e.beforeParse&&(n=await e.beforeParse(n,t,this.context));return n}async executeOnParse(e,t){for(let n of this.plugins){if(!n.handles||!n.onParse||!new Set(n.handles).has(t.elementType))continue;let r=await n.onParse(e,t,this.context);if(r)return r}return null}async executeOnSlide(e){let t=e;for(let e of this.plugins)e.onSlide&&(t=await e.onSlide(t,this.context));return t}async executeAfterGenerate(e,t){for(let n of this.plugins)n.afterGenerate&&await n.afterGenerate(e,t,this.context)}},u=class extends Error{constructor(e){super(`Assertion failed: ${e}`),this.name=`AssertionError`}};function d(e,t){if(!e)throw new u(t)}function f(e,t){if(e==null)throw new u(t)}const ee=e=>e.split(`,`).map(e=>e.trim().replace(/^["']|["']$/g,``).trim()).filter(e=>e!=null).join(`, `),p=e=>{if(!e||e===`transparent`)return``;let t=e.trim().replace(/^#/,``);if(/^[0-9a-fA-F]{3}$/.test(t))return t[0]+t[0]+t[1]+t[1]+t[2]+t[2];if(/^[0-9a-fA-F]{6}$/.test(t))return t;let n=e.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);if(n){let[,e,t,r]=n;return[e,t,r].map(e=>parseInt(e,10).toString(16).padStart(2,`0`)).join(``)}return``},te=e=>{let t=parseInt(e,10);if(!isNaN(t))return String(t);if(e===`bold`||e===`bolder`)return`700`;if(e===`lighter`)return`300`;if(e===`normal`)return`400`},ne=e=>{if(e===`italic`)return`italic`;if(e===`oblique`)return`oblique`;if(e===`normal`)return`normal`},re=e=>{if(e===`left`||e===`start`)return`left`;if(e===`center`)return`center`;if(e===`right`||e===`end`)return`right`;if(e===`justify`)return`justify`},ie=e=>{if(e===`top`)return`top`;if(e===`middle`)return`middle`;if(e===`bottom`)return`bottom`},m=e=>({fontFamily:ee(e.fontFamily)||z.FONT_FAMILY,fontSize:parseFloat(e.fontSize)||void 0,fontWeight:te(e.fontWeight),fontStyle:ne(e.fontStyle),letterSpacing:parseFloat(e.letterSpacing)||void 0,lineHeight:parseFloat(e.lineHeight)||void 0,color:p(e.color)||void 0,underline:e.textDecorationLine?.includes(`underline`)||!1,strikethrough:e.textDecorationLine?.includes(`line-through`)||!1,textAlign:re(e.textAlign),verticalAlign:ie(e.verticalAlign)}),ae=e=>({top:parseFloat(e.paddingTop)||0,right:parseFloat(e.paddingRight)||0,bottom:parseFloat(e.paddingBottom)||0,left:parseFloat(e.paddingLeft)||0}),h=e=>{let t=e.transform;if(!t||t===`none`)return;let n=t.match(/rotate\(([-\d.]+)/);if(n)return parseFloat(n[1])||void 0;let r=t.match(/matrix\(([^)]+)\)/);if(r){let e=r[1].split(`,`).map(e=>parseFloat(e.trim()));if(e.length>=2){let t=e[0],n=e[1],r=Math.atan2(n,t)*(180/Math.PI);return Math.abs(r)<.01?void 0:r}}},g=e=>{let t=parseFloat(e.opacity);return t===1?void 0:t||void 0},_=e=>parseInt(e.zIndex,10)||void 0,v=(e,t)=>({left:e.left-t.left,top:e.top-t.top}),y=(e,t=1)=>({width:e.width*t,height:e.height}),b=new Set([`h1`,`h2`,`h3`,`h4`,`h5`,`h6`,`p`,`span`,`div`,`a`,`li`,`label`,`strong`,`em`,`b`,`u`,`s`,`small`,`mark`]),oe=new Set([`img`,`picture`,`svg`]),se=new Set([`table`]),ce=new Set([`td`,`th`,`tr`,`thead`,`tbody`,`tfoot`,`caption`,`colgroup`,`col`]),le=(e,t=window)=>{let n=[],r=e.tagName.toLowerCase();if(se.has(r))return n.push(`table`),n;if(ce.has(r))return n;if(e.id.toLowerCase().includes(`chart`)&&n.push(`chart`),oe.has(r))return n.push(`image`),n;if(r===`hr`)return n.push(`line`),n;if(me(e))return n.push(`icon`),n;let i=t.getComputedStyle(e);return ue(i)&&n.push(`shape`),pe(i)&&n.push(`line`),b.has(r)&&fe(e)&&n.push(`text`),n},ue=e=>{let t=e.backgroundColor!==`transparent`&&e.backgroundColor!==`rgba(0, 0, 0, 0)`,n=e.backgroundImage!==`none`&&e.backgroundImage!==``,r=parseFloat(e.borderWidth)>0&&e.borderColor!==`transparent`&&e.borderColor!==`rgba(0, 0, 0, 0)`,i=e.boxShadow!==`none`&&e.boxShadow!==``,a=parseFloat(e.borderRadius)>0;return t||n||r||i||a},x=e=>{let t=e.toLowerCase();return b.has(e)?/^h[1-6]$/.test(t)?t:t===`p`?`p`:`body`:null},de=(e,t)=>{let n=parseFloat(e.borderRadius)||0,{width:r,height:i}=t;return n>=Math.min(r,i)/2*.9&&Math.abs(r-i)<2?`ellipse`:n>0?`roundRect`:`rect`},fe=e=>{for(let t of e.childNodes)if(t.nodeType===Node.TEXT_NODE&&t.textContent&&t.textContent.trim().length>0)return!0;return!1},pe=e=>{let t=parseFloat(e.borderLeftWidth)||0,n=parseFloat(e.borderRightWidth)||0,r=parseFloat(e.borderTopWidth)||0,i=parseFloat(e.borderBottomWidth)||0,a=[{side:`left`,width:t},{side:`right`,width:n},{side:`top`,width:r},{side:`bottom`,width:i}].filter(e=>e.width>0);return a.length===1?a[0].side:null},me=e=>e.tagName.toLowerCase()===`i`?Array.from(e.classList).some(e=>e.startsWith(`fa-`)&&e!==`fa`):!1,S=e=>{let t=[];for(let n of e.childNodes){if(n.nodeType===Node.TEXT_NODE){let e=n.textContent?.replace(/\s+/g,` `)||``;e.trim().length>0&&t.push({content:e})}if(n.nodeType===Node.ELEMENT_NODE){let e=n,r=e.tagName.toLowerCase();if(r===`br`){t.push({content:`
2
- `});continue}let i=e.className||``,a=e.ownerDocument.defaultView.getComputedStyle(e),o=S(e);if(!x(r))continue;let s={content:e.textContent||``,tagName:r,className:i,typography:m(a),children:o.length>0?o:void 0};r===`a`&&(s.href=e.getAttribute(`href`)||void 0),t.push(s)}}return t},he=e=>{let t=``,n=e=>{if(e.nodeType===Node.TEXT_NODE){t+=e.textContent||``;return}if(e.nodeType===Node.ELEMENT_NODE){let r=e.tagName.toLowerCase();if(r===`br`){t+=`
3
- `;return}for(let t of e.childNodes)n(t);(r===`p`||r===`div`)&&e.nextSibling&&(t+=`
4
- `)}};for(let t of e.childNodes)n(t);return t.trim()},ge=(e,t)=>{let n=e.querySelectorAll(`i`),r=0;for(let e of n)if(me(e)){let t=e.getBoundingClientRect().width,n=e.ownerDocument.defaultView.getComputedStyle(e),i=parseFloat(n.marginRight)||0;r+=t+i}return new DOMRect(t.left+r,t.top,t.width-r,t.height)},_e={name:`core:text`,handles:[`text`],onParse:(e,t)=>{let{computedStyle:n,boundingRect:r,tagName:i,slideElement:a}=t,o=e.textContent?.trim();if(!o)return null;let s=x(i);if(!s)return null;let c=a.getBoundingClientRect(),l=ge(e,r),u=v(l,c),d=y(l,Ue),f=S(e);return{type:`text`,id:crypto.randomUUID(),content:o,runs:f.length>0?f:void 0,position:u,dimensions:d,typography:m(n),textType:s,padding:ae(n),zIndex:_(n),rotation:h(n),opacity:g(n)}}},C=e=>{let t=e.match(/rgba\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*([\d.]+)\s*\)/);if(t){let e=parseFloat(t[1]);if(e<1)return e}},w=e=>{let t=[],n=/(rgba?\([^)]+\)|#[0-9a-fA-F]{3,6}|\w+)\s*([\d.]+%)?/g,r,i=0;for(;(r=n.exec(e))!==null;){let[,e,n]=r,a=p(e);if(!a)continue;let o=0;o=n?parseFloat(n)/100:i===0?0:1;let s=C(e);t.push({color:a,position:o,opacity:s}),i++}return t},ve=e=>{let t=e.match(/(\d+)deg/);if(t)return parseInt(t[1],10);for(let[t,n]of Object.entries({"to top":0,"to right":90,"to bottom":180,"to left":270,"to top right":45,"to bottom right":135,"to bottom left":225,"to top left":315}))if(e.includes(t))return n;return 180},T=e=>{let t=e.backgroundImage;if(t&&t!==`none`){if(t.includes(`linear-gradient`)){let e=w(t);if(e.length>=2)return{type:`gradient`,gradientType:`linear`,angle:ve(t),stops:e}}if(t.includes(`radial-gradient`)){let e=w(t);if(e.length>=2)return{type:`gradient`,gradientType:`radial`,stops:e}}}let n=e.backgroundColor;if(!n||n===`transparent`||n===`rgba(0, 0, 0, 0)`)return;let r=p(n);if(r)return{type:`solid`,color:r,opacity:C(n)}},ye=e=>{let t=parseFloat(e.borderWidth)||0;if(t===0)return;let n=e.borderColor,r=p(n);if(!r)return;let i=e.borderStyle,a=`solid`;i===`dashed`?a=`dashed`:i===`dotted`&&(a=`dotted`);let o,s=n.match(/rgba?\([^)]+,\s*([\d.]+)\)/);if(s){let e=parseFloat(s[1]);e<1&&(o=e)}return{color:r,width:t,style:a,opacity:o}},be=e=>{let t=parseFloat(e.borderRadius)||0;if(t!==0)return t},E={name:`core:shape`,handles:[`shape`],onParse:(e,t)=>{let{computedStyle:n,boundingRect:r,slideElement:i}=t,a=i.getBoundingClientRect();return{type:`shape`,id:crypto.randomUUID(),shapeType:de(n,r),position:v(r,a),dimensions:y(r),fill:T(n),stroke:ye(n),borderRadius:be(n),zIndex:_(n),rotation:h(n),opacity:g(n)}}},xe=(e,t)=>{let n=1,r=`rgb(0,0,0)`,i=`solid`;t===`left`?(n=parseFloat(e.borderLeftWidth)||1,r=e.borderLeftColor||`rgb(0,0,0)`,i=e.borderLeftStyle||`solid`):t===`right`?(n=parseFloat(e.borderRightWidth)||1,r=e.borderRightColor||`rgb(0,0,0)`,i=e.borderRightStyle||`solid`):t===`top`?(n=parseFloat(e.borderTopWidth)||1,r=e.borderTopColor||`rgb(0,0,0)`,i=e.borderTopStyle||`solid`):(n=parseFloat(e.borderBottomWidth)||1,r=e.borderBottomColor||`rgb(0,0,0)`,i=e.borderBottomStyle||`solid`);let a=p(r)||`000000`,o=`solid`;i===`dashed`?o=`dashed`:i===`dotted`&&(o=`dotted`);let s,c=r.match(/rgba\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*([\d.]+)\s*\)/);if(c){let e=parseFloat(c[1]);e<1&&(s=e)}return{color:a,width:n,style:o,opacity:s}},Se=(e,t,n)=>{let r=e.left-t.left,i=e.top-t.top,a=r+e.width,o=i+e.height;return n===`left`?{start:{left:r,top:i},end:{left:r,top:o}}:n===`right`?{start:{left:a,top:i},end:{left:a,top:o}}:n===`top`?{start:{left:r,top:i},end:{left:a,top:i}}:{start:{left:r,top:o},end:{left:a,top:o}}},D={name:`core:line`,handles:[`line`],onParse:(e,t)=>{let{computedStyle:n,boundingRect:r,tagName:i,slideElement:a}=t,o=a.getBoundingClientRect(),s,c,l;if(i===`hr`){let e=r.left-o.left,t=r.top-o.top,i=e+r.width;c={left:e,top:t},l={left:i,top:t};let a=parseFloat(n.borderTopWidth)||1;s={color:p(n.borderTopColor||`rgb(0,0,0)`)||`000000`,width:a,style:`solid`}}else{let e=pe(n);if(!e)return null;let t=Se(r,o,e);c=t.start,l=t.end,s=xe(n,e)}return{type:`line`,id:crypto.randomUUID(),start:c,end:l,stroke:s,zIndex:_(n),rotation:h(n),opacity:g(n)}}},O=(e,t,n)=>{if(t===0)return;let r=p(e);if(!r)return;let i=`solid`;n===`dashed`?i=`dashed`:n===`dotted`&&(i=`dotted`);let a=C(e);return{color:r,width:t,style:i,opacity:a}},k=e=>{let t=parseFloat(e.borderTopWidth)||0,n=parseFloat(e.borderRightWidth)||0,r=parseFloat(e.borderBottomWidth)||0,i=parseFloat(e.borderLeftWidth)||0;if(!(t>0||n>0||r>0||i>0))return;let a={};return t>0&&(a.top=O(e.borderTopColor,t,e.borderTopStyle)),n>0&&(a.right=O(e.borderRightColor,n,e.borderRightStyle)),r>0&&(a.bottom=O(e.borderBottomColor,r,e.borderBottomStyle)),i>0&&(a.left=O(e.borderLeftColor,i,e.borderLeftStyle)),a},Ce=e=>{let t=e.ownerDocument,n=t.defaultView.getComputedStyle(e),r=T(n),i=k(n),a=e.parentElement;if(a){let e=t.defaultView.getComputedStyle(a);r||=T(e),i||=k(e)}let o=S(e),s={id:crypto.randomUUID(),text:he(e),runs:o.length>0?o:void 0,typography:m(n),fill:r,border:i};return e.colSpan>1&&(s.colspan=e.colSpan),e.rowSpan>1&&(s.rowspan=e.rowSpan),s},we=e=>{let t=[],n=e.querySelectorAll(`tr`);for(let e of n){let n=[],r=e.querySelectorAll(`th, td`);for(let e of r)n.push(Ce(e));n.length>0&&t.push(n)}return t},Te=e=>{let t=e.querySelector(`tr`);if(!t)return[];let n=t.querySelectorAll(`th, td`);if(n.length===0)return[];let r=[];for(let e of n){let t=e.getBoundingClientRect().width;r.push(t)}return r},A={name:`core:table`,handles:[`table`],onParse:(e,t)=>{let{boundingRect:n,slideElement:r}=t,i=e,a=r.getBoundingClientRect(),o=we(i);if(o.length===0)return null;let s=i.querySelector(`thead`)!==null,c=i.querySelector(`th`)!==null,l=Te(i);return{type:`table`,id:crypto.randomUUID(),position:v(n,a),dimensions:y(n),rows:o,colWidths:l.length>0?l:void 0,headerRow:s||c}}},Ee=e=>{if(!e||typeof e!=`object`)return`unknown`;let t=e;return Array.isArray(t.data)&&t.data.length>0&&t.data[0]&&typeof t.data[0]==`object`&&`type`in t.data[0]?`plotly`:`unknown`},De=e=>{let t=new Map;return e.querySelectorAll(`script[type="application/json"][data-chart-id]`).forEach(n=>{let r=n.getAttribute(`data-chart-id`),i=n.getAttribute(`data-chart-type`);if(!(!r||!i)&&e.getElementById(r))try{let e=JSON.parse(n.textContent||`{}`),a=e;if(!(Array.isArray(a.data)&&a.data.length>0&&a.data[0]&&typeof a.data[0]==`object`&&`type`in a.data[0]))return;let o=Ee(e),s=a.data[0].type;t.set(r,{chartId:r,chartType:s||i,config:e,sourceLibrary:o})}catch{return}}),t},j=e=>Array.isArray(e)?e.map(e=>e==null?``:String(e)):[],M=e=>Array.isArray(e)?e.map(e=>{let t=Number(e);return isNaN(t)?0:t}):[],Oe=e=>{for(let t of e){if(t.labels&&Array.isArray(t.labels))return j(t.labels);if(t.orientation===`h`&&t.y&&Array.isArray(t.y))return j(t.y);if(t.x&&Array.isArray(t.x))return j(t.x)}return[]},ke=e=>{if(e.marker?.color&&typeof e.marker.color==`string`)return e.marker.color;if(e.line?.color&&typeof e.line.color==`string`)return e.line.color},Ae=e=>{if(e.marker?.colors&&Array.isArray(e.marker.colors))return e.marker.colors;if(e.marker?.color&&Array.isArray(e.marker.color))return e.marker.color},je=e=>{if(e.title){if(typeof e.title==`string`)return e.title;if(typeof e.title==`object`&&e.title.text)return e.title.text}},Me=e=>{if(e.title){if(typeof e.title==`string`)return 11;if(typeof e.title==`object`&&e.title.font)return e.title.font.size}},N=e=>{if(!(!e||!e.title)){if(typeof e.title==`string`)return e.title;if(typeof e.title==`object`&&e.title.text)return e.title.text}},Ne=e=>{let t=e.data||[],n=e.layout||{};if(t.length===0)throw Error(`No traces found in config.data`);let r=t[0],i=U[(r?.type||`bar`).toLowerCase()]||`bar`,a=Oe(t),o=t.map(e=>{let t={name:e.name||`Series`,values:[],color:ke(e),colors:Ae(e)},n=e.type||`bar`;return t.chartType=U[n.toLowerCase()]||n,e.values?t.values=M(e.values):e.orientation===`h`&&e.x?t.values=M(e.x):e.y&&(t.values=M(e.y)),e.yaxis===`y2`?t.yAxis=`y2`:e.yaxis===`y3`&&(t.yAxis=`y3`),t}),s={title:je(n),titleFontSize:Me(n),showLegend:n.showlegend!==!1,xAxisTitle:N(n.xaxis),yAxisTitle:N(n.yaxis),margin:n.margin};return n.yaxis2&&(s.hasSecondaryAxis=!0,s.yAxis2Title=N(n.yaxis2)),(t.some(e=>e.text&&Array.isArray(e.text)&&e.text.length>0)||r.textinfo)&&(s.showDataLabels=!0),i===`bar`&&(s.orientation=r.orientation===`h`?`horizontal`:`vertical`,n.barmode===`stack`?(s.barGrouping=`stacked`,s.barmode=`stack`):n.barmode===`group`?(s.barGrouping=`clustered`,s.barmode=`group`):n.barmode===`relative`&&(s.barGrouping=`percentStacked`,s.barmode=`relative`),r.textposition&&(s.dataLabelPosition=r.textposition)),i===`pie`&&(r.hole!==void 0&&(s.hole=r.hole),r.textinfo&&(s.dataLabelFormat=r.textinfo),r.textposition&&(s.dataLabelPosition=r.textposition)),n.font&&(s.font={family:n.font.family,size:n.font.size}),{chartType:i,series:o,labels:a,options:s}},P={name:`core:chart-plotly`,handles:[`chart`],beforeParse:(e,t,n)=>{let r=De(new DOMParser().parseFromString(e,`text/html`));if(r.size===0)return e;let i={extractedCharts:r,chartBoundsMap:new Map};return n.state.set(P.name,i),e},onParse:(e,t,n)=>{let r=n.state.get(P.name);if(!r||r.extractedCharts.size===0)return null;let i=e.ownerDocument,{slideIndex:a,slideElement:o}=t,s=o.getBoundingClientRect();return r.extractedCharts.forEach((e,t)=>{if(r.chartBoundsMap.has(t))return;let n=i.getElementById(t);if(!n||!o.contains(n))return;let c=n.getBoundingClientRect();r.chartBoundsMap.set(t,{left:c.left-s.left,top:c.top-s.top,width:c.width,height:c.height,slideIndex:a})}),null},onSlide:(e,t)=>{let n=t.state.get(P.name);if(!n||n.extractedCharts.size===0||n.chartBoundsMap.size===0)return e;let{extractedCharts:r,chartBoundsMap:i}=n,a=new Set,o=[];r.forEach((t,n)=>{let r=i.get(n);if(!r||r.slideIndex!==e.order)return;let s=-1,c=1/0;if(e.elements.forEach((e,t)=>{if(e.type!==`image`||a.has(t))return;let n=Math.sqrt((e.position.left-r.left)**2+(e.position.top-r.top)**2);n<c&&(c=n,s=t)}),s!==-1){let n;try{if(t.sourceLibrary===`plotly`)n=Ne(t.config);else return}catch{return}let i=e.elements[s],c=i.position.left,l=i.position.top,u=c+i.dimensions.width,d=l+i.dimensions.height;e.elements.forEach((e,t)=>{if(e.type!==`image`)return;let n=e,r=n.position.left,i=n.position.top,o=r+n.dimensions.width,s=i+n.dimensions.height;r>=c&&i>=l&&o<=u&&s<=d&&a.add(t)});let f={type:`chart`,originalType:`image`,id:crypto.randomUUID(),position:{left:r.left,top:r.top},dimensions:{width:r.width,height:r.height},data:n,sourceLibrary:t.sourceLibrary};o.push(f)}});let s=e.elements.filter((e,t)=>!a.has(t));return{...e,elements:[...s,...o]}}},Pe=e=>{let t=e.tagName.toLowerCase();if(t===`img`)return e.src||``;if(t===`svg`){let t=new XMLSerializer().serializeToString(e);return`data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(t)))}`}if(t===`picture`){let t=e.querySelector(`img`);if(t)return t.src||``}return``},Fe=e=>{let t=e.tagName.toLowerCase();if(t===`img`)return e.alt||void 0;if(t===`svg`){let t=e.querySelector(`title`);if(t)return t.textContent||void 0}},F={name:`core:image`,handles:[`image`],onParse:(e,t)=>{let{computedStyle:n,boundingRect:r,slideElement:i}=t,a=i.getBoundingClientRect(),o=Pe(e);return o?{type:`image`,id:crypto.randomUUID(),src:o,alt:Fe(e),position:v(r,a),dimensions:y(r),zIndex:_(n),rotation:h(n),opacity:g(n)}:null}},I=new Map,L=new Map,Ie=e=>e.includes(`fab`)||e.includes(`fa-brands`)?`brands`:e.includes(`far`)||e.includes(`fa-regular`)?`regular`:`solid`,Le=e=>e.find(e=>e.startsWith(`fa-`)&&e!==`fa`)||null,Re=async(e,t)=>{let n=e.replace(`fa-`,``),r=We[n]||n,i=r===n?[n]:[r,n],a=t===`solid`?[`solid`]:[t,`solid`];for(let e of i)for(let t of a){let n=[`https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.0.0/svgs/${t}/${e}.svg`,`https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@7.0.0/svgs/${t}/${e}.svg`];for(let e of n)try{let t=await fetch(e);if(!t.ok)continue;let n=await t.text(),r=new DOMParser().parseFromString(n,`image/svg+xml`).querySelector(`svg`);if(!r)continue;let i=r.getAttribute(`viewBox`)||`0 0 512 512`,a=Array.from(r.querySelectorAll(`path`)).map(e=>e.getAttribute(`d`)).filter(Boolean).join(` `);if(!a)continue;return{viewBox:i,path:a}}catch{continue}}return null},ze=async(e,t)=>{let n=`${t}:${e}`;if(I.has(n))return I.get(n);if(L.has(n))return L.get(n);let r=Re(e,t).then(e=>(e&&I.set(n,e),e)).finally(()=>{L.delete(n)});return L.set(n,r),r},Be=(e,t)=>{let n=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="${e.viewBox}"><path fill="#${t}" d="${e.path}"/></svg>`;return`data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(n)))}`},R={name:`core:icon-fontawesome`,handles:[`icon`],onParse:async(e,t)=>{let{computedStyle:n,boundingRect:r,slideElement:i}=t,a=Array.from(e.classList),o=Le(a);if(!o)return null;let s=await ze(o,Ie(a));if(!s)return null;let c=Be(s,p(n.color)||`000000`),l=i.getBoundingClientRect();return{type:`image`,originalType:`icon`,id:crypto.randomUUID(),src:c,alt:o,position:v(r,l),dimensions:y(r),zIndex:_(n),rotation:h(n),opacity:g(n)}}},Ve={reset:`\x1B[0m`,red:`\x1B[31m`,green:`\x1B[32m`,yellow:`\x1B[33m`,dim:`\x1B[2m`},z={SLIDE_SELECTOR:`.slide`,SLIDE_WIDTH:992,SLIDE_HEIGHT:558,FONT_FAMILY:``,CHART_FONT_SIZE:9},B={DPI:96,PPTX_PIXELS_TO_INCHES:73.7,RADIUS_MULTIPLIER:.75},V={solid:`solid`,dashed:`dash`,dotted:`sysDot`},He={100:`Thin`,200:`ExtraLight`,300:`Light`,400:``,500:`Medium`,600:`SemiBold`,700:`Bold`,800:`ExtraBold`,900:`Black`},H=[_e,E,D,A,F,R,P],Ue=1.03,U={pie:`pie`,bar:`bar`,line:`line`,scatter:`scatter`,area:`area`,doughnut:`doughnut`,radar:`radar`,bubble:`bubble`},W={pie:`pie`,bar:`bar`,line:`line`,scatter:`line`,area:`area`,doughnut:`doughnut`,radar:`radar`,bubble:`bubble`},We={"check-circle":`circle-check`,"times-circle":`circle-xmark`,"exclamation-circle":`circle-exclamation`,"exclamation-triangle":`triangle-exclamation`,"shield-alt":`shield`,search:`magnifying-glass`,times:`xmark`,bars:`bars`,cog:`gear`,trash:`trash-can`,edit:`pen-to-square`,"external-link-alt":`arrow-up-right-from-square`,"arrow-alt-circle-down":`circle-down`,"arrow-alt-circle-up":`circle-up`,"arrow-alt-circle-left":`circle-left`,"arrow-alt-circle-right":`circle-right`,"sign-in-alt":`right-to-bracket`,"sign-out-alt":`right-from-bracket`,percentage:`percent`};var G=class{config;pluginManager;presentation=null;source=null;parser;serializer;constructor(e){f(e.parser,`Parser strategy is required`),f(e.serializer,`Serializer strategy is required`),this.config={...e,selector:e.selector||`.slide`,dimensions:e.dimensions||{width:z.SLIDE_WIDTH,height:z.SLIDE_HEIGHT}},this.parser=e.parser,this.serializer=e.serializer,this.pluginManager=new l,this.serializer.setPluginManager&&this.serializer.setPluginManager(this.pluginManager);let t=e.plugins?.core??[],n=e.plugins?.extensions??[];t.forEach(e=>this.use(e)),n.forEach(e=>this.use(e))}use(e){return this.pluginManager.register(e),this}load(e){return typeof e==`string`?this.source=e:this.source=e.content,this}async convert(){f(this.source,`No HTML source loaded. Call load() first.`),this.config.debug&&console.group(`[html-in-pptx-out] convert`);let e={selector:this.config.selector,dimensions:this.config.dimensions},t=await this.pluginManager.executeBeforeParse(this.source,e),{elements:n,cleanup:r}=await this.parser.parse(t,e);this.config.debug&&console.log(`before: executeOnParse`,{elements:n});let i=new Map;for(let{slideIndex:e,element:t,parseContext:r}of n){let n=await this.pluginManager.executeOnParse(t,r);n&&(i.has(e)||i.set(e,[]),i.get(e).push(n))}this.config.debug&&console.log(`after: executeOnParse`,{slides:i}),r();let a=[],o=Array.from(i.keys()).sort((e,t)=>e-t);for(let e of o){let t={id:crypto.randomUUID(),order:e,elements:i.get(e)||[]};a.push(t)}this.presentation={slides:a,metadata:{createdAt:new Date,plugins:this.pluginManager.getPlugins().map(e=>e.name)},viewport:this.config.dimensions};for(let e=0;e<this.presentation.slides.length;e++)this.presentation.slides[e]=await this.pluginManager.executeOnSlide(this.presentation.slides[e]);return this.pluginManager.setPresentation(this.presentation),this.config.debug&&(console.log(`after: executeOnSlide`,{presentation:this.presentation}),console.groupEnd()),this}async export(e){return f(this.presentation,`No presentation to export. Call convert() first.`),await this.serializer.serialize(this.presentation,e)}async exportImages(e){throw Error(`Not implemented`)}getPresentation(){return f(this.presentation,`No presentation available. Call convert() first.`),this.presentation}};const Ge=(e,t)=>new Promise((n,r)=>{let i=document.createElement(`iframe`);i.style.position=`fixed`,i.style.left=`-9999px`,i.style.top=`-9999px`,i.style.width=`${t.width}px`,i.style.height=`${t.height}px`,i.style.opacity=`0`,i.style.pointerEvents=`none`,i.style.zIndex=`-1`,i.setAttribute(`aria-hidden`,`true`);let a=()=>{i.removeEventListener(`load`,a);let e=i.contentDocument;if(!e){r(Error(`Failed to access iframe document`));return}let t=()=>{e.readyState===`complete`?requestAnimationFrame(()=>n(i)):setTimeout(t,10)};t()};i.addEventListener(`load`,a),i.onerror=()=>r(Error(`Failed to load iframe`)),i.srcdoc=e,document.body.appendChild(i)}),Ke=e=>{e.remove()};var qe=class{async parse(e,t){let n=await Ge(e,t.dimensions),r=n.contentDocument.querySelectorAll(t.selector),i=[];for(let e=0;e<r.length;e++){let t=r[e],a=t.querySelectorAll(`*`),o=[t,...Array.from(a)],s=new Set;for(let r of o){let a=!1,o=r.parentElement;for(;o&&o!==t;){if(s.has(o)){a=!0;break}o=o.parentElement}if(a)continue;let c=le(r,n.contentWindow);if(c.length===0)continue;let l=n.contentWindow.getComputedStyle(r),u=r.getBoundingClientRect(),d=r.tagName.toLowerCase();for(let n of c){(n===`table`||n===`text`)&&s.add(r);let a={elementType:n,tagName:d,computedStyle:l,boundingRect:u,slideIndex:e,slideElement:t};i.push({slideIndex:e,element:r,parseContext:a})}}}return{elements:i,cleanup:()=>Ke(n)}}};const K=e=>e/B.DPI,q=e=>e/B.DPI*72,J=(e,t)=>{let n=e.left/t.width*100,r=e.top/t.height*100;return{x:`${n}%`,y:`${r}%`}},Y=(e,t)=>{let n=e.width/t.width*100,r=e.height/t.height*100;return{w:`${n}%`,h:`${r}%`}},Je=e=>({x:K(e.left),y:K(e.top)}),Ye=e=>({w:K(e.width),h:K(e.height)}),X=e=>{let t={};return e.fontFamily&&(t.fontFace=e.fontFamily.split(`,`)[0].trim()),e.fontSize&&(t.fontSize=q(e.fontSize)),e.color&&(t.color=e.color.toUpperCase()),e.fontWeight&&(parseInt(e.fontWeight,10)||400)>400&&(t.bold=!0),(e.fontStyle===`italic`||e.fontStyle===`oblique`)&&(t.italic=!0),e.underline&&(t.underline={style:`sng`}),e.strikethrough&&(t.strike=`sngStrike`),t},Z=e=>{let t=[];for(let n of e)if(n.children&&n.children.length>0){let e=Z(n.children);for(let r of e){let e={...r.options};if(n.typography){let t=X(n.typography);Object.assign(e,t,r.options)}n.href&&(e.hyperlink={url:n.href}),t.push({text:r.text,options:e})}}else{let e={};n.typography&&Object.assign(e,X(n.typography)),n.href&&(e.hyperlink={url:n.href}),t.push({text:n.content,options:e})}return t},Xe=(e,t,n)=>{let r=J(t.position,n),i=Y(t.dimensions,n),a={x:r.x,y:r.y,w:i.w,h:i.h,lineSpacingMultiple:1,valign:`top`,align:`left`,isTextBox:!0,wrap:!0,shrinkText:!1};if(t.typography){let e=t.typography,n=X(e);Object.assign(a,n),e.textAlign&&(a.align=e.textAlign),e.verticalAlign&&(a.valign=e.verticalAlign),e.letterSpacing&&(a.charSpacing=e.letterSpacing)}if(t.padding&&(a.margin=[q(t.padding.top),q(t.padding.right),q(t.padding.bottom),q(t.padding.left)]),t.rotation&&(a.rotate=t.rotation),t.opacity!==void 0&&t.opacity<1&&(a.transparency=Math.round((1-t.opacity)*100)),t.runs&&t.runs.length>0){let n=Z(t.runs);e.addText(n,a)}else e.addText(t.content,a)},Ze=e=>e,Qe=e=>V[e.style]||`solid`,$e=(e,t,n)=>{let r=J(t.position,n),i=Y(t.dimensions,n),a=Ze(t.shapeType)||c.default.ShapeType.rect,o={x:r.x,y:r.y,w:i.w,h:i.h};if(t.fill){let e={};if(t.fill.type===`solid`)e.color=t.fill.color.toUpperCase(),t.fill.opacity!==void 0&&t.fill.opacity<1&&(e.transparency=Math.round((1-t.fill.opacity)*100));else if(t.fill.type===`gradient`){let n=t.fill.stops[0];n&&(e.color=n.color.toUpperCase(),n.opacity!==void 0&&n.opacity<1&&(e.transparency=Math.round((1-n.opacity)*100)))}e.color&&(o.fill=e)}if(t.stroke){let e={color:t.stroke.color.toUpperCase(),width:t.stroke.width,dashType:Qe(t.stroke)};t.stroke.opacity!==void 0&&(e.transparency=Math.round((1-t.stroke.opacity)*100)),o.line=e}if(t.rotation&&(o.rotate=t.rotation),t.borderRadius&&t.shapeType===`roundRect`){let e=Math.min(t.dimensions.width,t.dimensions.height);o.rectRadius=Math.min(t.borderRadius/e,1)*B.RADIUS_MULTIPLIER}if(t.shadow){let e=t.shadow.offset.x,n=t.shadow.offset.y,r=Math.sqrt(e**2+n**2),i=(Math.atan2(n,e)*180/Math.PI%360+360)%360;o.shadow={type:t.shadow.type,color:t.shadow.color.toUpperCase(),blur:q(t.shadow.blur),offset:q(r),angle:i,opacity:t.shadow.opacity??1}}e.addShape(a,o)},et=e=>V[e.style]||`solid`,tt=(e,t,n)=>{let r=t.start.left/n.width*100,i=t.start.top/n.height*100,a=t.end.left/n.width*100,o=t.end.top/n.height*100,s=Math.abs(a-r),c=Math.abs(o-i),l={color:t.stroke.color.toUpperCase(),width:t.stroke.width,dashType:et(t.stroke)};t.stroke.opacity!==void 0&&(l.transparency=Math.round((1-t.stroke.opacity)*100));let u={x:`${Math.min(r,a)}%`,y:`${Math.min(i,o)}%`,w:`${s||.1}%`,h:`${c||.1}%`,line:l},d=t.end.left<t.start.left,f=t.end.top<t.start.top;d&&(u.flipH=!0),f&&(u.flipV=!0),e.addShape(`line`,u)},nt=(e,t,n)=>{let r=J(t.position,n),i=Y(t.dimensions,n),a={x:r.x,y:r.y,w:i.w,h:i.h};t.src.startsWith(`data:`)?a.data=t.src:a.path=t.src,t.alt&&(a.altText=t.alt),t.rotation&&(a.rotate=t.rotation),t.opacity!==void 0&&t.opacity<1&&(a.transparency=Math.round((1-t.opacity)*100)),t.fit&&(a.sizing={type:{contain:`contain`,cover:`cover`,stretch:`crop`}[t.fit]||`contain`,w:t.dimensions.width,h:t.dimensions.height}),e.addImage(a)},rt=(e,t)=>{let n=e.split(`,`)[0].trim();if(!t)return n;let r=He[parseInt(t,10)||400];return!r||r===``?n:`${n} ${r}`},it=(e,t,n)=>{let r=J(t.position,n),i=Y(t.dimensions,n),a=t.rows.map(e=>e.map(e=>{let t={text:e.runs&&e.runs.length>0?Z(e.runs):e.text};if(e.colspan&&(t.options={...t.options,colspan:e.colspan}),e.rowspan&&(t.options={...t.options,rowspan:e.rowspan}),e.typography){let n=e.typography,r=n.fontWeight&&parseInt(n.fontWeight,10)||400;t.options={...t.options,fontFace:n.fontFamily?rt(n.fontFamily,n.fontWeight):void 0,fontSize:n.fontSize?q(n.fontSize):void 0,color:n.color?n.color.toUpperCase():void 0,bold:r>400,italic:n.fontStyle===`italic`||n.fontStyle===`oblique`,underline:n.underline?{style:`sng`}:void 0,align:n.textAlign,valign:n.verticalAlign}}if(e.fill){if(e.fill.type===`solid`){let n={color:e.fill.color.toUpperCase()};e.fill.opacity!==void 0&&e.fill.opacity<1&&(n.transparency=Math.round((1-e.fill.opacity)*100)),t.options={...t.options,fill:n}}else if(e.fill.type===`gradient`){let n=e.fill.stops[0];n&&(t.options={...t.options,fill:{color:n.color.toUpperCase()}})}}if(e.border){let n=[`top`,`right`,`bottom`,`left`],r=[];for(let t of n){let n=e.border[t];if(n){let e=`solid`;(n.style===`dashed`||n.style===`dotted`)&&(e=`dash`),r.push({color:n.color.toUpperCase(),pt:n.width,type:e})}else r.push({type:`none`})}let i=r;t.options={...t.options,border:i}}return t})),o={x:r.x,y:r.y,w:i.w,h:i.h};t.colWidths&&t.colWidths.length>0&&(o.colW=t.colWidths.map(e=>K(e))),t.cellMinHeight&&(o.rowH=q(t.cellMinHeight)/72),t.headerRow&&(o.autoPageHeaderRows=1),e.addTable(a,o)},at=e=>{for(let t of e)if(!(!t.values||!Array.isArray(t.values))){for(let e of t.values)if(typeof e==`number`&&!Number.isInteger(e)){let e=0;for(let n of t.values)if(typeof n==`number`&&!Number.isInteger(n)){let t=n.toString().split(`.`)[1]?.length||0;e=Math.max(e,Math.min(t,2))}return e===1?`#,##0.0`:`#,##0.00`}}return`#,##0`},ot=e=>W[e]||`bar`,Q=e=>{let t=e.data.chartType;return t===`pie`&&e.data.options?.hole!==void 0&&e.data.options.hole>0?`doughnut`:W[t]||`bar`},st=e=>{let t=Je(e.position),n=Ye(e.dimensions),r=e.data,i={type:r.chartType,series:r.series,labels:r.labels,options:r.options},a=i.series.map(e=>({name:e.name,labels:i.labels,values:e.values,color:p(e.color||``)})),o={x:t.x,y:t.y,w:n.w,h:n.h,title:i.options?.title,showTitle:!!i.options?.title,titleFontSize:i.options?.titleFontSize||z.CHART_FONT_SIZE,showLegend:i.options?.showLegend!==!1,legendPos:`t`,legendFontSize:z.CHART_FONT_SIZE,showLabel:i.options?.showDataLabels===!0,dataLabelFontSize:z.CHART_FONT_SIZE};if(i.options?.showDataLabels===!0)if(i.type===`bar`){o.showValue=!0;let e=at(i.series);e&&(o.dataLabelFormatCode=e)}else i.type===`pie`&&(o.showPercent=!0);i.type===`pie`&&(o.dataLabelPosition=`outEnd`);let s=[];if(i.series.some(e=>e.colors&&e.colors.length>0)){let e=i.series.find(e=>e.colors&&e.colors.length>0);e?.colors&&s.push(...e.colors)}else i.series.forEach(e=>{e.color&&s.push(e.color)});if(s.length>0&&(o.chartColors=s.map(e=>p(e)).filter(e=>e!==void 0)),i.options?.xAxisTitle&&(o.catAxisTitle=i.options.xAxisTitle,o.showCatAxisTitle=!0,o.catAxisTitleFontSize=z.CHART_FONT_SIZE),i.options?.yAxisTitle&&(o.valAxisTitle=i.options.yAxisTitle,o.showValAxisTitle=!0,o.valAxisTitleFontSize=z.CHART_FONT_SIZE),o.catAxisLabelFontSize=z.CHART_FONT_SIZE,o.valAxisLabelFontSize=z.CHART_FONT_SIZE,o.catGridLine={style:`none`},o.valGridLine={style:`solid`,size:1,color:`D9D9D9`},i.options?.hole!==void 0&&i.options.hole>0&&(o.holeSize=Math.round(i.options.hole*100)),i.options?.orientation===`horizontal`?o.barDir=`bar`:(i.options?.orientation===`vertical`||i.type===`bar`)&&(o.barDir=`col`),i.options?.barGrouping&&(o.barGrouping=i.options.barGrouping),i.options?.hasSecondaryAxis){let t=new Map,n=new Map;if(i.series.forEach((e,r)=>{let o=e.chartType||i.type,s=a[r];e.yAxis===`y2`?(n.has(o)||n.set(o,[]),n.get(o).push(s)):(t.has(o)||t.set(o,[]),t.get(o).push(s))}),n.size===0)return{data:a,options:o,chartTypeKey:Q(e)};let r=[];return t.forEach((e,t)=>{r.push({typeKey:ot(t),data:e,options:{}})}),n.forEach((e,t)=>{let n=t===`line`||t===`area`;r.push({typeKey:ot(t),data:e,options:{secondaryValAxis:!0,secondaryCatAxis:!0,...n?{showValue:!0,dataLabelPosition:`t`}:{}}})}),{data:null,options:{x:o.x,y:o.y,w:o.w,h:o.h,title:o.title,showTitle:o.showTitle,titleFontSize:o.titleFontSize,showLegend:o.showLegend,legendPos:`t`,legendFontSize:z.CHART_FONT_SIZE,chartColors:o.chartColors,dataLabelFormatCode:o.dataLabelFormatCode,dataLabelFontSize:z.CHART_FONT_SIZE,valAxes:[{valAxisTitle:i.options.yAxisTitle||``,showValAxisTitle:!!i.options.yAxisTitle,valAxisTitleFontSize:z.CHART_FONT_SIZE,valAxisLabelFontSize:z.CHART_FONT_SIZE,valGridLine:{style:`solid`,size:1,color:`D9D9D9`}},{valAxisTitle:i.options.yAxis2Title||``,showValAxisTitle:!1,valAxisTitleFontSize:z.CHART_FONT_SIZE,valAxisLabelFontSize:z.CHART_FONT_SIZE,valGridLine:{style:`none`}}],catAxes:[{catAxisTitle:i.options.xAxisTitle||``,showCatAxisTitle:!!i.options.xAxisTitle,catAxisTitleFontSize:z.CHART_FONT_SIZE,catAxisLabelFontSize:z.CHART_FONT_SIZE,catGridLine:{style:`none`}},{catAxisLabelFontSize:z.CHART_FONT_SIZE,catAxisHidden:!0,catGridLine:{style:`none`}}]},chartTypesForCombo:r,chartTypeKey:Q(e)}}return{data:a,options:o,chartTypeKey:Q(e)}},ct=(e,t)=>{let{data:n,options:r,chartTypesForCombo:i,chartTypeKey:a}=st(t);if(t.data.options?.hasSecondaryAxis&&i){let t=i.map(e=>({type:e.typeKey,data:e.data,options:e.options||{}}));e.addChart(t,r)}else{let t=a;if(!t||!n)return;e.addChart(t,n,r)}};var $=class{pluginManager=null;setPluginManager(e){this.pluginManager=e}async serialize(e,t){d(e.slides.length>0,`No slides to export. Check selector or create a slide to export`);let n=new c.default,r=K(e.viewport.width),i=K(e.viewport.height);n.defineLayout({name:`custom`,width:r,height:i}),n.layout=`custom`,e.metadata.title&&(n.title=e.metadata.title),e.metadata.author&&(n.author=e.metadata.author),e.metadata.subject&&(n.subject=e.metadata.subject);for(let t of e.slides){let r=n.addSlide();for(let n of t.elements)switch(n.type){case`text`:Xe(r,n,e.viewport);break;case`image`:nt(r,n,e.viewport);break;case`shape`:$e(r,n,e.viewport);break;case`table`:it(r,n,e.viewport);break;case`chart`:ct(r,n);break;case`line`:tt(r,n,e.viewport);break}}return this.pluginManager&&await this.pluginManager.executeAfterGenerate(n,e),await n.write({outputType:`arraybuffer`})}},lt=class extends G{constructor(e={}){super({selector:e.selector||z.SLIDE_SELECTOR,dimensions:e.dimensions||{width:z.SLIDE_WIDTH,height:z.SLIDE_HEIGHT},plugins:{core:e.plugins?.core??H,extensions:e.plugins?.extensions??[]},parser:e.parser||new qe,serializer:e.serializer||new $,debug:e.debug})}};Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return Ve}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return R}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return A}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return D}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return G}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return _e}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return $}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return z}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return E}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return qe}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return H}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return lt}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return P}});
@@ -1,5 +0,0 @@
1
- import e from"pptxgenjs";var t=class{plugins=[];context={presentation:void 0,metadata:{},state:new Map};register(e){if(this.plugins.some(t=>t.name===e.name))throw Error(`Plugin "${e.name}" is already registered`);this.plugins.push(e)}unregister(e){let t=this.plugins.findIndex(t=>t.name===e);t!==-1&&this.plugins.splice(t,1)}getPlugins(){return[...this.plugins]}setPresentation(e){this.context.presentation=e}async executeBeforeParse(e,t){let n=e;for(let e of this.plugins)e.beforeParse&&(n=await e.beforeParse(n,t,this.context));return n}async executeOnParse(e,t){for(let n of this.plugins){if(!n.handles||!n.onParse||!new Set(n.handles).has(t.elementType))continue;let r=await n.onParse(e,t,this.context);if(r)return r}return null}async executeOnSlide(e){let t=e;for(let e of this.plugins)e.onSlide&&(t=await e.onSlide(t,this.context));return t}async executeAfterGenerate(e,t){for(let n of this.plugins)n.afterGenerate&&await n.afterGenerate(e,t,this.context)}},n=class extends Error{constructor(e){super(`Assertion failed: ${e}`),this.name=`AssertionError`}};function r(e,t){if(!e)throw new n(t)}function i(e,t){if(e==null)throw new n(t)}const a=e=>e.split(`,`).map(e=>e.trim().replace(/^["']|["']$/g,``).trim()).filter(e=>e!=null).join(`, `),o=e=>{if(!e||e===`transparent`)return``;let t=e.trim().replace(/^#/,``);if(/^[0-9a-fA-F]{3}$/.test(t))return t[0]+t[0]+t[1]+t[1]+t[2]+t[2];if(/^[0-9a-fA-F]{6}$/.test(t))return t;let n=e.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);if(n){let[,e,t,r]=n;return[e,t,r].map(e=>parseInt(e,10).toString(16).padStart(2,`0`)).join(``)}return``},s=e=>{let t=parseInt(e,10);if(!isNaN(t))return String(t);if(e===`bold`||e===`bolder`)return`700`;if(e===`lighter`)return`300`;if(e===`normal`)return`400`},c=e=>{if(e===`italic`)return`italic`;if(e===`oblique`)return`oblique`;if(e===`normal`)return`normal`},l=e=>{if(e===`left`||e===`start`)return`left`;if(e===`center`)return`center`;if(e===`right`||e===`end`)return`right`;if(e===`justify`)return`justify`},u=e=>{if(e===`top`)return`top`;if(e===`middle`)return`middle`;if(e===`bottom`)return`bottom`},d=e=>({fontFamily:a(e.fontFamily)||z.FONT_FAMILY,fontSize:parseFloat(e.fontSize)||void 0,fontWeight:s(e.fontWeight),fontStyle:c(e.fontStyle),letterSpacing:parseFloat(e.letterSpacing)||void 0,lineHeight:parseFloat(e.lineHeight)||void 0,color:o(e.color)||void 0,underline:e.textDecorationLine?.includes(`underline`)||!1,strikethrough:e.textDecorationLine?.includes(`line-through`)||!1,textAlign:l(e.textAlign),verticalAlign:u(e.verticalAlign)}),f=e=>({top:parseFloat(e.paddingTop)||0,right:parseFloat(e.paddingRight)||0,bottom:parseFloat(e.paddingBottom)||0,left:parseFloat(e.paddingLeft)||0}),p=e=>{let t=e.transform;if(!t||t===`none`)return;let n=t.match(/rotate\(([-\d.]+)/);if(n)return parseFloat(n[1])||void 0;let r=t.match(/matrix\(([^)]+)\)/);if(r){let e=r[1].split(`,`).map(e=>parseFloat(e.trim()));if(e.length>=2){let t=e[0],n=e[1],r=Math.atan2(n,t)*(180/Math.PI);return Math.abs(r)<.01?void 0:r}}},m=e=>{let t=parseFloat(e.opacity);return t===1?void 0:t||void 0},h=e=>parseInt(e.zIndex,10)||void 0,g=(e,t)=>({left:e.left-t.left,top:e.top-t.top}),_=(e,t=1)=>({width:e.width*t,height:e.height}),v=new Set([`h1`,`h2`,`h3`,`h4`,`h5`,`h6`,`p`,`span`,`div`,`a`,`li`,`label`,`strong`,`em`,`b`,`u`,`s`,`small`,`mark`]),y=new Set([`img`,`picture`,`svg`]),ee=new Set([`table`]),te=new Set([`td`,`th`,`tr`,`thead`,`tbody`,`tfoot`,`caption`,`colgroup`,`col`]),ne=(e,t=window)=>{let n=[],r=e.tagName.toLowerCase();if(ee.has(r))return n.push(`table`),n;if(te.has(r))return n;if(e.id.toLowerCase().includes(`chart`)&&n.push(`chart`),y.has(r))return n.push(`image`),n;if(r===`hr`)return n.push(`line`),n;if(oe(e))return n.push(`icon`),n;let i=t.getComputedStyle(e);return re(i)&&n.push(`shape`),x(i)&&n.push(`line`),v.has(r)&&ae(e)&&n.push(`text`),n},re=e=>{let t=e.backgroundColor!==`transparent`&&e.backgroundColor!==`rgba(0, 0, 0, 0)`,n=e.backgroundImage!==`none`&&e.backgroundImage!==``,r=parseFloat(e.borderWidth)>0&&e.borderColor!==`transparent`&&e.borderColor!==`rgba(0, 0, 0, 0)`,i=e.boxShadow!==`none`&&e.boxShadow!==``,a=parseFloat(e.borderRadius)>0;return t||n||r||i||a},b=e=>{let t=e.toLowerCase();return v.has(e)?/^h[1-6]$/.test(t)?t:t===`p`?`p`:`body`:null},ie=(e,t)=>{let n=parseFloat(e.borderRadius)||0,{width:r,height:i}=t;return n>=Math.min(r,i)/2*.9&&Math.abs(r-i)<2?`ellipse`:n>0?`roundRect`:`rect`},ae=e=>{for(let t of e.childNodes)if(t.nodeType===Node.TEXT_NODE&&t.textContent&&t.textContent.trim().length>0)return!0;return!1},x=e=>{let t=parseFloat(e.borderLeftWidth)||0,n=parseFloat(e.borderRightWidth)||0,r=parseFloat(e.borderTopWidth)||0,i=parseFloat(e.borderBottomWidth)||0,a=[{side:`left`,width:t},{side:`right`,width:n},{side:`top`,width:r},{side:`bottom`,width:i}].filter(e=>e.width>0);return a.length===1?a[0].side:null},oe=e=>e.tagName.toLowerCase()===`i`?Array.from(e.classList).some(e=>e.startsWith(`fa-`)&&e!==`fa`):!1,S=e=>{let t=[];for(let n of e.childNodes){if(n.nodeType===Node.TEXT_NODE){let e=n.textContent?.replace(/\s+/g,` `)||``;e.trim().length>0&&t.push({content:e})}if(n.nodeType===Node.ELEMENT_NODE){let e=n,r=e.tagName.toLowerCase();if(r===`br`){t.push({content:`
2
- `});continue}let i=e.className||``,a=e.ownerDocument.defaultView.getComputedStyle(e),o=S(e);if(!b(r))continue;let s={content:e.textContent||``,tagName:r,className:i,typography:d(a),children:o.length>0?o:void 0};r===`a`&&(s.href=e.getAttribute(`href`)||void 0),t.push(s)}}return t},se=e=>{let t=``,n=e=>{if(e.nodeType===Node.TEXT_NODE){t+=e.textContent||``;return}if(e.nodeType===Node.ELEMENT_NODE){let r=e.tagName.toLowerCase();if(r===`br`){t+=`
3
- `;return}for(let t of e.childNodes)n(t);(r===`p`||r===`div`)&&e.nextSibling&&(t+=`
4
- `)}};for(let t of e.childNodes)n(t);return t.trim()},ce=(e,t)=>{let n=e.querySelectorAll(`i`),r=0;for(let e of n)if(oe(e)){let t=e.getBoundingClientRect().width,n=e.ownerDocument.defaultView.getComputedStyle(e),i=parseFloat(n.marginRight)||0;r+=t+i}return new DOMRect(t.left+r,t.top,t.width-r,t.height)},C={name:`core:text`,handles:[`text`],onParse:(e,t)=>{let{computedStyle:n,boundingRect:r,tagName:i,slideElement:a}=t,o=e.textContent?.trim();if(!o)return null;let s=b(i);if(!s)return null;let c=a.getBoundingClientRect(),l=ce(e,r),u=g(l,c),v=_(l,Fe),y=S(e);return{type:`text`,id:crypto.randomUUID(),content:o,runs:y.length>0?y:void 0,position:u,dimensions:v,typography:d(n),textType:s,padding:f(n),zIndex:h(n),rotation:p(n),opacity:m(n)}}},w=e=>{let t=e.match(/rgba\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*([\d.]+)\s*\)/);if(t){let e=parseFloat(t[1]);if(e<1)return e}},le=e=>{let t=[],n=/(rgba?\([^)]+\)|#[0-9a-fA-F]{3,6}|\w+)\s*([\d.]+%)?/g,r,i=0;for(;(r=n.exec(e))!==null;){let[,e,n]=r,a=o(e);if(!a)continue;let s=0;s=n?parseFloat(n)/100:i===0?0:1;let c=w(e);t.push({color:a,position:s,opacity:c}),i++}return t},ue=e=>{let t=e.match(/(\d+)deg/);if(t)return parseInt(t[1],10);for(let[t,n]of Object.entries({"to top":0,"to right":90,"to bottom":180,"to left":270,"to top right":45,"to bottom right":135,"to bottom left":225,"to top left":315}))if(e.includes(t))return n;return 180},T=e=>{let t=e.backgroundImage;if(t&&t!==`none`){if(t.includes(`linear-gradient`)){let e=le(t);if(e.length>=2)return{type:`gradient`,gradientType:`linear`,angle:ue(t),stops:e}}if(t.includes(`radial-gradient`)){let e=le(t);if(e.length>=2)return{type:`gradient`,gradientType:`radial`,stops:e}}}let n=e.backgroundColor;if(!n||n===`transparent`||n===`rgba(0, 0, 0, 0)`)return;let r=o(n);if(r)return{type:`solid`,color:r,opacity:w(n)}},de=e=>{let t=parseFloat(e.borderWidth)||0;if(t===0)return;let n=e.borderColor,r=o(n);if(!r)return;let i=e.borderStyle,a=`solid`;i===`dashed`?a=`dashed`:i===`dotted`&&(a=`dotted`);let s,c=n.match(/rgba?\([^)]+,\s*([\d.]+)\)/);if(c){let e=parseFloat(c[1]);e<1&&(s=e)}return{color:r,width:t,style:a,opacity:s}},fe=e=>{let t=parseFloat(e.borderRadius)||0;if(t!==0)return t},E={name:`core:shape`,handles:[`shape`],onParse:(e,t)=>{let{computedStyle:n,boundingRect:r,slideElement:i}=t,a=i.getBoundingClientRect();return{type:`shape`,id:crypto.randomUUID(),shapeType:ie(n,r),position:g(r,a),dimensions:_(r),fill:T(n),stroke:de(n),borderRadius:fe(n),zIndex:h(n),rotation:p(n),opacity:m(n)}}},pe=(e,t)=>{let n=1,r=`rgb(0,0,0)`,i=`solid`;t===`left`?(n=parseFloat(e.borderLeftWidth)||1,r=e.borderLeftColor||`rgb(0,0,0)`,i=e.borderLeftStyle||`solid`):t===`right`?(n=parseFloat(e.borderRightWidth)||1,r=e.borderRightColor||`rgb(0,0,0)`,i=e.borderRightStyle||`solid`):t===`top`?(n=parseFloat(e.borderTopWidth)||1,r=e.borderTopColor||`rgb(0,0,0)`,i=e.borderTopStyle||`solid`):(n=parseFloat(e.borderBottomWidth)||1,r=e.borderBottomColor||`rgb(0,0,0)`,i=e.borderBottomStyle||`solid`);let a=o(r)||`000000`,s=`solid`;i===`dashed`?s=`dashed`:i===`dotted`&&(s=`dotted`);let c,l=r.match(/rgba\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*([\d.]+)\s*\)/);if(l){let e=parseFloat(l[1]);e<1&&(c=e)}return{color:a,width:n,style:s,opacity:c}},me=(e,t,n)=>{let r=e.left-t.left,i=e.top-t.top,a=r+e.width,o=i+e.height;return n===`left`?{start:{left:r,top:i},end:{left:r,top:o}}:n===`right`?{start:{left:a,top:i},end:{left:a,top:o}}:n===`top`?{start:{left:r,top:i},end:{left:a,top:i}}:{start:{left:r,top:o},end:{left:a,top:o}}},D={name:`core:line`,handles:[`line`],onParse:(e,t)=>{let{computedStyle:n,boundingRect:r,tagName:i,slideElement:a}=t,s=a.getBoundingClientRect(),c,l,u;if(i===`hr`){let e=r.left-s.left,t=r.top-s.top,i=e+r.width;l={left:e,top:t},u={left:i,top:t};let a=parseFloat(n.borderTopWidth)||1;c={color:o(n.borderTopColor||`rgb(0,0,0)`)||`000000`,width:a,style:`solid`}}else{let e=x(n);if(!e)return null;let t=me(r,s,e);l=t.start,u=t.end,c=pe(n,e)}return{type:`line`,id:crypto.randomUUID(),start:l,end:u,stroke:c,zIndex:h(n),rotation:p(n),opacity:m(n)}}},O=(e,t,n)=>{if(t===0)return;let r=o(e);if(!r)return;let i=`solid`;n===`dashed`?i=`dashed`:n===`dotted`&&(i=`dotted`);let a=w(e);return{color:r,width:t,style:i,opacity:a}},k=e=>{let t=parseFloat(e.borderTopWidth)||0,n=parseFloat(e.borderRightWidth)||0,r=parseFloat(e.borderBottomWidth)||0,i=parseFloat(e.borderLeftWidth)||0;if(!(t>0||n>0||r>0||i>0))return;let a={};return t>0&&(a.top=O(e.borderTopColor,t,e.borderTopStyle)),n>0&&(a.right=O(e.borderRightColor,n,e.borderRightStyle)),r>0&&(a.bottom=O(e.borderBottomColor,r,e.borderBottomStyle)),i>0&&(a.left=O(e.borderLeftColor,i,e.borderLeftStyle)),a},he=e=>{let t=e.ownerDocument,n=t.defaultView.getComputedStyle(e),r=T(n),i=k(n),a=e.parentElement;if(a){let e=t.defaultView.getComputedStyle(a);r||=T(e),i||=k(e)}let o=S(e),s={id:crypto.randomUUID(),text:se(e),runs:o.length>0?o:void 0,typography:d(n),fill:r,border:i};return e.colSpan>1&&(s.colspan=e.colSpan),e.rowSpan>1&&(s.rowspan=e.rowSpan),s},ge=e=>{let t=[],n=e.querySelectorAll(`tr`);for(let e of n){let n=[],r=e.querySelectorAll(`th, td`);for(let e of r)n.push(he(e));n.length>0&&t.push(n)}return t},_e=e=>{let t=e.querySelector(`tr`);if(!t)return[];let n=t.querySelectorAll(`th, td`);if(n.length===0)return[];let r=[];for(let e of n){let t=e.getBoundingClientRect().width;r.push(t)}return r},A={name:`core:table`,handles:[`table`],onParse:(e,t)=>{let{boundingRect:n,slideElement:r}=t,i=e,a=r.getBoundingClientRect(),o=ge(i);if(o.length===0)return null;let s=i.querySelector(`thead`)!==null,c=i.querySelector(`th`)!==null,l=_e(i);return{type:`table`,id:crypto.randomUUID(),position:g(n,a),dimensions:_(n),rows:o,colWidths:l.length>0?l:void 0,headerRow:s||c}}},ve=e=>{if(!e||typeof e!=`object`)return`unknown`;let t=e;return Array.isArray(t.data)&&t.data.length>0&&t.data[0]&&typeof t.data[0]==`object`&&`type`in t.data[0]?`plotly`:`unknown`},ye=e=>{let t=new Map;return e.querySelectorAll(`script[type="application/json"][data-chart-id]`).forEach(n=>{let r=n.getAttribute(`data-chart-id`),i=n.getAttribute(`data-chart-type`);if(!(!r||!i)&&e.getElementById(r))try{let e=JSON.parse(n.textContent||`{}`),a=e;if(!(Array.isArray(a.data)&&a.data.length>0&&a.data[0]&&typeof a.data[0]==`object`&&`type`in a.data[0]))return;let o=ve(e),s=a.data[0].type;t.set(r,{chartId:r,chartType:s||i,config:e,sourceLibrary:o})}catch{return}}),t},j=e=>Array.isArray(e)?e.map(e=>e==null?``:String(e)):[],M=e=>Array.isArray(e)?e.map(e=>{let t=Number(e);return isNaN(t)?0:t}):[],be=e=>{for(let t of e){if(t.labels&&Array.isArray(t.labels))return j(t.labels);if(t.orientation===`h`&&t.y&&Array.isArray(t.y))return j(t.y);if(t.x&&Array.isArray(t.x))return j(t.x)}return[]},xe=e=>{if(e.marker?.color&&typeof e.marker.color==`string`)return e.marker.color;if(e.line?.color&&typeof e.line.color==`string`)return e.line.color},Se=e=>{if(e.marker?.colors&&Array.isArray(e.marker.colors))return e.marker.colors;if(e.marker?.color&&Array.isArray(e.marker.color))return e.marker.color},Ce=e=>{if(e.title){if(typeof e.title==`string`)return e.title;if(typeof e.title==`object`&&e.title.text)return e.title.text}},we=e=>{if(e.title){if(typeof e.title==`string`)return 11;if(typeof e.title==`object`&&e.title.font)return e.title.font.size}},N=e=>{if(!(!e||!e.title)){if(typeof e.title==`string`)return e.title;if(typeof e.title==`object`&&e.title.text)return e.title.text}},Te=e=>{let t=e.data||[],n=e.layout||{};if(t.length===0)throw Error(`No traces found in config.data`);let r=t[0],i=U[(r?.type||`bar`).toLowerCase()]||`bar`,a=be(t),o=t.map(e=>{let t={name:e.name||`Series`,values:[],color:xe(e),colors:Se(e)},n=e.type||`bar`;return t.chartType=U[n.toLowerCase()]||n,e.values?t.values=M(e.values):e.orientation===`h`&&e.x?t.values=M(e.x):e.y&&(t.values=M(e.y)),e.yaxis===`y2`?t.yAxis=`y2`:e.yaxis===`y3`&&(t.yAxis=`y3`),t}),s={title:Ce(n),titleFontSize:we(n),showLegend:n.showlegend!==!1,xAxisTitle:N(n.xaxis),yAxisTitle:N(n.yaxis),margin:n.margin};return n.yaxis2&&(s.hasSecondaryAxis=!0,s.yAxis2Title=N(n.yaxis2)),(t.some(e=>e.text&&Array.isArray(e.text)&&e.text.length>0)||r.textinfo)&&(s.showDataLabels=!0),i===`bar`&&(s.orientation=r.orientation===`h`?`horizontal`:`vertical`,n.barmode===`stack`?(s.barGrouping=`stacked`,s.barmode=`stack`):n.barmode===`group`?(s.barGrouping=`clustered`,s.barmode=`group`):n.barmode===`relative`&&(s.barGrouping=`percentStacked`,s.barmode=`relative`),r.textposition&&(s.dataLabelPosition=r.textposition)),i===`pie`&&(r.hole!==void 0&&(s.hole=r.hole),r.textinfo&&(s.dataLabelFormat=r.textinfo),r.textposition&&(s.dataLabelPosition=r.textposition)),n.font&&(s.font={family:n.font.family,size:n.font.size}),{chartType:i,series:o,labels:a,options:s}},P={name:`core:chart-plotly`,handles:[`chart`],beforeParse:(e,t,n)=>{let r=ye(new DOMParser().parseFromString(e,`text/html`));if(r.size===0)return e;let i={extractedCharts:r,chartBoundsMap:new Map};return n.state.set(P.name,i),e},onParse:(e,t,n)=>{let r=n.state.get(P.name);if(!r||r.extractedCharts.size===0)return null;let i=e.ownerDocument,{slideIndex:a,slideElement:o}=t,s=o.getBoundingClientRect();return r.extractedCharts.forEach((e,t)=>{if(r.chartBoundsMap.has(t))return;let n=i.getElementById(t);if(!n||!o.contains(n))return;let c=n.getBoundingClientRect();r.chartBoundsMap.set(t,{left:c.left-s.left,top:c.top-s.top,width:c.width,height:c.height,slideIndex:a})}),null},onSlide:(e,t)=>{let n=t.state.get(P.name);if(!n||n.extractedCharts.size===0||n.chartBoundsMap.size===0)return e;let{extractedCharts:r,chartBoundsMap:i}=n,a=new Set,o=[];r.forEach((t,n)=>{let r=i.get(n);if(!r||r.slideIndex!==e.order)return;let s=-1,c=1/0;if(e.elements.forEach((e,t)=>{if(e.type!==`image`||a.has(t))return;let n=Math.sqrt((e.position.left-r.left)**2+(e.position.top-r.top)**2);n<c&&(c=n,s=t)}),s!==-1){let n;try{if(t.sourceLibrary===`plotly`)n=Te(t.config);else return}catch{return}let i=e.elements[s],c=i.position.left,l=i.position.top,u=c+i.dimensions.width,d=l+i.dimensions.height;e.elements.forEach((e,t)=>{if(e.type!==`image`)return;let n=e,r=n.position.left,i=n.position.top,o=r+n.dimensions.width,s=i+n.dimensions.height;r>=c&&i>=l&&o<=u&&s<=d&&a.add(t)});let f={type:`chart`,originalType:`image`,id:crypto.randomUUID(),position:{left:r.left,top:r.top},dimensions:{width:r.width,height:r.height},data:n,sourceLibrary:t.sourceLibrary};o.push(f)}});let s=e.elements.filter((e,t)=>!a.has(t));return{...e,elements:[...s,...o]}}},Ee=e=>{let t=e.tagName.toLowerCase();if(t===`img`)return e.src||``;if(t===`svg`){let t=new XMLSerializer().serializeToString(e);return`data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(t)))}`}if(t===`picture`){let t=e.querySelector(`img`);if(t)return t.src||``}return``},De=e=>{let t=e.tagName.toLowerCase();if(t===`img`)return e.alt||void 0;if(t===`svg`){let t=e.querySelector(`title`);if(t)return t.textContent||void 0}},F={name:`core:image`,handles:[`image`],onParse:(e,t)=>{let{computedStyle:n,boundingRect:r,slideElement:i}=t,a=i.getBoundingClientRect(),o=Ee(e);return o?{type:`image`,id:crypto.randomUUID(),src:o,alt:De(e),position:g(r,a),dimensions:_(r),zIndex:h(n),rotation:p(n),opacity:m(n)}:null}},I=new Map,L=new Map,Oe=e=>e.includes(`fab`)||e.includes(`fa-brands`)?`brands`:e.includes(`far`)||e.includes(`fa-regular`)?`regular`:`solid`,ke=e=>e.find(e=>e.startsWith(`fa-`)&&e!==`fa`)||null,Ae=async(e,t)=>{let n=e.replace(`fa-`,``),r=Ie[n]||n,i=r===n?[n]:[r,n],a=t===`solid`?[`solid`]:[t,`solid`];for(let e of i)for(let t of a){let n=[`https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.0.0/svgs/${t}/${e}.svg`,`https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@7.0.0/svgs/${t}/${e}.svg`];for(let e of n)try{let t=await fetch(e);if(!t.ok)continue;let n=await t.text(),r=new DOMParser().parseFromString(n,`image/svg+xml`).querySelector(`svg`);if(!r)continue;let i=r.getAttribute(`viewBox`)||`0 0 512 512`,a=Array.from(r.querySelectorAll(`path`)).map(e=>e.getAttribute(`d`)).filter(Boolean).join(` `);if(!a)continue;return{viewBox:i,path:a}}catch{continue}}return null},je=async(e,t)=>{let n=`${t}:${e}`;if(I.has(n))return I.get(n);if(L.has(n))return L.get(n);let r=Ae(e,t).then(e=>(e&&I.set(n,e),e)).finally(()=>{L.delete(n)});return L.set(n,r),r},Me=(e,t)=>{let n=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="${e.viewBox}"><path fill="#${t}" d="${e.path}"/></svg>`;return`data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(n)))}`},R={name:`core:icon-fontawesome`,handles:[`icon`],onParse:async(e,t)=>{let{computedStyle:n,boundingRect:r,slideElement:i}=t,a=Array.from(e.classList),s=ke(a);if(!s)return null;let c=await je(s,Oe(a));if(!c)return null;let l=Me(c,o(n.color)||`000000`),u=i.getBoundingClientRect();return{type:`image`,originalType:`icon`,id:crypto.randomUUID(),src:l,alt:s,position:g(r,u),dimensions:_(r),zIndex:h(n),rotation:p(n),opacity:m(n)}}},Ne={reset:`\x1B[0m`,red:`\x1B[31m`,green:`\x1B[32m`,yellow:`\x1B[33m`,dim:`\x1B[2m`},z={SLIDE_SELECTOR:`.slide`,SLIDE_WIDTH:992,SLIDE_HEIGHT:558,FONT_FAMILY:``,CHART_FONT_SIZE:9},B={DPI:96,PPTX_PIXELS_TO_INCHES:73.7,RADIUS_MULTIPLIER:.75},V={solid:`solid`,dashed:`dash`,dotted:`sysDot`},Pe={100:`Thin`,200:`ExtraLight`,300:`Light`,400:``,500:`Medium`,600:`SemiBold`,700:`Bold`,800:`ExtraBold`,900:`Black`},H=[C,E,D,A,F,R,P],Fe=1.03,U={pie:`pie`,bar:`bar`,line:`line`,scatter:`scatter`,area:`area`,doughnut:`doughnut`,radar:`radar`,bubble:`bubble`},W={pie:`pie`,bar:`bar`,line:`line`,scatter:`line`,area:`area`,doughnut:`doughnut`,radar:`radar`,bubble:`bubble`},Ie={"check-circle":`circle-check`,"times-circle":`circle-xmark`,"exclamation-circle":`circle-exclamation`,"exclamation-triangle":`triangle-exclamation`,"shield-alt":`shield`,search:`magnifying-glass`,times:`xmark`,bars:`bars`,cog:`gear`,trash:`trash-can`,edit:`pen-to-square`,"external-link-alt":`arrow-up-right-from-square`,"arrow-alt-circle-down":`circle-down`,"arrow-alt-circle-up":`circle-up`,"arrow-alt-circle-left":`circle-left`,"arrow-alt-circle-right":`circle-right`,"sign-in-alt":`right-to-bracket`,"sign-out-alt":`right-from-bracket`,percentage:`percent`};var G=class{config;pluginManager;presentation=null;source=null;parser;serializer;constructor(e){i(e.parser,`Parser strategy is required`),i(e.serializer,`Serializer strategy is required`),this.config={...e,selector:e.selector||`.slide`,dimensions:e.dimensions||{width:z.SLIDE_WIDTH,height:z.SLIDE_HEIGHT}},this.parser=e.parser,this.serializer=e.serializer,this.pluginManager=new t,this.serializer.setPluginManager&&this.serializer.setPluginManager(this.pluginManager);let n=e.plugins?.core??[],r=e.plugins?.extensions??[];n.forEach(e=>this.use(e)),r.forEach(e=>this.use(e))}use(e){return this.pluginManager.register(e),this}load(e){return typeof e==`string`?this.source=e:this.source=e.content,this}async convert(){i(this.source,`No HTML source loaded. Call load() first.`),this.config.debug&&console.group(`[html-in-pptx-out] convert`);let e={selector:this.config.selector,dimensions:this.config.dimensions},t=await this.pluginManager.executeBeforeParse(this.source,e),{elements:n,cleanup:r}=await this.parser.parse(t,e);this.config.debug&&console.log(`before: executeOnParse`,{elements:n});let a=new Map;for(let{slideIndex:e,element:t,parseContext:r}of n){let n=await this.pluginManager.executeOnParse(t,r);n&&(a.has(e)||a.set(e,[]),a.get(e).push(n))}this.config.debug&&console.log(`after: executeOnParse`,{slides:a}),r();let o=[],s=Array.from(a.keys()).sort((e,t)=>e-t);for(let e of s){let t={id:crypto.randomUUID(),order:e,elements:a.get(e)||[]};o.push(t)}this.presentation={slides:o,metadata:{createdAt:new Date,plugins:this.pluginManager.getPlugins().map(e=>e.name)},viewport:this.config.dimensions};for(let e=0;e<this.presentation.slides.length;e++)this.presentation.slides[e]=await this.pluginManager.executeOnSlide(this.presentation.slides[e]);return this.pluginManager.setPresentation(this.presentation),this.config.debug&&(console.log(`after: executeOnSlide`,{presentation:this.presentation}),console.groupEnd()),this}async export(e){return i(this.presentation,`No presentation to export. Call convert() first.`),await this.serializer.serialize(this.presentation,e)}async exportImages(e){throw Error(`Not implemented`)}getPresentation(){return i(this.presentation,`No presentation available. Call convert() first.`),this.presentation}};const Le=(e,t)=>new Promise((n,r)=>{let i=document.createElement(`iframe`);i.style.position=`fixed`,i.style.left=`-9999px`,i.style.top=`-9999px`,i.style.width=`${t.width}px`,i.style.height=`${t.height}px`,i.style.opacity=`0`,i.style.pointerEvents=`none`,i.style.zIndex=`-1`,i.setAttribute(`aria-hidden`,`true`);let a=()=>{i.removeEventListener(`load`,a);let e=i.contentDocument;if(!e){r(Error(`Failed to access iframe document`));return}let t=()=>{e.readyState===`complete`?requestAnimationFrame(()=>n(i)):setTimeout(t,10)};t()};i.addEventListener(`load`,a),i.onerror=()=>r(Error(`Failed to load iframe`)),i.srcdoc=e,document.body.appendChild(i)}),Re=e=>{e.remove()};var K=class{async parse(e,t){let n=await Le(e,t.dimensions),r=n.contentDocument.querySelectorAll(t.selector),i=[];for(let e=0;e<r.length;e++){let t=r[e],a=t.querySelectorAll(`*`),o=[t,...Array.from(a)],s=new Set;for(let r of o){let a=!1,o=r.parentElement;for(;o&&o!==t;){if(s.has(o)){a=!0;break}o=o.parentElement}if(a)continue;let c=ne(r,n.contentWindow);if(c.length===0)continue;let l=n.contentWindow.getComputedStyle(r),u=r.getBoundingClientRect(),d=r.tagName.toLowerCase();for(let n of c){(n===`table`||n===`text`)&&s.add(r);let a={elementType:n,tagName:d,computedStyle:l,boundingRect:u,slideIndex:e,slideElement:t};i.push({slideIndex:e,element:r,parseContext:a})}}}return{elements:i,cleanup:()=>Re(n)}}};const q=e=>e/B.DPI,J=e=>e/B.DPI*72,Y=(e,t)=>{let n=e.left/t.width*100,r=e.top/t.height*100;return{x:`${n}%`,y:`${r}%`}},X=(e,t)=>{let n=e.width/t.width*100,r=e.height/t.height*100;return{w:`${n}%`,h:`${r}%`}},ze=e=>({x:q(e.left),y:q(e.top)}),Be=e=>({w:q(e.width),h:q(e.height)}),Z=e=>{let t={};return e.fontFamily&&(t.fontFace=e.fontFamily.split(`,`)[0].trim()),e.fontSize&&(t.fontSize=J(e.fontSize)),e.color&&(t.color=e.color.toUpperCase()),e.fontWeight&&(parseInt(e.fontWeight,10)||400)>400&&(t.bold=!0),(e.fontStyle===`italic`||e.fontStyle===`oblique`)&&(t.italic=!0),e.underline&&(t.underline={style:`sng`}),e.strikethrough&&(t.strike=`sngStrike`),t},Q=e=>{let t=[];for(let n of e)if(n.children&&n.children.length>0){let e=Q(n.children);for(let r of e){let e={...r.options};if(n.typography){let t=Z(n.typography);Object.assign(e,t,r.options)}n.href&&(e.hyperlink={url:n.href}),t.push({text:r.text,options:e})}}else{let e={};n.typography&&Object.assign(e,Z(n.typography)),n.href&&(e.hyperlink={url:n.href}),t.push({text:n.content,options:e})}return t},Ve=(e,t,n)=>{let r=Y(t.position,n),i=X(t.dimensions,n),a={x:r.x,y:r.y,w:i.w,h:i.h,lineSpacingMultiple:1,valign:`top`,align:`left`,isTextBox:!0,wrap:!0,shrinkText:!1};if(t.typography){let e=t.typography,n=Z(e);Object.assign(a,n),e.textAlign&&(a.align=e.textAlign),e.verticalAlign&&(a.valign=e.verticalAlign),e.letterSpacing&&(a.charSpacing=e.letterSpacing)}if(t.padding&&(a.margin=[J(t.padding.top),J(t.padding.right),J(t.padding.bottom),J(t.padding.left)]),t.rotation&&(a.rotate=t.rotation),t.opacity!==void 0&&t.opacity<1&&(a.transparency=Math.round((1-t.opacity)*100)),t.runs&&t.runs.length>0){let n=Q(t.runs);e.addText(n,a)}else e.addText(t.content,a)},He=e=>e,Ue=e=>V[e.style]||`solid`,We=(t,n,r)=>{let i=Y(n.position,r),a=X(n.dimensions,r),o=He(n.shapeType)||e.ShapeType.rect,s={x:i.x,y:i.y,w:a.w,h:a.h};if(n.fill){let e={};if(n.fill.type===`solid`)e.color=n.fill.color.toUpperCase(),n.fill.opacity!==void 0&&n.fill.opacity<1&&(e.transparency=Math.round((1-n.fill.opacity)*100));else if(n.fill.type===`gradient`){let t=n.fill.stops[0];t&&(e.color=t.color.toUpperCase(),t.opacity!==void 0&&t.opacity<1&&(e.transparency=Math.round((1-t.opacity)*100)))}e.color&&(s.fill=e)}if(n.stroke){let e={color:n.stroke.color.toUpperCase(),width:n.stroke.width,dashType:Ue(n.stroke)};n.stroke.opacity!==void 0&&(e.transparency=Math.round((1-n.stroke.opacity)*100)),s.line=e}if(n.rotation&&(s.rotate=n.rotation),n.borderRadius&&n.shapeType===`roundRect`){let e=Math.min(n.dimensions.width,n.dimensions.height);s.rectRadius=Math.min(n.borderRadius/e,1)*B.RADIUS_MULTIPLIER}if(n.shadow){let e=n.shadow.offset.x,t=n.shadow.offset.y,r=Math.sqrt(e**2+t**2),i=(Math.atan2(t,e)*180/Math.PI%360+360)%360;s.shadow={type:n.shadow.type,color:n.shadow.color.toUpperCase(),blur:J(n.shadow.blur),offset:J(r),angle:i,opacity:n.shadow.opacity??1}}t.addShape(o,s)},Ge=e=>V[e.style]||`solid`,Ke=(e,t,n)=>{let r=t.start.left/n.width*100,i=t.start.top/n.height*100,a=t.end.left/n.width*100,o=t.end.top/n.height*100,s=Math.abs(a-r),c=Math.abs(o-i),l={color:t.stroke.color.toUpperCase(),width:t.stroke.width,dashType:Ge(t.stroke)};t.stroke.opacity!==void 0&&(l.transparency=Math.round((1-t.stroke.opacity)*100));let u={x:`${Math.min(r,a)}%`,y:`${Math.min(i,o)}%`,w:`${s||.1}%`,h:`${c||.1}%`,line:l},d=t.end.left<t.start.left,f=t.end.top<t.start.top;d&&(u.flipH=!0),f&&(u.flipV=!0),e.addShape(`line`,u)},qe=(e,t,n)=>{let r=Y(t.position,n),i=X(t.dimensions,n),a={x:r.x,y:r.y,w:i.w,h:i.h};t.src.startsWith(`data:`)?a.data=t.src:a.path=t.src,t.alt&&(a.altText=t.alt),t.rotation&&(a.rotate=t.rotation),t.opacity!==void 0&&t.opacity<1&&(a.transparency=Math.round((1-t.opacity)*100)),t.fit&&(a.sizing={type:{contain:`contain`,cover:`cover`,stretch:`crop`}[t.fit]||`contain`,w:t.dimensions.width,h:t.dimensions.height}),e.addImage(a)},Je=(e,t)=>{let n=e.split(`,`)[0].trim();if(!t)return n;let r=Pe[parseInt(t,10)||400];return!r||r===``?n:`${n} ${r}`},Ye=(e,t,n)=>{let r=Y(t.position,n),i=X(t.dimensions,n),a=t.rows.map(e=>e.map(e=>{let t={text:e.runs&&e.runs.length>0?Q(e.runs):e.text};if(e.colspan&&(t.options={...t.options,colspan:e.colspan}),e.rowspan&&(t.options={...t.options,rowspan:e.rowspan}),e.typography){let n=e.typography,r=n.fontWeight&&parseInt(n.fontWeight,10)||400;t.options={...t.options,fontFace:n.fontFamily?Je(n.fontFamily,n.fontWeight):void 0,fontSize:n.fontSize?J(n.fontSize):void 0,color:n.color?n.color.toUpperCase():void 0,bold:r>400,italic:n.fontStyle===`italic`||n.fontStyle===`oblique`,underline:n.underline?{style:`sng`}:void 0,align:n.textAlign,valign:n.verticalAlign}}if(e.fill){if(e.fill.type===`solid`){let n={color:e.fill.color.toUpperCase()};e.fill.opacity!==void 0&&e.fill.opacity<1&&(n.transparency=Math.round((1-e.fill.opacity)*100)),t.options={...t.options,fill:n}}else if(e.fill.type===`gradient`){let n=e.fill.stops[0];n&&(t.options={...t.options,fill:{color:n.color.toUpperCase()}})}}if(e.border){let n=[`top`,`right`,`bottom`,`left`],r=[];for(let t of n){let n=e.border[t];if(n){let e=`solid`;(n.style===`dashed`||n.style===`dotted`)&&(e=`dash`),r.push({color:n.color.toUpperCase(),pt:n.width,type:e})}else r.push({type:`none`})}let i=r;t.options={...t.options,border:i}}return t})),o={x:r.x,y:r.y,w:i.w,h:i.h};t.colWidths&&t.colWidths.length>0&&(o.colW=t.colWidths.map(e=>q(e))),t.cellMinHeight&&(o.rowH=J(t.cellMinHeight)/72),t.headerRow&&(o.autoPageHeaderRows=1),e.addTable(a,o)},Xe=e=>{for(let t of e)if(!(!t.values||!Array.isArray(t.values))){for(let e of t.values)if(typeof e==`number`&&!Number.isInteger(e)){let e=0;for(let n of t.values)if(typeof n==`number`&&!Number.isInteger(n)){let t=n.toString().split(`.`)[1]?.length||0;e=Math.max(e,Math.min(t,2))}return e===1?`#,##0.0`:`#,##0.00`}}return`#,##0`},Ze=e=>W[e]||`bar`,$=e=>{let t=e.data.chartType;return t===`pie`&&e.data.options?.hole!==void 0&&e.data.options.hole>0?`doughnut`:W[t]||`bar`},Qe=e=>{let t=ze(e.position),n=Be(e.dimensions),r=e.data,i={type:r.chartType,series:r.series,labels:r.labels,options:r.options},a=i.series.map(e=>({name:e.name,labels:i.labels,values:e.values,color:o(e.color||``)})),s={x:t.x,y:t.y,w:n.w,h:n.h,title:i.options?.title,showTitle:!!i.options?.title,titleFontSize:i.options?.titleFontSize||z.CHART_FONT_SIZE,showLegend:i.options?.showLegend!==!1,legendPos:`t`,legendFontSize:z.CHART_FONT_SIZE,showLabel:i.options?.showDataLabels===!0,dataLabelFontSize:z.CHART_FONT_SIZE};if(i.options?.showDataLabels===!0)if(i.type===`bar`){s.showValue=!0;let e=Xe(i.series);e&&(s.dataLabelFormatCode=e)}else i.type===`pie`&&(s.showPercent=!0);i.type===`pie`&&(s.dataLabelPosition=`outEnd`);let c=[];if(i.series.some(e=>e.colors&&e.colors.length>0)){let e=i.series.find(e=>e.colors&&e.colors.length>0);e?.colors&&c.push(...e.colors)}else i.series.forEach(e=>{e.color&&c.push(e.color)});if(c.length>0&&(s.chartColors=c.map(e=>o(e)).filter(e=>e!==void 0)),i.options?.xAxisTitle&&(s.catAxisTitle=i.options.xAxisTitle,s.showCatAxisTitle=!0,s.catAxisTitleFontSize=z.CHART_FONT_SIZE),i.options?.yAxisTitle&&(s.valAxisTitle=i.options.yAxisTitle,s.showValAxisTitle=!0,s.valAxisTitleFontSize=z.CHART_FONT_SIZE),s.catAxisLabelFontSize=z.CHART_FONT_SIZE,s.valAxisLabelFontSize=z.CHART_FONT_SIZE,s.catGridLine={style:`none`},s.valGridLine={style:`solid`,size:1,color:`D9D9D9`},i.options?.hole!==void 0&&i.options.hole>0&&(s.holeSize=Math.round(i.options.hole*100)),i.options?.orientation===`horizontal`?s.barDir=`bar`:(i.options?.orientation===`vertical`||i.type===`bar`)&&(s.barDir=`col`),i.options?.barGrouping&&(s.barGrouping=i.options.barGrouping),i.options?.hasSecondaryAxis){let t=new Map,n=new Map;if(i.series.forEach((e,r)=>{let o=e.chartType||i.type,s=a[r];e.yAxis===`y2`?(n.has(o)||n.set(o,[]),n.get(o).push(s)):(t.has(o)||t.set(o,[]),t.get(o).push(s))}),n.size===0)return{data:a,options:s,chartTypeKey:$(e)};let r=[];return t.forEach((e,t)=>{r.push({typeKey:Ze(t),data:e,options:{}})}),n.forEach((e,t)=>{let n=t===`line`||t===`area`;r.push({typeKey:Ze(t),data:e,options:{secondaryValAxis:!0,secondaryCatAxis:!0,...n?{showValue:!0,dataLabelPosition:`t`}:{}}})}),{data:null,options:{x:s.x,y:s.y,w:s.w,h:s.h,title:s.title,showTitle:s.showTitle,titleFontSize:s.titleFontSize,showLegend:s.showLegend,legendPos:`t`,legendFontSize:z.CHART_FONT_SIZE,chartColors:s.chartColors,dataLabelFormatCode:s.dataLabelFormatCode,dataLabelFontSize:z.CHART_FONT_SIZE,valAxes:[{valAxisTitle:i.options.yAxisTitle||``,showValAxisTitle:!!i.options.yAxisTitle,valAxisTitleFontSize:z.CHART_FONT_SIZE,valAxisLabelFontSize:z.CHART_FONT_SIZE,valGridLine:{style:`solid`,size:1,color:`D9D9D9`}},{valAxisTitle:i.options.yAxis2Title||``,showValAxisTitle:!1,valAxisTitleFontSize:z.CHART_FONT_SIZE,valAxisLabelFontSize:z.CHART_FONT_SIZE,valGridLine:{style:`none`}}],catAxes:[{catAxisTitle:i.options.xAxisTitle||``,showCatAxisTitle:!!i.options.xAxisTitle,catAxisTitleFontSize:z.CHART_FONT_SIZE,catAxisLabelFontSize:z.CHART_FONT_SIZE,catGridLine:{style:`none`}},{catAxisLabelFontSize:z.CHART_FONT_SIZE,catAxisHidden:!0,catGridLine:{style:`none`}}]},chartTypesForCombo:r,chartTypeKey:$(e)}}return{data:a,options:s,chartTypeKey:$(e)}},$e=(e,t)=>{let{data:n,options:r,chartTypesForCombo:i,chartTypeKey:a}=Qe(t);if(t.data.options?.hasSecondaryAxis&&i){let t=i.map(e=>({type:e.typeKey,data:e.data,options:e.options||{}}));e.addChart(t,r)}else{let t=a;if(!t||!n)return;e.addChart(t,n,r)}};var et=class{pluginManager=null;setPluginManager(e){this.pluginManager=e}async serialize(t,n){r(t.slides.length>0,`No slides to export. Check selector or create a slide to export`);let i=new e,a=q(t.viewport.width),o=q(t.viewport.height);i.defineLayout({name:`custom`,width:a,height:o}),i.layout=`custom`,t.metadata.title&&(i.title=t.metadata.title),t.metadata.author&&(i.author=t.metadata.author),t.metadata.subject&&(i.subject=t.metadata.subject);for(let e of t.slides){let n=i.addSlide();for(let r of e.elements)switch(r.type){case`text`:Ve(n,r,t.viewport);break;case`image`:qe(n,r,t.viewport);break;case`shape`:We(n,r,t.viewport);break;case`table`:Ye(n,r,t.viewport);break;case`chart`:$e(n,r);break;case`line`:Ke(n,r,t.viewport);break}}return this.pluginManager&&await this.pluginManager.executeAfterGenerate(i,t),await i.write({outputType:`arraybuffer`})}},tt=class extends G{constructor(e={}){super({selector:e.selector||z.SLIDE_SELECTOR,dimensions:e.dimensions||{width:z.SLIDE_WIDTH,height:z.SLIDE_HEIGHT},plugins:{core:e.plugins?.core??H,extensions:e.plugins?.extensions??[]},parser:e.parser||new K,serializer:e.serializer||new et,debug:e.debug})}};export{Ne as a,R as c,A as d,D as f,G as i,F as l,C as m,et as n,z as o,E as p,K as r,H as s,tt as t,P as u};
5
- //# sourceMappingURL=converter-DzUDHivU.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"converter-DzUDHivU.mjs","names":["types: ElementType[]","runs: TextRun[]","run: TextRun","textPlugin: Plugin<TextElementDTO>","stops: GradientStop[]","strokeStyle: \"solid\" | \"dashed\" | \"dotted\"","opacity: number | undefined","shapePlugin: Plugin<ShapeElementDTO>","strokeStyle: \"solid\" | \"dashed\" | \"dotted\"","opacity: number | undefined","linePlugin: Plugin<LineElementDTO>","stroke: Stroke","start: Position","end: Position","strokeStyle: \"solid\" | \"dashed\" | \"dotted\"","border: Border","cellDTO: TableCellDTO","rows: TableCellDTO[][]","cells: TableCellDTO[]","widths: number[]","tablePlugin: Plugin<TableElementDTO>","series: ChartSeries[]","seriesData: ChartSeries","options: ChartOptions","plotlyPlugin: Plugin","state: ChartPluginState","chartElements: ChartElementDTO[]","chartDataDTO: ChartData","chartElement: ChartElementDTO","imagePlugin: Plugin<ImageElementDTO>","fontAwesomePlugin: Plugin<ImageElementDTO>","STROKE_DASH_MAP: Record<\n string,\n | \"solid\"\n | \"dash\"\n | \"dashDot\"\n | \"lgDash\"\n | \"lgDashDot\"\n | \"lgDashDotDot\"\n | \"sysDash\"\n | \"sysDot\"\n>","FONT_WEIGHT_SUFFIX_MAP: Record<number, string>","DEFAULT_CORE_PLUGINS: Plugin[]","CHART_TYPE_MAP: Record<string, string>","PPTX_CHART_TYPE_MAP: Record<string, string>","FA5_TO_FA6_NAMES: Record<string, string>","slides: SlideDTO[]","slide: SlideDTO","elements: ParserElement[]","parseContext: ParseContext","props: PptxGenJS.TextPropsOptions","result: Array<{ text: string; options: PptxGenJS.TextPropsOptions }>","options: PptxGenJS.TextPropsOptions","textOptions: PptxGenJS.TextPropsOptions","getStrokeDashType","shapeType: PptxGenJS.ShapeType","shapeOptions: PptxGenJS.ShapeProps","fillProps: PptxGenJS.ShapeFillProps","lineProps: PptxGenJS.ShapeLineProps","lineProps: PptxGenJS.ShapeLineProps","lineOptions: PptxGenJS.ShapeProps","imageOptions: PptxGenJS.ImageProps","rows: PptxGenJS.TableRow[]","cellProps: PptxGenJS.TableCell","fillOptions: { color: string; transparency?: number }","borderArray: PptxGenJS.BorderProps[]","borderType: \"solid\" | \"dash\" | \"none\"","tableOptions: PptxGenJS.TableProps","data: ChartSeries[]","options: PptxGenJS.IChartOpts","allColors: string[]","chartTypesForCombo: ComboChartType[]"],"sources":["../src/lib/plugin-manager.ts","../src/utils/assert.ts","../src/utils/sanitize.ts","../src/lib/extractors/typography.ts","../src/lib/extractors/position.ts","../src/lib/extractors/classifier.ts","../src/lib/extractors/text.ts","../src/plugins/core/text.plugin.ts","../src/lib/extractors/color.ts","../src/lib/extractors/shape.ts","../src/plugins/core/shape.plugin.ts","../src/plugins/core/line.plugin.ts","../src/lib/extractors/stroke.ts","../src/plugins/core/table.plugin.ts","../src/lib/extractors/plotly.ts","../src/plugins/core/plotly.plugin.ts","../src/plugins/core/image.plugin.ts","../src/lib/extractors/fontawesome.ts","../src/plugins/core/fontawesome.plugin.ts","../src/constants.ts","../src/core/base-converter.ts","../src/lib/iframe-renderer.ts","../src/parsers/iframe.ts","../src/utils/units.ts","../src/serializers/elements/text.serializer.ts","../src/serializers/elements/shape.serializer.ts","../src/serializers/elements/line.serializer.ts","../src/serializers/elements/image.serializer.ts","../src/serializers/elements/table.serializer.ts","../src/serializers/elements/plotly.serializer.ts","../src/serializers/pptxgenjs.ts","../src/core/converter.ts"],"sourcesContent":["import type {\n Plugin,\n PluginManagerInterface,\n PluginContext,\n ParseContext,\n} from \"@/types/plugin.types\";\nimport type { SlideDTO, PresentationDTO } from \"@/types/presentation.types\";\nimport type { ParserConfig } from \"@/types/config.types\";\nimport type { ElementDTO } from \"@/types/elements.types\";\nimport type PptxGenJS from \"pptxgenjs\";\n\nexport class PluginManager implements PluginManagerInterface {\n private plugins: Plugin[] = [];\n private context: PluginContext = {\n presentation: undefined,\n metadata: {},\n state: new Map(),\n };\n\n register(plugin: Plugin): void {\n if (this.plugins.some((p) => p.name === plugin.name)) {\n throw new Error(`Plugin \"${plugin.name}\" is already registered`);\n }\n this.plugins.push(plugin);\n }\n\n unregister(name: string): void {\n const index = this.plugins.findIndex((p) => p.name === name);\n if (index !== -1) {\n this.plugins.splice(index, 1);\n }\n }\n\n getPlugins(): Plugin[] {\n return [...this.plugins];\n }\n\n setPresentation(presentation: PresentationDTO): void {\n this.context.presentation = presentation;\n }\n\n async executeBeforeParse(\n html: string,\n config: ParserConfig,\n ): Promise<string> {\n let result = html;\n\n for (const plugin of this.plugins) {\n if (plugin.beforeParse) {\n result = await plugin.beforeParse(result, config, this.context);\n }\n }\n\n return result;\n }\n\n async executeOnParse(\n element: HTMLElement,\n parseContext: ParseContext,\n ): Promise<ElementDTO | null> {\n for (const plugin of this.plugins) {\n if (!plugin.handles || !plugin.onParse) continue;\n\n const handlers = new Set(plugin.handles);\n if (!handlers.has(parseContext.elementType)) continue;\n\n const result = await plugin.onParse(element, parseContext, this.context);\n if (result) return result;\n }\n\n return null;\n }\n\n async executeOnSlide(slide: SlideDTO): Promise<SlideDTO> {\n let result = slide;\n\n for (const plugin of this.plugins) {\n if (plugin.onSlide) {\n result = await plugin.onSlide(result, this.context);\n }\n }\n\n return result;\n }\n\n async executeAfterGenerate(\n pptx: PptxGenJS,\n presentation: PresentationDTO,\n ): Promise<void> {\n for (const plugin of this.plugins) {\n if (plugin.afterGenerate) {\n await plugin.afterGenerate(pptx, presentation, this.context);\n }\n }\n }\n}\n","export class AssertionError extends Error {\n constructor(message: string) {\n super(`Assertion failed: ${message}`);\n this.name = 'AssertionError';\n }\n}\n\nexport function assert(condition: unknown, message: string): asserts condition {\n if (!condition) {\n throw new AssertionError(message);\n }\n}\n\nexport function assertNonNull<T>(\n value: T | null | undefined,\n message: string\n): asserts value is T {\n if (value === null || value === undefined) {\n throw new AssertionError(message);\n }\n}\n","export const sanitizeFontFamily = (fontFamily: string): string => {\n const fonts = fontFamily.split(\",\").map((font) => {\n const f = font\n .trim()\n .replace(/^[\"']|[\"']$/g, \"\")\n .trim();\n\n return f;\n });\n return fonts.filter((font) => font != null).join(\", \");\n};\n\nexport const sanitizeColor = (color: string): string => {\n if (!color || color === \"transparent\") return \"\";\n\n const cleaned = color.trim().replace(/^#/, \"\");\n\n if (/^[0-9a-fA-F]{3}$/.test(cleaned)) {\n return (\n cleaned[0] +\n cleaned[0] +\n cleaned[1] +\n cleaned[1] +\n cleaned[2] +\n cleaned[2]\n );\n }\n\n if (/^[0-9a-fA-F]{6}$/.test(cleaned)) {\n return cleaned;\n }\n\n const rgbMatch = color.match(/rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)/);\n if (rgbMatch) {\n const [, r, g, b] = rgbMatch;\n return [r, g, b]\n .map((v) => parseInt(v, 10).toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n return \"\";\n};\n","import type { Typography, Padding } from \"@/types/base.types\";\nimport { sanitizeFontFamily, sanitizeColor } from \"@/utils/sanitize\";\nimport { DEFAULTS } from \"@/constants\";\n\nexport const parseFontWeight = (value: string): string | undefined => {\n const num = parseInt(value, 10);\n if (!isNaN(num)) return String(num);\n if (value === \"bold\") return \"700\";\n if (value === \"bolder\") return \"700\";\n if (value === \"lighter\") return \"300\";\n if (value === \"normal\") return \"400\";\n return undefined;\n};\n\nexport const parseFontStyle = (\n value: string,\n): Typography[\"fontStyle\"] | undefined => {\n if (value === \"italic\") return \"italic\";\n if (value === \"oblique\") return \"oblique\";\n if (value === \"normal\") return \"normal\";\n return undefined;\n};\n\nexport const parseTextAlign = (\n value: string,\n): Typography[\"textAlign\"] | undefined => {\n if (value === \"left\" || value === \"start\") return \"left\";\n if (value === \"center\") return \"center\";\n if (value === \"right\" || value === \"end\") return \"right\";\n if (value === \"justify\") return \"justify\";\n return undefined;\n};\n\nexport const parseVerticalAlign = (\n value: string,\n): Typography[\"verticalAlign\"] | undefined => {\n if (value === \"top\") return \"top\";\n if (value === \"middle\") return \"middle\";\n if (value === \"bottom\") return \"bottom\";\n return undefined;\n};\n\nexport const extractTypography = (style: CSSStyleDeclaration): Typography => {\n const typography: Typography = {\n fontFamily: sanitizeFontFamily(style.fontFamily) || DEFAULTS.FONT_FAMILY,\n fontSize: parseFloat(style.fontSize) || undefined,\n fontWeight: parseFontWeight(style.fontWeight),\n fontStyle: parseFontStyle(style.fontStyle),\n letterSpacing: parseFloat(style.letterSpacing) || undefined,\n lineHeight: parseFloat(style.lineHeight) || undefined,\n color: sanitizeColor(style.color) || undefined,\n underline: style.textDecorationLine?.includes(\"underline\") || false,\n strikethrough: style.textDecorationLine?.includes(\"line-through\") || false,\n textAlign: parseTextAlign(style.textAlign),\n verticalAlign: parseVerticalAlign(style.verticalAlign),\n };\n\n return typography;\n};\n\nexport const extractPadding = (style: CSSStyleDeclaration): Padding => ({\n top: parseFloat(style.paddingTop) || 0,\n right: parseFloat(style.paddingRight) || 0,\n bottom: parseFloat(style.paddingBottom) || 0,\n left: parseFloat(style.paddingLeft) || 0,\n});\n\nexport const extractRotation = (\n style: CSSStyleDeclaration,\n): number | undefined => {\n const transform = style.transform;\n if (!transform || transform === \"none\") return undefined;\n\n const rotateMatch = transform.match(/rotate\\(([-\\d.]+)/);\n if (rotateMatch) {\n const deg = parseFloat(rotateMatch[1]);\n return deg || undefined;\n }\n\n const matrixMatch = transform.match(/matrix\\(([^)]+)\\)/);\n if (matrixMatch) {\n const values = matrixMatch[1].split(\",\").map((v) => parseFloat(v.trim()));\n if (values.length >= 2) {\n const a = values[0];\n const b = values[1];\n const radians = Math.atan2(b, a);\n const degrees = radians * (180 / Math.PI);\n return Math.abs(degrees) < 0.01 ? undefined : degrees;\n }\n }\n\n return undefined;\n};\n\nexport const extractOpacity = (\n style: CSSStyleDeclaration,\n): number | undefined => {\n const opacity = parseFloat(style.opacity);\n return opacity === 1 ? undefined : opacity || undefined;\n};\n\nexport const extractZIndex = (\n style: CSSStyleDeclaration,\n): number | undefined => {\n return parseInt(style.zIndex, 10) || undefined;\n};\n","import type { Position, Dimensions } from \"@/types/base.types\";\n\nexport const extractRelativePosition = (\n elementRect: DOMRect,\n containerRect: DOMRect,\n): Position => ({\n left: elementRect.left - containerRect.left,\n top: elementRect.top - containerRect.top,\n});\n\nexport const extractDimensions = (\n rect: DOMRect,\n buffer: number = 1,\n): Dimensions => ({\n width: rect.width * buffer,\n height: rect.height,\n});\n","import type { ElementType } from \"@/types/base.types\";\n\nconst TEXT_TAGS = new Set([\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"p\",\n \"span\",\n \"div\",\n \"a\",\n \"li\",\n \"label\",\n \"strong\",\n \"em\",\n \"b\",\n // \"i\",\n \"u\",\n \"s\",\n \"small\",\n \"mark\",\n]);\n\nconst IMAGE_TAGS = new Set([\"img\", \"picture\", \"svg\"]);\nconst TABLE_TAGS = new Set([\"table\"]);\nconst TABLE_INTERNAL_TAGS = new Set([\n \"td\",\n \"th\",\n \"tr\",\n \"thead\",\n \"tbody\",\n \"tfoot\",\n \"caption\",\n \"colgroup\",\n \"col\",\n]);\n\nexport const classifyElement = (\n element: HTMLElement,\n win: Window = window,\n): ElementType[] => {\n const types: ElementType[] = [];\n const tagName = element.tagName.toLowerCase();\n\n if (TABLE_TAGS.has(tagName)) {\n types.push(\"table\");\n return types;\n }\n\n if (TABLE_INTERNAL_TAGS.has(tagName)) {\n return types;\n }\n\n if (element.id.toLowerCase().includes(\"chart\")) {\n types.push(\"chart\");\n }\n\n if (IMAGE_TAGS.has(tagName)) {\n types.push(\"image\");\n return types;\n }\n\n if (tagName === \"hr\") {\n types.push(\"line\");\n return types;\n }\n\n if (classifyIcon(element)) {\n types.push(\"icon\");\n return types;\n }\n\n const style = win.getComputedStyle(element);\n\n const hasVisualStyling = classifyVisualElement(style);\n if (hasVisualStyling) {\n types.push(\"shape\");\n }\n\n const singleBorderSide = hasSingleBorderSide(style);\n if (singleBorderSide) {\n types.push(\"line\");\n }\n\n if (TEXT_TAGS.has(tagName) && hasDirectTextNode(element)) {\n types.push(\"text\");\n }\n\n return types;\n};\n\nconst classifyVisualElement = (style: CSSStyleDeclaration): boolean => {\n const hasBackgroundColor =\n style.backgroundColor !== \"transparent\" &&\n style.backgroundColor !== \"rgba(0, 0, 0, 0)\";\n\n const hasBackgroundImage =\n style.backgroundImage !== \"none\" && style.backgroundImage !== \"\";\n\n const hasBorder =\n parseFloat(style.borderWidth) > 0 &&\n style.borderColor !== \"transparent\" &&\n style.borderColor !== \"rgba(0, 0, 0, 0)\";\n\n const hasShadow = style.boxShadow !== \"none\" && style.boxShadow !== \"\";\n\n const hasBorderRadius = parseFloat(style.borderRadius) > 0;\n\n return (\n hasBackgroundColor ||\n hasBackgroundImage ||\n hasBorder ||\n hasShadow ||\n hasBorderRadius\n );\n};\n\nexport const classifyText = (\n tagName: string,\n): \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"p\" | \"body\" | null => {\n const tag = tagName.toLowerCase();\n if (!TEXT_TAGS.has(tagName)) return null;\n if (/^h[1-6]$/.test(tag))\n return tag as \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\";\n if (tag === \"p\") return \"p\";\n return \"body\";\n};\n\nexport const classifyShape = (\n style: CSSStyleDeclaration,\n boundingRect: DOMRect,\n): \"rect\" | \"ellipse\" | \"roundRect\" => {\n const borderRadius = parseFloat(style.borderRadius) || 0;\n const { width, height } = boundingRect;\n\n const minDimension = Math.min(width, height);\n const maxRadius = minDimension / 2;\n\n if (borderRadius >= maxRadius * 0.9) {\n if (Math.abs(width - height) < 2) {\n return \"ellipse\";\n }\n }\n\n if (borderRadius > 0) {\n return \"roundRect\";\n }\n\n return \"rect\";\n};\n\nconst hasDirectTextNode = (element: HTMLElement): boolean => {\n for (const node of element.childNodes) {\n if (node.nodeType === Node.TEXT_NODE) {\n if (node.textContent && node.textContent.trim().length > 0) {\n return true;\n }\n }\n }\n return false;\n};\n\nexport const hasSingleBorderSide = (\n style: CSSStyleDeclaration,\n): \"left\" | \"right\" | \"top\" | \"bottom\" | null => {\n const leftWidth = parseFloat(style.borderLeftWidth) || 0;\n const rightWidth = parseFloat(style.borderRightWidth) || 0;\n const topWidth = parseFloat(style.borderTopWidth) || 0;\n const bottomWidth = parseFloat(style.borderBottomWidth) || 0;\n\n const sides = [\n { side: \"left\" as const, width: leftWidth },\n { side: \"right\" as const, width: rightWidth },\n { side: \"top\" as const, width: topWidth },\n { side: \"bottom\" as const, width: bottomWidth },\n ];\n\n const activeSides = sides.filter((s) => s.width > 0);\n\n if (activeSides.length === 1) {\n return activeSides[0].side;\n }\n\n return null;\n};\n\nexport const classifyIcon = (element: HTMLElement): boolean => {\n if (element.tagName.toLowerCase() !== \"i\") return false;\n\n const classList = Array.from(element.classList);\n return classList.some((cls) => cls.startsWith(\"fa-\") && cls !== \"fa\");\n};\n","import type { TextRun } from \"@/types/elements.types\";\nimport { extractTypography } from \"./typography\";\nimport { classifyText } from \"./classifier\";\n\nexport const extractRuns = (node: Node): TextRun[] => {\n const runs: TextRun[] = [];\n\n for (const child of node.childNodes) {\n if (child.nodeType === Node.TEXT_NODE) {\n const text = child.textContent?.replace(/\\s+/g, \" \") || \"\";\n if (text.trim().length > 0) {\n runs.push({ content: text });\n }\n }\n\n if (child.nodeType === Node.ELEMENT_NODE) {\n const el = child as HTMLElement;\n const tagName = el.tagName.toLowerCase();\n\n if (tagName === \"br\") {\n runs.push({ content: \"\\n\" });\n continue;\n }\n\n const className = el.className || \"\";\n const doc = el.ownerDocument;\n const style = doc.defaultView!.getComputedStyle(el);\n\n const childRuns = extractRuns(el);\n const textType = classifyText(tagName);\n if (!textType) continue;\n\n const run: TextRun = {\n content: el.textContent || \"\",\n tagName: tagName,\n className: className,\n typography: extractTypography(style),\n children: childRuns.length > 0 ? childRuns : undefined,\n };\n\n if (tagName === \"a\") {\n run.href = el.getAttribute(\"href\") || undefined;\n }\n\n runs.push(run);\n }\n }\n\n return runs;\n};\n\nexport const extractTextContent = (node: Node): string => {\n let text = \"\";\n\n const processNode = (n: Node): void => {\n if (n.nodeType === Node.TEXT_NODE) {\n text += n.textContent || \"\";\n return;\n }\n\n if (n.nodeType === Node.ELEMENT_NODE) {\n const el = n as HTMLElement;\n const tagName = el.tagName.toLowerCase();\n\n if (tagName === \"br\") {\n text += \"\\n\";\n return;\n }\n\n for (const child of n.childNodes) {\n processNode(child);\n }\n\n if (tagName === \"p\" || tagName === \"div\") {\n if (n.nextSibling) {\n text += \"\\n\";\n }\n }\n }\n };\n\n for (const child of node.childNodes) {\n processNode(child);\n }\n\n return text.trim();\n};\n","import type { Plugin } from \"@/types/plugin.types\";\nimport type { TextElementDTO } from \"@/types/elements.types\";\nimport {\n extractTypography,\n extractPadding,\n extractRotation,\n extractOpacity,\n extractZIndex,\n} from \"@/lib/extractors/typography\";\nimport {\n extractRelativePosition,\n extractDimensions,\n} from \"@/lib/extractors/position\";\nimport { classifyText, classifyIcon } from \"@/lib/extractors/classifier\";\nimport { extractRuns } from \"@/lib/extractors/text\";\nimport { COORDINATE_BUFFER } from \"@/constants\";\n\nconst adjustBoundsForInlineIcons = (\n element: HTMLElement,\n rect: DOMRect,\n): DOMRect => {\n const iconElements = element.querySelectorAll<HTMLElement>(\"i\");\n let iconOffset = 0;\n\n for (const icon of iconElements) {\n if (classifyIcon(icon)) {\n const iconRect = icon.getBoundingClientRect();\n const width = iconRect.width;\n\n const style = icon.ownerDocument.defaultView!.getComputedStyle(icon);\n const marginRight = parseFloat(style.marginRight) || 0;\n\n iconOffset += width + marginRight;\n }\n }\n\n return new DOMRect(\n rect.left + iconOffset,\n rect.top,\n rect.width - iconOffset,\n rect.height,\n );\n};\n\nexport const textPlugin: Plugin<TextElementDTO> = {\n name: \"core:text\",\n handles: [\"text\"],\n onParse: (element, parseContext) => {\n const { computedStyle, boundingRect, tagName, slideElement } = parseContext;\n\n const content = element.textContent?.trim();\n if (!content) return null;\n\n const textType = classifyText(tagName);\n if (!textType) return null;\n\n const slideRect = slideElement.getBoundingClientRect();\n\n const adjustedRect = adjustBoundsForInlineIcons(element, boundingRect);\n\n const position = extractRelativePosition(adjustedRect, slideRect);\n const dimensions = extractDimensions(adjustedRect, COORDINATE_BUFFER);\n\n const runs = extractRuns(element);\n\n const textElement: TextElementDTO = {\n type: \"text\",\n id: crypto.randomUUID(),\n content,\n runs: runs.length > 0 ? runs : undefined,\n position: position,\n dimensions: dimensions,\n typography: extractTypography(computedStyle),\n textType,\n padding: extractPadding(computedStyle),\n zIndex: extractZIndex(computedStyle),\n rotation: extractRotation(computedStyle),\n opacity: extractOpacity(computedStyle),\n };\n\n return textElement;\n },\n};\n","import { sanitizeColor } from \"@/utils/sanitize\";\n\nexport const parseColorOpacity = (rgba: string): number | undefined => {\n const rgbaMatch = rgba.match(\n /rgba\\(\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*([\\d.]+)\\s*\\)/,\n );\n\n if (rgbaMatch) {\n const opacity = parseFloat(rgbaMatch[1]);\n if (opacity < 1) {\n return opacity;\n }\n }\n\n return undefined;\n};\n\nexport const parseHex = (hex: string): string | undefined => {\n return sanitizeColor(hex) || undefined;\n};\n\nexport const transformBgColorToSolidFill = (\n bgColor: string,\n): { color: string; opacity?: number } | undefined => {\n if (!bgColor || bgColor === \"transparent\" || bgColor === \"rgba(0, 0, 0, 0)\") {\n return undefined;\n }\n\n const hex = sanitizeColor(bgColor);\n if (!hex) return undefined;\n\n const opacity = parseColorOpacity(bgColor);\n\n return {\n color: hex,\n opacity: opacity,\n };\n};\n","import type {\n Fill,\n Stroke,\n Shadow,\n SolidFill,\n GradientFill,\n GradientStop,\n} from \"@/types/base.types\";\nimport { sanitizeColor } from \"@/utils/sanitize\";\nimport { parseColorOpacity } from \"@/lib/extractors/color\";\n\nconst parseGradientStops = (rgba: string): GradientStop[] => {\n const stops: GradientStop[] = [];\n const colorStopRegex = /(rgba?\\([^)]+\\)|#[0-9a-fA-F]{3,6}|\\w+)\\s*([\\d.]+%)?/g;\n let match;\n let index = 0;\n\n while ((match = colorStopRegex.exec(rgba)) !== null) {\n const [, colorPart, positionPart] = match;\n const hex = sanitizeColor(colorPart);\n if (!hex) continue;\n\n let position = 0;\n if (positionPart) {\n position = parseFloat(positionPart) / 100;\n } else {\n position = index === 0 ? 0 : 1;\n }\n\n const opacity = parseColorOpacity(colorPart);\n stops.push({ color: hex, position, opacity });\n index++;\n }\n\n return stops;\n};\n\nconst parseGradientAngle = (gradient: string): number => {\n const degMatch = gradient.match(/(\\d+)deg/);\n if (degMatch) {\n return parseInt(degMatch[1], 10);\n }\n\n const directionMap: Record<string, number> = {\n \"to top\": 0,\n \"to right\": 90,\n \"to bottom\": 180,\n \"to left\": 270,\n \"to top right\": 45,\n \"to bottom right\": 135,\n \"to bottom left\": 225,\n \"to top left\": 315,\n };\n\n for (const [direction, angle] of Object.entries(directionMap)) {\n if (gradient.includes(direction)) {\n return angle;\n }\n }\n\n return 180;\n};\n\nexport const extractFill = (style: CSSStyleDeclaration): Fill | undefined => {\n const bgImage = style.backgroundImage;\n\n if (bgImage && bgImage !== \"none\") {\n if (bgImage.includes(\"linear-gradient\")) {\n const stops = parseGradientStops(bgImage);\n if (stops.length >= 2) {\n const gradient: GradientFill = {\n type: \"gradient\",\n gradientType: \"linear\",\n angle: parseGradientAngle(bgImage),\n stops,\n };\n return gradient;\n }\n }\n\n if (bgImage.includes(\"radial-gradient\")) {\n const stops = parseGradientStops(bgImage);\n if (stops.length >= 2) {\n const gradient: GradientFill = {\n type: \"gradient\",\n gradientType: \"radial\",\n stops,\n };\n return gradient;\n }\n }\n }\n\n const bgColor = style.backgroundColor;\n if (!bgColor || bgColor === \"transparent\" || bgColor === \"rgba(0, 0, 0, 0)\") {\n return undefined;\n }\n\n const hex = sanitizeColor(bgColor);\n if (!hex) return undefined;\n\n const opacity = parseColorOpacity(bgColor);\n\n const fill: SolidFill = {\n type: \"solid\",\n color: hex,\n opacity: opacity,\n };\n\n return fill;\n};\n\nexport const extractStroke = (\n style: CSSStyleDeclaration,\n): Stroke | undefined => {\n const borderWidth = parseFloat(style.borderWidth) || 0;\n if (borderWidth === 0) return undefined;\n\n const borderColor = style.borderColor;\n const hex = sanitizeColor(borderColor);\n if (!hex) return undefined;\n\n const borderStyle = style.borderStyle;\n let strokeStyle: \"solid\" | \"dashed\" | \"dotted\" = \"solid\";\n if (borderStyle === \"dashed\") strokeStyle = \"dashed\";\n else if (borderStyle === \"dotted\") strokeStyle = \"dotted\";\n\n let opacity: number | undefined;\n const opacityMatch = borderColor.match(/rgba?\\([^)]+,\\s*([\\d.]+)\\)/);\n if (opacityMatch) {\n const extractedOpacity = parseFloat(opacityMatch[1]);\n if (extractedOpacity < 1) {\n opacity = extractedOpacity;\n }\n }\n\n return {\n color: hex,\n width: borderWidth,\n style: strokeStyle,\n opacity: opacity,\n };\n};\n\nexport const extractBorderRadius = (\n style: CSSStyleDeclaration,\n): number | undefined => {\n const radius = parseFloat(style.borderRadius) || 0;\n if (radius === 0) return undefined;\n return radius;\n};\n\nexport const extractShadow = (\n style: CSSStyleDeclaration,\n): Shadow | undefined => {\n const boxShadow = style.boxShadow;\n if (!boxShadow || boxShadow === \"none\") return undefined;\n\n const insetMatch = boxShadow.includes(\"inset\");\n const shadowType: \"outer\" | \"inner\" = insetMatch ? \"inner\" : \"outer\";\n\n const cleanShadow = boxShadow.replace(\"inset\", \"\").trim();\n\n const rgbaMatch = cleanShadow.match(\n /rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*([\\d.]+))?\\)/,\n );\n let color = \"000000\";\n let opacity = 1;\n\n if (rgbaMatch) {\n const [, r, g, b, a] = rgbaMatch;\n color = [r, g, b]\n .map((v) => parseInt(v, 10).toString(16).padStart(2, \"0\"))\n .join(\"\");\n if (a) opacity = parseFloat(a);\n }\n\n const valuesMatch = cleanShadow.match(\n /(?:rgba?\\([^)]+\\)|#[0-9a-fA-F]+|\\w+)\\s+(-?[\\d.]+)px\\s+(-?[\\d.]+)px\\s+([\\d.]+)px/,\n );\n\n if (!valuesMatch) return undefined;\n\n const [, offsetX, offsetY, blur] = valuesMatch;\n\n return {\n type: shadowType,\n color,\n blur: parseFloat(blur),\n offset: {\n x: parseFloat(offsetX),\n y: parseFloat(offsetY),\n },\n opacity: opacity < 1 ? opacity : undefined,\n };\n};\n","import type { Plugin } from \"@/types/plugin.types\";\nimport type { ShapeElementDTO } from \"@/types/elements.types\";\nimport {\n extractFill,\n extractStroke,\n extractBorderRadius,\n} from \"@/lib/extractors/shape\";\nimport {\n extractRotation,\n extractOpacity,\n extractZIndex,\n} from \"@/lib/extractors/typography\";\nimport {\n extractRelativePosition,\n extractDimensions,\n} from \"@/lib/extractors/position\";\nimport { classifyShape } from \"@/lib/extractors/classifier\";\n\nexport const shapePlugin: Plugin<ShapeElementDTO> = {\n name: \"core:shape\",\n handles: [\"shape\"],\n onParse: (_element, parseContext) => {\n const { computedStyle, boundingRect, slideElement } = parseContext;\n\n const slideRect = slideElement.getBoundingClientRect();\n\n const shapeElement: ShapeElementDTO = {\n type: \"shape\",\n id: crypto.randomUUID(),\n shapeType: classifyShape(computedStyle, boundingRect),\n position: extractRelativePosition(boundingRect, slideRect),\n dimensions: extractDimensions(boundingRect),\n fill: extractFill(computedStyle),\n stroke: extractStroke(computedStyle),\n borderRadius: extractBorderRadius(computedStyle),\n zIndex: extractZIndex(computedStyle),\n rotation: extractRotation(computedStyle),\n opacity: extractOpacity(computedStyle),\n };\n\n return shapeElement;\n },\n};\n","import type { Plugin } from \"@/types/plugin.types\";\nimport type { LineElementDTO } from \"@/types/elements.types\";\nimport type { Position, Stroke } from \"@/types/base.types\";\nimport {\n extractRotation,\n extractOpacity,\n extractZIndex,\n} from \"@/lib/extractors/typography\";\nimport { hasSingleBorderSide } from \"@/lib/extractors/classifier\";\nimport { sanitizeColor } from \"@/utils/sanitize\";\n\nconst extractLineStroke = (\n style: CSSStyleDeclaration,\n side: \"left\" | \"right\" | \"top\" | \"bottom\",\n): Stroke => {\n let width = 1;\n let borderColor = \"rgb(0,0,0)\";\n let borderStyle = \"solid\";\n\n if (side === \"left\") {\n width = parseFloat(style.borderLeftWidth) || 1;\n borderColor = style.borderLeftColor || \"rgb(0,0,0)\";\n borderStyle = style.borderLeftStyle || \"solid\";\n } else if (side === \"right\") {\n width = parseFloat(style.borderRightWidth) || 1;\n borderColor = style.borderRightColor || \"rgb(0,0,0)\";\n borderStyle = style.borderRightStyle || \"solid\";\n } else if (side === \"top\") {\n width = parseFloat(style.borderTopWidth) || 1;\n borderColor = style.borderTopColor || \"rgb(0,0,0)\";\n borderStyle = style.borderTopStyle || \"solid\";\n } else {\n width = parseFloat(style.borderBottomWidth) || 1;\n borderColor = style.borderBottomColor || \"rgb(0,0,0)\";\n borderStyle = style.borderBottomStyle || \"solid\";\n }\n\n const hex = sanitizeColor(borderColor) || \"000000\";\n\n let strokeStyle: \"solid\" | \"dashed\" | \"dotted\" = \"solid\";\n if (borderStyle === \"dashed\") strokeStyle = \"dashed\";\n else if (borderStyle === \"dotted\") strokeStyle = \"dotted\";\n\n let opacity: number | undefined;\n const rgbaMatch = borderColor.match(\n /rgba\\(\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*([\\d.]+)\\s*\\)/,\n );\n if (rgbaMatch) {\n const extractedOpacity = parseFloat(rgbaMatch[1]);\n if (extractedOpacity < 1) {\n opacity = extractedOpacity;\n }\n }\n\n return {\n color: hex,\n width: width,\n style: strokeStyle,\n opacity: opacity,\n };\n};\n\nconst calculateLinePositions = (\n boundingRect: DOMRect,\n slideRect: DOMRect,\n side: \"left\" | \"right\" | \"top\" | \"bottom\",\n): { start: Position; end: Position } => {\n const relLeft = boundingRect.left - slideRect.left;\n const relTop = boundingRect.top - slideRect.top;\n const relRight = relLeft + boundingRect.width;\n const relBottom = relTop + boundingRect.height;\n\n if (side === \"left\") {\n return {\n start: { left: relLeft, top: relTop },\n end: { left: relLeft, top: relBottom },\n };\n }\n\n if (side === \"right\") {\n return {\n start: { left: relRight, top: relTop },\n end: { left: relRight, top: relBottom },\n };\n }\n\n if (side === \"top\") {\n return {\n start: { left: relLeft, top: relTop },\n end: { left: relRight, top: relTop },\n };\n }\n\n return {\n start: { left: relLeft, top: relBottom },\n end: { left: relRight, top: relBottom },\n };\n};\n\nexport const linePlugin: Plugin<LineElementDTO> = {\n name: \"core:line\",\n handles: [\"line\"],\n onParse: (_element, parseContext) => {\n const { computedStyle, boundingRect, tagName, slideElement } = parseContext;\n\n const slideRect = slideElement.getBoundingClientRect();\n\n let stroke: Stroke;\n let start: Position;\n let end: Position;\n\n if (tagName === \"hr\") {\n const relLeft = boundingRect.left - slideRect.left;\n const relTop = boundingRect.top - slideRect.top;\n const relRight = relLeft + boundingRect.width;\n\n start = { left: relLeft, top: relTop };\n end = { left: relRight, top: relTop };\n\n const borderWidth = parseFloat(computedStyle.borderTopWidth) || 1;\n const borderColor = computedStyle.borderTopColor || \"rgb(0,0,0)\";\n const hex = sanitizeColor(borderColor) || \"000000\";\n\n stroke = {\n color: hex,\n width: borderWidth,\n style: \"solid\",\n };\n } else {\n const side = hasSingleBorderSide(computedStyle);\n if (!side) return null;\n\n const positions = calculateLinePositions(boundingRect, slideRect, side);\n start = positions.start;\n end = positions.end;\n stroke = extractLineStroke(computedStyle, side);\n }\n\n const lineElement: LineElementDTO = {\n type: \"line\",\n id: crypto.randomUUID(),\n start: start,\n end: end,\n stroke: stroke,\n zIndex: extractZIndex(computedStyle),\n rotation: extractRotation(computedStyle),\n opacity: extractOpacity(computedStyle),\n };\n\n return lineElement;\n },\n};\n","import type { Stroke } from \"@/types/base.types\";\nimport { sanitizeColor } from \"@/utils/sanitize\";\nimport { parseColorOpacity } from \"./color\";\n\nexport const extractStrokeFromBorder = (\n color: string,\n width: number,\n borderStyle: string,\n): Stroke | undefined => {\n if (width === 0) return undefined;\n\n const hex = sanitizeColor(color);\n if (!hex) return undefined;\n\n let strokeStyle: \"solid\" | \"dashed\" | \"dotted\" = \"solid\";\n if (borderStyle === \"dashed\") strokeStyle = \"dashed\";\n else if (borderStyle === \"dotted\") strokeStyle = \"dotted\";\n\n const opacity = parseColorOpacity(color);\n\n return {\n color: hex,\n width: width,\n style: strokeStyle,\n opacity: opacity,\n };\n};\n","import type { Plugin } from \"@/types/plugin.types\";\nimport type { TableElementDTO, TableCellDTO } from \"@/types/elements.types\";\nimport type { Border } from \"@/types/base.types\";\nimport { extractTypography } from \"@/lib/extractors/typography\";\nimport {\n extractRelativePosition,\n extractDimensions,\n} from \"@/lib/extractors/position\";\nimport { extractStrokeFromBorder } from \"@/lib/extractors/stroke\";\nimport { extractFill } from \"@/lib/extractors/shape\";\nimport { extractTextContent, extractRuns } from \"@/lib/extractors/text\";\n\nconst extractCellBorder = (style: CSSStyleDeclaration): Border | undefined => {\n const topWidth = parseFloat(style.borderTopWidth) || 0;\n const rightWidth = parseFloat(style.borderRightWidth) || 0;\n const bottomWidth = parseFloat(style.borderBottomWidth) || 0;\n const leftWidth = parseFloat(style.borderLeftWidth) || 0;\n\n const hasBorder =\n topWidth > 0 || rightWidth > 0 || bottomWidth > 0 || leftWidth > 0;\n if (!hasBorder) return undefined;\n\n const border: Border = {};\n\n if (topWidth > 0) {\n border.top = extractStrokeFromBorder(\n style.borderTopColor,\n topWidth,\n style.borderTopStyle,\n );\n }\n\n if (rightWidth > 0) {\n border.right = extractStrokeFromBorder(\n style.borderRightColor,\n rightWidth,\n style.borderRightStyle,\n );\n }\n\n if (bottomWidth > 0) {\n border.bottom = extractStrokeFromBorder(\n style.borderBottomColor,\n bottomWidth,\n style.borderBottomStyle,\n );\n }\n\n if (leftWidth > 0) {\n border.left = extractStrokeFromBorder(\n style.borderLeftColor,\n leftWidth,\n style.borderLeftStyle,\n );\n }\n\n return border;\n};\n\nconst parseTableCell = (cell: HTMLTableCellElement): TableCellDTO => {\n const doc = cell.ownerDocument;\n const style = doc.defaultView!.getComputedStyle(cell);\n\n let fill = extractFill(style);\n let border = extractCellBorder(style);\n\n const row = cell.parentElement;\n if (row) {\n const rowStyle = doc.defaultView!.getComputedStyle(row);\n if (!fill) {\n fill = extractFill(rowStyle);\n }\n if (!border) {\n border = extractCellBorder(rowStyle);\n }\n }\n\n const runs = extractRuns(cell);\n const cellDTO: TableCellDTO = {\n id: crypto.randomUUID(),\n text: extractTextContent(cell),\n runs: runs.length > 0 ? runs : undefined,\n typography: extractTypography(style),\n fill: fill,\n border: border,\n };\n\n if (cell.colSpan > 1) {\n cellDTO.colspan = cell.colSpan;\n }\n\n if (cell.rowSpan > 1) {\n cellDTO.rowspan = cell.rowSpan;\n }\n\n return cellDTO;\n};\n\nconst parseTableRows = (table: HTMLTableElement): TableCellDTO[][] => {\n const rows: TableCellDTO[][] = [];\n const tableRows = table.querySelectorAll(\"tr\");\n\n for (const row of tableRows) {\n const cells: TableCellDTO[] = [];\n const tableCells = row.querySelectorAll<HTMLTableCellElement>(\"th, td\");\n\n for (const cell of tableCells) {\n cells.push(parseTableCell(cell));\n }\n\n if (cells.length > 0) {\n rows.push(cells);\n }\n }\n\n return rows;\n};\n\nconst extractColumnWidths = (table: HTMLTableElement): number[] => {\n const firstRow = table.querySelector(\"tr\");\n if (!firstRow) return [];\n\n const cells = firstRow.querySelectorAll<HTMLTableCellElement>(\"th, td\");\n if (cells.length === 0) return [];\n\n const widths: number[] = [];\n\n for (const cell of cells) {\n const cellWidth = cell.getBoundingClientRect().width;\n widths.push(cellWidth);\n }\n\n return widths;\n};\n\nexport const tablePlugin: Plugin<TableElementDTO> = {\n name: \"core:table\",\n handles: [\"table\"],\n onParse: (element, parseContext) => {\n const { boundingRect, slideElement } = parseContext;\n\n const table = element as HTMLTableElement;\n const slideRect = slideElement.getBoundingClientRect();\n\n const rows = parseTableRows(table);\n if (rows.length === 0) return null;\n\n const hasHeader = table.querySelector(\"thead\") !== null;\n const firstRowHasHeader = table.querySelector(\"th\") !== null;\n const colWidths = extractColumnWidths(table);\n\n const tableElement: TableElementDTO = {\n type: \"table\",\n id: crypto.randomUUID(),\n position: extractRelativePosition(boundingRect, slideRect),\n dimensions: extractDimensions(boundingRect),\n rows: rows,\n colWidths: colWidths.length > 0 ? colWidths : undefined,\n headerRow: hasHeader || firstRowHasHeader,\n };\n\n return tableElement;\n },\n};\n","import type {\n ExtractedChart,\n SourceLibrary,\n ChartData,\n ChartSeries,\n ChartOptions,\n} from \"@/types/plotly.types\";\nimport { CHART_TYPE_MAP } from \"@/constants\";\n\nexport const detectSourceLibrary = (config: unknown): SourceLibrary => {\n if (!config || typeof config !== \"object\") {\n return \"unknown\";\n }\n\n const configObj = config as Record<string, unknown>;\n\n const hasStandardPlotly = Boolean(\n Array.isArray(configObj.data) &&\n configObj.data.length > 0 &&\n configObj.data[0] &&\n typeof configObj.data[0] === \"object\" &&\n \"type\" in (configObj.data[0] as object),\n );\n\n if (hasStandardPlotly) {\n return \"plotly\";\n }\n\n return \"unknown\";\n};\n\nexport const extractChartsFromHTML = (\n doc: Document,\n): Map<string, ExtractedChart> => {\n const charts = new Map<string, ExtractedChart>();\n\n const chartScripts = doc.querySelectorAll(\n 'script[type=\"application/json\"][data-chart-id]',\n );\n\n chartScripts.forEach((script) => {\n const chartId = script.getAttribute(\"data-chart-id\");\n const chartType = script.getAttribute(\"data-chart-type\");\n\n if (!chartId || !chartType) {\n return;\n }\n\n const chartDiv = doc.getElementById(chartId);\n if (!chartDiv) {\n return;\n }\n\n try {\n const config = JSON.parse(script.textContent || \"{}\");\n\n const configObj = config as Record<string, unknown>;\n const hasStandardPlotly = Boolean(\n Array.isArray(configObj.data) &&\n configObj.data.length > 0 &&\n configObj.data[0] &&\n typeof configObj.data[0] === \"object\" &&\n \"type\" in (configObj.data[0] as object),\n );\n\n if (!hasStandardPlotly) {\n return;\n }\n\n const sourceLibrary = detectSourceLibrary(config);\n const detectedChartType = (configObj.data as Array<{ type?: string }>)[0]\n .type as string;\n\n charts.set(chartId, {\n chartId,\n chartType: detectedChartType || chartType,\n config,\n sourceLibrary,\n });\n } catch {\n return;\n }\n });\n\n return charts;\n};\n\nconst parseLabels = (labels: unknown[]): string[] => {\n if (!Array.isArray(labels)) return [];\n return labels.map((label) => {\n if (label === null || label === undefined) return \"\";\n return String(label);\n });\n};\n\nconst parseValues = (values: unknown[]): number[] => {\n if (!Array.isArray(values)) return [];\n return values.map((value) => {\n const num = Number(value);\n return isNaN(num) ? 0 : num;\n });\n};\n\ninterface PlotlyTrace {\n type?: string;\n name?: string;\n x?: unknown[];\n y?: unknown[];\n labels?: unknown[];\n values?: unknown[];\n orientation?: string;\n yaxis?: string;\n text?: unknown[];\n textinfo?: string;\n textposition?: string;\n hole?: number;\n marker?: {\n color?: string | string[];\n colors?: string[];\n };\n line?: {\n color?: string;\n };\n}\n\ninterface PlotlyLayout {\n title?: string | { text?: string; font?: { size?: number } };\n showlegend?: boolean;\n barmode?: string;\n xaxis?: { title?: string | { text?: string } };\n yaxis?: { title?: string | { text?: string } };\n yaxis2?: { title?: string | { text?: string } };\n font?: { family?: string; size?: number };\n margin?: { t?: number; b?: number; l?: number; r?: number };\n}\n\ninterface PlotlyConfig {\n data: PlotlyTrace[];\n layout?: PlotlyLayout;\n}\n\nconst extractLabelsFromTraces = (traces: PlotlyTrace[]): string[] => {\n for (const trace of traces) {\n if (trace.labels && Array.isArray(trace.labels)) {\n return parseLabels(trace.labels);\n }\n\n if (trace.orientation === \"h\" && trace.y && Array.isArray(trace.y)) {\n return parseLabels(trace.y);\n }\n\n if (trace.x && Array.isArray(trace.x)) {\n return parseLabels(trace.x);\n }\n }\n return [];\n};\n\nconst extractColor = (trace: PlotlyTrace): string | undefined => {\n if (trace.marker?.color && typeof trace.marker.color === \"string\") {\n return trace.marker.color;\n }\n\n if (trace.line?.color && typeof trace.line.color === \"string\") {\n return trace.line.color;\n }\n\n return undefined;\n};\n\nconst extractColors = (trace: PlotlyTrace): string[] | undefined => {\n if (trace.marker?.colors && Array.isArray(trace.marker.colors)) {\n return trace.marker.colors;\n }\n\n if (trace.marker?.color && Array.isArray(trace.marker.color)) {\n return trace.marker.color;\n }\n\n return undefined;\n};\n\nconst extractTitle = (layout: PlotlyLayout): string | undefined => {\n if (!layout.title) return undefined;\n\n if (typeof layout.title === \"string\") {\n return layout.title;\n }\n\n if (typeof layout.title === \"object\" && layout.title.text) {\n return layout.title.text;\n }\n\n return undefined;\n};\n\nconst extractTitleFontSize = (layout: PlotlyLayout): number | undefined => {\n if (!layout.title) return undefined;\n\n if (typeof layout.title === \"string\") {\n return 11;\n }\n\n if (typeof layout.title === \"object\" && layout.title.font) {\n return layout.title.font.size;\n }\n\n return undefined;\n};\n\nconst extractAxisTitle = (axis: PlotlyLayout[\"xaxis\"]): string | undefined => {\n if (!axis || !axis.title) return undefined;\n\n if (typeof axis.title === \"string\") {\n return axis.title;\n }\n\n if (typeof axis.title === \"object\" && axis.title.text) {\n return axis.title.text;\n }\n\n return undefined;\n};\n\nexport const transformPlotlyToChartData = (config: PlotlyConfig): ChartData => {\n const traces = config.data || [];\n const layout = config.layout || {};\n\n if (traces.length === 0) {\n throw new Error(\"No traces found in config.data\");\n }\n\n const firstTrace = traces[0];\n const plotlyType = firstTrace?.type || \"bar\";\n const chartType = CHART_TYPE_MAP[plotlyType.toLowerCase()] || \"bar\";\n\n const labels = extractLabelsFromTraces(traces);\n\n const series: ChartSeries[] = traces.map((trace) => {\n const seriesData: ChartSeries = {\n name: trace.name || \"Series\",\n values: [],\n color: extractColor(trace),\n colors: extractColors(trace),\n };\n\n const traceType = trace.type || \"bar\";\n seriesData.chartType = CHART_TYPE_MAP[traceType.toLowerCase()] || traceType;\n\n if (trace.values) {\n seriesData.values = parseValues(trace.values);\n } else if (trace.orientation === \"h\" && trace.x) {\n seriesData.values = parseValues(trace.x);\n } else if (trace.y) {\n seriesData.values = parseValues(trace.y);\n }\n\n if (trace.yaxis === \"y2\") {\n seriesData.yAxis = \"y2\";\n } else if (trace.yaxis === \"y3\") {\n seriesData.yAxis = \"y3\";\n }\n\n return seriesData;\n });\n\n const options: ChartOptions = {\n title: extractTitle(layout),\n titleFontSize: extractTitleFontSize(layout),\n showLegend: layout.showlegend !== false,\n xAxisTitle: extractAxisTitle(layout.xaxis),\n yAxisTitle: extractAxisTitle(layout.yaxis),\n margin: layout.margin,\n };\n\n if (layout.yaxis2) {\n options.hasSecondaryAxis = true;\n options.yAxis2Title = extractAxisTitle(layout.yaxis2);\n }\n\n const hasTextLabels = traces.some(\n (trace) => trace.text && Array.isArray(trace.text) && trace.text.length > 0,\n );\n if (hasTextLabels || firstTrace.textinfo) {\n options.showDataLabels = true;\n }\n\n if (chartType === \"bar\") {\n options.orientation =\n firstTrace.orientation === \"h\" ? \"horizontal\" : \"vertical\";\n\n if (layout.barmode === \"stack\") {\n options.barGrouping = \"stacked\";\n options.barmode = \"stack\";\n } else if (layout.barmode === \"group\") {\n options.barGrouping = \"clustered\";\n options.barmode = \"group\";\n } else if (layout.barmode === \"relative\") {\n options.barGrouping = \"percentStacked\";\n options.barmode = \"relative\";\n }\n\n if (firstTrace.textposition) {\n options.dataLabelPosition = firstTrace.textposition;\n }\n }\n\n if (chartType === \"pie\") {\n if (firstTrace.hole !== undefined) {\n options.hole = firstTrace.hole;\n }\n\n if (firstTrace.textinfo) {\n options.dataLabelFormat = firstTrace.textinfo;\n }\n\n if (firstTrace.textposition) {\n options.dataLabelPosition = firstTrace.textposition;\n }\n }\n\n if (layout.font) {\n options.font = {\n family: layout.font.family,\n size: layout.font.size,\n };\n }\n\n return {\n chartType,\n series,\n labels,\n options,\n };\n};\n","import type { Plugin } from \"@/types/plugin.types\";\nimport type { ChartData, ExtractedChart } from \"@/types/plotly.types\";\nimport {\n extractChartsFromHTML,\n transformPlotlyToChartData,\n} from \"@/lib/extractors/plotly\";\nimport { ChartElementDTO, ImageElementDTO } from \"@/types/elements.types\";\n\ninterface ChartBounds {\n left: number;\n top: number;\n width: number;\n height: number;\n slideIndex: number;\n}\n\ninterface ChartPluginState {\n extractedCharts: Map<string, ExtractedChart>;\n chartBoundsMap: Map<string, ChartBounds>;\n}\n\nexport const plotlyPlugin: Plugin = {\n name: \"core:chart-plotly\",\n handles: [\"chart\"],\n beforeParse: (html, _config, context) => {\n const parser = new DOMParser();\n const doc = parser.parseFromString(html, \"text/html\");\n\n const extractedCharts = extractChartsFromHTML(doc);\n\n if (extractedCharts.size === 0) {\n return html;\n }\n\n const state: ChartPluginState = {\n extractedCharts,\n chartBoundsMap: new Map(),\n };\n\n context.state.set(plotlyPlugin.name, state);\n\n return html;\n },\n\n onParse: (element, parseContext, pluginContext) => {\n const state = pluginContext.state.get(plotlyPlugin.name) as\n | ChartPluginState\n | undefined;\n\n if (!state || state.extractedCharts.size === 0) return null;\n\n const doc = element.ownerDocument;\n const { slideIndex, slideElement } = parseContext;\n const slideRect = slideElement.getBoundingClientRect();\n\n state.extractedCharts.forEach((_, chartId) => {\n if (state.chartBoundsMap.has(chartId)) return;\n\n const chartDiv = doc.getElementById(chartId);\n if (!chartDiv || !slideElement.contains(chartDiv)) return;\n\n const chartRect = chartDiv.getBoundingClientRect();\n state.chartBoundsMap.set(chartId, {\n left: chartRect.left - slideRect.left,\n top: chartRect.top - slideRect.top,\n width: chartRect.width,\n height: chartRect.height,\n slideIndex,\n });\n });\n\n return null;\n },\n\n onSlide: (slide, context) => {\n const state = context.state.get(plotlyPlugin.name) as\n | ChartPluginState\n | undefined;\n\n if (!state || state.extractedCharts.size === 0) {\n return slide;\n }\n\n if (state.chartBoundsMap.size === 0) {\n return slide;\n }\n\n const { extractedCharts, chartBoundsMap } = state;\n\n const indicesToRemove = new Set<number>();\n const chartElements: ChartElementDTO[] = [];\n\n extractedCharts.forEach((chartData, chartId) => {\n const chartBounds = chartBoundsMap.get(chartId);\n if (!chartBounds || chartBounds.slideIndex !== slide.order) return;\n\n let bestMatchIndex = -1;\n let bestDistance = Infinity;\n\n slide.elements.forEach((el, index) => {\n if (el.type !== \"image\") return;\n if (indicesToRemove.has(index)) return;\n\n const distance = Math.sqrt(\n Math.pow(el.position.left - chartBounds.left, 2) +\n Math.pow(el.position.top - chartBounds.top, 2),\n );\n\n if (distance < bestDistance) {\n bestDistance = distance;\n bestMatchIndex = index;\n }\n });\n\n if (bestMatchIndex !== -1) {\n let chartDataDTO: ChartData;\n try {\n if (chartData.sourceLibrary === \"plotly\") {\n chartDataDTO = transformPlotlyToChartData(\n chartData.config as Parameters<\n typeof transformPlotlyToChartData\n >[0],\n );\n } else {\n return;\n }\n } catch {\n return;\n }\n\n const matchedImage = slide.elements[bestMatchIndex] as ImageElementDTO;\n const matchLeft = matchedImage.position.left;\n const matchTop = matchedImage.position.top;\n const matchRight = matchLeft + matchedImage.dimensions.width;\n const matchBottom = matchTop + matchedImage.dimensions.height;\n\n slide.elements.forEach((el, index) => {\n if (el.type !== \"image\") return;\n\n const img = el as ImageElementDTO;\n const imgLeft = img.position.left;\n const imgTop = img.position.top;\n const imgRight = imgLeft + img.dimensions.width;\n const imgBottom = imgTop + img.dimensions.height;\n\n const isOverlapping =\n imgLeft >= matchLeft &&\n imgTop >= matchTop &&\n imgRight <= matchRight &&\n imgBottom <= matchBottom;\n\n if (isOverlapping) {\n indicesToRemove.add(index);\n }\n });\n\n const chartElement: ChartElementDTO = {\n type: \"chart\",\n originalType: \"image\",\n id: crypto.randomUUID(),\n position: {\n left: chartBounds.left,\n top: chartBounds.top,\n },\n dimensions: {\n width: chartBounds.width,\n height: chartBounds.height,\n },\n data: chartDataDTO,\n sourceLibrary: chartData.sourceLibrary,\n };\n\n chartElements.push(chartElement);\n }\n });\n\n // remove previous elements and will replace with chart element\n const filteredElements = slide.elements.filter(\n (_, index) => !indicesToRemove.has(index),\n );\n\n return {\n ...slide,\n elements: [...filteredElements, ...chartElements],\n };\n },\n};\n","import type { Plugin } from \"@/types/plugin.types\";\nimport type { ImageElementDTO } from \"@/types/elements.types\";\nimport {\n extractRelativePosition,\n extractDimensions,\n} from \"@/lib/extractors/position\";\nimport {\n extractRotation,\n extractOpacity,\n extractZIndex,\n} from \"@/lib/extractors/typography\";\n\nconst extractImageSrc = (element: HTMLElement): string => {\n const tagName = element.tagName.toLowerCase();\n\n if (tagName === \"img\") {\n return (element as HTMLImageElement).src || \"\";\n }\n\n if (tagName === \"svg\") {\n const serializer = new XMLSerializer();\n const svgString = serializer.serializeToString(element);\n const base64 = btoa(unescape(encodeURIComponent(svgString)));\n return `data:image/svg+xml;base64,${base64}`;\n }\n\n if (tagName === \"picture\") {\n const img = element.querySelector(\"img\");\n if (img) {\n return img.src || \"\";\n }\n }\n\n return \"\";\n};\n\nconst extractImageAlt = (element: HTMLElement): string | undefined => {\n const tagName = element.tagName.toLowerCase();\n\n if (tagName === \"img\") {\n return (element as HTMLImageElement).alt || undefined;\n }\n\n if (tagName === \"svg\") {\n const title = element.querySelector(\"title\");\n if (title) {\n return title.textContent || undefined;\n }\n }\n\n return undefined;\n};\n\nexport const imagePlugin: Plugin<ImageElementDTO> = {\n name: \"core:image\",\n handles: [\"image\"],\n onParse: (element, parseContext) => {\n const { computedStyle, boundingRect, slideElement } = parseContext;\n\n const slideRect = slideElement.getBoundingClientRect();\n const src = extractImageSrc(element);\n\n if (!src) return null;\n\n const imageElement: ImageElementDTO = {\n type: \"image\",\n id: crypto.randomUUID(),\n src: src,\n alt: extractImageAlt(element),\n position: extractRelativePosition(boundingRect, slideRect),\n dimensions: extractDimensions(boundingRect),\n zIndex: extractZIndex(computedStyle),\n rotation: extractRotation(computedStyle),\n opacity: extractOpacity(computedStyle),\n };\n\n return imageElement;\n },\n};\n","import { FA5_TO_FA6_NAMES } from \"@/constants\";\n\nexport interface IconSVGData {\n viewBox: string;\n path: string;\n}\n\nconst iconStore = new Map<string, IconSVGData>();\nconst iconFetchPromiseStore = new Map<string, Promise<IconSVGData | null>>();\n\nexport const detectIconVariant = (classList: string[]): string => {\n if (classList.includes(\"fab\") || classList.includes(\"fa-brands\"))\n return \"brands\";\n if (classList.includes(\"far\") || classList.includes(\"fa-regular\"))\n return \"regular\";\n return \"solid\";\n};\n\nexport const parseIconClass = (classList: string[]): string | null => {\n return classList.find((cls) => cls.startsWith(\"fa-\") && cls !== \"fa\") || null;\n};\n\nconst fetchIconFromCDNInternal = async (\n iconClass: string,\n variant: string,\n): Promise<IconSVGData | null> => {\n const iconName = iconClass.replace(\"fa-\", \"\");\n const fa6Name = FA5_TO_FA6_NAMES[iconName] || iconName;\n const iconNames = fa6Name !== iconName ? [fa6Name, iconName] : [iconName];\n const variants = variant === \"solid\" ? [\"solid\"] : [variant, \"solid\"];\n\n for (const name of iconNames) {\n for (const v of variants) {\n const urls = [\n `https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.0.0/svgs/${v}/${name}.svg`,\n `https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@7.0.0/svgs/${v}/${name}.svg`,\n ];\n\n for (const url of urls) {\n try {\n const response = await fetch(url);\n if (!response.ok) continue;\n\n const svgText = await response.text();\n const parser = new DOMParser();\n const doc = parser.parseFromString(svgText, \"image/svg+xml\");\n const svg = doc.querySelector(\"svg\");\n\n if (!svg) continue;\n\n const viewBox = svg.getAttribute(\"viewBox\") || \"0 0 512 512\";\n const paths = Array.from(svg.querySelectorAll(\"path\"))\n .map((p) => p.getAttribute(\"d\"))\n .filter(Boolean)\n .join(\" \");\n\n if (!paths) continue;\n\n return { viewBox, path: paths };\n } catch {\n continue;\n }\n }\n }\n }\n\n return null;\n};\n\nexport const fetchIconFromCDN = async (\n iconClass: string,\n variant: string,\n): Promise<IconSVGData | null> => {\n const cacheKey = `${variant}:${iconClass}`;\n\n if (iconStore.has(cacheKey)) {\n return iconStore.get(cacheKey)!;\n }\n\n if (iconFetchPromiseStore.has(cacheKey)) {\n return iconFetchPromiseStore.get(cacheKey)!;\n }\n\n const fetchPromise = fetchIconFromCDNInternal(iconClass, variant)\n .then((result) => {\n if (result) {\n iconStore.set(cacheKey, result);\n }\n return result;\n })\n .finally(() => {\n iconFetchPromiseStore.delete(cacheKey);\n });\n\n iconFetchPromiseStore.set(cacheKey, fetchPromise);\n return fetchPromise;\n};\n\nexport const createIconSVGDataURI = (\n svgData: IconSVGData,\n color: string,\n): string => {\n const svgString = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"${svgData.viewBox}\"><path fill=\"#${color}\" d=\"${svgData.path}\"/></svg>`;\n const base64 = btoa(unescape(encodeURIComponent(svgString)));\n return `data:image/svg+xml;base64,${base64}`;\n};\n","import type { Plugin } from \"@/types/plugin.types\";\nimport type { ImageElementDTO } from \"@/types/elements.types\";\nimport {\n extractRelativePosition,\n extractDimensions,\n} from \"@/lib/extractors/position\";\nimport {\n extractRotation,\n extractOpacity,\n extractZIndex,\n} from \"@/lib/extractors/typography\";\nimport {\n detectIconVariant,\n parseIconClass,\n fetchIconFromCDN,\n createIconSVGDataURI,\n} from \"@/lib/extractors/fontawesome\";\nimport { sanitizeColor } from \"@/utils/sanitize\";\n\nexport const fontAwesomePlugin: Plugin<ImageElementDTO> = {\n name: \"core:icon-fontawesome\",\n handles: [\"icon\"],\n onParse: async (element, parseContext) => {\n const { computedStyle, boundingRect, slideElement } = parseContext;\n\n const classList = Array.from(element.classList);\n const iconClass = parseIconClass(classList);\n\n if (!iconClass) return null;\n\n const variant = detectIconVariant(classList);\n const svgData = await fetchIconFromCDN(iconClass, variant);\n\n if (!svgData) return null;\n\n const color = sanitizeColor(computedStyle.color) || \"000000\";\n const src = createIconSVGDataURI(svgData, color);\n\n const slideRect = slideElement.getBoundingClientRect();\n\n const imageElement: ImageElementDTO = {\n type: \"image\",\n originalType: \"icon\",\n id: crypto.randomUUID(),\n src: src,\n alt: iconClass,\n position: extractRelativePosition(boundingRect, slideRect),\n dimensions: extractDimensions(boundingRect),\n zIndex: extractZIndex(computedStyle),\n rotation: extractRotation(computedStyle),\n opacity: extractOpacity(computedStyle),\n };\n\n return imageElement;\n },\n};\n","import { Plugin } from \"@/types/plugin.types\";\nimport { textPlugin } from \"@/plugins/core/text.plugin\";\nimport { shapePlugin } from \"@/plugins/core/shape.plugin\";\nimport { linePlugin } from \"@/plugins/core/line.plugin\";\nimport { tablePlugin } from \"@/plugins/core/table.plugin\";\nimport { plotlyPlugin } from \"@/plugins/core/plotly.plugin\";\nimport { imagePlugin } from \"@/plugins/core/image.plugin\";\nimport { fontAwesomePlugin } from \"@/plugins/core/fontawesome.plugin\";\n\nexport const ANSI = {\n reset: \"\\x1b[0m\",\n red: \"\\x1b[31m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n dim: \"\\x1b[2m\",\n} as const;\n\nexport const DEFAULTS = {\n SLIDE_SELECTOR: \".slide\",\n SLIDE_WIDTH: 992,\n SLIDE_HEIGHT: 558,\n FONT_FAMILY: \"\",\n CHART_FONT_SIZE: 9,\n} as const;\n\nexport const SERIALIZER = {\n DPI: 96,\n PPTX_PIXELS_TO_INCHES: 73.7,\n RADIUS_MULTIPLIER: 0.75,\n} as const;\n\nexport const STROKE_DASH_MAP: Record<\n string,\n | \"solid\"\n | \"dash\"\n | \"dashDot\"\n | \"lgDash\"\n | \"lgDashDot\"\n | \"lgDashDotDot\"\n | \"sysDash\"\n | \"sysDot\"\n> = {\n solid: \"solid\",\n dashed: \"dash\",\n dotted: \"sysDot\",\n} as const;\n\nexport const FONT_WEIGHT_SUFFIX_MAP: Record<number, string> = {\n 100: \"Thin\",\n 200: \"ExtraLight\",\n 300: \"Light\",\n 400: \"\",\n 500: \"Medium\",\n 600: \"SemiBold\",\n 700: \"Bold\",\n 800: \"ExtraBold\",\n 900: \"Black\",\n} as const;\n\nexport const DEFAULT_CORE_PLUGINS: Plugin[] = [\n textPlugin,\n shapePlugin,\n linePlugin,\n tablePlugin,\n imagePlugin,\n fontAwesomePlugin,\n plotlyPlugin,\n];\nexport const COORDINATE_BUFFER = 1.03 as const;\n\nexport const CHART_TYPE_MAP: Record<string, string> = {\n pie: \"pie\",\n bar: \"bar\",\n line: \"line\",\n scatter: \"scatter\",\n area: \"area\",\n doughnut: \"doughnut\",\n radar: \"radar\",\n bubble: \"bubble\",\n} as const;\n\nexport const PPTX_CHART_TYPE_MAP: Record<string, string> = {\n pie: \"pie\",\n bar: \"bar\",\n line: \"line\",\n scatter: \"line\",\n area: \"area\",\n doughnut: \"doughnut\",\n radar: \"radar\",\n bubble: \"bubble\",\n} as const;\n\nexport const FA5_TO_FA6_NAMES: Record<string, string> = {\n \"check-circle\": \"circle-check\",\n \"times-circle\": \"circle-xmark\",\n \"exclamation-circle\": \"circle-exclamation\",\n \"exclamation-triangle\": \"triangle-exclamation\",\n \"shield-alt\": \"shield\",\n search: \"magnifying-glass\",\n times: \"xmark\",\n bars: \"bars\",\n cog: \"gear\",\n trash: \"trash-can\",\n edit: \"pen-to-square\",\n \"external-link-alt\": \"arrow-up-right-from-square\",\n \"arrow-alt-circle-down\": \"circle-down\",\n \"arrow-alt-circle-up\": \"circle-up\",\n \"arrow-alt-circle-left\": \"circle-left\",\n \"arrow-alt-circle-right\": \"circle-right\",\n \"sign-in-alt\": \"right-to-bracket\",\n \"sign-out-alt\": \"right-from-bracket\",\n percentage: \"percent\",\n} as const;\n","import type {\n ExportConfig,\n ImageExportConfig,\n HTMLSource,\n ConverterConfig,\n ParserStrategy,\n SerializerStrategy,\n} from \"@/types/config.types\";\nimport type { PresentationDTO, SlideDTO } from \"@/types/presentation.types\";\nimport type { ElementDTO } from \"@/types/elements.types\";\nimport type { Plugin } from \"@/types/plugin.types\";\nimport { PluginManager } from \"@/lib/plugin-manager\";\nimport { assertNonNull } from \"@/utils/assert\";\nimport { DEFAULTS } from \"@/constants\";\n\nexport class BaseConverter {\n protected config: Required<Pick<ConverterConfig, \"selector\" | \"dimensions\">> &\n ConverterConfig;\n protected pluginManager: PluginManager;\n protected presentation: PresentationDTO | null = null;\n protected source: string | null = null;\n protected parser: ParserStrategy;\n protected serializer: SerializerStrategy;\n\n constructor(config: ConverterConfig) {\n assertNonNull(config.parser, \"Parser strategy is required\");\n assertNonNull(config.serializer, \"Serializer strategy is required\");\n\n this.config = {\n ...config,\n selector: config.selector || \".slide\",\n dimensions: config.dimensions || {\n width: DEFAULTS.SLIDE_WIDTH,\n height: DEFAULTS.SLIDE_HEIGHT,\n },\n };\n this.parser = config.parser;\n this.serializer = config.serializer;\n this.pluginManager = new PluginManager();\n\n if (this.serializer.setPluginManager) {\n this.serializer.setPluginManager(this.pluginManager);\n }\n\n const corePlugins = config.plugins?.core ?? [];\n const extensionPlugins = config.plugins?.extensions ?? [];\n\n corePlugins.forEach((plugin) => this.use(plugin));\n extensionPlugins.forEach((plugin) => this.use(plugin));\n }\n\n use(plugin: Plugin): this {\n this.pluginManager.register(plugin);\n return this;\n }\n\n load(input: HTMLSource): this {\n if (typeof input === \"string\") {\n this.source = input;\n } else {\n this.source = input.content;\n }\n return this;\n }\n\n async convert(): Promise<this> {\n assertNonNull(this.source, \"No HTML source loaded. Call load() first.\");\n\n if (this.config.debug) {\n console.group(\"[html-in-pptx-out] convert\");\n }\n const parserConfig = {\n selector: this.config.selector,\n dimensions: this.config.dimensions,\n };\n\n const html = await this.pluginManager.executeBeforeParse(\n this.source,\n parserConfig,\n );\n\n const { elements, cleanup } = await this.parser.parse(html, parserConfig);\n\n if (this.config.debug) {\n console.log(\"before: executeOnParse\", {\n elements,\n });\n }\n\n const slidesMap = new Map<number, ElementDTO[]>();\n\n for (const { slideIndex, element, parseContext } of elements) {\n const dto = await this.pluginManager.executeOnParse(\n element,\n parseContext,\n );\n\n if (dto) {\n if (!slidesMap.has(slideIndex)) {\n slidesMap.set(slideIndex, []);\n }\n slidesMap.get(slideIndex)!.push(dto);\n }\n }\n\n if (this.config.debug) {\n console.log(\"after: executeOnParse\", {\n slides: slidesMap,\n });\n }\n\n cleanup();\n\n const slides: SlideDTO[] = [];\n const slideIndices = Array.from(slidesMap.keys()).sort((a, b) => a - b);\n\n for (const slideIndex of slideIndices) {\n const slide: SlideDTO = {\n id: crypto.randomUUID(),\n order: slideIndex,\n elements: slidesMap.get(slideIndex) || [],\n };\n slides.push(slide);\n }\n\n this.presentation = {\n slides: slides,\n metadata: {\n createdAt: new Date(),\n plugins: this.pluginManager.getPlugins().map((plugin) => plugin.name),\n },\n viewport: this.config.dimensions,\n };\n\n for (let i = 0; i < this.presentation.slides.length; i++) {\n this.presentation.slides[i] = await this.pluginManager.executeOnSlide(\n this.presentation.slides[i],\n );\n }\n\n this.pluginManager.setPresentation(this.presentation);\n\n if (this.config.debug) {\n console.log(\"after: executeOnSlide\", {\n presentation: this.presentation,\n });\n console.groupEnd();\n }\n\n return this;\n }\n\n async export(options: ExportConfig): Promise<ArrayBuffer> {\n assertNonNull(\n this.presentation,\n \"No presentation to export. Call convert() first.\",\n );\n\n const buffer = await this.serializer.serialize(this.presentation, options);\n return buffer;\n }\n\n async exportImages(_options: ImageExportConfig): Promise<void> {\n throw new Error(\"Not implemented\");\n }\n\n getPresentation(): PresentationDTO {\n assertNonNull(\n this.presentation,\n \"No presentation available. Call convert() first.\",\n );\n return this.presentation;\n }\n}\n","import { Dimensions } from \"@/types/base.types\";\n\nexport const createIframe = (\n html: string,\n dimension: Dimensions,\n): Promise<HTMLIFrameElement> => {\n return new Promise((resolve, reject) => {\n const iframe = document.createElement(\"iframe\");\n iframe.style.position = \"fixed\";\n iframe.style.left = \"-9999px\";\n iframe.style.top = \"-9999px\";\n (iframe.style.width = `${dimension.width}px`),\n (iframe.style.height = `${dimension.height}px`);\n iframe.style.opacity = \"0\";\n iframe.style.pointerEvents = \"none\";\n iframe.style.zIndex = \"-1\";\n iframe.setAttribute(\"aria-hidden\", \"true\");\n\n const handleLoad = () => {\n iframe.removeEventListener(\"load\", handleLoad);\n\n const doc = iframe.contentDocument;\n if (!doc) {\n reject(new Error(\"Failed to access iframe document\"));\n return;\n }\n\n const checkReady = () => {\n if (doc.readyState === \"complete\") {\n requestAnimationFrame(() => resolve(iframe));\n } else {\n setTimeout(checkReady, 10);\n }\n };\n\n checkReady();\n };\n\n iframe.addEventListener(\"load\", handleLoad);\n iframe.onerror = () => reject(new Error(\"Failed to load iframe\"));\n iframe.srcdoc = html;\n document.body.appendChild(iframe);\n });\n};\n\nexport const destroyIframe = (iframe: HTMLIFrameElement): void => {\n iframe.remove();\n};\n","import type {\n ParserStrategy,\n ParserConfig,\n ParserResult,\n ParserElement,\n} from \"@/types/config.types\";\nimport type { ParseContext } from \"@/types/plugin.types\";\nimport { createIframe, destroyIframe } from \"@/lib/iframe-renderer\";\nimport { classifyElement } from \"@/lib/extractors/classifier\";\n\nexport class IframeParser implements ParserStrategy {\n async parse(html: string, config: ParserConfig): Promise<ParserResult> {\n const iframe = await createIframe(html, config.dimensions);\n const doc = iframe.contentDocument!;\n const slideElements = doc.querySelectorAll<HTMLElement>(config.selector);\n\n const elements: ParserElement[] = [];\n\n for (let slideIndex = 0; slideIndex < slideElements.length; slideIndex++) {\n const slideElement = slideElements[slideIndex];\n const children = slideElement.querySelectorAll<HTMLElement>(\"*\");\n\n const allElements = [slideElement, ...Array.from(children)];\n\n const consumedElements = new Set<HTMLElement>();\n\n for (const child of allElements) {\n let isConsumed = false;\n let parent = child.parentElement;\n while (parent && parent !== slideElement) {\n if (consumedElements.has(parent)) {\n isConsumed = true;\n break;\n }\n parent = parent.parentElement;\n }\n if (isConsumed) continue;\n\n const elementTypes = classifyElement(child, iframe.contentWindow!);\n if (elementTypes.length === 0) continue;\n\n const computedStyle = iframe.contentWindow!.getComputedStyle(child);\n const boundingRect = child.getBoundingClientRect();\n const tagName = child.tagName.toLowerCase();\n\n for (const elementType of elementTypes) {\n if (elementType === \"table\" || elementType === \"text\") {\n consumedElements.add(child);\n }\n\n const parseContext: ParseContext = {\n elementType: elementType,\n tagName: tagName,\n computedStyle: computedStyle,\n boundingRect: boundingRect,\n slideIndex: slideIndex,\n slideElement: slideElement,\n };\n\n elements.push({\n slideIndex: slideIndex,\n element: child,\n parseContext: parseContext,\n });\n }\n }\n }\n\n return {\n elements,\n cleanup: () => destroyIframe(iframe),\n };\n }\n}\n","import { SERIALIZER } from \"@/constants\";\nimport type { Position, Dimensions } from \"@/types/base.types\";\n\nexport const pxToInches = (px: number): number => {\n return px / SERIALIZER.DPI;\n};\n\nexport const pxToPoints = (px: number): number => {\n return (px / SERIALIZER.DPI) * 72;\n};\n\nexport const positionToPercentage = (\n position: Position,\n viewport: Dimensions,\n): { x: `${number}%`; y: `${number}%` } => {\n const xPercent = (position.left / viewport.width) * 100;\n const yPercent = (position.top / viewport.height) * 100;\n\n return {\n x: `${xPercent}%`,\n y: `${yPercent}%`,\n };\n};\n\nexport const dimensionsToPercentage = (\n dimensions: Dimensions,\n viewport: Dimensions,\n): { w: `${number}%`; h: `${number}%` } => {\n const wPercent = (dimensions.width / viewport.width) * 100;\n const hPercent = (dimensions.height / viewport.height) * 100;\n\n return {\n w: `${wPercent}%`,\n h: `${hPercent}%`,\n };\n};\n\nexport const positionToInches = (\n position: Position,\n): { x: number; y: number } => {\n return {\n x: pxToInches(position.left),\n y: pxToInches(position.top),\n };\n};\n\nexport const dimensionsToInches = (\n dimensions: Dimensions,\n): { w: number; h: number } => {\n return {\n w: pxToInches(dimensions.width),\n h: pxToInches(dimensions.height),\n };\n};\n","import type { TextElementDTO, TextRun } from \"@/types/elements.types\";\nimport type { Dimensions, Typography } from \"@/types/base.types\";\nimport type PptxGenJS from \"pptxgenjs\";\nimport { dimensionsToPercentage } from \"@/utils/units\";\nimport { positionToPercentage } from \"@/utils/units\";\nimport { pxToPoints } from \"@/utils/units\";\n\nexport const transformTypographyToPptxTextProps = (\n typo: Typography,\n): PptxGenJS.TextPropsOptions => {\n const props: PptxGenJS.TextPropsOptions = {};\n\n if (typo.fontFamily) {\n props.fontFace = typo.fontFamily.split(\",\")[0].trim();\n }\n\n if (typo.fontSize) {\n props.fontSize = pxToPoints(typo.fontSize);\n }\n\n if (typo.color) {\n props.color = typo.color.toUpperCase();\n }\n\n if (typo.fontWeight) {\n const weight = parseInt(typo.fontWeight, 10) || 400;\n if (weight > 400) {\n props.bold = true;\n }\n }\n\n if (typo.fontStyle === \"italic\" || typo.fontStyle === \"oblique\") {\n props.italic = true;\n }\n\n if (typo.underline) {\n props.underline = { style: \"sng\" };\n }\n\n if (typo.strikethrough) {\n props.strike = \"sngStrike\";\n }\n\n return props;\n};\n\nexport const flattenRuns = (\n runs: TextRun[],\n): Array<{ text: string; options: PptxGenJS.TextPropsOptions }> => {\n const result: Array<{ text: string; options: PptxGenJS.TextPropsOptions }> =\n [];\n\n for (const run of runs) {\n if (run.children && run.children.length > 0) {\n const childResults = flattenRuns(run.children);\n for (const child of childResults) {\n const aggregatedOptions = { ...child.options };\n\n if (run.typography) {\n const runProps = transformTypographyToPptxTextProps(run.typography);\n Object.assign(aggregatedOptions, runProps, child.options);\n }\n\n if (run.href) {\n aggregatedOptions.hyperlink = { url: run.href };\n }\n\n result.push({ text: child.text, options: aggregatedOptions });\n }\n } else {\n const options: PptxGenJS.TextPropsOptions = {};\n\n if (run.typography) {\n Object.assign(\n options,\n transformTypographyToPptxTextProps(run.typography),\n );\n }\n\n if (run.href) {\n options.hyperlink = { url: run.href };\n }\n\n result.push({ text: run.content, options: options });\n }\n }\n\n return result;\n};\n\nexport const serializeText = (\n slide: PptxGenJS.Slide,\n element: TextElementDTO,\n viewport: Dimensions,\n): void => {\n const pos = positionToPercentage(element.position, viewport);\n const dims = dimensionsToPercentage(element.dimensions, viewport);\n\n const textOptions: PptxGenJS.TextPropsOptions = {\n x: pos.x,\n y: pos.y,\n w: dims.w,\n h: dims.h,\n /*\n * I'm setting lineSpacingMultiple to one bcs its not vertically aligned well idk why\n * Default line height to 1 for accurate vertical positioning.\n * Without this, pptxgenjs uses its own default which is shit\n */\n lineSpacingMultiple: 1,\n valign: \"top\",\n align: \"left\",\n isTextBox: true,\n wrap: true,\n shrinkText: false,\n };\n\n if (element.typography) {\n const typo = element.typography;\n const typoProps = transformTypographyToPptxTextProps(typo);\n Object.assign(textOptions, typoProps);\n\n if (typo.textAlign) {\n textOptions.align = typo.textAlign as\n | \"left\"\n | \"center\"\n | \"right\"\n | \"justify\";\n }\n\n if (typo.verticalAlign) {\n textOptions.valign = typo.verticalAlign as \"top\" | \"middle\" | \"bottom\";\n }\n\n if (typo.letterSpacing) {\n textOptions.charSpacing = typo.letterSpacing;\n }\n }\n\n if (element.padding) {\n textOptions.margin = [\n pxToPoints(element.padding.top),\n pxToPoints(element.padding.right),\n pxToPoints(element.padding.bottom),\n pxToPoints(element.padding.left),\n ];\n }\n\n if (element.rotation) {\n textOptions.rotate = element.rotation;\n }\n\n if (element.opacity !== undefined && element.opacity < 1) {\n textOptions.transparency = Math.round((1 - element.opacity) * 100);\n }\n\n if (element.runs && element.runs.length > 0) {\n const textProps = flattenRuns(element.runs);\n slide.addText(textProps, textOptions);\n } else {\n // if parser does not support runs fallback\n slide.addText(element.content, textOptions);\n }\n};\n","import type { ShapeElementDTO } from \"@/types/elements.types\";\nimport type { Dimensions, Stroke } from \"@/types/base.types\";\nimport PptxGenJS from \"pptxgenjs\";\nimport { dimensionsToPercentage } from \"@/utils/units\";\nimport { positionToPercentage } from \"@/utils/units\";\nimport { pxToPoints } from \"@/utils/units\";\nimport { SERIALIZER, STROKE_DASH_MAP } from \"@/constants\";\n\nconst getShapeType = (\n shape: ShapeElementDTO[\"shapeType\"],\n): PptxGenJS.ShapeType => {\n return shape as PptxGenJS.ShapeType;\n};\n\nconst getStrokeDashType = (\n stroke: Stroke,\n):\n | \"solid\"\n | \"dash\"\n | \"dashDot\"\n | \"lgDash\"\n | \"lgDashDot\"\n | \"lgDashDotDot\"\n | \"sysDash\"\n | \"sysDot\" => {\n return STROKE_DASH_MAP[stroke.style] || \"solid\";\n};\n\nexport const serializeShape = (\n slide: PptxGenJS.Slide,\n element: ShapeElementDTO,\n viewport: Dimensions,\n): void => {\n const pos = positionToPercentage(element.position, viewport);\n const dims = dimensionsToPercentage(element.dimensions, viewport);\n\n const shapeType: PptxGenJS.ShapeType =\n getShapeType(element.shapeType) || PptxGenJS.ShapeType.rect;\n\n const shapeOptions: PptxGenJS.ShapeProps = {\n x: pos.x,\n y: pos.y,\n w: dims.w,\n h: dims.h,\n };\n\n if (element.fill) {\n const fillProps: PptxGenJS.ShapeFillProps = {};\n\n if (element.fill.type === \"solid\") {\n fillProps.color = element.fill.color.toUpperCase();\n\n if (element.fill.opacity !== undefined && element.fill.opacity < 1) {\n const transparencyPercent = Math.round(\n (1 - element.fill.opacity) * 100,\n );\n fillProps.transparency = transparencyPercent;\n }\n } else if (element.fill.type === \"gradient\") {\n const firstStop = element.fill.stops[0];\n if (firstStop) {\n fillProps.color = firstStop.color.toUpperCase();\n\n if (firstStop.opacity !== undefined && firstStop.opacity < 1) {\n fillProps.transparency = Math.round((1 - firstStop.opacity) * 100);\n }\n }\n }\n\n if (fillProps.color) {\n shapeOptions.fill = fillProps;\n }\n }\n\n if (element.stroke) {\n const lineProps: PptxGenJS.ShapeLineProps = {\n color: element.stroke.color.toUpperCase(),\n width: element.stroke.width,\n dashType: getStrokeDashType(element.stroke),\n };\n\n if (element.stroke.opacity !== undefined) {\n lineProps.transparency = Math.round((1 - element.stroke.opacity) * 100);\n }\n\n shapeOptions.line = lineProps;\n }\n\n if (element.rotation) {\n shapeOptions.rotate = element.rotation;\n }\n\n if (element.borderRadius && element.shapeType === \"roundRect\") {\n const minDimension = Math.min(\n element.dimensions.width,\n element.dimensions.height,\n );\n const normalizedRadius =\n Math.min(element.borderRadius / minDimension, 1) *\n SERIALIZER.RADIUS_MULTIPLIER;\n shapeOptions.rectRadius = normalizedRadius;\n }\n\n if (element.shadow) {\n const offsetX = element.shadow.offset.x;\n const offsetY = element.shadow.offset.y;\n const offsetDistance = Math.sqrt(offsetX ** 2 + offsetY ** 2);\n\n const angleRadians = Math.atan2(offsetY, offsetX);\n const angleDegrees = (angleRadians * 180) / Math.PI;\n const normalizedAngle = ((angleDegrees % 360) + 360) % 360;\n\n shapeOptions.shadow = {\n type: element.shadow.type,\n color: element.shadow.color.toUpperCase(),\n blur: pxToPoints(element.shadow.blur),\n offset: pxToPoints(offsetDistance),\n angle: normalizedAngle,\n opacity: element.shadow.opacity ?? 1,\n };\n }\n\n slide.addShape(shapeType, shapeOptions);\n};\n","import type { LineElementDTO } from \"@/types/elements.types\";\nimport type { Dimensions, Stroke } from \"@/types/base.types\";\nimport type PptxGenJS from \"pptxgenjs\";\nimport { STROKE_DASH_MAP } from \"@/constants\";\n\nconst getStrokeDashType = (\n stroke: Stroke,\n):\n | \"solid\"\n | \"dash\"\n | \"dashDot\"\n | \"lgDash\"\n | \"lgDashDot\"\n | \"lgDashDotDot\"\n | \"sysDash\"\n | \"sysDot\" => {\n return STROKE_DASH_MAP[stroke.style] || \"solid\";\n};\n\nexport const serializeLine = (\n slide: PptxGenJS.Slide,\n element: LineElementDTO,\n viewport: Dimensions,\n): void => {\n const startXPercent = (element.start.left / viewport.width) * 100;\n const startYPercent = (element.start.top / viewport.height) * 100;\n const endXPercent = (element.end.left / viewport.width) * 100;\n const endYPercent = (element.end.top / viewport.height) * 100;\n\n const width = Math.abs(endXPercent - startXPercent);\n const height = Math.abs(endYPercent - startYPercent);\n\n const lineProps: PptxGenJS.ShapeLineProps = {\n color: element.stroke.color.toUpperCase(),\n width: element.stroke.width,\n dashType: getStrokeDashType(element.stroke),\n };\n\n if (element.stroke.opacity !== undefined) {\n lineProps.transparency = Math.round((1 - element.stroke.opacity) * 100);\n }\n\n const lineOptions: PptxGenJS.ShapeProps = {\n x: `${Math.min(startXPercent, endXPercent)}%`,\n y: `${Math.min(startYPercent, endYPercent)}%`,\n w: `${width || 0.1}%`,\n h: `${height || 0.1}%`,\n line: lineProps,\n };\n\n const flipH = element.end.left < element.start.left;\n const flipV = element.end.top < element.start.top;\n\n if (flipH) {\n lineOptions.flipH = true;\n }\n\n if (flipV) {\n lineOptions.flipV = true;\n }\n\n slide.addShape(\"line\", lineOptions);\n};\n","import type { ImageElementDTO } from \"@/types/elements.types\";\nimport type { Dimensions } from \"@/types/base.types\";\nimport type PptxGenJS from \"pptxgenjs\";\nimport { dimensionsToPercentage } from \"@/utils/units\";\nimport { positionToPercentage } from \"@/utils/units\";\n\nexport const serializeImage = (\n slide: PptxGenJS.Slide,\n element: ImageElementDTO,\n viewport: Dimensions,\n): void => {\n const pos = positionToPercentage(element.position, viewport);\n const dims = dimensionsToPercentage(element.dimensions, viewport);\n\n const imageOptions: PptxGenJS.ImageProps = {\n x: pos.x,\n y: pos.y,\n w: dims.w,\n h: dims.h,\n };\n\n if (element.src.startsWith(\"data:\")) {\n imageOptions.data = element.src;\n } else {\n imageOptions.path = element.src;\n }\n\n if (element.alt) {\n imageOptions.altText = element.alt;\n }\n\n if (element.rotation) {\n imageOptions.rotate = element.rotation;\n }\n\n if (element.opacity !== undefined && element.opacity < 1) {\n imageOptions.transparency = Math.round((1 - element.opacity) * 100);\n }\n\n if (element.fit) {\n const fitMap: Record<string, \"contain\" | \"cover\" | \"crop\"> = {\n contain: \"contain\",\n cover: \"cover\",\n stretch: \"crop\",\n };\n imageOptions.sizing = {\n type: fitMap[element.fit] || \"contain\",\n w: element.dimensions.width,\n h: element.dimensions.height,\n };\n }\n\n slide.addImage(imageOptions);\n};\n","import type { TableElementDTO } from \"@/types/elements.types\";\nimport type { Dimensions } from \"@/types/base.types\";\nimport type PptxGenJS from \"pptxgenjs\";\nimport { dimensionsToPercentage } from \"@/utils/units\";\nimport { positionToPercentage } from \"@/utils/units\";\nimport { pxToPoints } from \"@/utils/units\";\nimport { pxToInches } from \"@/utils/units\";\nimport { FONT_WEIGHT_SUFFIX_MAP } from \"@/constants\";\nimport { flattenRuns } from \"./text.serializer\";\n\nconst getFontFaceWithWeight = (fontFamily: string, fontWeight?: string): string => {\n const baseFontFace = fontFamily.split(\",\")[0].trim();\n if (!fontWeight) return baseFontFace;\n\n const weight = parseInt(fontWeight, 10) || 400;\n const suffix = FONT_WEIGHT_SUFFIX_MAP[weight];\n\n if (!suffix || suffix === \"\") return baseFontFace;\n\n return `${baseFontFace} ${suffix}`;\n};\n\nexport const serializeTable = (\n slide: PptxGenJS.Slide,\n element: TableElementDTO,\n viewport: Dimensions,\n): void => {\n const pos = positionToPercentage(element.position, viewport);\n const dims = dimensionsToPercentage(element.dimensions, viewport);\n\n const rows: PptxGenJS.TableRow[] = element.rows.map((row) =>\n row.map((cell) => {\n const cellProps: PptxGenJS.TableCell = {\n text: cell.runs && cell.runs.length > 0 ? flattenRuns(cell.runs) : cell.text,\n };\n\n if (cell.colspan) {\n cellProps.options = {\n ...cellProps.options,\n colspan: cell.colspan,\n };\n }\n\n if (cell.rowspan) {\n cellProps.options = {\n ...cellProps.options,\n rowspan: cell.rowspan,\n };\n }\n\n if (cell.typography) {\n const typo = cell.typography;\n const weight = typo.fontWeight ? parseInt(typo.fontWeight, 10) || 400 : 400;\n\n cellProps.options = {\n ...cellProps.options,\n fontFace: typo.fontFamily\n ? getFontFaceWithWeight(typo.fontFamily, typo.fontWeight)\n : undefined,\n fontSize: typo.fontSize ? pxToPoints(typo.fontSize) : undefined,\n color: typo.color ? typo.color.toUpperCase() : undefined,\n bold: weight > 400,\n italic: typo.fontStyle === \"italic\" || typo.fontStyle === \"oblique\",\n underline: typo.underline ? { style: \"sng\" } : undefined,\n align: typo.textAlign as \"left\" | \"center\" | \"right\" | undefined,\n valign: typo.verticalAlign as \"top\" | \"middle\" | \"bottom\" | undefined,\n };\n }\n\n if (cell.fill) {\n if (cell.fill.type === \"solid\") {\n const fillOptions: { color: string; transparency?: number } = {\n color: cell.fill.color.toUpperCase(),\n };\n\n if (cell.fill.opacity !== undefined && cell.fill.opacity < 1) {\n fillOptions.transparency = Math.round((1 - cell.fill.opacity) * 100);\n }\n\n cellProps.options = {\n ...cellProps.options,\n fill: fillOptions,\n };\n } else if (cell.fill.type === \"gradient\") {\n const firstStop = cell.fill.stops[0];\n if (firstStop) {\n cellProps.options = {\n ...cellProps.options,\n fill: { color: firstStop.color.toUpperCase() },\n };\n }\n }\n }\n\n if (cell.border) {\n const sides = [\"top\", \"right\", \"bottom\", \"left\"] as const;\n const borderArray: PptxGenJS.BorderProps[] = [];\n\n for (const side of sides) {\n const stroke = cell.border[side];\n if (stroke) {\n let borderType: \"solid\" | \"dash\" | \"none\" = \"solid\";\n if (stroke.style === \"dashed\" || stroke.style === \"dotted\") {\n borderType = \"dash\";\n }\n\n borderArray.push({\n color: stroke.color.toUpperCase(),\n pt: stroke.width,\n type: borderType,\n });\n } else {\n borderArray.push({ type: \"none\" });\n }\n }\n\n const borderOptions = borderArray as [\n PptxGenJS.BorderProps,\n PptxGenJS.BorderProps,\n PptxGenJS.BorderProps,\n PptxGenJS.BorderProps,\n ];\n\n cellProps.options = {\n ...cellProps.options,\n border: borderOptions,\n };\n }\n\n return cellProps;\n }),\n );\n\n const tableOptions: PptxGenJS.TableProps = {\n x: pos.x,\n y: pos.y,\n w: dims.w,\n h: dims.h,\n };\n\n if (element.colWidths && element.colWidths.length > 0) {\n tableOptions.colW = element.colWidths.map((widthPx) => pxToInches(widthPx));\n }\n\n if (element.cellMinHeight) {\n tableOptions.rowH = pxToPoints(element.cellMinHeight) / 72;\n }\n\n if (element.headerRow) {\n tableOptions.autoPageHeaderRows = 1;\n }\n\n slide.addTable(rows, tableOptions);\n};\n","import type { ChartElementDTO, ChartSeries } from \"@/types/elements.types\";\nimport { positionToInches, dimensionsToInches } from \"@/utils/units\";\nimport { DEFAULTS, PPTX_CHART_TYPE_MAP } from \"@/constants\";\nimport PptxGenJS from \"pptxgenjs\";\nimport { sanitizeColor } from \"@/utils/sanitize\";\n\nconst detectDecimalFormat = (\n series: ChartElementDTO[\"data\"][\"series\"],\n): string => {\n for (const s of series) {\n if (!s.values || !Array.isArray(s.values)) continue;\n\n for (const value of s.values) {\n if (typeof value === \"number\" && !Number.isInteger(value)) {\n let maxDecimals = 0;\n for (const v of s.values) {\n if (typeof v === \"number\" && !Number.isInteger(v)) {\n const decimals = v.toString().split(\".\")[1]?.length || 0;\n maxDecimals = Math.max(maxDecimals, Math.min(decimals, 2));\n }\n }\n\n if (maxDecimals === 1) return \"#,##0.0\";\n return \"#,##0.00\";\n }\n }\n }\n\n return \"#,##0\";\n};\n\nconst mapChartTypeToPptxGenJS = (chartType: string): string => {\n return PPTX_CHART_TYPE_MAP[chartType] || \"bar\";\n};\n\nconst getPptxChartTypeKey = (element: ChartElementDTO): string => {\n const chartType = element.data.chartType;\n\n if (\n chartType === \"pie\" &&\n element.data.options?.hole !== undefined &&\n element.data.options.hole > 0\n ) {\n return \"doughnut\";\n }\n\n return PPTX_CHART_TYPE_MAP[chartType] || \"bar\";\n};\n\ninterface ComboChartType {\n typeKey: string;\n data: ChartSeries[];\n options: PptxGenJS.IChartOpts;\n}\n\ninterface TransformedChartData {\n data: ChartSeries[] | null;\n options: PptxGenJS.IChartOpts;\n chartTypesForCombo?: ComboChartType[];\n chartTypeKey: string;\n}\n\nexport const transformChartToPptxGenJS = (\n element: ChartElementDTO,\n): TransformedChartData => {\n const pos = positionToInches(element.position);\n const dims = dimensionsToInches(element.dimensions);\n\n const chartData = element.data;\n const normalized = {\n type: chartData.chartType,\n series: chartData.series,\n labels: chartData.labels,\n options: chartData.options,\n };\n\n const data: ChartSeries[] = normalized.series.map((series) => ({\n name: series.name,\n labels: normalized.labels,\n values: series.values,\n color: sanitizeColor(series.color || \"\"),\n }));\n\n const options: PptxGenJS.IChartOpts = {\n x: pos.x,\n y: pos.y,\n w: dims.w,\n h: dims.h,\n title: normalized.options?.title,\n showTitle: normalized.options?.title ? true : false,\n titleFontSize:\n normalized.options?.titleFontSize || DEFAULTS.CHART_FONT_SIZE,\n showLegend: normalized.options?.showLegend !== false,\n legendPos: \"t\",\n legendFontSize: DEFAULTS.CHART_FONT_SIZE,\n showLabel: normalized.options?.showDataLabels === true,\n dataLabelFontSize: DEFAULTS.CHART_FONT_SIZE,\n };\n\n const showDataLabels = normalized.options?.showDataLabels === true;\n\n if (showDataLabels) {\n if (normalized.type === \"bar\") {\n options.showValue = true;\n const formatCode = detectDecimalFormat(normalized.series);\n if (formatCode) {\n options.dataLabelFormatCode = formatCode;\n }\n } else if (normalized.type === \"pie\") {\n options.showPercent = true;\n }\n }\n\n if (normalized.type === \"pie\") {\n options.dataLabelPosition = \"outEnd\";\n }\n\n const allColors: string[] = [];\n\n const hasColorsArray = normalized.series.some(\n (s) => s.colors && s.colors.length > 0,\n );\n\n if (hasColorsArray) {\n const seriesWithColors = normalized.series.find(\n (s) => s.colors && s.colors.length > 0,\n );\n if (seriesWithColors?.colors) {\n allColors.push(...seriesWithColors.colors);\n }\n } else {\n normalized.series.forEach((series) => {\n if (series.color) {\n allColors.push(series.color);\n }\n });\n }\n\n if (allColors.length > 0) {\n options.chartColors = allColors\n .map((c) => sanitizeColor(c))\n .filter((c): c is string => c !== undefined);\n }\n\n if (normalized.options?.xAxisTitle) {\n options.catAxisTitle = normalized.options.xAxisTitle;\n options.showCatAxisTitle = true;\n options.catAxisTitleFontSize = DEFAULTS.CHART_FONT_SIZE;\n }\n if (normalized.options?.yAxisTitle) {\n options.valAxisTitle = normalized.options.yAxisTitle;\n options.showValAxisTitle = true;\n options.valAxisTitleFontSize = DEFAULTS.CHART_FONT_SIZE;\n }\n\n options.catAxisLabelFontSize = DEFAULTS.CHART_FONT_SIZE;\n options.valAxisLabelFontSize = DEFAULTS.CHART_FONT_SIZE;\n\n options.catGridLine = { style: \"none\" };\n options.valGridLine = { style: \"solid\", size: 1, color: \"D9D9D9\" };\n\n if (normalized.options?.hole !== undefined && normalized.options.hole > 0) {\n options.holeSize = Math.round(normalized.options.hole * 100);\n }\n\n if (normalized.options?.orientation === \"horizontal\") {\n options.barDir = \"bar\";\n } else if (\n normalized.options?.orientation === \"vertical\" ||\n normalized.type === \"bar\"\n ) {\n options.barDir = \"col\";\n }\n\n if (normalized.options?.barGrouping) {\n options.barGrouping = normalized.options.barGrouping;\n }\n\n if (normalized.options?.hasSecondaryAxis) {\n const primaryAxisSeriesMap = new Map<string, ChartSeries[]>();\n const secondaryAxisSeriesMap = new Map<string, ChartSeries[]>();\n\n normalized.series.forEach((series, idx) => {\n const seriesChartType = series.chartType || normalized.type;\n const seriesData = data[idx];\n\n if (series.yAxis === \"y2\") {\n if (!secondaryAxisSeriesMap.has(seriesChartType)) {\n secondaryAxisSeriesMap.set(seriesChartType, []);\n }\n secondaryAxisSeriesMap.get(seriesChartType)!.push(seriesData);\n } else {\n if (!primaryAxisSeriesMap.has(seriesChartType)) {\n primaryAxisSeriesMap.set(seriesChartType, []);\n }\n primaryAxisSeriesMap.get(seriesChartType)!.push(seriesData);\n }\n });\n\n if (secondaryAxisSeriesMap.size === 0) {\n return { data, options, chartTypeKey: getPptxChartTypeKey(element) };\n }\n\n const chartTypesForCombo: ComboChartType[] = [];\n\n primaryAxisSeriesMap.forEach((seriesDataArray, seriesChartType) => {\n chartTypesForCombo.push({\n typeKey: mapChartTypeToPptxGenJS(seriesChartType),\n data: seriesDataArray,\n options: {},\n });\n });\n\n secondaryAxisSeriesMap.forEach((seriesDataArray, seriesChartType) => {\n const isLineChart =\n seriesChartType === \"line\" || seriesChartType === \"area\";\n chartTypesForCombo.push({\n typeKey: mapChartTypeToPptxGenJS(seriesChartType),\n data: seriesDataArray,\n options: {\n secondaryValAxis: true,\n secondaryCatAxis: true,\n ...(isLineChart ? { showValue: true, dataLabelPosition: \"t\" } : {}),\n },\n });\n });\n\n const globalOptions: PptxGenJS.IChartOpts = {\n x: options.x,\n y: options.y,\n w: options.w,\n h: options.h,\n title: options.title,\n showTitle: options.showTitle,\n titleFontSize: options.titleFontSize,\n showLegend: options.showLegend,\n legendPos: \"t\",\n legendFontSize: DEFAULTS.CHART_FONT_SIZE,\n chartColors: options.chartColors,\n dataLabelFormatCode: options.dataLabelFormatCode,\n // dlbs fontsize\n dataLabelFontSize: DEFAULTS.CHART_FONT_SIZE,\n valAxes: [\n {\n valAxisTitle: normalized.options.yAxisTitle || \"\",\n showValAxisTitle: normalized.options.yAxisTitle ? true : false,\n valAxisTitleFontSize: DEFAULTS.CHART_FONT_SIZE,\n valAxisLabelFontSize: DEFAULTS.CHART_FONT_SIZE,\n valGridLine: { style: \"solid\", size: 1, color: \"D9D9D9\" },\n },\n {\n valAxisTitle: normalized.options.yAxis2Title || \"\",\n showValAxisTitle: false,\n valAxisTitleFontSize: DEFAULTS.CHART_FONT_SIZE,\n valAxisLabelFontSize: DEFAULTS.CHART_FONT_SIZE,\n valGridLine: { style: \"none\" },\n },\n ],\n catAxes: [\n {\n catAxisTitle: normalized.options.xAxisTitle || \"\",\n showCatAxisTitle: normalized.options.xAxisTitle ? true : false,\n catAxisTitleFontSize: DEFAULTS.CHART_FONT_SIZE,\n catAxisLabelFontSize: DEFAULTS.CHART_FONT_SIZE,\n catGridLine: { style: \"none\" },\n },\n {\n catAxisLabelFontSize: DEFAULTS.CHART_FONT_SIZE,\n catAxisHidden: true,\n catGridLine: { style: \"none\" },\n },\n ],\n };\n\n return {\n data: null,\n options: globalOptions,\n chartTypesForCombo,\n chartTypeKey: getPptxChartTypeKey(element),\n };\n }\n\n return { data, options, chartTypeKey: getPptxChartTypeKey(element) };\n};\n\nexport const serializeChart = (\n slide: PptxGenJS.Slide,\n element: ChartElementDTO,\n): void => {\n const { data, options, chartTypesForCombo, chartTypeKey } =\n transformChartToPptxGenJS(element);\n\n if (element.data.options?.hasSecondaryAxis && chartTypesForCombo) {\n const comboChartTypes = chartTypesForCombo.map((chartTypeInfo) => ({\n type: chartTypeInfo.typeKey,\n data: chartTypeInfo.data,\n options: chartTypeInfo.options || {},\n }));\n\n slide.addChart(comboChartTypes as any, options as any);\n } else {\n const chartType = chartTypeKey;\n\n if (!chartType || !data) {\n return;\n }\n\n slide.addChart(chartType as any, data as any, options as any);\n }\n};\n","import type { SerializerStrategy, ExportConfig } from \"@/types/config.types\";\nimport type { PresentationDTO } from \"@/types/presentation.types\";\nimport type { PluginManagerInterface } from \"@/types/plugin.types\";\nimport PptxGenJS from \"pptxgenjs\";\nimport { pxToInches } from \"@/utils/units\";\nimport { serializeText } from \"./elements/text.serializer\";\nimport { serializeShape } from \"./elements/shape.serializer\";\nimport { serializeLine } from \"./elements/line.serializer\";\nimport { serializeImage } from \"./elements/image.serializer\";\nimport { serializeTable } from \"./elements/table.serializer\";\nimport { serializeChart } from \"./elements/plotly.serializer\";\nimport { assert } from \"@/utils/assert\";\n\nexport class PptxSerializer implements SerializerStrategy {\n private pluginManager: PluginManagerInterface | null = null;\n\n setPluginManager(pluginManager: PluginManagerInterface): void {\n this.pluginManager = pluginManager;\n }\n\n async serialize(\n presentation: PresentationDTO,\n _options: ExportConfig,\n ): Promise<ArrayBuffer> {\n assert(\n presentation.slides.length > 0,\n \"No slides to export. Check selector or create a slide to export\",\n );\n const pptx = new PptxGenJS();\n\n const widthInches = pxToInches(presentation.viewport.width);\n const heightInches = pxToInches(presentation.viewport.height);\n\n pptx.defineLayout({\n name: \"custom\",\n width: widthInches,\n height: heightInches,\n });\n pptx.layout = \"custom\";\n\n if (presentation.metadata.title) {\n pptx.title = presentation.metadata.title;\n }\n if (presentation.metadata.author) {\n pptx.author = presentation.metadata.author;\n }\n if (presentation.metadata.subject) {\n pptx.subject = presentation.metadata.subject;\n }\n\n for (const slideDTO of presentation.slides) {\n const slide = pptx.addSlide();\n\n for (const element of slideDTO.elements) {\n switch (element.type) {\n case \"text\":\n serializeText(slide, element, presentation.viewport);\n break;\n case \"image\":\n serializeImage(slide, element, presentation.viewport);\n break;\n case \"shape\":\n serializeShape(slide, element, presentation.viewport);\n break;\n case \"table\":\n serializeTable(slide, element, presentation.viewport);\n break;\n case \"chart\":\n serializeChart(slide, element);\n break;\n case \"line\":\n serializeLine(slide, element, presentation.viewport);\n break;\n }\n }\n }\n\n if (this.pluginManager) {\n await this.pluginManager.executeAfterGenerate(pptx, presentation);\n }\n\n const buffer = await pptx.write({ outputType: \"arraybuffer\" });\n return buffer as ArrayBuffer;\n }\n}\n","import type { ConverterConfig } from \"@/types/config.types\";\nimport { BaseConverter } from \"./base-converter\";\nimport { DEFAULT_CORE_PLUGINS, DEFAULTS } from \"@/constants\";\nimport { IframeParser } from \"@/parsers/iframe\";\nimport { PptxSerializer } from \"@/serializers/pptxgenjs\";\n\nexport class HtmlToPptx extends BaseConverter {\n constructor(config: Partial<ConverterConfig> = {}) {\n super({\n selector: config.selector || DEFAULTS.SLIDE_SELECTOR,\n dimensions: config.dimensions || {\n width: DEFAULTS.SLIDE_WIDTH,\n height: DEFAULTS.SLIDE_HEIGHT,\n },\n plugins: {\n core: config.plugins?.core ?? DEFAULT_CORE_PLUGINS,\n extensions: config.plugins?.extensions ?? [],\n },\n parser: config.parser || new IframeParser(),\n serializer: config.serializer || new PptxSerializer(),\n debug: config.debug,\n });\n }\n}\n"],"mappings":"yBAWA,IAAa,EAAb,KAA6D,CAC3D,QAA4B,EAAE,CAC9B,QAAiC,CAC/B,aAAc,IAAA,GACd,SAAU,EAAE,CACZ,MAAO,IAAI,IACZ,CAED,SAAS,EAAsB,CAC7B,GAAI,KAAK,QAAQ,KAAM,GAAM,EAAE,OAAS,EAAO,KAAK,CAClD,MAAU,MAAM,WAAW,EAAO,KAAK,yBAAyB,CAElE,KAAK,QAAQ,KAAK,EAAO,CAG3B,WAAW,EAAoB,CAC7B,IAAM,EAAQ,KAAK,QAAQ,UAAW,GAAM,EAAE,OAAS,EAAK,CACxD,IAAU,IACZ,KAAK,QAAQ,OAAO,EAAO,EAAE,CAIjC,YAAuB,CACrB,MAAO,CAAC,GAAG,KAAK,QAAQ,CAG1B,gBAAgB,EAAqC,CACnD,KAAK,QAAQ,aAAe,EAG9B,MAAM,mBACJ,EACA,EACiB,CACjB,IAAI,EAAS,EAEb,IAAK,IAAM,KAAU,KAAK,QACpB,EAAO,cACT,EAAS,MAAM,EAAO,YAAY,EAAQ,EAAQ,KAAK,QAAQ,EAInE,OAAO,EAGT,MAAM,eACJ,EACA,EAC4B,CAC5B,IAAK,IAAM,KAAU,KAAK,QAAS,CAIjC,GAHI,CAAC,EAAO,SAAW,CAAC,EAAO,SAG3B,CADa,IAAI,IAAI,EAAO,QAAQ,CAC1B,IAAI,EAAa,YAAY,CAAE,SAE7C,IAAM,EAAS,MAAM,EAAO,QAAQ,EAAS,EAAc,KAAK,QAAQ,CACxE,GAAI,EAAQ,OAAO,EAGrB,OAAO,KAGT,MAAM,eAAe,EAAoC,CACvD,IAAI,EAAS,EAEb,IAAK,IAAM,KAAU,KAAK,QACpB,EAAO,UACT,EAAS,MAAM,EAAO,QAAQ,EAAQ,KAAK,QAAQ,EAIvD,OAAO,EAGT,MAAM,qBACJ,EACA,EACe,CACf,IAAK,IAAM,KAAU,KAAK,QACpB,EAAO,eACT,MAAM,EAAO,cAAc,EAAM,EAAc,KAAK,QAAQ,GC3FvD,EAAb,cAAoC,KAAM,CACxC,YAAY,EAAiB,CAC3B,MAAM,qBAAqB,IAAU,CACrC,KAAK,KAAO,mBAIhB,SAAgB,EAAO,EAAoB,EAAoC,CAC7E,GAAI,CAAC,EACH,MAAM,IAAI,EAAe,EAAQ,CAIrC,SAAgB,EACd,EACA,EACoB,CACpB,GAAI,GAAU,KACZ,MAAM,IAAI,EAAe,EAAQ,CClBrC,MAAa,EAAsB,GACnB,EAAW,MAAM,IAAI,CAAC,IAAK,GAC7B,EACP,MAAM,CACN,QAAQ,eAAgB,GAAG,CAC3B,MAAM,CAGT,CACW,OAAQ,GAAS,GAAQ,KAAK,CAAC,KAAK,KAAK,CAG3C,EAAiB,GAA0B,CACtD,GAAI,CAAC,GAAS,IAAU,cAAe,MAAO,GAE9C,IAAM,EAAU,EAAM,MAAM,CAAC,QAAQ,KAAM,GAAG,CAE9C,GAAI,mBAAmB,KAAK,EAAQ,CAClC,OACE,EAAQ,GACR,EAAQ,GACR,EAAQ,GACR,EAAQ,GACR,EAAQ,GACR,EAAQ,GAIZ,GAAI,mBAAmB,KAAK,EAAQ,CAClC,OAAO,EAGT,IAAM,EAAW,EAAM,MAAM,iCAAiC,CAC9D,GAAI,EAAU,CACZ,GAAM,EAAG,EAAG,EAAG,GAAK,EACpB,MAAO,CAAC,EAAG,EAAG,EAAE,CACb,IAAK,GAAM,SAAS,EAAG,GAAG,CAAC,SAAS,GAAG,CAAC,SAAS,EAAG,IAAI,CAAC,CACzD,KAAK,GAAG,CAGb,MAAO,ICpCI,EAAmB,GAAsC,CACpE,IAAM,EAAM,SAAS,EAAO,GAAG,CAC/B,GAAI,CAAC,MAAM,EAAI,CAAE,OAAO,OAAO,EAAI,CAEnC,GADI,IAAU,QACV,IAAU,SAAU,MAAO,MAC/B,GAAI,IAAU,UAAW,MAAO,MAChC,GAAI,IAAU,SAAU,MAAO,OAIpB,EACX,GACwC,CACxC,GAAI,IAAU,SAAU,MAAO,SAC/B,GAAI,IAAU,UAAW,MAAO,UAChC,GAAI,IAAU,SAAU,MAAO,UAIpB,EACX,GACwC,CACxC,GAAI,IAAU,QAAU,IAAU,QAAS,MAAO,OAClD,GAAI,IAAU,SAAU,MAAO,SAC/B,GAAI,IAAU,SAAW,IAAU,MAAO,MAAO,QACjD,GAAI,IAAU,UAAW,MAAO,WAIrB,EACX,GAC4C,CAC5C,GAAI,IAAU,MAAO,MAAO,MAC5B,GAAI,IAAU,SAAU,MAAO,SAC/B,GAAI,IAAU,SAAU,MAAO,UAIpB,EAAqB,IACD,CAC7B,WAAY,EAAmB,EAAM,WAAW,EAAI,EAAS,YAC7D,SAAU,WAAW,EAAM,SAAS,EAAI,IAAA,GACxC,WAAY,EAAgB,EAAM,WAAW,CAC7C,UAAW,EAAe,EAAM,UAAU,CAC1C,cAAe,WAAW,EAAM,cAAc,EAAI,IAAA,GAClD,WAAY,WAAW,EAAM,WAAW,EAAI,IAAA,GAC5C,MAAO,EAAc,EAAM,MAAM,EAAI,IAAA,GACrC,UAAW,EAAM,oBAAoB,SAAS,YAAY,EAAI,GAC9D,cAAe,EAAM,oBAAoB,SAAS,eAAe,EAAI,GACrE,UAAW,EAAe,EAAM,UAAU,CAC1C,cAAe,EAAmB,EAAM,cAAc,CACvD,EAKU,EAAkB,IAAyC,CACtE,IAAK,WAAW,EAAM,WAAW,EAAI,EACrC,MAAO,WAAW,EAAM,aAAa,EAAI,EACzC,OAAQ,WAAW,EAAM,cAAc,EAAI,EAC3C,KAAM,WAAW,EAAM,YAAY,EAAI,EACxC,EAEY,EACX,GACuB,CACvB,IAAM,EAAY,EAAM,UACxB,GAAI,CAAC,GAAa,IAAc,OAAQ,OAExC,IAAM,EAAc,EAAU,MAAM,oBAAoB,CACxD,GAAI,EAEF,OADY,WAAW,EAAY,GAAG,EACxB,IAAA,GAGhB,IAAM,EAAc,EAAU,MAAM,oBAAoB,CACxD,GAAI,EAAa,CACf,IAAM,EAAS,EAAY,GAAG,MAAM,IAAI,CAAC,IAAK,GAAM,WAAW,EAAE,MAAM,CAAC,CAAC,CACzE,GAAI,EAAO,QAAU,EAAG,CACtB,IAAM,EAAI,EAAO,GACX,EAAI,EAAO,GAEX,EADU,KAAK,MAAM,EAAG,EAAE,EACL,IAAM,KAAK,IACtC,OAAO,KAAK,IAAI,EAAQ,CAAG,IAAO,IAAA,GAAY,KAOvC,EACX,GACuB,CACvB,IAAM,EAAU,WAAW,EAAM,QAAQ,CACzC,OAAO,IAAY,EAAI,IAAA,GAAY,GAAW,IAAA,IAGnC,EACX,GAEO,SAAS,EAAM,OAAQ,GAAG,EAAI,IAAA,GCtG1B,GACX,EACA,KACc,CACd,KAAM,EAAY,KAAO,EAAc,KACvC,IAAK,EAAY,IAAM,EAAc,IACtC,EAEY,GACX,EACA,EAAiB,KACD,CAChB,MAAO,EAAK,MAAQ,EACpB,OAAQ,EAAK,OACd,ECdK,EAAY,IAAI,IAAI,CACxB,KACA,KACA,KACA,KACA,KACA,KACA,IACA,OACA,MACA,IACA,KACA,QACA,SACA,KACA,IAEA,IACA,IACA,QACA,OACD,CAAC,CAEI,EAAa,IAAI,IAAI,CAAC,MAAO,UAAW,MAAM,CAAC,CAC/C,GAAa,IAAI,IAAI,CAAC,QAAQ,CAAC,CAC/B,GAAsB,IAAI,IAAI,CAClC,KACA,KACA,KACA,QACA,QACA,QACA,UACA,WACA,MACD,CAAC,CAEW,IACX,EACA,EAAc,SACI,CAClB,IAAMA,EAAuB,EAAE,CACzB,EAAU,EAAQ,QAAQ,aAAa,CAE7C,GAAI,GAAW,IAAI,EAAQ,CAEzB,OADA,EAAM,KAAK,QAAQ,CACZ,EAGT,GAAI,GAAoB,IAAI,EAAQ,CAClC,OAAO,EAOT,GAJI,EAAQ,GAAG,aAAa,CAAC,SAAS,QAAQ,EAC5C,EAAM,KAAK,QAAQ,CAGjB,EAAW,IAAI,EAAQ,CAEzB,OADA,EAAM,KAAK,QAAQ,CACZ,EAGT,GAAI,IAAY,KAEd,OADA,EAAM,KAAK,OAAO,CACX,EAGT,GAAI,GAAa,EAAQ,CAEvB,OADA,EAAM,KAAK,OAAO,CACX,EAGT,IAAM,EAAQ,EAAI,iBAAiB,EAAQ,CAgB3C,OAdyB,GAAsB,EAAM,EAEnD,EAAM,KAAK,QAAQ,CAGI,EAAoB,EAAM,EAEjD,EAAM,KAAK,OAAO,CAGhB,EAAU,IAAI,EAAQ,EAAI,GAAkB,EAAQ,EACtD,EAAM,KAAK,OAAO,CAGb,GAGH,GAAyB,GAAwC,CACrE,IAAM,EACJ,EAAM,kBAAoB,eAC1B,EAAM,kBAAoB,mBAEtB,EACJ,EAAM,kBAAoB,QAAU,EAAM,kBAAoB,GAE1D,EACJ,WAAW,EAAM,YAAY,CAAG,GAChC,EAAM,cAAgB,eACtB,EAAM,cAAgB,mBAElB,EAAY,EAAM,YAAc,QAAU,EAAM,YAAc,GAE9D,EAAkB,WAAW,EAAM,aAAa,CAAG,EAEzD,OACE,GACA,GACA,GACA,GACA,GAIS,EACX,GACkE,CAClE,IAAM,EAAM,EAAQ,aAAa,CAKjC,OAJK,EAAU,IAAI,EAAQ,CACvB,WAAW,KAAK,EAAI,CACf,EACL,IAAQ,IAAY,IACjB,OAJ6B,MAOzB,IACX,EACA,IACqC,CACrC,IAAM,EAAe,WAAW,EAAM,aAAa,EAAI,EACjD,CAAE,QAAO,UAAW,EAe1B,OAVI,GAHiB,KAAK,IAAI,EAAO,EAAO,CACX,EAED,IAC1B,KAAK,IAAI,EAAQ,EAAO,CAAG,EACtB,UAIP,EAAe,EACV,YAGF,QAGH,GAAqB,GAAkC,CAC3D,IAAK,IAAM,KAAQ,EAAQ,WACzB,GAAI,EAAK,WAAa,KAAK,WACrB,EAAK,aAAe,EAAK,YAAY,MAAM,CAAC,OAAS,EACvD,MAAO,GAIb,MAAO,IAGI,EACX,GAC+C,CAC/C,IAAM,EAAY,WAAW,EAAM,gBAAgB,EAAI,EACjD,EAAa,WAAW,EAAM,iBAAiB,EAAI,EACnD,EAAW,WAAW,EAAM,eAAe,EAAI,EAC/C,EAAc,WAAW,EAAM,kBAAkB,EAAI,EASrD,EAPQ,CACZ,CAAE,KAAM,OAAiB,MAAO,EAAW,CAC3C,CAAE,KAAM,QAAkB,MAAO,EAAY,CAC7C,CAAE,KAAM,MAAgB,MAAO,EAAU,CACzC,CAAE,KAAM,SAAmB,MAAO,EAAa,CAChD,CAEyB,OAAQ,GAAM,EAAE,MAAQ,EAAE,CAMpD,OAJI,EAAY,SAAW,EAClB,EAAY,GAAG,KAGjB,MAGI,GAAgB,GACvB,EAAQ,QAAQ,aAAa,GAAK,IAEpB,MAAM,KAAK,EAAQ,UAAU,CAC9B,KAAM,GAAQ,EAAI,WAAW,MAAM,EAAI,IAAQ,KAAK,CAHnB,GCzLvC,EAAe,GAA0B,CACpD,IAAMC,EAAkB,EAAE,CAE1B,IAAK,IAAM,KAAS,EAAK,WAAY,CACnC,GAAI,EAAM,WAAa,KAAK,UAAW,CACrC,IAAM,EAAO,EAAM,aAAa,QAAQ,OAAQ,IAAI,EAAI,GACpD,EAAK,MAAM,CAAC,OAAS,GACvB,EAAK,KAAK,CAAE,QAAS,EAAM,CAAC,CAIhC,GAAI,EAAM,WAAa,KAAK,aAAc,CACxC,IAAM,EAAK,EACL,EAAU,EAAG,QAAQ,aAAa,CAExC,GAAI,IAAY,KAAM,CACpB,EAAK,KAAK,CAAE,QAAS;EAAM,CAAC,CAC5B,SAGF,IAAM,EAAY,EAAG,WAAa,GAE5B,EADM,EAAG,cACG,YAAa,iBAAiB,EAAG,CAE7C,EAAY,EAAY,EAAG,CAEjC,GAAI,CADa,EAAa,EAAQ,CACvB,SAEf,IAAMC,EAAe,CACnB,QAAS,EAAG,aAAe,GAClB,UACE,YACX,WAAY,EAAkB,EAAM,CACpC,SAAU,EAAU,OAAS,EAAI,EAAY,IAAA,GAC9C,CAEG,IAAY,MACd,EAAI,KAAO,EAAG,aAAa,OAAO,EAAI,IAAA,IAGxC,EAAK,KAAK,EAAI,EAIlB,OAAO,GAGI,GAAsB,GAAuB,CACxD,IAAI,EAAO,GAEL,EAAe,GAAkB,CACrC,GAAI,EAAE,WAAa,KAAK,UAAW,CACjC,GAAQ,EAAE,aAAe,GACzB,OAGF,GAAI,EAAE,WAAa,KAAK,aAAc,CAEpC,IAAM,EADK,EACQ,QAAQ,aAAa,CAExC,GAAI,IAAY,KAAM,CACpB,GAAQ;EACR,OAGF,IAAK,IAAM,KAAS,EAAE,WACpB,EAAY,EAAM,EAGhB,IAAY,KAAO,IAAY,QAC7B,EAAE,cACJ,GAAQ;KAMhB,IAAK,IAAM,KAAS,EAAK,WACvB,EAAY,EAAM,CAGpB,OAAO,EAAK,MAAM,ECpEd,IACJ,EACA,IACY,CACZ,IAAM,EAAe,EAAQ,iBAA8B,IAAI,CAC3D,EAAa,EAEjB,IAAK,IAAM,KAAQ,EACjB,GAAI,GAAa,EAAK,CAAE,CAEtB,IAAM,EADW,EAAK,uBAAuB,CACtB,MAEjB,EAAQ,EAAK,cAAc,YAAa,iBAAiB,EAAK,CAC9D,EAAc,WAAW,EAAM,YAAY,EAAI,EAErD,GAAc,EAAQ,EAI1B,OAAO,IAAI,QACT,EAAK,KAAO,EACZ,EAAK,IACL,EAAK,MAAQ,EACb,EAAK,OACN,EAGUC,EAAqC,CAChD,KAAM,YACN,QAAS,CAAC,OAAO,CACjB,SAAU,EAAS,IAAiB,CAClC,GAAM,CAAE,gBAAe,eAAc,UAAS,gBAAiB,EAEzD,EAAU,EAAQ,aAAa,MAAM,CAC3C,GAAI,CAAC,EAAS,OAAO,KAErB,IAAM,EAAW,EAAa,EAAQ,CACtC,GAAI,CAAC,EAAU,OAAO,KAEtB,IAAM,EAAY,EAAa,uBAAuB,CAEhD,EAAe,GAA2B,EAAS,EAAa,CAEhE,EAAW,EAAwB,EAAc,EAAU,CAC3D,EAAa,EAAkB,EAAc,GAAkB,CAE/D,EAAO,EAAY,EAAQ,CAiBjC,MAfoC,CAClC,KAAM,OACN,GAAI,OAAO,YAAY,CACvB,UACA,KAAM,EAAK,OAAS,EAAI,EAAO,IAAA,GACrB,WACE,aACZ,WAAY,EAAkB,EAAc,CAC5C,WACA,QAAS,EAAe,EAAc,CACtC,OAAQ,EAAc,EAAc,CACpC,SAAU,EAAgB,EAAc,CACxC,QAAS,EAAe,EAAc,CACvC,EAIJ,CChFY,EAAqB,GAAqC,CACrE,IAAM,EAAY,EAAK,MACrB,uDACD,CAED,GAAI,EAAW,CACb,IAAM,EAAU,WAAW,EAAU,GAAG,CACxC,GAAI,EAAU,EACZ,OAAO,ICCP,GAAsB,GAAiC,CAC3D,IAAMC,EAAwB,EAAE,CAC1B,EAAiB,uDACnB,EACA,EAAQ,EAEZ,MAAQ,EAAQ,EAAe,KAAK,EAAK,IAAM,MAAM,CACnD,GAAM,EAAG,EAAW,GAAgB,EAC9B,EAAM,EAAc,EAAU,CACpC,GAAI,CAAC,EAAK,SAEV,IAAI,EAAW,EACf,AAGE,EAHE,EACS,WAAW,EAAa,CAAG,IAE3B,IAAU,EAAI,EAAI,EAG/B,IAAM,EAAU,EAAkB,EAAU,CAC5C,EAAM,KAAK,CAAE,MAAO,EAAK,WAAU,UAAS,CAAC,CAC7C,IAGF,OAAO,GAGH,GAAsB,GAA6B,CACvD,IAAM,EAAW,EAAS,MAAM,WAAW,CAC3C,GAAI,EACF,OAAO,SAAS,EAAS,GAAI,GAAG,CAclC,IAAK,GAAM,CAAC,EAAW,KAAU,OAAO,QAXK,CAC3C,SAAU,EACV,WAAY,GACZ,YAAa,IACb,UAAW,IACX,eAAgB,GAChB,kBAAmB,IACnB,iBAAkB,IAClB,cAAe,IAChB,CAE4D,CAC3D,GAAI,EAAS,SAAS,EAAU,CAC9B,OAAO,EAIX,MAAO,MAGI,EAAe,GAAiD,CAC3E,IAAM,EAAU,EAAM,gBAEtB,GAAI,GAAW,IAAY,OAAQ,CACjC,GAAI,EAAQ,SAAS,kBAAkB,CAAE,CACvC,IAAM,EAAQ,GAAmB,EAAQ,CACzC,GAAI,EAAM,QAAU,EAOlB,MAN+B,CAC7B,KAAM,WACN,aAAc,SACd,MAAO,GAAmB,EAAQ,CAClC,QACD,CAKL,GAAI,EAAQ,SAAS,kBAAkB,CAAE,CACvC,IAAM,EAAQ,GAAmB,EAAQ,CACzC,GAAI,EAAM,QAAU,EAMlB,MAL+B,CAC7B,KAAM,WACN,aAAc,SACd,QACD,EAMP,IAAM,EAAU,EAAM,gBACtB,GAAI,CAAC,GAAW,IAAY,eAAiB,IAAY,mBACvD,OAGF,IAAM,EAAM,EAAc,EAAQ,CAC7B,KAUL,MANwB,CACtB,KAAM,QACN,MAAO,EACP,QALc,EAAkB,EAAQ,CAMzC,EAKU,GACX,GACuB,CACvB,IAAM,EAAc,WAAW,EAAM,YAAY,EAAI,EACrD,GAAI,IAAgB,EAAG,OAEvB,IAAM,EAAc,EAAM,YACpB,EAAM,EAAc,EAAY,CACtC,GAAI,CAAC,EAAK,OAEV,IAAM,EAAc,EAAM,YACtBC,EAA6C,QAC7C,IAAgB,SAAU,EAAc,SACnC,IAAgB,WAAU,EAAc,UAEjD,IAAIC,EACE,EAAe,EAAY,MAAM,6BAA6B,CACpE,GAAI,EAAc,CAChB,IAAM,EAAmB,WAAW,EAAa,GAAG,CAChD,EAAmB,IACrB,EAAU,GAId,MAAO,CACL,MAAO,EACP,MAAO,EACP,MAAO,EACE,UACV,EAGU,GACX,GACuB,CACvB,IAAM,EAAS,WAAW,EAAM,aAAa,EAAI,EAC7C,OAAW,EACf,OAAO,GCnIIC,EAAuC,CAClD,KAAM,aACN,QAAS,CAAC,QAAQ,CAClB,SAAU,EAAU,IAAiB,CACnC,GAAM,CAAE,gBAAe,eAAc,gBAAiB,EAEhD,EAAY,EAAa,uBAAuB,CAgBtD,MAdsC,CACpC,KAAM,QACN,GAAI,OAAO,YAAY,CACvB,UAAW,GAAc,EAAe,EAAa,CACrD,SAAU,EAAwB,EAAc,EAAU,CAC1D,WAAY,EAAkB,EAAa,CAC3C,KAAM,EAAY,EAAc,CAChC,OAAQ,GAAc,EAAc,CACpC,aAAc,GAAoB,EAAc,CAChD,OAAQ,EAAc,EAAc,CACpC,SAAU,EAAgB,EAAc,CACxC,QAAS,EAAe,EAAc,CACvC,EAIJ,CC/BK,IACJ,EACA,IACW,CACX,IAAI,EAAQ,EACR,EAAc,aACd,EAAc,QAEd,IAAS,QACX,EAAQ,WAAW,EAAM,gBAAgB,EAAI,EAC7C,EAAc,EAAM,iBAAmB,aACvC,EAAc,EAAM,iBAAmB,SAC9B,IAAS,SAClB,EAAQ,WAAW,EAAM,iBAAiB,EAAI,EAC9C,EAAc,EAAM,kBAAoB,aACxC,EAAc,EAAM,kBAAoB,SAC/B,IAAS,OAClB,EAAQ,WAAW,EAAM,eAAe,EAAI,EAC5C,EAAc,EAAM,gBAAkB,aACtC,EAAc,EAAM,gBAAkB,UAEtC,EAAQ,WAAW,EAAM,kBAAkB,EAAI,EAC/C,EAAc,EAAM,mBAAqB,aACzC,EAAc,EAAM,mBAAqB,SAG3C,IAAM,EAAM,EAAc,EAAY,EAAI,SAEtCC,EAA6C,QAC7C,IAAgB,SAAU,EAAc,SACnC,IAAgB,WAAU,EAAc,UAEjD,IAAIC,EACE,EAAY,EAAY,MAC5B,uDACD,CACD,GAAI,EAAW,CACb,IAAM,EAAmB,WAAW,EAAU,GAAG,CAC7C,EAAmB,IACrB,EAAU,GAId,MAAO,CACL,MAAO,EACA,QACP,MAAO,EACE,UACV,EAGG,IACJ,EACA,EACA,IACuC,CACvC,IAAM,EAAU,EAAa,KAAO,EAAU,KACxC,EAAS,EAAa,IAAM,EAAU,IACtC,EAAW,EAAU,EAAa,MAClC,EAAY,EAAS,EAAa,OAuBxC,OArBI,IAAS,OACJ,CACL,MAAO,CAAE,KAAM,EAAS,IAAK,EAAQ,CACrC,IAAK,CAAE,KAAM,EAAS,IAAK,EAAW,CACvC,CAGC,IAAS,QACJ,CACL,MAAO,CAAE,KAAM,EAAU,IAAK,EAAQ,CACtC,IAAK,CAAE,KAAM,EAAU,IAAK,EAAW,CACxC,CAGC,IAAS,MACJ,CACL,MAAO,CAAE,KAAM,EAAS,IAAK,EAAQ,CACrC,IAAK,CAAE,KAAM,EAAU,IAAK,EAAQ,CACrC,CAGI,CACL,MAAO,CAAE,KAAM,EAAS,IAAK,EAAW,CACxC,IAAK,CAAE,KAAM,EAAU,IAAK,EAAW,CACxC,EAGUC,EAAqC,CAChD,KAAM,YACN,QAAS,CAAC,OAAO,CACjB,SAAU,EAAU,IAAiB,CACnC,GAAM,CAAE,gBAAe,eAAc,UAAS,gBAAiB,EAEzD,EAAY,EAAa,uBAAuB,CAElDC,EACAC,EACAC,EAEJ,GAAI,IAAY,KAAM,CACpB,IAAM,EAAU,EAAa,KAAO,EAAU,KACxC,EAAS,EAAa,IAAM,EAAU,IACtC,EAAW,EAAU,EAAa,MAExC,EAAQ,CAAE,KAAM,EAAS,IAAK,EAAQ,CACtC,EAAM,CAAE,KAAM,EAAU,IAAK,EAAQ,CAErC,IAAM,EAAc,WAAW,EAAc,eAAe,EAAI,EAIhE,EAAS,CACP,MAHU,EADQ,EAAc,gBAAkB,aACd,EAAI,SAIxC,MAAO,EACP,MAAO,QACR,KACI,CACL,IAAM,EAAO,EAAoB,EAAc,CAC/C,GAAI,CAAC,EAAM,OAAO,KAElB,IAAM,EAAY,GAAuB,EAAc,EAAW,EAAK,CACvE,EAAQ,EAAU,MAClB,EAAM,EAAU,IAChB,EAAS,GAAkB,EAAe,EAAK,CAcjD,MAXoC,CAClC,KAAM,OACN,GAAI,OAAO,YAAY,CAChB,QACF,MACG,SACR,OAAQ,EAAc,EAAc,CACpC,SAAU,EAAgB,EAAc,CACxC,QAAS,EAAe,EAAc,CACvC,EAIJ,CCnJY,GACX,EACA,EACA,IACuB,CACvB,GAAI,IAAU,EAAG,OAEjB,IAAM,EAAM,EAAc,EAAM,CAChC,GAAI,CAAC,EAAK,OAEV,IAAIC,EAA6C,QAC7C,IAAgB,SAAU,EAAc,SACnC,IAAgB,WAAU,EAAc,UAEjD,IAAM,EAAU,EAAkB,EAAM,CAExC,MAAO,CACL,MAAO,EACA,QACP,MAAO,EACE,UACV,ECbG,EAAqB,GAAmD,CAC5E,IAAM,EAAW,WAAW,EAAM,eAAe,EAAI,EAC/C,EAAa,WAAW,EAAM,iBAAiB,EAAI,EACnD,EAAc,WAAW,EAAM,kBAAkB,EAAI,EACrD,EAAY,WAAW,EAAM,gBAAgB,EAAI,EAIvD,GAAI,EADF,EAAW,GAAK,EAAa,GAAK,EAAc,GAAK,EAAY,GACnD,OAEhB,IAAMC,EAAiB,EAAE,CAkCzB,OAhCI,EAAW,IACb,EAAO,IAAM,EACX,EAAM,eACN,EACA,EAAM,eACP,EAGC,EAAa,IACf,EAAO,MAAQ,EACb,EAAM,iBACN,EACA,EAAM,iBACP,EAGC,EAAc,IAChB,EAAO,OAAS,EACd,EAAM,kBACN,EACA,EAAM,kBACP,EAGC,EAAY,IACd,EAAO,KAAO,EACZ,EAAM,gBACN,EACA,EAAM,gBACP,EAGI,GAGH,GAAkB,GAA6C,CACnE,IAAM,EAAM,EAAK,cACX,EAAQ,EAAI,YAAa,iBAAiB,EAAK,CAEjD,EAAO,EAAY,EAAM,CACzB,EAAS,EAAkB,EAAM,CAE/B,EAAM,EAAK,cACjB,GAAI,EAAK,CACP,IAAM,EAAW,EAAI,YAAa,iBAAiB,EAAI,CACvD,AACE,IAAO,EAAY,EAAS,CAE9B,AACE,IAAS,EAAkB,EAAS,CAIxC,IAAM,EAAO,EAAY,EAAK,CACxBC,EAAwB,CAC5B,GAAI,OAAO,YAAY,CACvB,KAAM,GAAmB,EAAK,CAC9B,KAAM,EAAK,OAAS,EAAI,EAAO,IAAA,GAC/B,WAAY,EAAkB,EAAM,CAC9B,OACE,SACT,CAUD,OARI,EAAK,QAAU,IACjB,EAAQ,QAAU,EAAK,SAGrB,EAAK,QAAU,IACjB,EAAQ,QAAU,EAAK,SAGlB,GAGH,GAAkB,GAA8C,CACpE,IAAMC,EAAyB,EAAE,CAC3B,EAAY,EAAM,iBAAiB,KAAK,CAE9C,IAAK,IAAM,KAAO,EAAW,CAC3B,IAAMC,EAAwB,EAAE,CAC1B,EAAa,EAAI,iBAAuC,SAAS,CAEvE,IAAK,IAAM,KAAQ,EACjB,EAAM,KAAK,GAAe,EAAK,CAAC,CAG9B,EAAM,OAAS,GACjB,EAAK,KAAK,EAAM,CAIpB,OAAO,GAGH,GAAuB,GAAsC,CACjE,IAAM,EAAW,EAAM,cAAc,KAAK,CAC1C,GAAI,CAAC,EAAU,MAAO,EAAE,CAExB,IAAM,EAAQ,EAAS,iBAAuC,SAAS,CACvE,GAAI,EAAM,SAAW,EAAG,MAAO,EAAE,CAEjC,IAAMC,EAAmB,EAAE,CAE3B,IAAK,IAAM,KAAQ,EAAO,CACxB,IAAM,EAAY,EAAK,uBAAuB,CAAC,MAC/C,EAAO,KAAK,EAAU,CAGxB,OAAO,GAGIC,EAAuC,CAClD,KAAM,aACN,QAAS,CAAC,QAAQ,CAClB,SAAU,EAAS,IAAiB,CAClC,GAAM,CAAE,eAAc,gBAAiB,EAEjC,EAAQ,EACR,EAAY,EAAa,uBAAuB,CAEhD,EAAO,GAAe,EAAM,CAClC,GAAI,EAAK,SAAW,EAAG,OAAO,KAE9B,IAAM,EAAY,EAAM,cAAc,QAAQ,GAAK,KAC7C,EAAoB,EAAM,cAAc,KAAK,GAAK,KAClD,EAAY,GAAoB,EAAM,CAY5C,MAVsC,CACpC,KAAM,QACN,GAAI,OAAO,YAAY,CACvB,SAAU,EAAwB,EAAc,EAAU,CAC1D,WAAY,EAAkB,EAAa,CACrC,OACN,UAAW,EAAU,OAAS,EAAI,EAAY,IAAA,GAC9C,UAAW,GAAa,EACzB,EAIJ,CC1JY,GAAuB,GAAmC,CACrE,GAAI,CAAC,GAAU,OAAO,GAAW,SAC/B,MAAO,UAGT,IAAM,EAAY,EAclB,OAXE,MAAM,QAAQ,EAAU,KAAK,EAC3B,EAAU,KAAK,OAAS,GACxB,EAAU,KAAK,IACf,OAAO,EAAU,KAAK,IAAO,UAC7B,SAAW,EAAU,KAAK,GAIrB,SAGF,WAGI,GACX,GACgC,CAChC,IAAM,EAAS,IAAI,IAkDnB,OAhDqB,EAAI,iBACvB,iDACD,CAEY,QAAS,GAAW,CAC/B,IAAM,EAAU,EAAO,aAAa,gBAAgB,CAC9C,EAAY,EAAO,aAAa,kBAAkB,CAEpD,MAAC,GAAW,CAAC,IAIA,EAAI,eAAe,EAAQ,CAK5C,GAAI,CACF,IAAM,EAAS,KAAK,MAAM,EAAO,aAAe,KAAK,CAE/C,EAAY,EASlB,GAAI,EAPF,MAAM,QAAQ,EAAU,KAAK,EAC3B,EAAU,KAAK,OAAS,GACxB,EAAU,KAAK,IACf,OAAO,EAAU,KAAK,IAAO,UAC7B,SAAW,EAAU,KAAK,IAI5B,OAGF,IAAM,EAAgB,GAAoB,EAAO,CAC3C,EAAqB,EAAU,KAAkC,GACpE,KAEH,EAAO,IAAI,EAAS,CAClB,UACA,UAAW,GAAqB,EAChC,SACA,gBACD,CAAC,MACI,CACN,SAEF,CAEK,GAGH,EAAe,GACd,MAAM,QAAQ,EAAO,CACnB,EAAO,IAAK,GACb,GAAU,KAAoC,GAC3C,OAAO,EAAM,CACpB,CAJiC,EAAE,CAOjC,EAAe,GACd,MAAM,QAAQ,EAAO,CACnB,EAAO,IAAK,GAAU,CAC3B,IAAM,EAAM,OAAO,EAAM,CACzB,OAAO,MAAM,EAAI,CAAG,EAAI,GACxB,CAJiC,EAAE,CA6CjC,GAA2B,GAAoC,CACnE,IAAK,IAAM,KAAS,EAAQ,CAC1B,GAAI,EAAM,QAAU,MAAM,QAAQ,EAAM,OAAO,CAC7C,OAAO,EAAY,EAAM,OAAO,CAGlC,GAAI,EAAM,cAAgB,KAAO,EAAM,GAAK,MAAM,QAAQ,EAAM,EAAE,CAChE,OAAO,EAAY,EAAM,EAAE,CAG7B,GAAI,EAAM,GAAK,MAAM,QAAQ,EAAM,EAAE,CACnC,OAAO,EAAY,EAAM,EAAE,CAG/B,MAAO,EAAE,EAGL,GAAgB,GAA2C,CAC/D,GAAI,EAAM,QAAQ,OAAS,OAAO,EAAM,OAAO,OAAU,SACvD,OAAO,EAAM,OAAO,MAGtB,GAAI,EAAM,MAAM,OAAS,OAAO,EAAM,KAAK,OAAU,SACnD,OAAO,EAAM,KAAK,OAMhB,GAAiB,GAA6C,CAClE,GAAI,EAAM,QAAQ,QAAU,MAAM,QAAQ,EAAM,OAAO,OAAO,CAC5D,OAAO,EAAM,OAAO,OAGtB,GAAI,EAAM,QAAQ,OAAS,MAAM,QAAQ,EAAM,OAAO,MAAM,CAC1D,OAAO,EAAM,OAAO,OAMlB,GAAgB,GAA6C,CAC5D,KAAO,MAEZ,IAAI,OAAO,EAAO,OAAU,SAC1B,OAAO,EAAO,MAGhB,GAAI,OAAO,EAAO,OAAU,UAAY,EAAO,MAAM,KACnD,OAAO,EAAO,MAAM,OAMlB,GAAwB,GAA6C,CACpE,KAAO,MAEZ,IAAI,OAAO,EAAO,OAAU,SAC1B,MAAO,IAGT,GAAI,OAAO,EAAO,OAAU,UAAY,EAAO,MAAM,KACnD,OAAO,EAAO,MAAM,KAAK,OAMvB,EAAoB,GAAoD,CACxE,MAAC,GAAQ,CAAC,EAAK,OAEnB,IAAI,OAAO,EAAK,OAAU,SACxB,OAAO,EAAK,MAGd,GAAI,OAAO,EAAK,OAAU,UAAY,EAAK,MAAM,KAC/C,OAAO,EAAK,MAAM,OAMT,GAA8B,GAAoC,CAC7E,IAAM,EAAS,EAAO,MAAQ,EAAE,CAC1B,EAAS,EAAO,QAAU,EAAE,CAElC,GAAI,EAAO,SAAW,EACpB,MAAU,MAAM,iCAAiC,CAGnD,IAAM,EAAa,EAAO,GAEpB,EAAY,GADC,GAAY,MAAQ,OACK,aAAa,GAAK,MAExD,EAAS,GAAwB,EAAO,CAExCC,EAAwB,EAAO,IAAK,GAAU,CAClD,IAAMC,EAA0B,CAC9B,KAAM,EAAM,MAAQ,SACpB,OAAQ,EAAE,CACV,MAAO,GAAa,EAAM,CAC1B,OAAQ,GAAc,EAAM,CAC7B,CAEK,EAAY,EAAM,MAAQ,MAiBhC,MAhBA,GAAW,UAAY,EAAe,EAAU,aAAa,GAAK,EAE9D,EAAM,OACR,EAAW,OAAS,EAAY,EAAM,OAAO,CACpC,EAAM,cAAgB,KAAO,EAAM,EAC5C,EAAW,OAAS,EAAY,EAAM,EAAE,CAC/B,EAAM,IACf,EAAW,OAAS,EAAY,EAAM,EAAE,EAGtC,EAAM,QAAU,KAClB,EAAW,MAAQ,KACV,EAAM,QAAU,OACzB,EAAW,MAAQ,MAGd,GACP,CAEIC,EAAwB,CAC5B,MAAO,GAAa,EAAO,CAC3B,cAAe,GAAqB,EAAO,CAC3C,WAAY,EAAO,aAAe,GAClC,WAAY,EAAiB,EAAO,MAAM,CAC1C,WAAY,EAAiB,EAAO,MAAM,CAC1C,OAAQ,EAAO,OAChB,CAuDD,OArDI,EAAO,SACT,EAAQ,iBAAmB,GAC3B,EAAQ,YAAc,EAAiB,EAAO,OAAO,GAGjC,EAAO,KAC1B,GAAU,EAAM,MAAQ,MAAM,QAAQ,EAAM,KAAK,EAAI,EAAM,KAAK,OAAS,EAC3E,EACoB,EAAW,YAC9B,EAAQ,eAAiB,IAGvB,IAAc,QAChB,EAAQ,YACN,EAAW,cAAgB,IAAM,aAAe,WAE9C,EAAO,UAAY,SACrB,EAAQ,YAAc,UACtB,EAAQ,QAAU,SACT,EAAO,UAAY,SAC5B,EAAQ,YAAc,YACtB,EAAQ,QAAU,SACT,EAAO,UAAY,aAC5B,EAAQ,YAAc,iBACtB,EAAQ,QAAU,YAGhB,EAAW,eACb,EAAQ,kBAAoB,EAAW,eAIvC,IAAc,QACZ,EAAW,OAAS,IAAA,KACtB,EAAQ,KAAO,EAAW,MAGxB,EAAW,WACb,EAAQ,gBAAkB,EAAW,UAGnC,EAAW,eACb,EAAQ,kBAAoB,EAAW,eAIvC,EAAO,OACT,EAAQ,KAAO,CACb,OAAQ,EAAO,KAAK,OACpB,KAAM,EAAO,KAAK,KACnB,EAGI,CACL,YACA,SACA,SACA,UACD,ECxTUC,EAAuB,CAClC,KAAM,oBACN,QAAS,CAAC,QAAQ,CAClB,aAAc,EAAM,EAAS,IAAY,CAIvC,IAAM,EAAkB,GAHT,IAAI,WAAW,CACX,gBAAgB,EAAM,YAAY,CAEH,CAElD,GAAI,EAAgB,OAAS,EAC3B,OAAO,EAGT,IAAMC,EAA0B,CAC9B,kBACA,eAAgB,IAAI,IACrB,CAID,OAFA,EAAQ,MAAM,IAAI,EAAa,KAAM,EAAM,CAEpC,GAGT,SAAU,EAAS,EAAc,IAAkB,CACjD,IAAM,EAAQ,EAAc,MAAM,IAAI,EAAa,KAAK,CAIxD,GAAI,CAAC,GAAS,EAAM,gBAAgB,OAAS,EAAG,OAAO,KAEvD,IAAM,EAAM,EAAQ,cACd,CAAE,aAAY,gBAAiB,EAC/B,EAAY,EAAa,uBAAuB,CAkBtD,OAhBA,EAAM,gBAAgB,SAAS,EAAG,IAAY,CAC5C,GAAI,EAAM,eAAe,IAAI,EAAQ,CAAE,OAEvC,IAAM,EAAW,EAAI,eAAe,EAAQ,CAC5C,GAAI,CAAC,GAAY,CAAC,EAAa,SAAS,EAAS,CAAE,OAEnD,IAAM,EAAY,EAAS,uBAAuB,CAClD,EAAM,eAAe,IAAI,EAAS,CAChC,KAAM,EAAU,KAAO,EAAU,KACjC,IAAK,EAAU,IAAM,EAAU,IAC/B,MAAO,EAAU,MACjB,OAAQ,EAAU,OAClB,aACD,CAAC,EACF,CAEK,MAGT,SAAU,EAAO,IAAY,CAC3B,IAAM,EAAQ,EAAQ,MAAM,IAAI,EAAa,KAAK,CAQlD,GAJI,CAAC,GAAS,EAAM,gBAAgB,OAAS,GAIzC,EAAM,eAAe,OAAS,EAChC,OAAO,EAGT,GAAM,CAAE,kBAAiB,kBAAmB,EAEtC,EAAkB,IAAI,IACtBC,EAAmC,EAAE,CAE3C,EAAgB,SAAS,EAAW,IAAY,CAC9C,IAAM,EAAc,EAAe,IAAI,EAAQ,CAC/C,GAAI,CAAC,GAAe,EAAY,aAAe,EAAM,MAAO,OAE5D,IAAI,EAAiB,GACjB,EAAe,IAiBnB,GAfA,EAAM,SAAS,SAAS,EAAI,IAAU,CAEpC,GADI,EAAG,OAAS,SACZ,EAAgB,IAAI,EAAM,CAAE,OAEhC,IAAM,EAAW,KAAK,MACX,EAAG,SAAS,KAAO,EAAY,OAAM,GACnC,EAAG,SAAS,IAAM,EAAY,MAAK,EAC/C,CAEG,EAAW,IACb,EAAe,EACf,EAAiB,IAEnB,CAEE,IAAmB,GAAI,CACzB,IAAIC,EACJ,GAAI,CACF,GAAI,EAAU,gBAAkB,SAC9B,EAAe,GACb,EAAU,OAGX,MAED,YAEI,CACN,OAGF,IAAM,EAAe,EAAM,SAAS,GAC9B,EAAY,EAAa,SAAS,KAClC,EAAW,EAAa,SAAS,IACjC,EAAa,EAAY,EAAa,WAAW,MACjD,EAAc,EAAW,EAAa,WAAW,OAEvD,EAAM,SAAS,SAAS,EAAI,IAAU,CACpC,GAAI,EAAG,OAAS,QAAS,OAEzB,IAAM,EAAM,EACN,EAAU,EAAI,SAAS,KACvB,EAAS,EAAI,SAAS,IACtB,EAAW,EAAU,EAAI,WAAW,MACpC,EAAY,EAAS,EAAI,WAAW,OAGxC,GAAW,GACX,GAAU,GACV,GAAY,GACZ,GAAa,GAGb,EAAgB,IAAI,EAAM,EAE5B,CAEF,IAAMC,EAAgC,CACpC,KAAM,QACN,aAAc,QACd,GAAI,OAAO,YAAY,CACvB,SAAU,CACR,KAAM,EAAY,KAClB,IAAK,EAAY,IAClB,CACD,WAAY,CACV,MAAO,EAAY,MACnB,OAAQ,EAAY,OACrB,CACD,KAAM,EACN,cAAe,EAAU,cAC1B,CAED,EAAc,KAAK,EAAa,GAElC,CAGF,IAAM,EAAmB,EAAM,SAAS,QACrC,EAAG,IAAU,CAAC,EAAgB,IAAI,EAAM,CAC1C,CAED,MAAO,CACL,GAAG,EACH,SAAU,CAAC,GAAG,EAAkB,GAAG,EAAc,CAClD,EAEJ,CC9KK,GAAmB,GAAiC,CACxD,IAAM,EAAU,EAAQ,QAAQ,aAAa,CAE7C,GAAI,IAAY,MACd,OAAQ,EAA6B,KAAO,GAG9C,GAAI,IAAY,MAAO,CAErB,IAAM,EADa,IAAI,eAAe,CACT,kBAAkB,EAAQ,CAEvD,MAAO,6BADQ,KAAK,SAAS,mBAAmB,EAAU,CAAC,CAAC,GAI9D,GAAI,IAAY,UAAW,CACzB,IAAM,EAAM,EAAQ,cAAc,MAAM,CACxC,GAAI,EACF,OAAO,EAAI,KAAO,GAItB,MAAO,IAGH,GAAmB,GAA6C,CACpE,IAAM,EAAU,EAAQ,QAAQ,aAAa,CAE7C,GAAI,IAAY,MACd,OAAQ,EAA6B,KAAO,IAAA,GAG9C,GAAI,IAAY,MAAO,CACrB,IAAM,EAAQ,EAAQ,cAAc,QAAQ,CAC5C,GAAI,EACF,OAAO,EAAM,aAAe,IAAA,KAOrBC,EAAuC,CAClD,KAAM,aACN,QAAS,CAAC,QAAQ,CAClB,SAAU,EAAS,IAAiB,CAClC,GAAM,CAAE,gBAAe,eAAc,gBAAiB,EAEhD,EAAY,EAAa,uBAAuB,CAChD,EAAM,GAAgB,EAAQ,CAgBpC,OAdK,EAEiC,CACpC,KAAM,QACN,GAAI,OAAO,YAAY,CAClB,MACL,IAAK,GAAgB,EAAQ,CAC7B,SAAU,EAAwB,EAAc,EAAU,CAC1D,WAAY,EAAkB,EAAa,CAC3C,OAAQ,EAAc,EAAc,CACpC,SAAU,EAAgB,EAAc,CACxC,QAAS,EAAe,EAAc,CACvC,CAZgB,MAgBpB,CCvEK,EAAY,IAAI,IAChB,EAAwB,IAAI,IAErB,GAAqB,GAC5B,EAAU,SAAS,MAAM,EAAI,EAAU,SAAS,YAAY,CACvD,SACL,EAAU,SAAS,MAAM,EAAI,EAAU,SAAS,aAAa,CACxD,UACF,QAGI,GAAkB,GACtB,EAAU,KAAM,GAAQ,EAAI,WAAW,MAAM,EAAI,IAAQ,KAAK,EAAI,KAGrE,GAA2B,MAC/B,EACA,IACgC,CAChC,IAAM,EAAW,EAAU,QAAQ,MAAO,GAAG,CACvC,EAAU,GAAiB,IAAa,EACxC,EAAY,IAAY,EAAiC,CAAC,EAAS,CAAhC,CAAC,EAAS,EAAS,CACtD,EAAW,IAAY,QAAU,CAAC,QAAQ,CAAG,CAAC,EAAS,QAAQ,CAErE,IAAK,IAAM,KAAQ,EACjB,IAAK,IAAM,KAAK,EAAU,CACxB,IAAM,EAAO,CACX,yEAAyE,EAAE,GAAG,EAAK,MACnF,yEAAyE,EAAE,GAAG,EAAK,MACpF,CAED,IAAK,IAAM,KAAO,EAChB,GAAI,CACF,IAAM,EAAW,MAAM,MAAM,EAAI,CACjC,GAAI,CAAC,EAAS,GAAI,SAElB,IAAM,EAAU,MAAM,EAAS,MAAM,CAG/B,EAFS,IAAI,WAAW,CACX,gBAAgB,EAAS,gBAAgB,CAC5C,cAAc,MAAM,CAEpC,GAAI,CAAC,EAAK,SAEV,IAAM,EAAU,EAAI,aAAa,UAAU,EAAI,cACzC,EAAQ,MAAM,KAAK,EAAI,iBAAiB,OAAO,CAAC,CACnD,IAAK,GAAM,EAAE,aAAa,IAAI,CAAC,CAC/B,OAAO,QAAQ,CACf,KAAK,IAAI,CAEZ,GAAI,CAAC,EAAO,SAEZ,MAAO,CAAE,UAAS,KAAM,EAAO,MACzB,CACN,UAMR,OAAO,MAGI,GAAmB,MAC9B,EACA,IACgC,CAChC,IAAM,EAAW,GAAG,EAAQ,GAAG,IAE/B,GAAI,EAAU,IAAI,EAAS,CACzB,OAAO,EAAU,IAAI,EAAS,CAGhC,GAAI,EAAsB,IAAI,EAAS,CACrC,OAAO,EAAsB,IAAI,EAAS,CAG5C,IAAM,EAAe,GAAyB,EAAW,EAAQ,CAC9D,KAAM,IACD,GACF,EAAU,IAAI,EAAU,EAAO,CAE1B,GACP,CACD,YAAc,CACb,EAAsB,OAAO,EAAS,EACtC,CAGJ,OADA,EAAsB,IAAI,EAAU,EAAa,CAC1C,GAGI,IACX,EACA,IACW,CACX,IAAM,EAAY,oDAAoD,EAAQ,QAAQ,iBAAiB,EAAM,OAAO,EAAQ,KAAK,WAEjI,MAAO,6BADQ,KAAK,SAAS,mBAAmB,EAAU,CAAC,CAAC,ICpFjDC,EAA6C,CACxD,KAAM,wBACN,QAAS,CAAC,OAAO,CACjB,QAAS,MAAO,EAAS,IAAiB,CACxC,GAAM,CAAE,gBAAe,eAAc,gBAAiB,EAEhD,EAAY,MAAM,KAAK,EAAQ,UAAU,CACzC,EAAY,GAAe,EAAU,CAE3C,GAAI,CAAC,EAAW,OAAO,KAGvB,IAAM,EAAU,MAAM,GAAiB,EADvB,GAAkB,EAAU,CACc,CAE1D,GAAI,CAAC,EAAS,OAAO,KAGrB,IAAM,EAAM,GAAqB,EADnB,EAAc,EAAc,MAAM,EAAI,SACJ,CAE1C,EAAY,EAAa,uBAAuB,CAetD,MAbsC,CACpC,KAAM,QACN,aAAc,OACd,GAAI,OAAO,YAAY,CAClB,MACL,IAAK,EACL,SAAU,EAAwB,EAAc,EAAU,CAC1D,WAAY,EAAkB,EAAa,CAC3C,OAAQ,EAAc,EAAc,CACpC,SAAU,EAAgB,EAAc,CACxC,QAAS,EAAe,EAAc,CACvC,EAIJ,CC9CY,GAAO,CAClB,MAAO,UACP,IAAK,WACL,MAAO,WACP,OAAQ,WACR,IAAK,UACN,CAEY,EAAW,CACtB,eAAgB,SAChB,YAAa,IACb,aAAc,IACd,YAAa,GACb,gBAAiB,EAClB,CAEY,EAAa,CACxB,IAAK,GACL,sBAAuB,KACvB,kBAAmB,IACpB,CAEYC,EAUT,CACF,MAAO,QACP,OAAQ,OACR,OAAQ,SACT,CAEYC,GAAiD,CAC5D,IAAK,OACL,IAAK,aACL,IAAK,QACL,IAAK,GACL,IAAK,SACL,IAAK,WACL,IAAK,OACL,IAAK,YACL,IAAK,QACN,CAEYC,EAAiC,CAC5C,EACA,EACA,EACA,EACA,EACA,EACA,EACD,CACY,GAAoB,KAEpBC,EAAyC,CACpD,IAAK,MACL,IAAK,MACL,KAAM,OACN,QAAS,UACT,KAAM,OACN,SAAU,WACV,MAAO,QACP,OAAQ,SACT,CAEYC,EAA8C,CACzD,IAAK,MACL,IAAK,MACL,KAAM,OACN,QAAS,OACT,KAAM,OACN,SAAU,WACV,MAAO,QACP,OAAQ,SACT,CAEYC,GAA2C,CACtD,eAAgB,eAChB,eAAgB,eAChB,qBAAsB,qBACtB,uBAAwB,uBACxB,aAAc,SACd,OAAQ,mBACR,MAAO,QACP,KAAM,OACN,IAAK,OACL,MAAO,YACP,KAAM,gBACN,oBAAqB,6BACrB,wBAAyB,cACzB,sBAAuB,YACvB,wBAAyB,cACzB,yBAA0B,eAC1B,cAAe,mBACf,eAAgB,qBAChB,WAAY,UACb,CCjGD,IAAa,EAAb,KAA2B,CACzB,OAEA,cACA,aAAiD,KACjD,OAAkC,KAClC,OACA,WAEA,YAAY,EAAyB,CACnC,EAAc,EAAO,OAAQ,8BAA8B,CAC3D,EAAc,EAAO,WAAY,kCAAkC,CAEnE,KAAK,OAAS,CACZ,GAAG,EACH,SAAU,EAAO,UAAY,SAC7B,WAAY,EAAO,YAAc,CAC/B,MAAO,EAAS,YAChB,OAAQ,EAAS,aAClB,CACF,CACD,KAAK,OAAS,EAAO,OACrB,KAAK,WAAa,EAAO,WACzB,KAAK,cAAgB,IAAI,EAErB,KAAK,WAAW,kBAClB,KAAK,WAAW,iBAAiB,KAAK,cAAc,CAGtD,IAAM,EAAc,EAAO,SAAS,MAAQ,EAAE,CACxC,EAAmB,EAAO,SAAS,YAAc,EAAE,CAEzD,EAAY,QAAS,GAAW,KAAK,IAAI,EAAO,CAAC,CACjD,EAAiB,QAAS,GAAW,KAAK,IAAI,EAAO,CAAC,CAGxD,IAAI,EAAsB,CAExB,OADA,KAAK,cAAc,SAAS,EAAO,CAC5B,KAGT,KAAK,EAAyB,CAM5B,OALI,OAAO,GAAU,SACnB,KAAK,OAAS,EAEd,KAAK,OAAS,EAAM,QAEf,KAGT,MAAM,SAAyB,CAC7B,EAAc,KAAK,OAAQ,4CAA4C,CAEnE,KAAK,OAAO,OACd,QAAQ,MAAM,6BAA6B,CAE7C,IAAM,EAAe,CACnB,SAAU,KAAK,OAAO,SACtB,WAAY,KAAK,OAAO,WACzB,CAEK,EAAO,MAAM,KAAK,cAAc,mBACpC,KAAK,OACL,EACD,CAEK,CAAE,WAAU,WAAY,MAAM,KAAK,OAAO,MAAM,EAAM,EAAa,CAErE,KAAK,OAAO,OACd,QAAQ,IAAI,yBAA0B,CACpC,WACD,CAAC,CAGJ,IAAM,EAAY,IAAI,IAEtB,IAAK,GAAM,CAAE,aAAY,UAAS,kBAAkB,EAAU,CAC5D,IAAM,EAAM,MAAM,KAAK,cAAc,eACnC,EACA,EACD,CAEG,IACG,EAAU,IAAI,EAAW,EAC5B,EAAU,IAAI,EAAY,EAAE,CAAC,CAE/B,EAAU,IAAI,EAAW,CAAE,KAAK,EAAI,EAIpC,KAAK,OAAO,OACd,QAAQ,IAAI,wBAAyB,CACnC,OAAQ,EACT,CAAC,CAGJ,GAAS,CAET,IAAMC,EAAqB,EAAE,CACvB,EAAe,MAAM,KAAK,EAAU,MAAM,CAAC,CAAC,MAAM,EAAG,IAAM,EAAI,EAAE,CAEvE,IAAK,IAAM,KAAc,EAAc,CACrC,IAAMC,EAAkB,CACtB,GAAI,OAAO,YAAY,CACvB,MAAO,EACP,SAAU,EAAU,IAAI,EAAW,EAAI,EAAE,CAC1C,CACD,EAAO,KAAK,EAAM,CAGpB,KAAK,aAAe,CACV,SACR,SAAU,CACR,UAAW,IAAI,KACf,QAAS,KAAK,cAAc,YAAY,CAAC,IAAK,GAAW,EAAO,KAAK,CACtE,CACD,SAAU,KAAK,OAAO,WACvB,CAED,IAAK,IAAI,EAAI,EAAG,EAAI,KAAK,aAAa,OAAO,OAAQ,IACnD,KAAK,aAAa,OAAO,GAAK,MAAM,KAAK,cAAc,eACrD,KAAK,aAAa,OAAO,GAC1B,CAYH,OATA,KAAK,cAAc,gBAAgB,KAAK,aAAa,CAEjD,KAAK,OAAO,QACd,QAAQ,IAAI,wBAAyB,CACnC,aAAc,KAAK,aACpB,CAAC,CACF,QAAQ,UAAU,EAGb,KAGT,MAAM,OAAO,EAA6C,CAOxD,OANA,EACE,KAAK,aACL,mDACD,CAEc,MAAM,KAAK,WAAW,UAAU,KAAK,aAAc,EAAQ,CAI5E,MAAM,aAAa,EAA4C,CAC7D,MAAU,MAAM,kBAAkB,CAGpC,iBAAmC,CAKjC,OAJA,EACE,KAAK,aACL,mDACD,CACM,KAAK,eCzKhB,MAAa,IACX,EACA,IAEO,IAAI,SAAS,EAAS,IAAW,CACtC,IAAM,EAAS,SAAS,cAAc,SAAS,CAC/C,EAAO,MAAM,SAAW,QACxB,EAAO,MAAM,KAAO,UACpB,EAAO,MAAM,IAAM,UAClB,EAAO,MAAM,MAAQ,GAAG,EAAU,MAAM,IACtC,EAAO,MAAM,OAAS,GAAG,EAAU,OAAO,IAC7C,EAAO,MAAM,QAAU,IACvB,EAAO,MAAM,cAAgB,OAC7B,EAAO,MAAM,OAAS,KACtB,EAAO,aAAa,cAAe,OAAO,CAE1C,IAAM,MAAmB,CACvB,EAAO,oBAAoB,OAAQ,EAAW,CAE9C,IAAM,EAAM,EAAO,gBACnB,GAAI,CAAC,EAAK,CACR,EAAW,MAAM,mCAAmC,CAAC,CACrD,OAGF,IAAM,MAAmB,CACnB,EAAI,aAAe,WACrB,0BAA4B,EAAQ,EAAO,CAAC,CAE5C,WAAW,EAAY,GAAG,EAI9B,GAAY,EAGd,EAAO,iBAAiB,OAAQ,EAAW,CAC3C,EAAO,YAAgB,EAAW,MAAM,wBAAwB,CAAC,CACjE,EAAO,OAAS,EAChB,SAAS,KAAK,YAAY,EAAO,EACjC,CAGS,GAAiB,GAAoC,CAChE,EAAO,QAAQ,ECpCjB,IAAa,EAAb,KAAoD,CAClD,MAAM,MAAM,EAAc,EAA6C,CACrE,IAAM,EAAS,MAAM,GAAa,EAAM,EAAO,WAAW,CAEpD,EADM,EAAO,gBACO,iBAA8B,EAAO,SAAS,CAElEC,EAA4B,EAAE,CAEpC,IAAK,IAAI,EAAa,EAAG,EAAa,EAAc,OAAQ,IAAc,CACxE,IAAM,EAAe,EAAc,GAC7B,EAAW,EAAa,iBAA8B,IAAI,CAE1D,EAAc,CAAC,EAAc,GAAG,MAAM,KAAK,EAAS,CAAC,CAErD,EAAmB,IAAI,IAE7B,IAAK,IAAM,KAAS,EAAa,CAC/B,IAAI,EAAa,GACb,EAAS,EAAM,cACnB,KAAO,GAAU,IAAW,GAAc,CACxC,GAAI,EAAiB,IAAI,EAAO,CAAE,CAChC,EAAa,GACb,MAEF,EAAS,EAAO,cAElB,GAAI,EAAY,SAEhB,IAAM,EAAe,GAAgB,EAAO,EAAO,cAAe,CAClE,GAAI,EAAa,SAAW,EAAG,SAE/B,IAAM,EAAgB,EAAO,cAAe,iBAAiB,EAAM,CAC7D,EAAe,EAAM,uBAAuB,CAC5C,EAAU,EAAM,QAAQ,aAAa,CAE3C,IAAK,IAAM,KAAe,EAAc,EAClC,IAAgB,SAAW,IAAgB,SAC7C,EAAiB,IAAI,EAAM,CAG7B,IAAMC,EAA6B,CACpB,cACJ,UACM,gBACD,eACF,aACE,eACf,CAED,EAAS,KAAK,CACA,aACZ,QAAS,EACK,eACf,CAAC,GAKR,MAAO,CACL,WACA,YAAe,GAAc,EAAO,CACrC,GCpEL,MAAa,EAAc,GAClB,EAAK,EAAW,IAGZ,EAAc,GACjB,EAAK,EAAW,IAAO,GAGpB,GACX,EACA,IACyC,CACzC,IAAM,EAAY,EAAS,KAAO,EAAS,MAAS,IAC9C,EAAY,EAAS,IAAM,EAAS,OAAU,IAEpD,MAAO,CACL,EAAG,GAAG,EAAS,GACf,EAAG,GAAG,EAAS,GAChB,EAGU,GACX,EACA,IACyC,CACzC,IAAM,EAAY,EAAW,MAAQ,EAAS,MAAS,IACjD,EAAY,EAAW,OAAS,EAAS,OAAU,IAEzD,MAAO,CACL,EAAG,GAAG,EAAS,GACf,EAAG,GAAG,EAAS,GAChB,EAGU,GACX,IAEO,CACL,EAAG,EAAW,EAAS,KAAK,CAC5B,EAAG,EAAW,EAAS,IAAI,CAC5B,EAGU,GACX,IAEO,CACL,EAAG,EAAW,EAAW,MAAM,CAC/B,EAAG,EAAW,EAAW,OAAO,CACjC,EC7CU,EACX,GAC+B,CAC/B,IAAMC,EAAoC,EAAE,CAiC5C,OA/BI,EAAK,aACP,EAAM,SAAW,EAAK,WAAW,MAAM,IAAI,CAAC,GAAG,MAAM,EAGnD,EAAK,WACP,EAAM,SAAW,EAAW,EAAK,SAAS,EAGxC,EAAK,QACP,EAAM,MAAQ,EAAK,MAAM,aAAa,EAGpC,EAAK,aACQ,SAAS,EAAK,WAAY,GAAG,EAAI,KACnC,MACX,EAAM,KAAO,KAIb,EAAK,YAAc,UAAY,EAAK,YAAc,aACpD,EAAM,OAAS,IAGb,EAAK,YACP,EAAM,UAAY,CAAE,MAAO,MAAO,EAGhC,EAAK,gBACP,EAAM,OAAS,aAGV,GAGI,EACX,GACiE,CACjE,IAAMC,EACJ,EAAE,CAEJ,IAAK,IAAM,KAAO,EAChB,GAAI,EAAI,UAAY,EAAI,SAAS,OAAS,EAAG,CAC3C,IAAM,EAAe,EAAY,EAAI,SAAS,CAC9C,IAAK,IAAM,KAAS,EAAc,CAChC,IAAM,EAAoB,CAAE,GAAG,EAAM,QAAS,CAE9C,GAAI,EAAI,WAAY,CAClB,IAAM,EAAW,EAAmC,EAAI,WAAW,CACnE,OAAO,OAAO,EAAmB,EAAU,EAAM,QAAQ,CAGvD,EAAI,OACN,EAAkB,UAAY,CAAE,IAAK,EAAI,KAAM,EAGjD,EAAO,KAAK,CAAE,KAAM,EAAM,KAAM,QAAS,EAAmB,CAAC,MAE1D,CACL,IAAMC,EAAsC,EAAE,CAE1C,EAAI,YACN,OAAO,OACL,EACA,EAAmC,EAAI,WAAW,CACnD,CAGC,EAAI,OACN,EAAQ,UAAY,CAAE,IAAK,EAAI,KAAM,EAGvC,EAAO,KAAK,CAAE,KAAM,EAAI,QAAkB,UAAS,CAAC,CAIxD,OAAO,GAGI,IACX,EACA,EACA,IACS,CACT,IAAM,EAAM,EAAqB,EAAQ,SAAU,EAAS,CACtD,EAAO,EAAuB,EAAQ,WAAY,EAAS,CAE3DC,EAA0C,CAC9C,EAAG,EAAI,EACP,EAAG,EAAI,EACP,EAAG,EAAK,EACR,EAAG,EAAK,EAMR,oBAAqB,EACrB,OAAQ,MACR,MAAO,OACP,UAAW,GACX,KAAM,GACN,WAAY,GACb,CAED,GAAI,EAAQ,WAAY,CACtB,IAAM,EAAO,EAAQ,WACf,EAAY,EAAmC,EAAK,CAC1D,OAAO,OAAO,EAAa,EAAU,CAEjC,EAAK,YACP,EAAY,MAAQ,EAAK,WAOvB,EAAK,gBACP,EAAY,OAAS,EAAK,eAGxB,EAAK,gBACP,EAAY,YAAc,EAAK,eAqBnC,GAjBI,EAAQ,UACV,EAAY,OAAS,CACnB,EAAW,EAAQ,QAAQ,IAAI,CAC/B,EAAW,EAAQ,QAAQ,MAAM,CACjC,EAAW,EAAQ,QAAQ,OAAO,CAClC,EAAW,EAAQ,QAAQ,KAAK,CACjC,EAGC,EAAQ,WACV,EAAY,OAAS,EAAQ,UAG3B,EAAQ,UAAY,IAAA,IAAa,EAAQ,QAAU,IACrD,EAAY,aAAe,KAAK,OAAO,EAAI,EAAQ,SAAW,IAAI,EAGhE,EAAQ,MAAQ,EAAQ,KAAK,OAAS,EAAG,CAC3C,IAAM,EAAY,EAAY,EAAQ,KAAK,CAC3C,EAAM,QAAQ,EAAW,EAAY,MAGrC,EAAM,QAAQ,EAAQ,QAAS,EAAY,ECxJzC,GACJ,GAEO,EAGHC,GACJ,GAUO,EAAgB,EAAO,QAAU,QAG7B,IACX,EACA,EACA,IACS,CACT,IAAM,EAAM,EAAqB,EAAQ,SAAU,EAAS,CACtD,EAAO,EAAuB,EAAQ,WAAY,EAAS,CAE3DC,EACJ,GAAa,EAAQ,UAAU,EAAI,EAAU,UAAU,KAEnDC,EAAqC,CACzC,EAAG,EAAI,EACP,EAAG,EAAI,EACP,EAAG,EAAK,EACR,EAAG,EAAK,EACT,CAED,GAAI,EAAQ,KAAM,CAChB,IAAMC,EAAsC,EAAE,CAE9C,GAAI,EAAQ,KAAK,OAAS,QACxB,EAAU,MAAQ,EAAQ,KAAK,MAAM,aAAa,CAE9C,EAAQ,KAAK,UAAY,IAAA,IAAa,EAAQ,KAAK,QAAU,IAI/D,EAAU,aAHkB,KAAK,OAC9B,EAAI,EAAQ,KAAK,SAAW,IAC9B,UAGM,EAAQ,KAAK,OAAS,WAAY,CAC3C,IAAM,EAAY,EAAQ,KAAK,MAAM,GACjC,IACF,EAAU,MAAQ,EAAU,MAAM,aAAa,CAE3C,EAAU,UAAY,IAAA,IAAa,EAAU,QAAU,IACzD,EAAU,aAAe,KAAK,OAAO,EAAI,EAAU,SAAW,IAAI,GAKpE,EAAU,QACZ,EAAa,KAAO,GAIxB,GAAI,EAAQ,OAAQ,CAClB,IAAMC,EAAsC,CAC1C,MAAO,EAAQ,OAAO,MAAM,aAAa,CACzC,MAAO,EAAQ,OAAO,MACtB,SAAUJ,GAAkB,EAAQ,OAAO,CAC5C,CAEG,EAAQ,OAAO,UAAY,IAAA,KAC7B,EAAU,aAAe,KAAK,OAAO,EAAI,EAAQ,OAAO,SAAW,IAAI,EAGzE,EAAa,KAAO,EAOtB,GAJI,EAAQ,WACV,EAAa,OAAS,EAAQ,UAG5B,EAAQ,cAAgB,EAAQ,YAAc,YAAa,CAC7D,IAAM,EAAe,KAAK,IACxB,EAAQ,WAAW,MACnB,EAAQ,WAAW,OACpB,CAID,EAAa,WAFX,KAAK,IAAI,EAAQ,aAAe,EAAc,EAAE,CAChD,EAAW,kBAIf,GAAI,EAAQ,OAAQ,CAClB,IAAM,EAAU,EAAQ,OAAO,OAAO,EAChC,EAAU,EAAQ,OAAO,OAAO,EAChC,EAAiB,KAAK,KAAK,GAAW,EAAI,GAAW,EAAE,CAIvD,GAFe,KAAK,MAAM,EAAS,EAAQ,CACZ,IAAO,KAAK,GACR,IAAO,KAAO,IAEvD,EAAa,OAAS,CACpB,KAAM,EAAQ,OAAO,KACrB,MAAO,EAAQ,OAAO,MAAM,aAAa,CACzC,KAAM,EAAW,EAAQ,OAAO,KAAK,CACrC,OAAQ,EAAW,EAAe,CAClC,MAAO,EACP,QAAS,EAAQ,OAAO,SAAW,EACpC,CAGH,EAAM,SAAS,EAAW,EAAa,ECrHnC,GACJ,GAUO,EAAgB,EAAO,QAAU,QAG7B,IACX,EACA,EACA,IACS,CACT,IAAM,EAAiB,EAAQ,MAAM,KAAO,EAAS,MAAS,IACxD,EAAiB,EAAQ,MAAM,IAAM,EAAS,OAAU,IACxD,EAAe,EAAQ,IAAI,KAAO,EAAS,MAAS,IACpD,EAAe,EAAQ,IAAI,IAAM,EAAS,OAAU,IAEpD,EAAQ,KAAK,IAAI,EAAc,EAAc,CAC7C,EAAS,KAAK,IAAI,EAAc,EAAc,CAE9CK,EAAsC,CAC1C,MAAO,EAAQ,OAAO,MAAM,aAAa,CACzC,MAAO,EAAQ,OAAO,MACtB,SAAU,GAAkB,EAAQ,OAAO,CAC5C,CAEG,EAAQ,OAAO,UAAY,IAAA,KAC7B,EAAU,aAAe,KAAK,OAAO,EAAI,EAAQ,OAAO,SAAW,IAAI,EAGzE,IAAMC,EAAoC,CACxC,EAAG,GAAG,KAAK,IAAI,EAAe,EAAY,CAAC,GAC3C,EAAG,GAAG,KAAK,IAAI,EAAe,EAAY,CAAC,GAC3C,EAAG,GAAG,GAAS,GAAI,GACnB,EAAG,GAAG,GAAU,GAAI,GACpB,KAAM,EACP,CAEK,EAAQ,EAAQ,IAAI,KAAO,EAAQ,MAAM,KACzC,EAAQ,EAAQ,IAAI,IAAM,EAAQ,MAAM,IAE1C,IACF,EAAY,MAAQ,IAGlB,IACF,EAAY,MAAQ,IAGtB,EAAM,SAAS,OAAQ,EAAY,ECvDxB,IACX,EACA,EACA,IACS,CACT,IAAM,EAAM,EAAqB,EAAQ,SAAU,EAAS,CACtD,EAAO,EAAuB,EAAQ,WAAY,EAAS,CAE3DC,EAAqC,CACzC,EAAG,EAAI,EACP,EAAG,EAAI,EACP,EAAG,EAAK,EACR,EAAG,EAAK,EACT,CAEG,EAAQ,IAAI,WAAW,QAAQ,CACjC,EAAa,KAAO,EAAQ,IAE5B,EAAa,KAAO,EAAQ,IAG1B,EAAQ,MACV,EAAa,QAAU,EAAQ,KAG7B,EAAQ,WACV,EAAa,OAAS,EAAQ,UAG5B,EAAQ,UAAY,IAAA,IAAa,EAAQ,QAAU,IACrD,EAAa,aAAe,KAAK,OAAO,EAAI,EAAQ,SAAW,IAAI,EAGjE,EAAQ,MAMV,EAAa,OAAS,CACpB,KAN2D,CAC3D,QAAS,UACT,MAAO,QACP,QAAS,OACV,CAEc,EAAQ,MAAQ,UAC7B,EAAG,EAAQ,WAAW,MACtB,EAAG,EAAQ,WAAW,OACvB,EAGH,EAAM,SAAS,EAAa,EC1CxB,IAAyB,EAAoB,IAAgC,CACjF,IAAM,EAAe,EAAW,MAAM,IAAI,CAAC,GAAG,MAAM,CACpD,GAAI,CAAC,EAAY,OAAO,EAGxB,IAAM,EAAS,GADA,SAAS,EAAY,GAAG,EAAI,KAK3C,MAFI,CAAC,GAAU,IAAW,GAAW,EAE9B,GAAG,EAAa,GAAG,KAGf,IACX,EACA,EACA,IACS,CACT,IAAM,EAAM,EAAqB,EAAQ,SAAU,EAAS,CACtD,EAAO,EAAuB,EAAQ,WAAY,EAAS,CAE3DC,EAA6B,EAAQ,KAAK,IAAK,GACnD,EAAI,IAAK,GAAS,CAChB,IAAMC,EAAiC,CACrC,KAAM,EAAK,MAAQ,EAAK,KAAK,OAAS,EAAI,EAAY,EAAK,KAAK,CAAG,EAAK,KACzE,CAgBD,GAdI,EAAK,UACP,EAAU,QAAU,CAClB,GAAG,EAAU,QACb,QAAS,EAAK,QACf,EAGC,EAAK,UACP,EAAU,QAAU,CAClB,GAAG,EAAU,QACb,QAAS,EAAK,QACf,EAGC,EAAK,WAAY,CACnB,IAAM,EAAO,EAAK,WACZ,EAAS,EAAK,YAAa,SAAS,EAAK,WAAY,GAAG,EAAU,IAExE,EAAU,QAAU,CAClB,GAAG,EAAU,QACb,SAAU,EAAK,WACX,GAAsB,EAAK,WAAY,EAAK,WAAW,CACvD,IAAA,GACJ,SAAU,EAAK,SAAW,EAAW,EAAK,SAAS,CAAG,IAAA,GACtD,MAAO,EAAK,MAAQ,EAAK,MAAM,aAAa,CAAG,IAAA,GAC/C,KAAM,EAAS,IACf,OAAQ,EAAK,YAAc,UAAY,EAAK,YAAc,UAC1D,UAAW,EAAK,UAAY,CAAE,MAAO,MAAO,CAAG,IAAA,GAC/C,MAAO,EAAK,UACZ,OAAQ,EAAK,cACd,CAGH,GAAI,EAAK,SACH,EAAK,KAAK,OAAS,QAAS,CAC9B,IAAMC,EAAwD,CAC5D,MAAO,EAAK,KAAK,MAAM,aAAa,CACrC,CAEG,EAAK,KAAK,UAAY,IAAA,IAAa,EAAK,KAAK,QAAU,IACzD,EAAY,aAAe,KAAK,OAAO,EAAI,EAAK,KAAK,SAAW,IAAI,EAGtE,EAAU,QAAU,CAClB,GAAG,EAAU,QACb,KAAM,EACP,SACQ,EAAK,KAAK,OAAS,WAAY,CACxC,IAAM,EAAY,EAAK,KAAK,MAAM,GAC9B,IACF,EAAU,QAAU,CAClB,GAAG,EAAU,QACb,KAAM,CAAE,MAAO,EAAU,MAAM,aAAa,CAAE,CAC/C,GAKP,GAAI,EAAK,OAAQ,CACf,IAAM,EAAQ,CAAC,MAAO,QAAS,SAAU,OAAO,CAC1CC,EAAuC,EAAE,CAE/C,IAAK,IAAM,KAAQ,EAAO,CACxB,IAAM,EAAS,EAAK,OAAO,GAC3B,GAAI,EAAQ,CACV,IAAIC,EAAwC,SACxC,EAAO,QAAU,UAAY,EAAO,QAAU,YAChD,EAAa,QAGf,EAAY,KAAK,CACf,MAAO,EAAO,MAAM,aAAa,CACjC,GAAI,EAAO,MACX,KAAM,EACP,CAAC,MAEF,EAAY,KAAK,CAAE,KAAM,OAAQ,CAAC,CAItC,IAAM,EAAgB,EAOtB,EAAU,QAAU,CAClB,GAAG,EAAU,QACb,OAAQ,EACT,CAGH,OAAO,GACP,CACH,CAEKC,EAAqC,CACzC,EAAG,EAAI,EACP,EAAG,EAAI,EACP,EAAG,EAAK,EACR,EAAG,EAAK,EACT,CAEG,EAAQ,WAAa,EAAQ,UAAU,OAAS,IAClD,EAAa,KAAO,EAAQ,UAAU,IAAK,GAAY,EAAW,EAAQ,CAAC,EAGzE,EAAQ,gBACV,EAAa,KAAO,EAAW,EAAQ,cAAc,CAAG,IAGtD,EAAQ,YACV,EAAa,mBAAqB,GAGpC,EAAM,SAAS,EAAM,EAAa,EClJ9B,GACJ,GACW,CACX,IAAK,IAAM,KAAK,EACV,MAAC,EAAE,QAAU,CAAC,MAAM,QAAQ,EAAE,OAAO,EAEzC,KAAK,IAAM,KAAS,EAAE,OACpB,GAAI,OAAO,GAAU,UAAY,CAAC,OAAO,UAAU,EAAM,CAAE,CACzD,IAAI,EAAc,EAClB,IAAK,IAAM,KAAK,EAAE,OAChB,GAAI,OAAO,GAAM,UAAY,CAAC,OAAO,UAAU,EAAE,CAAE,CACjD,IAAM,EAAW,EAAE,UAAU,CAAC,MAAM,IAAI,CAAC,IAAI,QAAU,EACvD,EAAc,KAAK,IAAI,EAAa,KAAK,IAAI,EAAU,EAAE,CAAC,CAK9D,OADI,IAAgB,EAAU,UACvB,YAKb,MAAO,SAGH,GAA2B,GACxB,EAAoB,IAAc,MAGrC,EAAuB,GAAqC,CAChE,IAAM,EAAY,EAAQ,KAAK,UAU/B,OAPE,IAAc,OACd,EAAQ,KAAK,SAAS,OAAS,IAAA,IAC/B,EAAQ,KAAK,QAAQ,KAAO,EAErB,WAGF,EAAoB,IAAc,OAgB9B,GACX,GACyB,CACzB,IAAM,EAAM,GAAiB,EAAQ,SAAS,CACxC,EAAO,GAAmB,EAAQ,WAAW,CAE7C,EAAY,EAAQ,KACpB,EAAa,CACjB,KAAM,EAAU,UAChB,OAAQ,EAAU,OAClB,OAAQ,EAAU,OAClB,QAAS,EAAU,QACpB,CAEKC,EAAsB,EAAW,OAAO,IAAK,IAAY,CAC7D,KAAM,EAAO,KACb,OAAQ,EAAW,OACnB,OAAQ,EAAO,OACf,MAAO,EAAc,EAAO,OAAS,GAAG,CACzC,EAAE,CAEGC,EAAgC,CACpC,EAAG,EAAI,EACP,EAAG,EAAI,EACP,EAAG,EAAK,EACR,EAAG,EAAK,EACR,MAAO,EAAW,SAAS,MAC3B,UAAW,IAAW,SAAS,MAC/B,cACE,EAAW,SAAS,eAAiB,EAAS,gBAChD,WAAY,EAAW,SAAS,aAAe,GAC/C,UAAW,IACX,eAAgB,EAAS,gBACzB,UAAW,EAAW,SAAS,iBAAmB,GAClD,kBAAmB,EAAS,gBAC7B,CAID,GAFuB,EAAW,SAAS,iBAAmB,MAGxD,EAAW,OAAS,MAAO,CAC7B,EAAQ,UAAY,GACpB,IAAM,EAAa,GAAoB,EAAW,OAAO,CACrD,IACF,EAAQ,oBAAsB,QAEvB,EAAW,OAAS,QAC7B,EAAQ,YAAc,IAItB,EAAW,OAAS,QACtB,EAAQ,kBAAoB,UAG9B,IAAMC,EAAsB,EAAE,CAM9B,GAJuB,EAAW,OAAO,KACtC,GAAM,EAAE,QAAU,EAAE,OAAO,OAAS,EACtC,CAEmB,CAClB,IAAM,EAAmB,EAAW,OAAO,KACxC,GAAM,EAAE,QAAU,EAAE,OAAO,OAAS,EACtC,CACG,GAAkB,QACpB,EAAU,KAAK,GAAG,EAAiB,OAAO,MAG5C,EAAW,OAAO,QAAS,GAAW,CAChC,EAAO,OACT,EAAU,KAAK,EAAO,MAAM,EAE9B,CA2CJ,GAxCI,EAAU,OAAS,IACrB,EAAQ,YAAc,EACnB,IAAK,GAAM,EAAc,EAAE,CAAC,CAC5B,OAAQ,GAAmB,IAAM,IAAA,GAAU,EAG5C,EAAW,SAAS,aACtB,EAAQ,aAAe,EAAW,QAAQ,WAC1C,EAAQ,iBAAmB,GAC3B,EAAQ,qBAAuB,EAAS,iBAEtC,EAAW,SAAS,aACtB,EAAQ,aAAe,EAAW,QAAQ,WAC1C,EAAQ,iBAAmB,GAC3B,EAAQ,qBAAuB,EAAS,iBAG1C,EAAQ,qBAAuB,EAAS,gBACxC,EAAQ,qBAAuB,EAAS,gBAExC,EAAQ,YAAc,CAAE,MAAO,OAAQ,CACvC,EAAQ,YAAc,CAAE,MAAO,QAAS,KAAM,EAAG,MAAO,SAAU,CAE9D,EAAW,SAAS,OAAS,IAAA,IAAa,EAAW,QAAQ,KAAO,IACtE,EAAQ,SAAW,KAAK,MAAM,EAAW,QAAQ,KAAO,IAAI,EAG1D,EAAW,SAAS,cAAgB,aACtC,EAAQ,OAAS,OAEjB,EAAW,SAAS,cAAgB,YACpC,EAAW,OAAS,SAEpB,EAAQ,OAAS,OAGf,EAAW,SAAS,cACtB,EAAQ,YAAc,EAAW,QAAQ,aAGvC,EAAW,SAAS,iBAAkB,CACxC,IAAM,EAAuB,IAAI,IAC3B,EAAyB,IAAI,IAmBnC,GAjBA,EAAW,OAAO,SAAS,EAAQ,IAAQ,CACzC,IAAM,EAAkB,EAAO,WAAa,EAAW,KACjD,EAAa,EAAK,GAEpB,EAAO,QAAU,MACd,EAAuB,IAAI,EAAgB,EAC9C,EAAuB,IAAI,EAAiB,EAAE,CAAC,CAEjD,EAAuB,IAAI,EAAgB,CAAE,KAAK,EAAW,GAExD,EAAqB,IAAI,EAAgB,EAC5C,EAAqB,IAAI,EAAiB,EAAE,CAAC,CAE/C,EAAqB,IAAI,EAAgB,CAAE,KAAK,EAAW,GAE7D,CAEE,EAAuB,OAAS,EAClC,MAAO,CAAE,OAAM,UAAS,aAAc,EAAoB,EAAQ,CAAE,CAGtE,IAAMC,EAAuC,EAAE,CAuE/C,OArEA,EAAqB,SAAS,EAAiB,IAAoB,CACjE,EAAmB,KAAK,CACtB,QAAS,GAAwB,EAAgB,CACjD,KAAM,EACN,QAAS,EAAE,CACZ,CAAC,EACF,CAEF,EAAuB,SAAS,EAAiB,IAAoB,CACnE,IAAM,EACJ,IAAoB,QAAU,IAAoB,OACpD,EAAmB,KAAK,CACtB,QAAS,GAAwB,EAAgB,CACjD,KAAM,EACN,QAAS,CACP,iBAAkB,GAClB,iBAAkB,GAClB,GAAI,EAAc,CAAE,UAAW,GAAM,kBAAmB,IAAK,CAAG,EAAE,CACnE,CACF,CAAC,EACF,CAiDK,CACL,KAAM,KACN,QAjD0C,CAC1C,EAAG,EAAQ,EACX,EAAG,EAAQ,EACX,EAAG,EAAQ,EACX,EAAG,EAAQ,EACX,MAAO,EAAQ,MACf,UAAW,EAAQ,UACnB,cAAe,EAAQ,cACvB,WAAY,EAAQ,WACpB,UAAW,IACX,eAAgB,EAAS,gBACzB,YAAa,EAAQ,YACrB,oBAAqB,EAAQ,oBAE7B,kBAAmB,EAAS,gBAC5B,QAAS,CACP,CACE,aAAc,EAAW,QAAQ,YAAc,GAC/C,iBAAkB,IAAW,QAAQ,WACrC,qBAAsB,EAAS,gBAC/B,qBAAsB,EAAS,gBAC/B,YAAa,CAAE,MAAO,QAAS,KAAM,EAAG,MAAO,SAAU,CAC1D,CACD,CACE,aAAc,EAAW,QAAQ,aAAe,GAChD,iBAAkB,GAClB,qBAAsB,EAAS,gBAC/B,qBAAsB,EAAS,gBAC/B,YAAa,CAAE,MAAO,OAAQ,CAC/B,CACF,CACD,QAAS,CACP,CACE,aAAc,EAAW,QAAQ,YAAc,GAC/C,iBAAkB,IAAW,QAAQ,WACrC,qBAAsB,EAAS,gBAC/B,qBAAsB,EAAS,gBAC/B,YAAa,CAAE,MAAO,OAAQ,CAC/B,CACD,CACE,qBAAsB,EAAS,gBAC/B,cAAe,GACf,YAAa,CAAE,MAAO,OAAQ,CAC/B,CACF,CACF,CAKC,qBACA,aAAc,EAAoB,EAAQ,CAC3C,CAGH,MAAO,CAAE,OAAM,UAAS,aAAc,EAAoB,EAAQ,CAAE,EAGzD,IACX,EACA,IACS,CACT,GAAM,CAAE,OAAM,UAAS,qBAAoB,gBACzC,GAA0B,EAAQ,CAEpC,GAAI,EAAQ,KAAK,SAAS,kBAAoB,EAAoB,CAChE,IAAM,EAAkB,EAAmB,IAAK,IAAmB,CACjE,KAAM,EAAc,QACpB,KAAM,EAAc,KACpB,QAAS,EAAc,SAAW,EAAE,CACrC,EAAE,CAEH,EAAM,SAAS,EAAwB,EAAe,KACjD,CACL,IAAM,EAAY,EAElB,GAAI,CAAC,GAAa,CAAC,EACjB,OAGF,EAAM,SAAS,EAAkB,EAAa,EAAe,GCtSjE,IAAa,GAAb,KAA0D,CACxD,cAAuD,KAEvD,iBAAiB,EAA6C,CAC5D,KAAK,cAAgB,EAGvB,MAAM,UACJ,EACA,EACsB,CACtB,EACE,EAAa,OAAO,OAAS,EAC7B,kEACD,CACD,IAAM,EAAO,IAAI,EAEX,EAAc,EAAW,EAAa,SAAS,MAAM,CACrD,EAAe,EAAW,EAAa,SAAS,OAAO,CAE7D,EAAK,aAAa,CAChB,KAAM,SACN,MAAO,EACP,OAAQ,EACT,CAAC,CACF,EAAK,OAAS,SAEV,EAAa,SAAS,QACxB,EAAK,MAAQ,EAAa,SAAS,OAEjC,EAAa,SAAS,SACxB,EAAK,OAAS,EAAa,SAAS,QAElC,EAAa,SAAS,UACxB,EAAK,QAAU,EAAa,SAAS,SAGvC,IAAK,IAAM,KAAY,EAAa,OAAQ,CAC1C,IAAM,EAAQ,EAAK,UAAU,CAE7B,IAAK,IAAM,KAAW,EAAS,SAC7B,OAAQ,EAAQ,KAAhB,CACE,IAAK,OACH,GAAc,EAAO,EAAS,EAAa,SAAS,CACpD,MACF,IAAK,QACH,GAAe,EAAO,EAAS,EAAa,SAAS,CACrD,MACF,IAAK,QACH,GAAe,EAAO,EAAS,EAAa,SAAS,CACrD,MACF,IAAK,QACH,GAAe,EAAO,EAAS,EAAa,SAAS,CACrD,MACF,IAAK,QACH,GAAe,EAAO,EAAQ,CAC9B,MACF,IAAK,OACH,GAAc,EAAO,EAAS,EAAa,SAAS,CACpD,OAUR,OALI,KAAK,eACP,MAAM,KAAK,cAAc,qBAAqB,EAAM,EAAa,CAGpD,MAAM,EAAK,MAAM,CAAE,WAAY,cAAe,CAAC,GC3ErD,GAAb,cAAgC,CAAc,CAC5C,YAAY,EAAmC,EAAE,CAAE,CACjD,MAAM,CACJ,SAAU,EAAO,UAAY,EAAS,eACtC,WAAY,EAAO,YAAc,CAC/B,MAAO,EAAS,YAChB,OAAQ,EAAS,aAClB,CACD,QAAS,CACP,KAAM,EAAO,SAAS,MAAQ,EAC9B,WAAY,EAAO,SAAS,YAAc,EAAE,CAC7C,CACD,OAAQ,EAAO,QAAU,IAAI,EAC7B,WAAY,EAAO,YAAc,IAAI,GACrC,MAAO,EAAO,MACf,CAAC"}