{"release_id":"01a1998d-9802-0000-b0f7-33a23307f4ed","chunk_id":"01a1998d-990d-77b1-b7bd-a842f6bc9a93","file":"CPdntxJP.mjs","mappings":"qTAWA,MAAMA,EAAO,yEAEPC,EAAOC,GACZA,EAAE,QAAQ,KAAM,OAAO,EAAE,QAAQ,KAAM,MAAM,EAAE,QAAQ,KAAM,MAAM,EAAE,QAAQ,KAAM,QAAQ,EASrF,SAASC,EACfC,EACAC,EACS,CAMT,MAAMC,EAAQ,KAAK,IAAI,IAAOF,EAAM,MAAO,IAAOA,EAAM,MAAM,EACxDG,EAAIH,EAAM,MAAQE,EAClBE,EAAIJ,EAAM,OAASE,EACnBG,GAAK,KAAIF,GAAK,EACdG,EAAI,KAAO,IAAOF,GAAK,EACvBG,EAAQP,EAAM,IAAI,QACvB,QACA,WAAWK,EAAE,QAAQ,CAAC,CAAC,QAAQC,EAAE,QAAQ,CAAC,CAAC,YAAYH,EAAE,QAAQ,CAAC,CAAC,aAAaC,EAAE,QAAQ,CAAC,CAAC,IAAA,EAE7F,MACC,2GAA2GP,EAAID,CAAI,CAAC,6OAGxCC,EAAII,EAAM,KAAK,CAAC,6DAClCJ,EAAII,EAAM,QAAQ,CAAC,UAC7EM,EACA,YAAY,KAAI,CAAC,iEAAsEV,EAAII,EAAM,OAAO,CAAC,eAG3G,CAEO,SAASO,EAAUC,EAA4B,CACrD,OAAO,IAAI,QAAQ,CAACC,EAASC,IAAW,CACvC,MAAMC,EAAM,IAAI,MAChBA,EAAI,OAAS,IAAM,CAClB,MAAMC,EAAS,SAAS,cAAc,QAAQ,EAC9CA,EAAO,MAAQ,KACfA,EAAO,OAAS,KAChB,MAAMC,EAAMD,EAAO,WAAW,IAAI,EAClC,GAAI,CAACC,EAAK,OAAOH,EAAO,IAAI,MAAM,WAAW,CAAC,EAC9CG,EAAI,UAAUF,EAAK,EAAG,EAAG,KAAG,IAAC,EAC7BC,EAAO,OAAQE,GAAOA,EAAIL,EAAQK,CAAC,EAAIJ,EAAO,IAAI,MAAM,QAAQ,CAAC,EAAI,WAAW,CACjF,EACAC,EAAI,QAAU,IAAMD,EAAO,IAAI,MAAM,kBAAkB,CAAC,EACxDC,EAAI,IAAM,oCAAoC,mBAAmBH,CAAG,CAAC,EACtE,CAAC,CACF,CAIO,SAASO,GAAyB,CACxC,OAAO,OAAO,OAAW,KAAe,OAAO,WAAW,mBAAmB,EAAE,OAChF,CAIA,eAAsBC,EAASC,EAAYC,EAAwD,CAClG,GAAIH,IAAiB,CACpB,MAAMI,EAAO,IAAI,KAAK,CAACF,CAAI,EAAGC,EAAU,CAAE,KAAM,YAAa,EAC7D,GAAI,UAAU,WAAW,CAAE,MAAO,CAACC,CAAI,CAAA,CAAG,EACzC,GAAI,CACH,aAAM,UAAU,MAAM,CAAE,MAAO,CAACA,CAAI,EAAG,EAChC,OACR,OAASC,EAAK,CACb,GAAKA,GAAe,OAAS,aAAc,OAAO,IAEnD,CAEF,CACA,MAAMC,EAAO,IAAI,gBAAgBJ,CAAI,EAC/BK,EAAI,SAAS,cAAc,GAAG,EACpC,OAAAA,EAAE,KAAOD,EACTC,EAAE,SAAWJ,EACb,SAAS,KAAK,YAAYI,CAAC,EAC3BA,EAAE,MAAA,EACFA,EAAE,OAAA,EACF,WAAW,IAAM,IAAI,gBAAgBD,CAAI,EAAG,GAAM,EAC3C,UACR","names":["FONT","esc","s","frameSvg","stage","frame","scale","w","h","x","y","inner","renderPng","svg","resolve","reject","img","canvas","ctx","b","isTouchDevice","sharePng","blob","filename","file","err","href","a"],"sources":["../../../../../../src/lib/tools/share-image.ts"],"sourcesContent":["/**\n * A tool's picture as a PNG to share (RAT-575): the page's own SVG, framed\n * with a title and the address, drawn on a canvas in the browser. Nothing is\n * uploaded — the file goes straight to the share sheet or the downloads.\n *\n * Built ahead of the click: iOS Safari drops the user's tap across an await,\n * so the button only ever hands over a file that already exists.\n */\n\nconst W = 1080;\nconst H = 1350;\nconst FONT = \"-apple-system, BlinkMacSystemFont, 'Helvetica Neue', Arial, sans-serif\";\n\nconst esc = (s: string) =>\n\ts.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n\nexport interface ShareFrame {\n\ttitle: string;\n\tsubtitle: string;\n\t/** the page's address, without the scheme */\n\taddress: string;\n}\n\nexport function frameSvg(\n\tstage: { svg: string; width: number; height: number },\n\tframe: ShareFrame\n): string {\n\tconst pad = 72;\n\tconst top = 250;\n\tconst bottom = 150;\n\tconst boxW = W - pad * 2;\n\tconst boxH = H - top - bottom;\n\tconst scale = Math.min(boxW / stage.width, boxH / stage.height);\n\tconst w = stage.width * scale;\n\tconst h = stage.height * scale;\n\tconst x = (W - w) / 2;\n\tconst y = top + (boxH - h) / 2;\n\tconst inner = stage.svg.replace(\n\t\t'<svg ',\n\t\t`<svg x=\"${x.toFixed(1)}\" y=\"${y.toFixed(1)}\" width=\"${w.toFixed(1)}\" height=\"${h.toFixed(1)}\" `\n\t);\n\treturn (\n\t\t`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${W}\" height=\"${H}\" viewBox=\"0 0 ${W} ${H}\" font-family=\"${esc(FONT)}\">` +\n\t\t`<rect width=\"${W}\" height=\"${H}\" fill=\"#0c0c0c\"/>` +\n\t\t`<text x=\"${pad}\" y=\"118\" font-size=\"44\" font-weight=\"800\" fill=\"#f5f5f7\">ratemyd<tspan fill=\"#ff4d6d\">.</tspan></text>` +\n\t\t`<text x=\"${pad}\" y=\"186\" font-size=\"34\" font-weight=\"600\" fill=\"#f5f5f7\">${esc(frame.title)}</text>` +\n\t\t`<text x=\"${pad}\" y=\"228\" font-size=\"26\" fill=\"#8e8e93\">${esc(frame.subtitle)}</text>` +\n\t\tinner +\n\t\t`<text x=\"${W / 2}\" y=\"${H - 64}\" text-anchor=\"middle\" font-size=\"26\" fill=\"#8e8e93\">${esc(frame.address)}</text>` +\n\t\t`</svg>`\n\t);\n}\n\nexport function renderPng(svg: string): Promise<Blob> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst img = new Image();\n\t\timg.onload = () => {\n\t\t\tconst canvas = document.createElement('canvas');\n\t\t\tcanvas.width = W;\n\t\t\tcanvas.height = H;\n\t\t\tconst ctx = canvas.getContext('2d');\n\t\t\tif (!ctx) return reject(new Error('no canvas'));\n\t\t\tctx.drawImage(img, 0, 0, W, H);\n\t\t\tcanvas.toBlob((b) => (b ? resolve(b) : reject(new Error('no png'))), 'image/png');\n\t\t};\n\t\timg.onerror = () => reject(new Error('svg did not load'));\n\t\timg.src = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;\n\t});\n}\n\n/** Touch devices get the share sheet (the only way into Photos on iOS);\n *  mouse users get a plain download. Same rule as the foil card (RAT-131). */\nexport function isTouchDevice(): boolean {\n\treturn typeof window !== 'undefined' && window.matchMedia('(pointer: coarse)').matches;\n}\n\n/** Hands an already-built PNG to the share sheet, or saves it. Call it straight\n *  from the click handler. Resolves to how it went out, or null if dismissed. */\nexport async function sharePng(blob: Blob, filename: string): Promise<'share' | 'download' | null> {\n\tif (isTouchDevice()) {\n\t\tconst file = new File([blob], filename, { type: 'image/png' });\n\t\tif (navigator.canShare?.({ files: [file] })) {\n\t\t\ttry {\n\t\t\t\tawait navigator.share({ files: [file] });\n\t\t\t\treturn 'share';\n\t\t\t} catch (err) {\n\t\t\t\tif ((err as Error)?.name === 'AbortError') return null;\n\t\t\t\t// anything else: fall through to a download\n\t\t\t}\n\t\t}\n\t}\n\tconst href = URL.createObjectURL(blob);\n\tconst a = document.createElement('a');\n\ta.href = href;\n\ta.download = filename;\n\tdocument.body.appendChild(a);\n\ta.click();\n\ta.remove();\n\tsetTimeout(() => URL.revokeObjectURL(href), 10_000);\n\treturn 'download';\n}\n"],"version":3}