PageSourceSearch

https://sendwishonline.com/6329.325d8e34fa4bd6ce.js

js sendwishonline.com collected 2026-10-03 22:42:25 UTC 16,496 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunksendwishonline=self.webpackChunksendwishonline||[]).push([[6329],{97817:(S,u,c)=>{c.d(u,{a:()=>f,r:()=>b});const b={widthPx:1760,heightPx:1100,orientation:"landscape",slotsPerPage:2};class f extends Error{constructor(v,g){super(g),this.code=v,this.name="PdfGenerationError"}}},86329:(S,u,c)=>{c.d(u,{p:()=>U});var b=c(74911),f=c(97817),p=c(65879),v=c(96814),g=c(20553),k=c(51545),h=c(7123);const P=new Set(k._.map(l=>l.class)),L=new Set(["B","STRONG","I","EM","U","S","STRIKE","SPAN","DIV","P","BR","UL","OL","LI"]),A=new Set(["left","center","right","justify"]),M=new Set(["none","uppercase","lowercase","capitalize"]),H=new Set(["default","message","image"]),y=/^#([0-9a-f]{3}|[0-9a-f]{6})$/i;let T=(()=>{class l{constructor(t){this.platformId=t,this.fontFaceCache=new Map}generate(t,i,e=f.r){if(!(0,v.NF)(this.platformId))throw new f.a("invalid-response","PDF HTML generation must run in the browser.");if(!i||0===i.length)throw new f.a("invalid-response","At least one message is required to generate a PDF.");this.fontFaceCache.clear();const o=new Map,s=[{kind:"cover"},{kind:"closing"},...i.map(m=>({kind:"message",message:m}))],a=this.buildPages(t,s,e,o),r=this.buildFontFacesCss(o),n=this.buildGoogleFontsLinkTag(o);return{html:this.wrapDocument(a,e,r,n),assets:[]}}buildPages(t,i,e,o){const s=e.slotsPerPage,a=[];for(let r=0;r<i.length;r+=s){const n=i.slice(r,r+s);a.push(this.buildPageHtml(t,n,e,o,r))}return a.join("\n")}buildPageHtml(t,i,e,o,s){const a=i.length>1?"":" pdf-slot--single",r=i.map((n,d)=>this.buildSlotHtml(t,n,o,`p${s}-${d}`,a)).join("\n");return`<section class="pdf-page" style="width:${e.widthPx}px;height:${e.heightPx}px;">${r}</section>`}buildSlotHtml(t,i,e,o,s){return"cover"===i.kind?this.buildCoverHtml(t,o,s):"closing"===i.kind?this.buildClosingHtml(t,o,s):this.buildMessageHtml(i.message,e,o,s)}buildCoverHtml(t,i,e){return t.coverImage&&this.isSafeImageUrl(t.coverImage)?`\n      <div class="pdf-slot pdf-slot--bleed${e} slot-${i}">\n        <img class="pdf-slot-cover-image" src="${this.escapeAttribute(t.coverImage)}" loading="eager">\n      </div>`:`\n      <div class="pdf-slot pdf-slot--center${e} slot-${i}">\n        <h1 class="pdf-cover-title">${this.escapeHtml(t.cardTitle||`Group Card For ${t.recipientName||""}`.trim())}</h1>\n        ${t.senderName?`<p class="pdf-cover-sender">from ${this.escapeHtml(t.senderName)}</p>`:""}\n      </div>`}buildClosingHtml(t,i,e){const o=t.cardLogo&&this.isSafeImageUrl(t.cardLogo)&&"blank"!==t.cardLogo.trim().toLowerCase()?t.cardLogo:"https://sendwishonline.com/assets/images/logo/new-logo.svg",s=`<img class="pdf-closing-logo" src="${this.escapeAttribute(o)}" loading="eager">`,a=t.businessDetails,r=a?[a.business_name,a.phone_number,a.email_id,a.website_url].filter(d=>!!d&&d.trim().length>0).map(d=>`<div>${this.escapeHtml(d)}</div>`).join(""):"";return`\n      <div class="pdf-slot pdf-slot--center${e} slot-${i}">\n        ${s}\n        <p class="pdf-closing-tagline">Thank you for celebrating with SendWish!</p>\n        ${r?`<div class="pdf-closing-business">${r}</div>`:""}\n        ${t.shareUrl&&/^https?:\/\//i.test(t.shareUrl)?`<img class="pdf-closing-qr" src="https://api.qrserver.com/v1/create-qr-code/?size=240x240&data=${encodeURIComponent(t.shareUrl)}" loading="eager">`:""}\n      </div>`}buildMessageHtml(t,i,e,o){const s=this.sanitizeMessage(t),a=(0,h.uE)(s),r=(0,h.LQ)(s),n=this.resolveFontFace(s.font_name);n&&i.set(n.family,n);const d=`'${(n?.family||"Arial").replace(/'/g,"\\'")}', Arial, sans-serif`,m=this.buildMediaHtml(s,a),w="transparent"===r?"":`background-color:${r};`;if("image"===a)return`\n      <div class="pdf-slot pdf-slot--${a}${o} slot-${e}" style="${w}">\n        <style>.slot-${e}, .slot-${e} * { font-family: ${d} !important; }</style>\n        ${m}\n      </div>`;const G=(0,h.vj)(s),F=!!s.user_name,D=!!m,j=F?`<div class="card-message-signature ${this.signatureGradientClass(s)}"><span>~ <b>${s.user_name}</b></span></div>`:"";return`\n      <div class="pdf-slot pdf-slot--${a}${o} slot-${e}" style="${w}">\n        <style>.slot-${e}, .slot-${e} * { font-family: ${d} !important; }</style>\n        ${m}\n        <div class="${["pdf-slot-text",F?"has-signature":"",D?"pdf-slot-text--after-media":""].filter(
1Boolean).join(" ")}">${G}</div>\n        ${j}\n      </div>`}signatureGradientClass(t){let e=0;const o=t.uuid||t.user_name||"";for(let s=0;s<o.length;s++)e=31*e+o.charCodeAt(s)>>>0;return"sig-gradient-"+e%6}buildMediaHtml(t,i){if("image"===i){const e=(0,h.gs)(t).filter(a=>this.isSafeImageUrl(a));if(0===e.length)return"";const o=(0,h.B3)(t);return`<div class="pdf-collage pdf-collage--full pdf-collage-${o}">${e.slice(0,o).map(a=>`<img src="${this.escapeAttribute(a)}" loading="eager">`).join("")}</div>`}if(t.image&&this.isSafeImageUrl(t.image))return`<img class="pdf-message-image" src="${this.escapeAttribute(t.image)}" loading="eager">`;if(t.video_path||t.video_id){const e=this.resolveVideoThumbnail(t);return e?`\n          <div class="pdf-video-thumb">\n            <img class="pdf-message-image" src="${this.escapeAttribute(e)}" loading="eager">\n            <span class="pdf-video-play">&#9654;</span>\n          </div>`:this.buildMediaCardHtml("video",t.font_color)}return t.audio_path?this.buildAudioCardHtml():""}resolveVideoThumbnail(t){const i=t.video_path||"",e=/(?:youtube\.com\/(?:watch\?v=|shorts\/)|youtu\.be\/)([a-zA-Z0-9_-]{11})/.exec(i);return e?`https://img.youtube.com/vi/${e[1]}/hqdefault.jpg`:t.video_id&&!i.includes("tiktok.com")?`${g.N.cloudinaryVideoBaseUrl}/${t.video_id}.jpg`:null}buildAudioCardHtml(){return'\n      <div class="pdf-media-card pdf-media-card--audio">\n        <div class="pdf-media-icon">\n          <svg width="36" height="36" viewBox="0 0 24 24" fill="currentColor">\n            <path d="M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5-3c0 2.76-2.24 5-5 5s-5-2.24-5-5H5c0 3.53 2.61 6.43 6 6.92V21h2v-2.08c3.39-.49 6-3.39 6-6.92h-2z"/>\n          </svg>\n        </div>\n        <div class="pdf-media-label">Voice Message</div>\n      </div>'}buildMediaCardHtml(t,i){return`\n      <div class="pdf-media-card" style="color:${this.escapeAttribute(i)};">\n        <div class="pdf-media-icon"><svg width="36" height="36" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg></div>\n        <div class="pdf-media-label">Video Message</div>\n      </div>`}isSafeImageUrl(t){return!!t&&(/^(https?:)?\/\//i.test(t)||t.startsWith("data:image/")||t.startsWith("/"))}sanitizeMessage(t){const i=P.has(t.font_name)?t.font_name:"",e=Math.min(96,Math.max(8,parseInt(String(t.font_size),10)||18)),o=y.test(t.font_color||"")?t.font_color:"#000000",s=H.has(t.layout_type||"")?t.layout_type:"default";return{...t,font_name:i,font_size:String(e),font_color:o,layout_type:s,user_name:this.escapeHtml(t.user_name||""),text:this.sanitizeRichText(t.text||""),font_setting:this.sanitizeFontSetting(t.font_setting),message_background:this.sanitizeMessageBackgroun
1d(t.message_background)}}sanitizeFontSetting(t){if(!t)return"";try{const i=JSON.parse(t),e=Math.min(300,Math.max(50,Number(i.lineHeight)||100)),o=Math.min(20,Math.max(-5,Number(i.letterSpacing)||0)),s=M.has(i.textCase)?i.textCase:"none";return JSON.stringify({lineHeight:e,letterSpacing:o,textCase:s})}catch{return""}}sanitizeMessageBackground(t){if(!t)return"";try{const i=JSON.parse(t);if("object"!=typeof i||null===i)return"";const e=y.test(i.color||"")?i.color:"",o=Math.min(100,Math.max(0,Number(i.opacity)??100));return e?JSON.stringify({color:e,opacity:o}):""}catch{return""}}sanitizeRichText(t){const i=document.createElement("div");return i.innerHTML=t,this.cleanNode(i),i.innerHTML}cleanNode(t){const i=Array.from(t.childNodes);for(const e of i){if(e.nodeType===Node.TEXT_NODE)continue;if(e.nodeType!==Node.ELEMENT_NODE){t.removeChild(e);continue}const o=e;if(!L.has(o.tagName)){for(;o.firstChild;)t.insertBefore(o.firstChild,o);t.removeChild(o);continue}const s=o.style?.textAlign;Array.from(o.attributes).forEach(a=>o.removeAttribute(a.name)),s&&A.has(s)&&(o.style.textAlign=s),this.cleanNode(o)}}escapeHtml(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}escapeAttribute(t){return this.escapeHtml(t)}resolveFontFace(t){if(!t)return null;if(this.fontFaceCache.has(t))return this.fontFaceCache.get(t);const{classFamilyMap:i,fontFaceSrcMap:e}=this.readStylesheetFontMaps(),o=i.get(t);if(!o)return null;const s=this.firstFontFamilyName(o),a=e.get(s.toLowerCase())||null,r={family:s,srcUrl:a};return this.fontFaceCache.set(t,r),r}firstFontFamilyName(t){return t.split(",")[0].trim().replace(/^["']|["']$/g,"")}readStylesheetFontMaps(){const t=new Map,i=new Map;for(const e of Array.from(document.styleSheets)){let o;try{o=e.cssRules}catch{continue}for(const s of Array.from(o))if(s instanceof CSSFontFaceRule){const a=this.firstFontFamilyName(s.style.getPropertyValue("font-family")),r=s.style.getPropertyValue("src"),n=/url\((['"]?)(.*?)\1\)/.exec(r);a&&n&&i.set(a.toLowerCase(),n[2])}else if(s instanceof CSSStyleRule){const a=s.selectorText.split(",").map(n=>n.trim()),r=s.style.getPropertyValue("font-family");if(!r)continue;for(const n of a)n.startsWith(".")&&t.set(n.slice(1),r)}}return{classFamilyMap:t,fontFaceSrcMap:i}}buildFontFacesCss(t){let i="";for(const e of t.values())e.srcUrl&&(i+=`@font-face { font-family: '${e.family.replace(/'/g,"\\'")}'; src: url('${e.srcUrl}'); font-display: swap; }\n`);return i}buildGoogleFontsLinkTag(t){const i=Array.from(t.values()).filter(e=>!e.srcUrl).map(e=>`family=${encodeURIComponent(e.family)}:wght@400;600;700`);return 0===i.length?"":`<link rel="stylesheet" href="https://fonts.googleapis.com/css2?${i.join("&")}&display=swap">`}wrapDocument(t,i,e,o){return`<!doctype html>\n<html>\n<head>\n<meta charset="UTF-8">\n${o}\n<style>\n  @page { size: ${i.widthPx}px ${i.heightPx}px; margin: 0; }\n  html, body { margin: 0; padding: 0; }\n  * { box-sizing: border-box; }\n  body { font-family: Arial, sans-serif; }\n  .pdf-page {\n    position: relative;\n    width: ${i.widthPx}px;\n    height: ${i.heightPx}px;\n    overflow: hidden;\n    display: flex;\n    gap: 28px;\n    padding: 28px;\n    background: #faf7f0;\n    page-break-after: always;\n  }\n  .pdf-page:last-child { page-break-after: auto; }\n  .pdf-slot {\n    position: relative;\n    flex: 1 1 50%;\n    min-width: 0;\n    padding: 44px;\n    overflow: hidden;\n    display: flex;\n    flex-direction: column;\n    background: #fffdf8;\n    border: 1px solid #e6ddc8;\n    border-radius: 14px;\n  }\n  .pdf-slot--single { flex: 1 1 100%; }\n  .pdf-slot--bleed { padding: 0; overflow: hidden; }\n  .pdf-slot--center { align-items: center; justify-content: center; text-align: center; }\n  .pdf-slot-cover-image { width: 100%; height: 100%; object-fit: cover; }\n  .pdf-cover-title { font-size: 42px; margin: 0 0 12px; }\n  .pdf-cover-sender { font-size: 20px; opacity: 0.75; margin: 0; }\n  .pdf-closing-logo { max-width: 160px; max-height: 160px; object-fit: contain; margin-bottom: 20px; }\n  .pdf-closing-tagline { font-size: 20px; margin: 0 0 16px; }\n  .pdf-closing-business { font-size: 15px; opacity: 0.8; line-height: 1.6; margin-bottom: 20px; }\n  .pdf-closing-qr { width: 140px; height: 140px; }\n  .pdf-message-image {\n    width: 100%;\n    height: 460px;\n    object-fit: cover;\n    border-radius: 8px;\n    margin-bottom: 20px;\n  }\n  .pdf-collage { display: grid; gap: 0; margin-bottom: 24px; height: 460px; overflow: hidden; border-radius: 6px; background: #f8f9fa; }\n  .pdf-collage--full { flex: 1; height: auto; margin-bottom: 0; }\n  .pdf-collage-1 { grid-template-columns: 1fr; grid-template-rows: 1fr; }\n  /* Matches the book: two photos stacked top/bottom, not side by side. */\n  .pdf-collage-2 { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; }\n  .pdf-collage-2 img:first-child { border-bottom: 3px solid #fff; }\n  .pdf-collage-4 { grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; }\n  .pdf-collage-4 img:nth-child(1) { border-right: 5px solid #fff; border-bottom: 5px solid #fff; }\n  .pdf-collage-4 img:nth-child(2) { border-bottom: 5px solid #fff; }\n  .pdf-collage-4 img:nth-child(3) { border-right: 5px solid #fff; }\n  .pdf-collage img {\n    width: 100%;\n    height: 100%;\n    /* Grid items default to min-height/min-width:auto, which for an <img> is\n       its natural intrinsic size \u2014 that silently overrides the 1fr track and\n       breaks object-fit, looking exactly like a cover crop. */\n    min-height: 0;\n    min-width: 0;\n    /* fill, matching the book \u2014 cover crops the photo, and contain leaves a\n       visible gap whenever a photo's aspect ratio doesn't match its cell. */\n    object-fit: f
1ill;\n    display: block;\n  }\n  .pdf-slot-text {\n    flex: 1;\n    display: flex;\n    flex-direction: column;\n    justify-content: center;\n    word-break: break-word;\n    white-space: normal;\n  }\n  .pdf-slot-text.has-signature { padding-bottom: 104px; }\n  .pdf-slot-text--after-media { justify-content: flex-start; }\n  .pdf-video-thumb { position: relative; margin-bottom: 20px; }\n  .pdf-video-thumb .pdf-message-image { margin-bottom: 0; }\n  .pdf-video-play {\n    position: absolute;\n    top: 50%;\n    left: 50%;\n    transform: translate(-50%, -50%);\n    font-size: 34px;\n    color: #fff;\n    text-shadow: 0 1px 6px rgba(0, 0, 0, 0.6);\n  }\n  .pdf-media-card {\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    justify-content: center;\n    gap: 10px;\n    padding: 28px 40px;\n    margin-bottom: 20px;\n    border-radius: 12px;\n    background: #f7f7f7;\n    color: #2b2b2b;\n  }\n  .pdf-media-card--audio { background: #f7f7f7; color: #2b2b2b; }\n  .pdf-media-label { font-size: 14px; color: #2b2b2b; }\n  /* Full-width colored bar pinned to the bottom of the card \u2014 background\n     comes from signatureGradientClass(), not the message's own font_color. */\n  .card-message-signature {\n    position: absolute;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    padding: 30px 28px;\n    border-radius: 0 0 14px 14px;\n  }\n  .card-message-signature span {\n    color: #fff;\n    font-weight: 700;\n    font-style: normal;\n    font-size: 32px !important;\n    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);\n  }\n  .sig-gradient-0 { background: linear-gradient(90deg, #6a8dff, #7b6bff); }\n  .sig-gradient-1 { background: linear-gradient(90deg, #ff7a9c, #b06bff); }\n  .sig-gradient-2 { background: linear-gradient(90deg, #ff9a5a, #ff6f6f); }\n  .sig-gradient-3 { background: linear-gradient(90deg, #33c39a, #35a2b8); }\n  .sig-gradient-4 { background: linear-gradient(90deg, #b06bff, #6a8dff); }\n  .sig-gradient-5 { background: linear-gradient(90deg, #ffb454, #ff7a9c); }\n  ${e}\n</style>\n</head>\n<body>\n${t}\n</body>\n</html>`}static{this.\u0275fac=function(i){return new(i||l)(p.LFG(p.Lbi))}}static{this.\u0275prov=p.Yz7({token:l,factory:l.\u0275fac,providedIn:"root"})}}return l})();var x=c(69862),$=c(58504),C=c(37398),z=c(26306);let E=(()=>{class l{constructor(t){this.http=t}generatePdf(t,i){const e=new FormData;return e.append("files",new Blob([t.html],{type:"text/html"}),"index.html"),t.assets.forEach(o=>{e.append("files",o.blob,o.filename)}),e.append("uuid",i),this.post(`${g.N.PDF_API_URL}/api/pdf/generate`,e)}generatePdfFromUrl(t,i,e){return this.post(`${g.N.PDF_API_URL}/api/pdf/generate-from-url`,{url:t,uuid:i,kind:e})}post(t,i){return this.http.post(t,i).pipe((0,C.U)(e=>{if(!e?.url)throw new f.a("invalid-response","PDF service returned no URL.");return{url:e.url}}),(0,z.K)(e=>{if(e instanceof f.a)return(0,$._)(()=>e);const o=e instanceof x.UA?e.status:0,s=0===o||o>=500?"gotenberg-unavailable":"upload-failed";return(0,$._)(()=>new f.a(s,"Failed to generate the PDF. Please try again."))}))}static{this.\u0275fac=function(i){return new(i||l)(p.LFG(x.eN))}}static{this.\u0275prov=p.Yz7({token:l,factory:l.\u0275fac,providedIn:"root"})}}return l})(),U=(()=>{class l{constructor(t,i){this.pdfHtmlGenerator=t,this.gotenbergService=i}generateGroupCardPdf(t,i,e,o=f.r){return(0,b.P)(()=>{const s=this.pdfHtmlGenerator.generate(t,i,o);return this.gotenbergService.generatePdf(s,e)})}generateGroupCardPdfFromUrl(t,i,e){return this.gotenbergService.generatePdfFromUrl(t,i,e)}static{this.\u0275fac=function(i){return new(i||l)(p.LFG(T),p.LFG(E))}}static{this.\u0275prov=p.Yz7({token:l,factory:l.\u0275fac,providedIn:"root"})}}return l})()}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.