@parag.more.withsurface.com/forms-sdk 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/surface-forms-sdk.min.js +1 -21
- package/dist/types/bind/scheduler/embedUtils.d.ts +1 -0
- package/dist/types/core/engine/formEngine.d.ts +2 -0
- package/docs/api.md +9 -5
- package/docs/reference/engine.md +9 -6
- package/llms.txt +41 -23
- package/package.json +1 -1
- package/skills/surface-forms-sdk/SKILL.md +50 -23
- package/skills/surface-forms-sdk/debugging.md +21 -19
- package/skills/surface-forms-sdk/patterns.md +42 -1
- package/dist/types/core/identity/journey.testStubs.d.ts +0 -4
|
@@ -1,21 +1 @@
|
|
|
1
|
-
"use strict";var SurfaceFormsSDK=(()=>{var $e=Object.defineProperty;var en=Object.getOwnPropertyDescriptor;var tn=Object.getOwnPropertyNames;var nn=Object.prototype.hasOwnProperty;var rn=(e,n)=>{for(var t in n)$e(e,t,{get:n[t],enumerable:!0})},on=(e,n,t,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let o of tn(n))!nn.call(e,o)&&o!==t&&$e(e,o,{get:()=>n[o],enumerable:!(r=en(n,o))||r.enumerable});return e};var sn=e=>on($e({},"__esModule",{value:!0}),e);var yr={};rn(yr,{DEFAULT_API_BASE_URL:()=>Q,DEFAULT_REDIRECT_TIMEOUT_MS:()=>Ot,ENRICHMENT_STATE_ID:()=>Oe,IDENTITY_INFO_ANSWER_KEYS:()=>Mt,JOURNEY_COOKIE_NAME:()=>re,LEAD_DATA_STORAGE_KEY:()=>te,LEAD_DATA_TTL_MS:()=>Ut,RECENT_VISIT_COOKIE_NAME:()=>oe,SurfaceForms:()=>Gt,attachEmailValidation:()=>qe,attachEnrichment:()=>Fe,bindForm:()=>ae,buildIdentifyPayload:()=>xe,buildRedirectUrl:()=>We,buildResponsesArray:()=>Ke,buildStepTransitionEventBatch:()=>ke,buildUrlData:()=>Re,constructUrlParamsObject:()=>Je,createEmailValidator:()=>he,createEmitter:()=>Se,createFormEngine:()=>Te,createFormJourneyTracker:()=>_e,createJourneyTracker:()=>Le,createPushEventClient:()=>we,createSchedulerClient:()=>ge,createStartedDetector:()=>Ie,createSubmitResponsePayload:()=>Ee,createTransport:()=>be,createUpdateResponsePayload:()=>z,enrichmentSourcesOf:()=>pe,ensureIdentified:()=>ne,fetchRuntimeConfig:()=>le,getBrowserFingerprint:()=>Ce,getHash:()=>Ye,hasEnabledEnrichmentProvider:()=>fe,identifyLead:()=>Pe,mountBookingWidget:()=>de,mountScheduler:()=>Rt,observeDropoff:()=>Ae,observeFormView:()=>ie,parseCookiesObject:()=>Qe,parsePrefillParams:()=>Dt,parseQuestionId:()=>ze,performRedirect:()=>Ft,readLeadData:()=>Y,schedulerQuestionsOf:()=>me,statefulQuestionIdsOf:()=>dt,statefulQuestionsOf:()=>J,stepsOf:()=>ce,submitResponse:()=>ve,toSchedulerAnswerState:()=>St,updateResponse:()=>ee,writeLeadData:()=>Me});var ie=(e,n)=>{if(typeof IntersectionObserver>"u")return n(),()=>{};let t=!1,r=new IntersectionObserver(o=>{let[a]=o;!a?.isIntersecting||t||(t=!0,r.disconnect(),n())});return r.observe(e),()=>r.disconnect()};var ot="input, select, textarea",an=e=>e.matches(ot)?[e]:Array.from(e.querySelectorAll(ot)).filter(n=>n.closest("[data-question-id]")===e),dn=(e,n,t)=>{let r=e.getAttribute("data-field-name")??n.getAttribute("data-field-name");return r||(t==="Dropdown"&&n instanceof HTMLSelectElement?"selected":n instanceof HTMLInputElement&&n.type==="email"?"email":"input")},st=(e,n)=>{let t=e.getAttribute("data-question-type")??n.getAttribute("data-question-type");return t||(n instanceof HTMLInputElement&&n.type==="email"?"EmailForm":"ShortInput")},it=e=>e instanceof HTMLInputElement&&(e.type==="checkbox"||e.type==="radio")&&e.type==="checkbox"?e.checked:e.value,ln=e=>e instanceof HTMLInputElement&&(e.type==="radio"||e.type==="checkbox"),at=e=>{let n=e.findIndex(t=>t.checked);return{value:n===-1?"":e[n].value,index:n}},un={MultipleOptionsQuestion:e=>({choices:e.map((n,t)=>({key:n.value,value:n.checked,index:t}))}),MultipleChoiceQuestion:e=>({choices:e.map(n=>({key:n.value,value:n.checked}))}),MMChoiceQuestion:e=>({choices:e.map(n=>({key:n.value,value:n.checked}))}),GraphicOptions:at,MultipleChoiceSingleAnswer:at},ae=({engine:e,root:n,expectedQuestionIds:t})=>{let r=[],o=new Set,a=(u,c,p)=>{u.addEventListener(c,p),r.push(()=>u.removeEventListener(c,p))};for(let u of Array.from(n.querySelectorAll("[data-question-id]"))){let c=u.getAttribute("data-question-id"),p=an(u);if(p.length===0)continue;o.add(c);let A=st(u,p[0]),h=un[A],f=p.filter(ln);if(h&&f.length>0){let y=()=>e.setAnswer(c,{type:A,...h(f)});for(let S of f)a(S,"change",y);f.some(S=>S.checked)&&y();continue}for(let y of p){let S=st(u,y),g=dn(u,y,S),M=()=>e.setAnswer(c,{type:S,[g]:it(y)});a(y,"input",M),a(y,"change",M);let k=it(y);k!==""&&k!==!1&&M()}}let i=(t??[]).filter(u=>!o.has(u));i.length>0&&console.warn(`Surface SDK: form record declares questionIds with no bound element: ${i.join(", ")}. Answers for these will never be captured \u2014 check data-question-id attributes (validate_form_html catches this at authoring time).`);let s="[data-surface-goto-step], .surface-disqualify-button, .surface-submit-button, .surface-next-button";for(let u of Array.from(n.querySelectorAll(s))){let c=u.getAttribute("data-surface-goto-step"),p=[c!=null?"goto":null,u.classList.contains("surface-disqualify-button")?"disqualify":null,u.classList.contains("surface-submit-button")?"submit":null,u.classList.contains("surface-next-button")?"next":null].filter(h=>h!=null),A=p[0];p.length>1&&console.warn(`Surface SDK: element carries multiple navigation markers (${p.join(", ")}); only "${A}" is bound.`),a(u,"click",h=>{h.preventDefault(),A==="goto"?e.goToStep(c).catch(f=>console.warn(`Surface SDK: ${String(f)}`)):A==="disqualify"?e.disqualify():A==="submit"?e.submit():e.next()})}n instanceof HTMLFormElement&&a(n,"submit",u=>{u.preventDefault(),e.submit()});let d=Array.from(n.querySelectorAll("[data-step-id]")),l=()=>{let{currentStepId:u}=e.state();for(let c of d)c.hidden=c.getAttribute("data-step-id")!==u};return d.length>0&&(l(),r.push(e.on("stepChanged",l))),r.push(ie(n,()=>e.markViewed())),()=>r.forEach(u=>u())};var cn=()=>{let e=new Date;return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}`},pn=e=>{let[n,t]=e.split("-").map(Number);return new Date(n,t-1,1).toLocaleDateString(void 0,{month:"long",year:"numeric"})},mn=e=>{let[n,t,r]=e.split("-").map(Number);return new Date(n,t-1,r).toLocaleDateString(void 0,{weekday:"short",month:"short",day:"numeric"})},fn=(e,n)=>{let[t,r]=e.split("-").map(Number),o=new Date(t,r-1+n,1);return`${o.getFullYear()}-${String(o.getMonth()+1).padStart(2,"0")}`},de=({container:e,scheduler:n,eventTypeId:t,timezone:r=Intl.DateTimeFormat().resolvedOptions().timeZone,duration:o,prefill:a,identity:i,formatters:s,onEvent:d,onComplete:l})=>{let u=s?.month??pn,c=s?.date??mn,p=s?.time??(b=>new Date(b.start).toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit",timeZone:r})),A=document.createElement("div");A.className="surface-booking",e.appendChild(A);let h=cn(),f=[],y=null,S=null,g=!1,M=0,k=(b,D,I)=>{let v=document.createElement(b);return v.className=D,I!=null&&(v.textContent=I),v},x=b=>{g||A.replaceChildren(...b)},R=(b,D)=>{let I=k("p","surface-booking-error",b),v=k("button","surface-booking-retry","Try again");v.type="button",v.addEventListener("click",D),x([I,v])},U=async()=>{let b=h,D=++M;x([k("p","surface-booking-loading","Loading availability\u2026")]);let I=await n.getMonthAvailability({eventTypeId:t,month:b,timezone:r,duration:o});if(g||D!==M)return;if(!I.ok){R("Unable to load availability.",()=>{U()});return}f=I.data.data?.dates??[];let v=k("p","surface-booking-month",u(b));v.dataset.value=b;let L=k("div","surface-booking-month-nav");for(let[F,T]of[["Previous month",-1],["Next month",1]]){let P=k("button","surface-booking-month-button",F);P.type="button",P.addEventListener("click",()=>{h=fn(h,T),U()}),L.appendChild(P)}let O=k("ul","surface-booking-dates");for(let F of f.filter(T=>T.slots&&T.slots.length>0)){let T=k("li","surface-booking-date"),P=k("button","surface-booking-date-button",c(F.date));P.dataset.value=F.date,P.type="button",P.addEventListener("click",()=>{y=F,d?.({type:"date_selected",date:F.date}),w()}),T.appendChild(P),O.appendChild(T)}O.childElementCount===0&&O.appendChild(k("li","surface-booking-no-dates","No availability this month.")),x([v,L,O])},w=async()=>{if(!y)return;let b=++M,D=y.slots??[];if(D.length===0){let O=await n.getSlots({eventTypeId:t,date:y.date,timezone:r,duration:o});if(g||b!==M)return;if(!O.ok){R("Unable to load times.",()=>{w()});return}D=O.data.data?.slots??[]}let I=k("p","surface-booking-day",c(y.date));I.dataset.value=y.date;let v=k("button","surface-booking-back","Back");v.type="button",v.addEventListener("click",()=>{U()});let L=k("ul","surface-booking-slots");for(let O of D){let F=k("li","surface-booking-slot"),T=k("button","surface-booking-slot-button",p(O));T.dataset.value=O.start,T.type="button",T.addEventListener("click",()=>{S=O,d?.({type:"slot_selected",slot:O}),_()}),F.appendChild(T),L.appendChild(F)}x([I,v,L])},_=b=>{if(!S)return;b==null&&d?.({type:"form_opened"});let D=k("form","surface-booking-form"),I=k("input","surface-booking-name");I.name="name",I.placeholder="Name",I.value=a?.name??"";let v=k("input","surface-booking-email");v.type="email",v.name="email",v.placeholder="Email",v.value=a?.email??"";let L=k("button","surface-booking-submit","Book");L.type="submit",D.append(I,v,L),b&&D.appendChild(k("p","surface-booking-error",b)),D.addEventListener("submit",O=>{O.preventDefault(),(async()=>{L.disabled=!0;let F=typeof i=="function"?await i():i,T=await n.book({eventTypeId:t,startTime:S.start,endTime:S.end,timezone:r,inviteeName:I.value,inviteeEmail:v.value,duration:o,...F});if(!g){if(!T.ok){_("Booking failed. Please try again.");return}x([k("p","surface-booking-booked","Booked!")]),d?.({type:"booking_confirmed",booking:T.data}),l(T.data)}})()}),x([D])};return d?.({type:"viewed"}),U(),()=>{g=!0,A.remove()}};var le=(e,n,{preview:t=!1,previewToken:r}={})=>e.get(`/api/v1/public/forms/${n}/runtime-config${t?`?preview=1${r?`&pt=${encodeURIComponent(r)}`:""}`:""}`),ue=e=>{let n=e.components;if(Array.isArray(n))return n;let t=n?.layout;return Array.isArray(t)?t.flatMap(r=>{let o=r.row;return Array.isArray(o)?o.map(a=>a.type==="GridLayoutRowItem"?a.component:a):[]}):[]},ce=e=>(e.steps??[]).map(n=>({id:n.id,...n.endStepKind!==void 0&&{endStepKind:n.endStepKind}})),J=e=>(e.steps??[]).flatMap(ue).flatMap(n=>{let t=n;return typeof t?.state?.questionId!="string"?[]:[{questionId:t.state.questionId,...typeof t.type=="string"&&{componentType:t.type}}]}),dt=e=>J(e).map(n=>n.questionId),pe=e=>(e.steps??[]).flatMap(ue).flatMap(n=>{let t=n;if(typeof t?.state?.questionId!="string")return[];if(t.type==="IdentityInfo"){let r=typeof t.content?.enrichmentSourceField=="string"?t.content.enrichmentSourceField:"emailAddress";return[{questionId:t.state.questionId,fieldNames:[...new Set([r,"websiteUrl"])]}]}return t.type==="EmailForm"?[{questionId:t.state.questionId,fieldNames:["email"]}]:[]}),lt=e=>{let n=e;return typeof n?.stepId=="string"&&typeof n?.questionId=="string"?{stepId:n.stepId,questionId:n.questionId}:void 0},gn=e=>{let n=lt(e),t=e?.variable;return n&&typeof t=="string"?{...n,variable:t}:void 0},me=e=>(e.steps??[]).flatMap(n=>ue(n).flatMap(t=>{let r=t;if(r?.type!=="CalendlyScreen"&&r?.type!=="DynamicScheduler")return[];if(typeof r.state?.questionId!="string")return[];let o=r.content??{},a={};for(let s of["dataUrl","eventTypeId","savvyCalLinkId","revenueHeroRouterId"])typeof o[s]=="string"&&(a[s]=o[s]);for(let s of["addSchedulerQueryParams","skipFormIfPrefilled"])typeof o[s]=="boolean"&&(a[s]=o[s]);for(let s of["linkNameToStep","linkLastNameToStep","linkEmailToStep"]){let d=lt(o[s]);d&&(a[s]=d)}let i=Object.entries(o.dataUrlParams??{}).flatMap(([s,d])=>{let l=gn(d);return l?[[s,l]]:[]});return i.length>0&&(a.dataUrlParams=Object.fromEntries(i)),Array.isArray(o.calendars)&&(a.calendars=o.calendars),o.defaultCalendar!=null&&(a.defaultCalendar=o.defaultCalendar),[{questionId:r.state.questionId,stepId:n.id,componentType:r.type,calendarType:typeof o.calendarType=="string"?o.calendarType:"Calendly",content:a}]})),ut=e=>(e.steps??[]).flatMap(ue).some(n=>typeof n?.content?.enrichmentSourceField=="string"),fe=e=>{let n=e?.enrichment;return n?.version!==2||!Array.isArray(n.providers)?!1:n.providers.some(t=>t?.enabled===!0&&Array.isArray(t.enabledFields)&&t.enabledFields.length>0)};var X=e=>/^[a-z][a-z0-9+.-]*:\/\//i.test(e)?e:`https://${e}`,B=(e,n)=>{let t;try{t=new URL(X(e))}catch{return null}for(let[r,o]of Object.entries(n))o!=null&&!t.searchParams.has(r)&&t.searchParams.set(r,o);return t.toString()},yn=(e,n)=>{let t=document.createElement("iframe");return t.className="surface-scheduler-frame",t.src=n,t.style.width="100%",t.style.height="100%",t.style.border="0",e.appendChild(t),t},W=e=>new Promise((n,t)=>{let r=document.querySelector(`script[src="${e}"]`);if(r){if(r.dataset.surfaceLoaded==="true")return n();r.addEventListener("load",()=>n()),r.addEventListener("error",()=>t(new Error(`Failed to load ${e}`)));return}let o=document.createElement("script");o.src=e,o.async=!0,o.addEventListener("load",()=>{o.dataset.surfaceLoaded="true",n()}),o.addEventListener("error",()=>{o.remove(),t(new Error(`Failed to load ${e}`))}),document.head.appendChild(o)}),hn=(e,n)=>{let t;try{t=new URL(e)}catch{return!1}return n.some(r=>"exact"in r?e===r.exact:t.protocol!=="https:"?!1:"hostRegex"in r?r.hostRegex.test(t.hostname):t.hostname===r.hostSuffix||t.hostname.endsWith(`.${r.hostSuffix}`))},q=(e,n)=>(console.warn(`Surface SDK: scheduler question "${e.questionId}" is missing ${n} on the record.`),()=>{}),j=e=>{let n=!1,t;return e().then(r=>{n?r?.():t=r}).catch(r=>console.warn("Surface SDK: scheduler embed failed",r)),()=>{n=!0,t?.()}},Z=(e,n)=>{let t=r=>{if(hn(r.origin,e))try{n(r.data)}catch(o){console.warn("Surface SDK: scheduler message handler failed",o)}};return window.addEventListener("message",t),()=>window.removeEventListener("message",t)},V=(e,{needsResponseId:n=!1,build:t})=>j(async()=>{let r=n?await e.ensureResponseId():null,o=t(r);if(o.src==null)return;let a=yn(e.container,o.src),i=o.origins&&o.onMessage?Z(o.origins,o.onMessage):void 0,s=o.poll&&r!=null?vn({transport:e.form.transport,...o.poll}):void 0;return()=>{i?.(),s?.(),a.remove()}}),vn=({transport:e,path:n,onResult:t,intervalMs:r=2e3,timeoutMs:o=3e5})=>{let a=Date.now(),i=!1,s=null,d=()=>{i=!0,s!=null&&clearInterval(s),s=null},l=async()=>{if(i)return;if(Date.now()-a>o)return d();let u=await e.get(n);i||!u.ok||t(u.data)==="stop"&&d()};return l(),s=setInterval(()=>{l()},r),d};var ct=e=>{let n=e.content.dataUrl;if(!n)return q(e.question,"dataUrl");let t=X(n),r=t.split("/").pop()?.split("?")[0]??"surface",o=t.replace(/^https?:\/\/(app\.)?cal\.com\//,""),a=`surface-cal-${e.question.questionId}`,i=document.createElement("div");i.id=a,e.container.appendChild(i);let s=l=>{let u=l.detail?.data?.booking?.uid;e.confirmBooking({uri:u?`https://app.cal.com/booking/${u}`:"",raw:l.detail})};window.addEventListener(`CAL:${r}:bookingSuccessful`,s);let d=j(async()=>{await W("https://app.cal.com/embed/embed.js");let l=window.Cal;l&&(l("init",r,{origin:"https://cal.com"}),l.ns?.[r]?.("inline",{elementOrSelector:`#${a}`,calLink:o,config:{...e.prefill.name&&{name:e.prefill.name},...e.prefill.email&&{email:e.prefill.email}}}))});return()=>{window.removeEventListener(`CAL:${r}:bookingSuccessful`,s),d(),i.remove()}};var pt=e=>{let n=e.content.dataUrl;if(!n)return q(e.question,"dataUrl");let t=!1,r=(a,i)=>{t||(t=!0,e.confirmBooking({uri:a,raw:i}))},o=e.content.addSchedulerQueryParams!==!1;return V(e,{needsResponseId:!0,build:a=>({src:B(n,{embed_domain:"1",embed_type:"Inline",...o&&{hide_event_type_details:"1",hide_gdpr_banner:"1"},...Object.keys(e.urlParams).length>0?e.urlParams:{name:e.prefill.name,email:e.prefill.email},...a!=null&&{utm_source:`surface-${a}`}}),origins:[{exact:"https://calendly.com"}],onMessage:i=>{let s=i;typeof s?.event!="string"||!s.event.startsWith("calendly.")||(s.event==="calendly.event_type_viewed"&&e.emit({type:"viewed"}),s.event==="calendly.date_and_time_selected"&&e.emit({type:"slot_selected"}),s.event==="calendly.event_scheduled"&&r(s.payload?.invitee?.uri??"",i))},poll:{path:`/api/v1/calendly/check-event/${a}`,onResult:i=>i.status==="pending"?"continue":i.status==="canceled"?(t&&e.cancelBooking(),"stop"):typeof i.url=="string"&&i.url&&i.responseId===a?(r(i.url,i),"stop"):t?"stop":"continue"}})})};var mt=e=>{let n=e.content.dataUrl;return n?V(e,{build:()=>({src:B(n,{embed:"true",...e.urlParams}),origins:[{hostSuffix:"chilipiper.com"}],onMessage:t=>{let r=t;r?.action==="booking-confirmed"&&e.confirmBooking({uri:r.args?.eventId??"",raw:t})}})}):q(e.question,"dataUrl")};var ft=e=>{let n=e.content.dataUrl;return n?V(e,{build:()=>({src:B(n,{embed:"true",...e.urlParams})})}):q(e.question,"dataUrl")};var gt=e=>{let n=e.content.dataUrl;if(!n)return q(e.question,"dataUrl");let t=B(n,{embed:"true",...e.urlParams});if(t==null)return()=>{};let r=`surface-hubspot-${e.question.questionId}`,o=document.createElement("div");o.id=r,o.className="meetings-iframe-container",o.dataset.src=t,e.container.appendChild(o);let a=Z([{exact:"https://meetings.hubspot.com"},{hostRegex:/^meetings-[a-z0-9]+\.hubspot\.com$/}],s=>{s?.meetingBookSucceeded===!0&&e.confirmBooking({uri:" ",raw:s})}),i=j(async()=>{await W("https://static.hsappstatic.net/MeetingsEmbed/ex/MeetingsEmbedCode.js"),window.MeetingsEmbedCode?.createMeetingsIframe(`#${r}`)});return()=>{a(),i(),o.remove()}};var bn=["reclaim.ai","reclaim.com","reclaimai.com"],yt=e=>{let n=e.content.dataUrl,t=(()=>{try{return new URL(X(n??"")).hostname}catch{return null}})(),r=t!=null&&bn.some(o=>t===o||t.endsWith(`.${o}`));return!n||!r?q(e.question,"a valid reclaim.ai dataUrl"):V(e,{needsResponseId:!0,build:o=>({src:B(n,{...o!=null&&{"data-responseId":o},...e.urlParams}),poll:{path:`/api/v1/reclaimai/check-event/${o}`,onResult:a=>{if(a.status==="pending")return"continue";if(a.meetingId!=null&&a.responseId===o){let i=[a.schedulingLinkId,a.meetingId].find(s=>typeof s=="string"&&s.length>0);return e.confirmBooking({uri:i??"",raw:a}),"stop"}return"continue"}}})})};var ht=e=>{let n=e.content.revenueHeroRouterId;if(!n)return q(e.question,"revenueHeroRouterId");let t=`surface-revenuehero-${e.question.questionId}`,r=document.createElement("div");r.id=t,e.container.appendChild(r);let o=Z([{hostSuffix:"revenuehero.io"}],i=>{let s=i;s?.type!=="MEETING_BOOKED"||s.meeting==null||e.confirmBooking({uri:s.meeting.id??"",...s.meeting.attributes?.meeting_time!=null&&{meetingTime:s.meeting.attributes.meeting_time},raw:i})}),a=j(async()=>{await W("https://assets.revenuehero.io/scheduler.min.js");let i=window.RevenueHero;if(!i)return;let s=new i({routerId:n,showLoader:!1}),d={...e.urlParams,...e.prefill.email&&{email:e.prefill.email},...e.prefill.name&&{name:e.prefill.name}},l=await s.submit(d);s.dialog.setEmbedTarget(`#${t}`),s.dialog.open(l)});return()=>{o(),a(),r.remove()}};var vt=e=>{let n=e.content.savvyCalLinkId;if(!n)return q(e.question,"savvyCalLinkId");let t=`surface-savvycal-${e.question.questionId}`,r=document.createElement("div");r.id=t,e.container.appendChild(r);let o=i=>{let s=i.detail;s&&e.confirmBooking({uri:s.url??"",raw:s})};window.addEventListener("savvycal.scheduled",o);let a=j(async()=>{await W("https://embed.savvycal.com/v1/embed.js");let i=window.SavvyCal;if(!i)return;i("init");let s=[e.prefill.name,e.prefill.lastName].filter(Boolean).join(" ");i("inline",{link:n,selector:`#${t}`,...s&&{displayName:s},...e.prefill.email&&{email:e.prefill.email}})});return()=>{window.removeEventListener("savvycal.scheduled",o),a(),r.remove()}};var bt=e=>new URLSearchParams(Object.fromEntries(Object.entries(e).filter(([,n])=>n!=null))),ge=({transport:e,preview:n=!1})=>{let t=n?"true":void 0,r=o=>{if(!o.ok)return o;let a=o.data.data;return a?.id?{ok:!0,data:a}:{ok:!1,error:{kind:"http",status:200,body:o.data}}};return{getPublicEventType:o=>e.get(`/api/v1/scheduler/event-types/${o}/public`),getAvailabilitySummary:({eventTypeId:o,timezone:a})=>{let i=new URLSearchParams({eventTypeId:o,timezone:a??Intl.DateTimeFormat().resolvedOptions().timeZone});return e.get(`/api/v1/scheduler/availability-summary?${i}`)},getMonthAvailability:({eventTypeId:o,month:a,timezone:i,duration:s,hostId:d,ownerEmail:l})=>{let[u,c]=a.split("-").map(Number),p=bt({eventTypeId:o,month:String(c),year:String(u),timezone:i,duration:s?String(s):void 0,preview:t,hostId:d,ownerEmail:l});return e.get(`/api/v1/scheduler/availability?${p}`)},getSlots:({eventTypeId:o,date:a,timezone:i,duration:s,hostId:d,ownerEmail:l})=>{let u=bt({eventTypeId:o,date:a,timezone:i,duration:s?String(s):void 0,preview:t,hostId:d,ownerEmail:l});return e.get(`/api/v1/scheduler/slots?${u}`)},book:async({eventTypeId:o,startTime:a,endTime:i,timezone:s,inviteeName:d,inviteeEmail:l,duration:u,intakeResponses:c,guestEmails:p,captchaToken:A,responseId:h,leadSessionId:f,fingerprint:y,hostRouting:S})=>{if(n)return{ok:!0,data:{id:"preview-booking-"+Date.now(),startTime:a,endTime:i,timezone:s,inviteeName:d||"Test User",inviteeEmail:l||"test@example.com",meetingJoinLink:null,cancelToken:"preview-cancel-"+Date.now(),rescheduleToken:"preview-reschedule-"+Date.now(),attendees:[{name:"Host",email:"host@example.com",isHost:!0}]}};let g=await e.post("/api/v1/scheduler/book",{eventTypeId:o,startTime:a,timezone:s,inviteeName:d,inviteeEmail:l.trim(),...u?{duration:u}:{},...c&&Object.keys(c).length>0?{intakeResponses:c}:{},...p&&p.length>0?{guestEmails:p}:{},...A?{captchaToken:A}:{},meta:{source:"form",...h?{responseId:h}:{},...f?{leadSessionId:f}:{},...y?{fingerprint:y}:{},...S?{hostRouting:S}:{}}});return r(g)},reschedule:async({bookingId:o,rescheduleToken:a,newStartTime:i,timezone:s})=>{let d=await e.post(`/api/v1/scheduler/bookings/${o}/reschedule`,{rescheduleToken:a,newStartTime:i,timezone:s});return r(d)}}},St=e=>{let n=e.attendees?.find(t=>t.isHost);return{type:"DynamicScheduler",eventScheduled:!0,uri:e.id,meetingTime:e.startTime,meetingEndTime:e.endTime,ownerEmails:n?.email??"",guestEmails:e.inviteeEmail,inviteeName:e.inviteeName,googleMeetLink:e.meetingJoinLink??""}};var kt=e=>{let n=e.content.eventTypeId;if(!n)throw new Error(`mountScheduler: Surface scheduler question "${e.question.questionId}" has no eventTypeId on the record.`);let t=ge({transport:e.form.transport,preview:e.form.preview}),r=[e.prefill.name,e.prefill.lastName].filter(Boolean).join(" ");return e.mergeAnswer({eventScheduled:!1,uri:"",schedulerSubStep:"date"}),de({container:e.container,scheduler:t,eventTypeId:n,prefill:{...r&&{name:r},...e.prefill.email&&{email:e.prefill.email}},formatters:e.formatters,identity:async()=>{let o=await e.ensureResponseId(),a=e.form.identity();return{...o!=null&&{responseId:o},...a.leadSessionId!=null&&{leadSessionId:a.leadSessionId},...a.fingerprint!=null&&{fingerprint:a.fingerprint}}},onEvent:o=>{if(o.type==="booking_confirmed"){let{booking:i}=o,s=i.attendees?.find(d=>d.isHost);e.confirmBooking({uri:i.id,meetingTime:i.startTime,meetingEndTime:i.endTime,inviteeName:i.inviteeName,guestEmails:i.inviteeEmail,ownerEmails:s?.email??"",joinLink:i.meetingJoinLink??"",raw:i},{schedulerSubStep:"booked"});return}let a={date_selected:"time",form_opened:"form"}[o.type];a&&e.mergeAnswer({schedulerSubStep:a}),e.emit(o)},onComplete:()=>{}})};var Sn={hostEmail:"ownerEmails",startTime:"meetingTime",endTime:"meetingEndTime",joinUrl:"googleMeetLink",duration:"durationMinutes",timezone:"hostTimezone"},wt=e=>{let n=e.content.dataUrl;if(!n)return q(e.question,"dataUrl");let[t,...r]=(e.prefill.name??"").split(/\s+/),o=e.prefill.lastName??(r.length>0?r.join(" "):void 0);return V(e,{needsResponseId:!0,build:a=>({src:B(n,{embed:"true",origin:window.location.origin,...t&&{firstname:t},...o&&{lastname:o},...e.prefill.email&&{email:e.prefill.email},...a!=null&&{utm_source:`surface-${a}`},...e.urlParams}),origins:[{exact:"https://scheduler.zoom.us"}],onMessage:i=>{let s=i;if(s?.type!=="bookingForm")return;let d=s.payload??{},l=[d.bookerFirstName,d.bookerLastName].filter(Boolean).join(" ");e.confirmBooking({uri:d.scheduledEventId??"",guestEmails:d.bookerEmail??"",...l&&{inviteeName:l},raw:i})},poll:{path:`/api/v1/zoom/check-event/${a}`,onResult:i=>{if(i.status==="pending"||i.hostEmail==null&&i.startTime==null)return"continue";let s={};for(let[d,l]of Object.entries(Sn))typeof i[d]=="string"&&(s[l]=i[d]);return e.mergeAnswer(s,{save:!0}),"stop"}}})})};var It={Surface:kt,Calendly:pt,Cal:ct,SavvyCal:vt,ChiliCal:mt,Hubspot:gt,RevenueHero:ht,Zoom:wt,ReclaimAI:yt,Clari:ft};var Et="surface-scheduler-styles",kn=`
|
|
2
|
-
\${--surface-scheduler-accent:#2563eb;--surface-scheduler-border:#e2e8f0;--surface-scheduler-text:#0f172a;--surface-scheduler-muted:#64748b;--surface-scheduler-radius:8px;font-family:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;color:var(--surface-scheduler-text)}
|
|
3
|
-
%{display:flex;flex-direction:column;gap:12px;max-width:26rem;padding:16px;border:1px solid var(--surface-scheduler-border);border-radius:var(--surface-scheduler-radius)}
|
|
4
|
-
%-month,%-day{margin:0;font-size:1rem;font-weight:600}
|
|
5
|
-
%-month-nav{display:flex;gap:8px}
|
|
6
|
-
$ button{font:inherit;cursor:pointer;border-radius:calc(var(--surface-scheduler-radius) - 2px)}
|
|
7
|
-
%-month-button,%-back,%-retry{padding:4px 10px;border:1px solid var(--surface-scheduler-border);background:transparent;color:var(--surface-scheduler-muted)}
|
|
8
|
-
%-month-button:hover,%-back:hover{color:var(--surface-scheduler-text)}
|
|
9
|
-
%-dates,%-slots{display:grid;grid-template-columns:repeat(auto-fill,minmax(7.5rem,1fr));gap:8px;margin:0;padding:0;list-style:none}
|
|
10
|
-
%-date-button,%-slot-button{width:100%;padding:8px 6px;border:1px solid var(--surface-scheduler-border);background:transparent;color:var(--surface-scheduler-text)}
|
|
11
|
-
%-date-button:hover,%-slot-button:hover{border-color:var(--surface-scheduler-accent);color:var(--surface-scheduler-accent)}
|
|
12
|
-
%-form{display:flex;flex-direction:column;gap:8px}
|
|
13
|
-
%-name,%-email{font:inherit;padding:8px 10px;border:1px solid var(--surface-scheduler-border);border-radius:calc(var(--surface-scheduler-radius) - 2px)}
|
|
14
|
-
%-name:focus,%-email:focus{outline:2px solid var(--surface-scheduler-accent);outline-offset:-1px}
|
|
15
|
-
%-submit{padding:8px 14px;border:0;background:var(--surface-scheduler-accent);color:#fff}
|
|
16
|
-
%-submit:disabled{opacity:.6;cursor:default}
|
|
17
|
-
%-loading,%-no-dates{color:var(--surface-scheduler-muted)}
|
|
18
|
-
%-error{color:#b91c1c;margin:0}
|
|
19
|
-
%-booked{font-weight:600;color:var(--surface-scheduler-accent)}
|
|
20
|
-
.surface-scheduler-frame{display:block;min-height:640px}
|
|
21
|
-
`,Tt=()=>{if(document.getElementById(Et))return;let e=document.createElement("style");e.id=Et,e.textContent=kn.replace(/%/g,"$ .surface-booking").replace(/\$/g,".surface-scheduler"),document.head.appendChild(e)};var ye=(e,n)=>{for(let t of Object.values(e.state().answers))if(t[n]!=null)return t[n]},Be=(e,n)=>{for(let t of n){let r=e?.[t];if(typeof r=="string"&&r.length>0)return r}},wn=(e,n,t)=>({name:t?.name??Be(n.linkNameToStep&&ye(e,n.linkNameToStep.questionId),["fullName","firstName","input"]),lastName:t?.lastName??Be(n.linkLastNameToStep&&ye(e,n.linkLastNameToStep.questionId),["lastName","input"]),email:t?.email??Be(n.linkEmailToStep&&ye(e,n.linkEmailToStep.questionId),["email","emailAddress","workEmailAddress","input"])}),In=(e,n)=>{let{content:t}=e;if(e.componentType!=="DynamicScheduler")return t;let r=t.calendars??[],o;if(n!=null){if(o=r.find(s=>s.name===n),!o){let s=r.map(d=>String(d.name)).join(", ")||"(none)";throw new Error(`mountScheduler: no calendar named "${n}" on question "${e.questionId}" \u2014 available: ${s}.`)}}else if(o=t.defaultCalendar??void 0,!o&&r.length===1&&(o=r[0]),!o)throw new Error(`mountScheduler: question "${e.questionId}" routes between ${r.length} calendars with no default \u2014 pass calendarId to choose one (condition evaluation is the caller's own routing).`);let a={...t},i=[o.dataUrl,o.url].find(s=>typeof s=="string"&&s.length>0);i!=null&&(a.dataUrl=i);for(let s of["eventTypeId","savvyCalLinkId","revenueHeroRouterId"])typeof o[s]=="string"&&(a[s]=o[s]);return a},En=(e,{questionId:n,stepId:t})=>{if(!e.runtimeConfig)throw new Error("mountScheduler: no record to read scheduler config from (the form was booted with caller-provided steps) \u2014 init without `steps`, or mount the widget manually.");let r=me(e.runtimeConfig.config),o=r.filter(i=>(n==null||i.questionId===n)&&(t==null||i.stepId===t));if(o.length===1)return o[0];let a=r.map(i=>`"${i.questionId}" (${i.calendarType}, step "${i.stepId}")`).join(", ");throw new Error(o.length===0?`mountScheduler: no scheduler question${n?` "${n}"`:""}${t?` on step "${t}"`:""} \u2014 the record has: ${a||"none"}.`:`mountScheduler: ${o.length} scheduler questions match \u2014 pass questionId. Candidates: ${a}.`)},Rt=({form:e,container:n,questionId:t,stepId:r,styled:o=!0,persist:a=!0,prefill:i,formatters:s,calendarId:d,onEvent:l,onComplete:u})=>{let c=En(e,{questionId:t,stepId:r}),p=c.calendarType,A=It[p];if(!A)throw new Error(`mountScheduler: unsupported provider "${c.calendarType}" on question "${c.questionId}".`);let h=In(c,d),f=!1,y=!1,S=w=>{if(f)return;if(w.type==="viewed"){if(y)return;y=!0}let _={...w,questionId:c.questionId,stepId:c.stepId,provider:p};e.notifyScheduler(_);try{l?.(_)}catch(b){console.warn("Surface SDK: mountScheduler onEvent handler failed",b)}},g=(w,_)=>{a&&(e.setAnswer(c.questionId,{type:c.componentType,...w}),_?.save&&!e.state().finished&&e.savePartial())},M=(w,_)=>{let b={...w,provider:p},D={eventScheduled:!0,uri:b.uri},I={meetingTime:b.meetingTime,meetingEndTime:b.meetingEndTime,ownerEmails:b.ownerEmails,guestEmails:b.guestEmails,inviteeName:b.inviteeName,googleMeetLink:b.joinLink};for(let[v,L]of Object.entries(I))L!==void 0&&(D[v]=L);g({...D,..._},{save:!0}),S({type:"booking_confirmed",booking:b});try{u?.(b)}catch(v){console.warn("Surface SDK: mountScheduler onComplete handler failed",v)}},k=w=>{g({eventScheduled:!1,eventCancelled:!0,...w!=null&&{cancelReason:w}},{save:!0}),S({type:"booking_cancelled",...w!=null&&{reason:w}})},x=async()=>e.preview?null:(e.state().responseId==null&&a&&await e.savePartial(),e.state().responseId);o&&(Tt(),n.classList.add("surface-scheduler"));let R=Object.fromEntries(Object.entries(h.dataUrlParams??{}).flatMap(([w,_])=>{let b=ye(e,_.questionId)?.[_.variable];return typeof b=="string"&&b.length>0?[[w,b]]:[]})),U=A({form:e,container:n,question:c,content:h,prefill:wn(e,h,i),urlParams:R,formatters:s,styled:o,emit:S,confirmBooking:M,cancelBooking:k,mergeAnswer:g,ensureResponseId:x});return S({type:"viewed"}),()=>{f||(f=!0,o&&n.classList.remove("surface-scheduler"),U())}};var Tn="/api/v1/edge/emailValidation",At=e=>({email:e,isValid:!0,status:"unknown",reason:"validation_failed",failed:!0}),Rn=(e,n)=>!n||typeof n.isValid!="boolean"?At(e):{email:e,isValid:n.isValid,status:n.status,reason:n.reason,...n.blacklistEntryIds?.length?{blacklistEntryIds:n.blacklistEntryIds}:{},...n.validationSuccessfullyRan===!1?{failed:!0}:{}},he=({transport:e,environmentId:n,preview:t=!1})=>{let r=new Map,o=a=>{let i=[...new Set(a.map(d=>d.trim()).filter(d=>d!==""))];if(t)for(let d of i)r.has(d)||r.set(d,Promise.resolve({email:d,isValid:!0,status:"preview"}));let s=i.filter(d=>!r.has(d));if(s.length>0){let d=e.post(Tn,{emails:s,environmentId:n}).then(l=>l.ok?l.data.data??{}:{}).catch(()=>({}));for(let l of s)r.set(l,d.then(u=>Rn(l,u[l])))}return Promise.all(i.map(d=>r.get(d)))};return{validateBatch:o,validate:async a=>{let[i]=await o([a]);return i??At(a.trim())}}};var An="/api/v1/responses/",_t="/api/v1/responses/update",_n="/api/v1/responses/getResponse",ve=async(e,n)=>{let t=await e.post(An,n,{credentials:!0});if(!t.ok)return t;let r=t.data.data?.id;return r?{ok:!0,data:{responseId:r,leadId:t.data.data?.meta?.leadId??null,resumeToken:t.data.data?.resumeToken??null}}:{ok:!1,error:{kind:"http",status:200,body:t.data}}},ee=(e,n)=>{e.beacon(_t,n)},Ct=(e,n)=>e.post(_t,n,{keepalive:!0,credentials:!0}),Cn=e=>typeof e?.questionId=="string"&&typeof e?.response=="object"&&e.response!==null,xt=async(e,{responseId:n,resumeToken:t})=>{let r=await e.get(`${_n}?rid=${encodeURIComponent(n)}&rt=${encodeURIComponent(t)}`);return r.ok?{ok:!0,data:{answers:(Array.isArray(r.data.data?.data)?r.data.data.data:[]).filter(Cn).filter(a=>a.response.type!=="URL_DATA")}}:r};var Q="https://forms.withsurface.com",Pt="0.1.0",Ve=(e={})=>({...e,"X-Surface-Sdk-Version":Pt}),xn=e=>`${e}${e.includes("?")?"&":"?"}sdv=${Pt}`,be=({apiBaseUrl:e=Q}={})=>{let n=e.replace(/\/$/,""),t=i=>`${n}${i}`;return{get:async i=>{try{let s=await fetch(t(i),{headers:Ve()});if(!s.ok){let d=await s.json().catch(()=>{});return{ok:!1,error:{kind:"http",status:s.status,body:d}}}return{ok:!0,data:await s.json()}}catch(s){return{ok:!1,error:{kind:"network",cause:s}}}},post:async(i,s,d)=>{try{let l=await fetch(t(i),{method:"POST",headers:Ve({"Content-Type":"application/json"}),body:JSON.stringify(s),...d?.keepalive?{keepalive:!0}:{},...d?.credentials?{credentials:"include"}:{}});if(!l.ok){let u=await l.json().catch(()=>{});return{ok:!1,error:{kind:"http",status:l.status,body:u}}}return{ok:!0,data:await l.json()}}catch(l){return{ok:!1,error:{kind:"network",cause:l}}}},beacon:(i,s)=>{let d;try{d=JSON.stringify(s)}catch{return!1}let l=xn(t(i));try{if(typeof navigator<"u"&&typeof navigator.sendBeacon=="function"&&navigator.sendBeacon(l,new Blob([d],{type:"application/json"})))return!0}catch{}try{fetch(l,{method:"POST",keepalive:!0,credentials:"include",headers:Ve({"Content-Type":"application/json"}),body:d}).catch(()=>{})}catch{}return!1}}};var Mt=["firstName","lastName","fullName","emailAddress","workEmailAddress","phoneNumber","companyName","numberOfEmployees","websiteUrl","title","streetAddress","aptSuiteEtc","city","state","country","zipCode","companyRevenue","profilePictureUrl"];var Se=()=>{let e=new Map;return{on:(n,t)=>{let r=e.get(n)??new Set;return r.add(t),e.set(n,r),()=>{r.delete(t)}},emit:(n,t)=>{e.get(n)?.forEach(r=>{try{r(t)}catch(o){console.error(`Surface SDK: "${String(n)}" handler threw`,o)}})}}};var Pn="/api/v1/pushEvent",Mn=/bot|crawl|spider|slurp|baidu|bingpreview|googlebot|yandex|duckduck|ahrefs|semrush|facebookexternalhit|embedly|quora link preview|pinterest|twitterbot|linkedinbot|whatsapp|telegram|discord|headless|lighthouse|pagespeed/i,Ln=()=>{let e=navigator.userAgent;return e?Mn.test(e):!1},On=e=>!!(e?.type&&e?.entityType&&e?.entityId),ke=({sessionId:e,formId:n,currentStepId:t,nextStepId:r,stepCompletionTime:o})=>({events:[{type:"form_step_submitted",entityType:"form_step",entityId:n,stepId:t,leadSessionId:e,properties:[{key:"stepCompletionTime",value:o}]},{type:"form_step_viewed",entityType:"form_step",entityId:n,stepId:r,leadSessionId:e,properties:[]}]}),we=({transport:e,preview:n=!1})=>({push:t=>{if(n||typeof navigator>"u")return;let r="events"in t?t.events:[t];Ln()||r.some(o=>!On(o))||e.beacon(Pn,t)}});var Ie=e=>{let n=je(e),t=!1;return r=>t||He(n,r)?!1:(t=!0,!0)},je=e=>{if(Array.isArray(e))return e.map(je);if(e!==null&&typeof e=="object"){let n={};for(let[t,r]of Object.entries(e))n[t]=je(r);return n}return e},He=(e,n)=>{if(Object.is(e,n))return!0;if(Array.isArray(e)||Array.isArray(n))return!Array.isArray(e)||!Array.isArray(n)||e.length!==n.length?!1:e.every((t,r)=>He(t,n[r]));if(e!==null&&n!==null&&typeof e=="object"&&typeof n=="object"){let t=Object.keys(e),r=Object.keys(n);return t.length!==r.length?!1:t.every(o=>He(e[o],n[o]))}return!1};var Ke=(e,n)=>{let t=[],r={},o;for(let a in e){let i=e[a];for(let s in i){let d=i[s];!o&&d?.eventScheduled===!0&&typeof d.uri=="string"&&d.uri.length>0&&!d.uri.includes("calendly.com")&&!d.uri.includes("cal.com")&&(o=d.uri),t.push({questionId:s,response:{...i[s]}})}}for(let a in n){let i=n[a];i.type!=="SCHEDULER_AVAILABILITY_DATA"&&(t.push({questionId:a,response:{...i}}),i.type==="APOLLO_EMAIL_ENRICHMENT"&&i.processed&&(r=i.data??{}))}return{responses:t,enrichedFields:r,bookingId:o}},Lt=({formId:e,answers:n,externalStates:t,submittingOnStepId:r,finished:o,invalidResponse:a,trackCookies:i,meta:s={},personAttributeEnrichedFields:d,fingerprint:l,leadSessionId:u})=>{let{responses:c,enrichedFields:p,bookingId:A}=Ke(n,t),h=i?s:Object.fromEntries(Object.entries(s).filter(([f])=>f!=="cookies"));return{responses:c,enrichedFields:d??p??{},formId:e,finished:o,invalidResponse:a,stepId:r,fingerprint:l,leadSessionId:u,meta:A?{...h,bookingId:A}:h}},Ee=e=>({...Lt(e),responseShapeVersion:"2.0"}),z=e=>({...Lt(e),responseId:e.responseId});var Te=({formId:e,environmentId:n,steps:t,transport:r,resolveNextStep:o,trackPartialResponses:a=!0,trackCookies:i=!1,externalStates:s={},meta:d={},identity:l,pushEvents:u,formJourney:c,preview:p=!1,resume:A})=>{if(t.length===0)throw new Error("createFormEngine requires at least one step");let h=o??(m=>{let E=t.findIndex(H=>H.id===m),$=t[E+1];return $?{stepId:$.id,reason:"linear"}:"END"}),f=Se(),y=new Set,S=!0,g,M=()=>{S=!0,y.forEach(m=>m())},k=()=>l?.()??{},x={},R=t[0].id,U=A?.responseId??null,w=null;if(A?.answers){let m={};for(let[E,$]of Object.entries(A.answers))m[E]={...$};x[R]=m}let _=!1,b=null,D=!1,I=Date.now(),v=[],L=Ie(x);c?.setFormId(e),U!=null&&c?.setResponseId(U),c?.recordEntry(R);let O=async(m,E,$)=>{if(p)return;let H={formId:e,answers:x,externalStates:s,submittingOnStepId:m,finished:E,invalidResponse:$,trackCookies:i,meta:d,fingerprint:k().fingerprint,leadSessionId:k().leadSessionId};if(U==null){let K=await ve(r,Ee(H));if(!K.ok){K.error.kind==="network"&&u?.push({type:"response_submission_error",entityType:"response",entityId:e,stepId:m,leadSessionId:k().leadSessionId,properties:[{key:"error",value:"network"}]}),f.emit("error",{scope:"submit",error:K.error});return}U=K.data.responseId,w=K.data.resumeToken,c?.setResponseId(U),u?.push({type:"response_submission_created",entityType:"response",entityId:e,stepId:m,leadSessionId:k().leadSessionId,properties:[{key:"responseId",value:U}]})}else if(E){let K=await Ct(r,z({...H,responseId:U}));if(!K.ok){ee(r,z({...H,responseId:U})),f.emit("error",{scope:"submit",error:K.error});return}}else ee(r,z({...H,responseId:U}));M(),f.emit("saved",{responseId:U,finished:E,resumeToken:w})},F=Promise.resolve(),T=m=>{let E=F.then(()=>_?void 0:m());return F=E.catch(()=>{}),E},P=()=>{if(!_||b==null)return;let m=b;F=F.then(()=>{if(U!=null)return O(m.stepId,!0,m.invalid)}).catch(()=>{})},C=null,N=m=>{if(_)return Promise.resolve();if(C)return m?C.then(()=>N(!0)):C;let E=T(()=>Zt(m)).finally(()=>{C===E&&(C=null)});return C=E,E},G=m=>{let E=R;for(;v.length>0&&R!==m;)R=v.pop();M(),c?.recordTransition({fromStepId:E,toStepId:R,reason:"back_nav"}),f.emit("stepChanged",{fromStepId:E,toStepId:R})},se=m=>{if(!t.some($=>$.id===m))return Promise.reject(new Error(`goToStep: no step with id "${m}"`));if(_)return Promise.resolve();if(C)return C.then(()=>se(m));if(m===R)return Promise.resolve();if(v.includes(m))return G(m),Promise.resolve();let E=T(async()=>{m!==R&&(f.emit("stepCompleted",{stepId:R}),await nt({stepId:m,reason:"conditional_match"}))}).finally(()=>{C===E&&(C=null)});return C=E,E},tt=()=>{if(_)return Promise.resolve();if(C)return C.then(()=>tt());let m=T(async()=>{f.emit("stepCompleted",{stepId:R}),await rt(!0)}).finally(()=>{C===m&&(C=null)});return C=m,m},nt=async m=>{let E=R;u?.push(ke({sessionId:k().leadSessionId,formId:e,currentStepId:E,nextStepId:m.stepId,stepCompletionTime:(Date.now()-I)/1e3})),c?.recordTransition({fromStepId:E,toStepId:m.stepId,reason:m.reason??"linear"}),a&&await O(E,!1,!1),v.push(E),R=m.stepId,M(),f.emit("stepChanged",{fromStepId:E,toStepId:R})},Xt=m=>{let E=t.find(H=>H.endStepKind===m);if(!E||E.id===R)return;let $=R;v.push($),R=E.id,M(),f.emit("stepChanged",{fromStepId:$,toStepId:R})},rt=async m=>{let E=R;_=!0,b={stepId:E,invalid:m},await O(E,!0,m),Xt(m?"disqualified":"thank_you"),m?(c?.recordTerminal({outcome:"disqualified",disqualification:{reason:"conditional_match",atStepId:E}}),f.emit("disqualified",{stepId:E})):(c?.recordTerminal({outcome:"completed"}),u?.push({type:"form_completed",entityType:"form",entityId:e,stepId:null,leadSessionId:k().leadSessionId,properties:[],environmentId:n,leadId:k().leadId}),f.emit("completed",{formId:e})),M()},Zt=async m=>{let E=h(R,x),$=m||E==="END"||E==="INVALID"||E==null;if(f.emit("stepCompleted",{stepId:R}),!$){await nt(E);return}await rt(E==="INVALID")};return{setAnswer:(m,E)=>{let $=x[R]??(x[R]={});$[m]={...$[m],...E},L(x)&&(u?.push({type:"form_started",entityType:"form",entityId:e,stepId:null,leadSessionId:k().leadSessionId,properties:[]}),f.emit("started",{formId:e})),M(),P()},setExternalState:(m,E)=>{s[m]=E,M(),P()},mergeMeta:m=>{Object.assign(d,m),P()},next:()=>N(!1),goToStep:se,submit:()=>N(!0),disqualify:tt,back:()=>{let m=v.pop();if(m==null||_)return;let E=R;R=m,M(),c?.recordTransition({fromStepId:E,toStepId:m,reason:"back_nav"}),f.emit("stepChanged",{fromStepId:E,toStepId:m})},savePartial:()=>{let m=R;return T(()=>O(m,!1,!1))},notifyScheduler:m=>f.emit("scheduler",m),flush:()=>F.then(()=>{}),markViewed:()=>{D||(D=!0,u?.push({type:"form_viewed",entityType:"form",entityId:e,stepId:null,leadSessionId:k().leadSessionId,properties:[],environmentId:n,leadId:k().leadId}),u?.push({type:"form_step_viewed",entityType:"form_step",entityId:e,stepId:t[0].id,leadSessionId:k().leadSessionId,properties:[]}),f.emit("viewed",{formId:e}))},on:f.on,state:()=>(S&&(g={currentStepId:R,answers:x,externalStates:s,responseId:U,resumeToken:w,finished:_},S=!1),g),subscribe:m=>(y.add(m),()=>y.delete(m))}};var Ot=400,Fn=(e,n="https")=>!e||e.startsWith(n)?e:`${n}://${e}`,We=(e,{leadId:n,sessionId:t}={})=>{if(!e||!e.trim())return"";try{let r=new URL(Fn(e));return n&&r.searchParams.set("leadId",n),t&&r.searchParams.set("sessionId",t),r.toString()}catch{return e}},Ft=({url:e,redirectType:n="CurrentWindow",leadId:t,sessionId:r,preview:o=!1})=>{if(!e||o||typeof window>"u")return;let a=We(e,{leadId:t,sessionId:r});a&&(n==="CurrentWindow"?window.location.href=a:n==="NewTab"&&window.open(a,"_blank"))};var Je=e=>{let n=new URL(e);if(!n.search)return{};let t={};return new URLSearchParams(n.search).forEach((r,o)=>{t[o]=r}),t},Qe=e=>{let n={};for(let t of e.split(";")){let r=t.trim(),o=r.indexOf("=");if(o<=0)continue;let a=r.substring(o+1);try{n[r.substring(0,o)]=decodeURIComponent(a)}catch{n[r.substring(0,o)]=a}}return n},Re=({defaultUrl:e,trackCookies:n=!1}={})=>{let t=typeof window<"u",r={type:"URL_DATA",fullUrl:e??(t?window.location.href:void 0),referrer:t&&typeof document<"u"?document.referrer||"":void 0};if(r.fullUrl)try{r.params=Je(r.fullUrl)}catch{}return n?r.cookies=t&&typeof document<"u"?Qe(document.cookie):{}:r.cookies={},r};var ze=e=>{let n=e.indexOf("_");return{originalId:e,questionId:n>=0?e.slice(0,n).trim():e,fieldName:n>=0?e.slice(n+1).trim():null}},Dn=new Set(["url","referrer","cookies"]),Dt=e=>{let n=typeof e=="string"?new URLSearchParams(e):e,t=null;for(let r of n.keys()){if(Dn.has(r))continue;let{originalId:o,questionId:a,fieldName:i}=ze(r);if(i==null)continue;let s={originalId:o,questionId:a,fieldName:i,value:n.get(r)};t??(t=Object.create(null)),t[a]=[...t[a]??[],s]}return t};var Ae=(e,n)=>{if(typeof window>"u")return()=>{};let t=r=>{let{started:o,formId:a,stepId:i,sessionId:s}=n();!o||r.persisted||e.push({type:"form_step_dropoff",entityType:"form_step",entityId:a,stepId:i,leadSessionId:s,properties:[]})};return window.addEventListener("pagehide",t),()=>window.removeEventListener("pagehide",t)};var Un="/api/v1/form-journey/track";var Nn=new Set(["completed","disqualified","dropped_off","partial"]),_e=({transport:e,preview:n=!1})=>{let t={responseId:null,formId:null,nextOrdinal:1,enteredAt:new Map,pendingClose:null,visits:[],truncated:!1,terminal:{},frozen:!1,flushScheduled:!1},r=()=>{t.flushScheduled=!1,!n&&(!t.responseId||!t.formId||t.visits.length===0&&!t.terminal.outcome||(e.beacon(Un,{responseId:t.responseId,formId:t.formId,events:t.visits,...t.terminal}),t.terminal={}))},o=()=>{t.flushScheduled||(t.flushScheduled=!0,queueMicrotask(()=>{t.flushScheduled&&r()}))},a=s=>{if(!t.pendingClose)return;let{ordinal:d,stepId:l}=t.pendingClose,u=t.enteredAt.get(d),c=t.visits.find(A=>A.ordinal===d),p=u?Date.parse(s)-Date.parse(u):null;c?(c.exitedAt=s,c.durationMs=p):t.visits.push({ordinal:d,stepId:l,enteredAt:u??s,exitedAt:s,durationMs:p,fromStepId:null,transitionReason:"initial"}),t.pendingClose=null},i=s=>t.visits.length>=50?(t.truncated=!0,!1):(t.visits.push(s),!0);return{hasRecordedTransition:()=>t.nextOrdinal>1,setResponseId:s=>{t.responseId=s,o()},setFormId:s=>{t.formId=s,o()},recordEntry:s=>{if(t.frozen||t.truncated)return;let d=new Date().toISOString();t.nextOrdinal===1&&(t.enteredAt.set(1,d),t.pendingClose={ordinal:1,stepId:s},t.nextOrdinal=2)},recordTransition:({fromStepId:s,toStepId:d,reason:l,transitionMeta:u})=>{if(t.frozen||t.truncated)return;let c=new Date().toISOString();a(c);let p=t.nextOrdinal++;t.enteredAt.set(p,c);let A=i({ordinal:p,stepId:d,enteredAt:c,exitedAt:null,durationMs:null,fromStepId:s,transitionReason:l,transitionMeta:u??null});t.pendingClose=A?{ordinal:p,stepId:d}:null,o()},recordTerminal:({outcome:s,disqualification:d})=>{if(t.frozen)return;let l=new Date().toISOString();a(l),t.terminal={outcome:s,disqualification:d?{reason:d.reason,matched:d.matched}:void 0,disqualifiedAtStepId:d?.atStepId,disqualifiedTriggerStepId:d?.triggerStepId},Nn.has(s)&&(t.frozen=!0),s==="in_progress"?r():o()}}};async function Ye(e){let n=new TextEncoder().encode(e),t=await crypto.subtle.digest("SHA-256",n);return Array.from(new Uint8Array(t)).map(r=>r.toString(16).padStart(2,"0")).join("")}var Ce=async e=>{let n=navigator.userAgentData||{},t={deviceType:/Mobi|Android/i.test(navigator.userAgent)?"Mobile":"Desktop",screen:{width:screen.width,height:screen.height,colorDepth:screen.colorDepth},userAgent:navigator.userAgent,browser:n.brands||n.uaList||[{brand:"unknown",version:"unknown"}],os:n.platform||"unknown",language:navigator.language,...navigator.plugins!=null?{plugins:Array.from(navigator.plugins).map(r=>r.name)}:{},timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,environmentId:e};return{...t,id:await Ye(JSON.stringify(t))}};var qn="/api/v1/lead/identify",xe=({environmentId:e,fingerprintId:n,pageUrl:t,source:r="sdkForm",formId:o,leadId:a=null,sessionIdFromParams:i=null,referrer:s})=>{let d=new URL(t);return{environmentId:e,source:r,sourceURL:d.href.replace(/\/$/,""),sourceURLDomain:d.hostname,sourceURLPath:d.pathname.replace(/\/$/,""),sourceUrlSearchParams:d.search,fingerprint:n,formId:o,leadId:a,sessionIdFromParams:i,...s!=null?{referrer:s}:{}}},Pe=async(e,n)=>{let t=await e.post(qn,n,{keepalive:!0,credentials:!0});if(!t.ok)return null;let r=t.data.data?.data;return!r?.leadId||!r?.sessionId?null:{leadId:r.leadId,sessionId:r.sessionId,existing:r.existing,leadHasExistingBookingAttr:r.leadHasExistingBookingAttr,leadHasExistingEmailAttr:r.leadHasExistingEmailAttr}};var te="surfaceLeadData",Ut=6e5,Y=()=>{if(typeof localStorage>"u")return null;try{let e=localStorage.getItem(te);if(!e)return null;let n=JSON.parse(e);return Date.now()>(n.expiry??0)?(localStorage.removeItem(te),null):{leadId:n.leadId,leadSessionId:n.leadSessionId,fingerprint:n.fingerprint,landingPageUrl:n.landingPageUrl,expiry:n.expiry}}catch{return null}},Me=e=>{if(!(typeof localStorage>"u"))try{localStorage.setItem(te,JSON.stringify({...e,expiry:Date.now()+6e5}))}catch{}};var ne=async({transport:e,environmentId:n,formId:t,pageUrl:r,source:o,preview:a=!1})=>{if(a||typeof window>"u")return null;let i=Y();if(i?.leadSessionId&&i?.fingerprint)return i;let s=r??window.location.href,d=await Ce(n),l=await Pe(e,xe({environmentId:n,fingerprintId:d.id,pageUrl:s,formId:t,source:o,leadId:i?.leadId??null,sessionIdFromParams:i?.leadSessionId??null}));if(l==null)return null;let u={leadId:l.leadId,leadSessionId:l.sessionId,fingerprint:d.id,landingPageUrl:s};return Me(u),u};var re="surface_journey_id",oe="surface_recent_visit",$n=5184e3,Bn=86400,Nt="/api/v1/lead/track",qt=e=>{if(typeof document>"u")return null;for(let n of document.cookie.split(";")){let t=n.trim(),r=t.indexOf("=");if(r===-1||t.substring(0,r)!==e)continue;let o=t.substring(r+1);try{return decodeURIComponent(o)}catch{return o}}return null},$t=(e,n,t,r)=>{if(typeof document>"u")return;let o=r?`; domain=${r}`:"";document.cookie=`${e}=${encodeURIComponent(n)}; path=/; max-age=${t}; samesite=lax${o}`},Ge=()=>{let e=typeof window>"u"?"":window.location?.hostname??"";if(!e||!e.includes("."))return;let n=e.split(".");return"."+(n.length===2?e:n.slice(1).join("."))},Le=({transport:e,environmentId:n})=>{let t=qt(re),r=()=>{t&&$t(re,t,$n,Ge())},o=d=>{let l=Y();return{...t?{id:t}:{},data:{type:"page_view",payload:{url:d,timestamp:new Date().toISOString(),referrer:typeof document>"u"?"":document.referrer||""}},metadata:{environmentId:n,...l?{...l.leadId?{leadId:l.leadId}:{},...l.leadSessionId?{leadSessionId:l.leadSessionId}:{},fingerprint:l.fingerprint,...l.landingPageUrl?{landingPageUrl:l.landingPageUrl}:{}}:{}}}},a=async d=>{if(typeof window>"u")return;let l=d??window.location.href;if(qt(oe)===l)return;let u=o(l);if(t&&e.beacon(Nt,u))r();else{let c=await e.post(Nt,u);c.ok&&c.data.data?.id&&(t=c.data.data.id),r()}$t(oe,l,Bn,Ge())};return{trackPageView:a,observeRouteChanges:()=>{if(typeof window>"u")return()=>{};let d=window.location.href,l=()=>{let p=window.location.href;p!==d&&(d=p,a(p))};window.addEventListener("popstate",l);let u=history.pushState,c=history.replaceState;return history.pushState=function(...p){u.apply(history,p),setTimeout(l,0)},history.replaceState=function(...p){c.apply(history,p),setTimeout(l,0)},()=>{window.removeEventListener("popstate",l),history.pushState=u,history.replaceState=c}},clear:()=>{let d=Ge(),l=d?`; domain=${d}`:"";typeof document>"u"||(document.cookie=`${re}=; path=/; max-age=0; samesite=lax${l}`,document.cookie=`${oe}=; path=/; max-age=0; samesite=lax${l}`,t=null)}}};var Vn="/api/v1/services/enrichment/realtime",Oe="selfServeEnrichment";var jn=/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/,Hn=/^(?:https?:\/\/)?(?:www\.)?([a-z0-9-]+(?:\.[a-z0-9-]+)+)/i,Bt=e=>{let n=e.trim();if(jn.test(n))return{email:n};let t=n.match(Hn)?.[1];return t?{domain:t}:null},Fe=({engine:e,transport:n,formId:t,sources:r})=>{let o=new Set,a=new Set,i,s,d=!1,l=async h=>{let f=Bt(h);if(!f)return;let y=f.email??f.domain;if(!(o.has(y)||a.has(y))){a.add(y);try{let S=await n.post(Vn,{formId:t,...f});if(d||!S.ok)return;let g=S.data.data??{};if(Object.keys(g).length===0)return;o.add(y);let M=e.state().externalStates[Oe],k=M?.type==="APOLLO_EMAIL_ENRICHMENT"?M.data??{}:{};e.setExternalState(Oe,{type:"APOLLO_EMAIL_ENRICHMENT",processed:!0,data:{...g,...k}})}finally{a.delete(y)}}},u=()=>{let h=[],f={};for(let y of Object.values(e.state().answers))Object.assign(f,y);for(let{questionId:y,fieldNames:S}of r){let g=f[y];if(g)for(let M of S){let k=g[M];typeof k=="string"&&k.trim().length>0&&h.push(k)}}return h},c=()=>{let h=u().find(f=>{let y=Bt(f);return y!=null&&!o.has(y.email??y.domain)});h===void 0||h===s||(s=h,clearTimeout(i),i=setTimeout(()=>{s=void 0,l(h)},1e3))},p=()=>{if(s===void 0)return;clearTimeout(i);let h=s;s=void 0,l(h)},A=[e.subscribe(c),e.on("stepCompleted",p),e.on("completed",p)];return()=>{d=!0,clearTimeout(i),A.forEach(h=>h())}};var Kn=new Set(["MultipleOptionsQuestion","MultipleChoiceQuestion","MMChoiceQuestion"]),Wn=(e,n)=>typeof e=="object"&&e!==null&&typeof e.key=="string"&&typeof e.value=="boolean"&&(!n||typeof e.index=="number"),Vt=({questions:e,questionId:n,merged:t})=>{let r=`Surface SDK [debug]: setAnswer("${n}")`,o=e.size>0?e.get(n):void 0;if(e.size>0&&!o){console.warn(`${r} \u2014 the record has no stateful question with this id; the answer will be dropped.`),console.debug(`Surface SDK [debug]: answer ${n}`,t);return}t.type===void 0?console.warn(`${r} \u2014 state has no "type" discriminator; the wire schema rejects untyped states. Include type: "${o?.componentType??"<ComponentType>"}".`):o?.componentType!==void 0&&t.type!==o.componentType&&console.warn(`${r} \u2014 state type "${String(t.type)}" but the record's component is ${o.componentType}.`);let a=o?.componentType??t.type;if(typeof a=="string"&&Kn.has(a)){let i=a==="MultipleOptionsQuestion";(!Array.isArray(t.choices)||t.choices.some(d=>!Wn(d,i)))&&console.warn(`${r} \u2014 ${a} answers need the ENTIRE option list under "choices" as {key, value${i?", index":""}} objects, not ${JSON.stringify(t.choices??t)}. See get_sdk_binding_map's answerShape.`)}console.debug(`Surface SDK [debug]: answer ${n}`,t)};var Jn="Lead",Qn="generate_lead",zn="lead_created",Kt=/^tw-([a-z0-9]+)-([a-z0-9]+)$/i,Yn=e=>{let n=e?.trim().match(Kt);return n?n[1]:null},jt=e=>/^\d+$/.test(e?.trim()??""),Gn=e=>{if(e.enabled===!1||(e.trigger??"reached_qualified")==="reached_step"&&!e.triggerStepId?.trim())return!1;switch(e.provider){case"x":return Kt.test(e.eventId?.trim()??"");case"meta":case"openai":return!!e.pixelId?.trim();case"ga4":return!!e.measurementId?.trim();case"linkedin":return jt(e.partnerId)&&jt(e.conversionId);default:return!1}},Xn=(e,n)=>{let t=n.toLowerCase();for(let[r,o]of Object.entries(e))if(r.toLowerCase()===t)return o},Ht=(e,n)=>{let t=Xn(n,e.param)?.trim()??"",r=e.values??[];switch(e.operator){case"is_present":return t.length>0;case"equals_any":return r.some(o=>o.trim().toLowerCase()===t.toLowerCase());case"contains":return t.length>0&&r.some(o=>t.toLowerCase().includes(o.trim().toLowerCase()));default:return!1}},Zn=(e,n,t="and")=>e.length===0?!0:t==="or"?e.some(r=>Ht(r,n)):e.every(r=>Ht(r,n)),er=e=>{if(!Gn(e))return null;switch(e.provider){case"x":{let n=Yn(e.eventId);return n?{provider:"x",event:{event_id:e.eventId.trim(),pixel_id:n}}:null}case"meta":return{provider:"meta",event:{pixel_id:e.pixelId.trim(),event_name:e.eventName?.trim()||Jn}};case"openai":return{provider:"openai",event:{pixel_id:e.pixelId.trim(),event_name:e.eventName?.trim()||zn}};case"ga4":return{provider:"ga4",event:{measurement_id:e.measurementId.trim(),event_name:e.eventName?.trim()||Qn}};case"linkedin":return{provider:"linkedin",event:{partner_id:e.partnerId.trim(),conversion_id:e.conversionId.trim()}};default:return null}},De=(e,n,t,r)=>{let o=[];for(let a of e){if((a.trigger??"reached_qualified")!==n||n==="reached_step"&&(!r||a.triggerStepId!==r)||!Zn(a.conditions??[],t,a.conditionsOperator??"and"))continue;let i=er(a);i&&o.push({rule:a,conversion:i})}return o},tr=(e,n)=>{if(!e.twq){let t=e.twq=function(...o){t.exe?t.exe.apply(t,o):t.queue.push(o)};t.version="1.1",t.queue=[];let r=e.document.createElement("script");r.async=!0,r.src="https://static.ads-twitter.com/uwt.js",e.document.head.appendChild(r)}e.twq("config",n)},nr=(e,n)=>{if(!e.fbq){let t=e.fbq=function(...o){t.callMethod?t.callMethod.apply(t,o):t.queue.push(o)};e._fbq||(e._fbq=t),t.push=t,t.loaded=!0,t.version="2.0",t.queue=[];let r=e.document.createElement("script");r.async=!0,r.src="https://connect.facebook.net/en_US/fbevents.js",e.document.head.appendChild(r)}e.fbq("init",n)},rr=(e,n)=>{if(!e.oaiq){let t=e.oaiq=function(...o){t.q.push(o)};t.q=[];let r=e.document.createElement("script");r.async=!0,r.src="https://bzrcdn.openai.com/sdk/oaiq.min.js",e.document.head.appendChild(r)}e.oaiq("init",{pixelId:n})},or=(e,n)=>{if(!e.gtag){e.dataLayer=e.dataLayer||[],e.gtag=function(...r){e.dataLayer.push(r)};let t=e.document.createElement("script");t.async=!0,t.src=`https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(n)}`,e.document.head.appendChild(t),e.gtag("js",new Date)}e.gtag("config",n,{send_page_view:!1})},sr=(e,n)=>{if(!e.lintrk){e._linkedin_partner_id=n;let t=e.lintrk=function(o,a){t.q.push([o,a])};t.q=[];let r=e.document.createElement("script");r.async=!0,r.src="https://snap.licdn.com/li.lms-analytics/insight.min.js",e.document.head.appendChild(r)}e._linkedin_data_partner_ids=e._linkedin_data_partner_ids||[],e._linkedin_data_partner_ids.includes(n)||e._linkedin_data_partner_ids.push(n)},Wt=(e,n,t)=>{let r=e;try{switch(n.provider){case"x":return tr(r,n.event.pixel_id),r.twq("event",n.event.event_id,{conversion_id:t.responseId,...t.twclid?{twclid:t.twclid}:{},...t.email?{email_address:t.email}:{}}),!0;case"meta":return nr(r,n.event.pixel_id),r.fbq("track",n.event.event_name,{},{eventID:t.responseId}),!0;case"openai":return rr(r,n.event.pixel_id),r.oaiq("measure",n.event.event_name,{type:"customer_action"},{event_id:t.responseId}),!0;case"ga4":return or(r,n.event.measurement_id),r.gtag("event",n.event.event_name,{transaction_id:t.responseId,send_to:n.event.measurement_id}),!0;case"linkedin":return sr(r,n.event.partner_id),r.lintrk("track",{conversion_id:n.event.conversion_id}),!0;default:return!1}}catch{return!1}};var Xe=(e,n)=>e.document.querySelector(`script[src="${n}"]`)!=null,Ue=(e,n,t,r)=>{if(Xe(e,n))return;let o=e.document.createElement("script");o.async=!0,o.src=n,r&&(o.id=r),e.document[t].appendChild(o)},ir=(e,n)=>{let t=`https://www.googletagmanager.com/gtm.js?id=${encodeURIComponent(n)}`;Xe(e,t)||(e.dataLayer=e.dataLayer||[],e.dataLayer.push({"gtm.start":new Date().getTime(),event:"gtm.js"}),Ue(e,t,"head"))},ar=(e,n)=>{let t=`https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(n)}`;if(Xe(e,t))return;e.dataLayer=e.dataLayer||[],e.gtag||(e.gtag=function(){e.dataLayer.push(arguments)},e.gtag("js",new Date)),Ue(e,t,"head");let r=e.self!==e.top;e.gtag("config",n,{...r&&{cookie_flags:"SameSite=None;Secure;Partitioned"}})},dr=(e,n)=>{if(!e.fbq){let t=e.fbq=function(...r){t.callMethod?t.callMethod.apply(t,r):t.queue.push(r)};e._fbq||(e._fbq=t),t.push=t,t.loaded=!0,t.version="2.0",t.queue=[],Ue(e,"https://connect.facebook.net/en_US/fbevents.js","head")}e.fbq("init",n)},lr=(e,n)=>{Ue(e,`https://js.hs-scripts.com/${n}.js`,"body","hs-script-loader")},Jt=(e,n)=>{let t=e;n.gtmId&&ir(t,n.gtmId),n.gaMeasurementId&&ar(t,n.gaMeasurementId),n.metaPixelId&&dr(t,n.metaPixelId),n.hubspotTracking?.trackingId&&lr(t,n.hubspotTracking.trackingId);let r=i=>{n.gtmId&&(t.dataLayer=t.dataLayer||[],t.dataLayer.push(i))},o=(i,s)=>{n.gaMeasurementId&&t.gtag?.("event",i,s)},a=(i,s)=>{n.metaPixelId&&t.fbq?.("trackCustom",i,s)};return{formStarted:(i,s)=>{r({event:"SurfaceFormStarted",formId:i,...s}),a("SurfaceFormStarted",{formId:i,...s}),o("SurfaceFormStarted",{formId:i,...s})},stepSubmitted:i=>{r({event:"SurfaceFormStepSubmitted",...i}),a("SurfaceFormStepSubmitted",i),o("SurfaceFormStepSubmitted",i)},formCompleted:(i,s)=>{r({event:"SurfaceFormSubmitEvent",formId:i,...s}),a("SurfaceFormCompleted",{formId:i,...s}),o("SurfaceFormCompleted",{formId:i,...s})}}};var ur=e=>{try{return Object.fromEntries(new URLSearchParams(e.location.search).entries())}catch{return{}}},Ne=(e,n)=>{let t=n.toLowerCase();for(let[r,o]of Object.entries(e))if(r.toLowerCase()===t)return o?.trim()||void 0},cr=e=>({twclid:Ne(e,"twclid"),fbclid:Ne(e,"fbclid"),gclid:Ne(e,"gclid"),li_fat_id:Ne(e,"li_fat_id")}),pr=["email","emailAddress","workEmailAddress"],Ze=e=>{for(let n of Object.values(e))for(let t of pr){let r=n[t];if(typeof r=="string"&&r.trim().length>0)return r.trim()}},Qt=e=>Object.values(e).some(n=>n.eventScheduled===!0),et=e=>{let n={};for(let t of Object.values(e.state().answers))Object.assign(n,t);return n},zt=({engine:e,formId:n,settings:t,win:r})=>{let o=r??window,a=Jt(o,t),i=t.adsConversions??[],s=ur(o),d={url:o.location.href,urlParams:s},l=new Set,u=new Set,c=new Set,p=new Set,A=!1,h=!1,f=!1,y=!1,S=!1,g=e.state().responseId==null,M=!g,k=(I,v)=>{let L=I.filter(({rule:F})=>!l.has(F.id));if(L.length===0)return;L.forEach(({rule:F})=>l.add(F.id));let O={responseId:v,email:Ze(et(e)),...cr(s)};L.forEach(({conversion:F})=>Wt(o,F,O))},x=(I,v)=>{if(!v){p.add(I);return}k(De(i,I,s),v)},R=(I,v)=>{if(!v){c.add(I);return}k(De(i,"reached_step",s,I),v)},U=I=>{if(!I){A=!0;return}h=!0,A=!1;let v=new Map;for(let L of["reached_qualified","form_submitted"])for(let O of De(i,L,s))v.set(O.rule.id,O);k(Array.from(v.values()),I)},w=()=>{let I=et(e);!y&&g&&Ze(I)!==void 0&&(y=!0,x("email_provided",e.state().responseId)),!S&&g&&Qt(I)&&(S=!0,x("meeting_booked",e.state().responseId))},_=[];_.push(e.on("started",()=>{a.formStarted(n,d)}));let b;_.push(e.on("stepCompleted",({stepId:I})=>{let v=et(e);b={stepId:I,formId:n,emailProvided:Ze(v)!==void 0,meetingBooked:Qt(v),...d},!f&&g&&(f=!0,x("step_submitted",e.state().responseId))})),_.push(e.on("stepChanged",({toStepId:I})=>{b&&(e.state().finished||a.stepSubmitted(b),b=void 0),!u.has(I)&&(u.add(I),R(I,e.state().responseId))})),_.push(e.on("completed",()=>{b=void 0,a.formCompleted(n,d),h||U(e.state().responseId)})),_.push(e.on("saved",({responseId:I})=>{if(M||(M=!0,x("form_started",I)),A&&U(I),c.size>0){let v=Array.from(c);c.clear(),v.forEach(L=>R(L,I))}if(p.size>0){let v=Array.from(p);p.clear(),v.forEach(L=>x(L,I))}})),_.push(e.subscribe(w));let D=e.state().currentStepId;return u.add(D),R(D,e.state().responseId),w(),()=>_.forEach(I=>I())};var mr=["email","emailAddress","workEmailAddress"],fr=/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/,qe=({engine:e,validator:n})=>{let t=new Set,r=new Map,o,a=!1,i,s=!1,d=()=>{let h=[];for(let f of Object.values(e.state().answers))for(let y of Object.values(f))for(let S of mr){let g=y[S];typeof g=="string"&&fr.test(g.trim())&&h.push(g.trim())}return h},l=()=>{let h=new Set(d()),f=[...r.values()].filter(g=>h.has(g.email));if(f.length===0)return;let y=JSON.stringify(f.map(g=>[g.email,g.isValid,g.failed===!0]));if(y===i)return;i=y;let S=f.find(g=>g.status&&g.reason);e.mergeMeta({isEmailValid:f.some(g=>g.isValid),emailValidation:S?{status:S.status,reason:S.reason,...S.blacklistEntryIds?.length&&{blacklistEntryIds:S.blacklistEntryIds}}:void 0,emailValidationFailed:f.some(g=>g.failed===!0)})},u=async()=>{let h=d().filter(y=>!t.has(y));if(h.length===0)return;h.forEach(y=>t.add(y));let f=await n.validateBatch(h);s||(f.forEach(y=>r.set(y.email,y)),l())},c=()=>{if(!d().some(h=>!t.has(h))){l();return}a=!0,clearTimeout(o),o=setTimeout(()=>{a=!1,u()},300)},p=()=>{a&&(a=!1,clearTimeout(o),u())},A=[e.subscribe(c),e.on("stepCompleted",p),e.on("completed",p)];return()=>{s=!0,clearTimeout(o),A.forEach(h=>h())}};var Yt=new Set(["surfaceTagStatus","isEmailValid","emailValidation","emailValidationFailed"]),gr=new Set(["CalendlyScreen","DynamicScheduler","FileUploader"]),Gt={init:async({environmentId:e,formId:n,steps:t,settings:r={},apiBaseUrl:o,container:a,expectedQuestionIds:i,resolveNextStep:s,urlDataStateId:d,source:l,journey:u=!1,emailValidation:c=!1,preview:p=!1,previewToken:A,debug:h=!1,resume:f,meta:y})=>{let S=be({apiBaseUrl:o}),g;if(!t){let T=await le(S,n,{preview:p,previewToken:A});if(!T.ok||!T.data.data){let C=(o??Q).replace(/\/$/,""),N=T.ok?"empty response":T.error.kind==="http"?`HTTP ${T.error.status}`:"network error";throw new Error(`SurfaceForms.init: could not fetch runtime config for form "${n}" (${N} from ${C}/api/v1/public/forms/${n}/runtime-config). If this environment is not served from ${Q}, pass apiBaseUrl \u2014 the get_sdk_binding_map MCP tool returns the correct value.`)}g=T.data.data,t=ce(g.config),i=i??J(g.config).filter(C=>!gr.has(C.componentType??"")).map(C=>C.questionId);let P=g.settings??{};r={trackPartialResponses:P.trackPartialResponses,trackCookies:P.trackCookie,gtmId:P.gtmId,gaMeasurementId:P.gaMeasurementId,metaPixelId:P.metaPixelId,hubspotTracking:P.hubspotTracking,adsConversions:P.adsConversions,...r}}let M=r.trackCookies??!1,k;if(f&&!p){let T=await xt(S,f);T.ok?k={responseId:f.responseId,answers:Object.fromEntries(T.data.answers.map(P=>[P.questionId,P.response]))}:console.warn(`Surface SDK: resume fetch for response "${f.responseId}" failed \u2014 starting a fresh session.`)}let x=await ne({transport:S,environmentId:e,formId:n,source:l,preview:p}),R=we({transport:S,preview:p}),U=_e({transport:S,preview:p}),w=Te({formId:n,environmentId:e,steps:t,transport:S,resolveNextStep:s,trackPartialResponses:r.trackPartialResponses??!0,trackCookies:M,externalStates:d?{[d]:Re({trackCookies:M})}:{},meta:{...y,surfaceTagStatus:"sdk"},identity:()=>({fingerprint:x?.fingerprint,leadSessionId:x?.leadSessionId??void 0,leadId:x?.leadId??void 0}),pushEvents:R,formJourney:U,preview:p,resume:k}),_=[],b=w;if(h){let T=new Map((g?J(g.config):[]).map(C=>[C.questionId,C])),P=(C,N)=>((...G)=>(console.debug(`Surface SDK [debug]: ${C} requested from step ${w.state().currentStepId}`),N(...G)));b={...w,setAnswer:(C,N)=>{let G=w.state().currentStepId;w.setAnswer(C,N);let se=w.state().answers[G]?.[C]??N;Vt({questions:T,questionId:C,merged:se})},next:P("next",w.next),back:P("back",w.back),goToStep:P("goToStep",w.goToStep),submit:P("submit",w.submit),disqualify:P("disqualify",w.disqualify)};for(let C of["viewed","started","stepChanged","stepCompleted","completed","disqualified","saved","error","scheduler"])_.push(w.on(C,N=>console.debug(`Surface SDK [debug]: ${C}`,N)))}let D=!1;_.push(w.on("started",()=>{D=!0})),_.push(Ae(R,()=>({started:D,formId:n,stepId:w.state().currentStepId,sessionId:x?.leadSessionId??void 0}))),a&&_.push(ae({engine:b,root:a,expectedQuestionIds:i}));let I=!!r.gtmId||!!r.gaMeasurementId||!!r.metaPixelId||!!r.hubspotTracking?.trackingId||(r.adsConversions?.length??0)>0;I&&!p&&typeof window<"u"&&_.push(zt({engine:w,formId:n,settings:r}));let v=g?pe(g.config):[],L=g!=null&&v.length>0&&fe(g.settings);L&&!p?_.push(Fe({engine:w,transport:S,formId:n,sources:v})):h&&g&&!L&&ut(g.config)&&console.warn("Surface SDK: the record declares an enrichmentSourceField, but this environment has no enabled enrichment provider \u2014 no enrichment will run (capabilities.enrichment is false).");let O=he({transport:S,environmentId:e,preview:p});c&&!p&&_.push(qe({engine:w,validator:O}));let F;return u&&!p&&(F=Le({transport:S,environmentId:e}),F.trackPageView(),_.push(F.observeRouteChanges())),{setAnswer:b.setAnswer,setExternalState:w.setExternalState,next:b.next,back:b.back,goToStep:b.goToStep,submit:b.submit,disqualify:b.disqualify,savePartial:w.savePartial,notifyScheduler:w.notifyScheduler,flush:w.flush,markViewed:w.markViewed,mergeMeta:T=>{let P=Object.entries(T),C=P.filter(([N])=>Yt.has(N));C.length>0&&console.warn(`Surface SDK: mergeMeta dropped reserved key(s) ${C.map(([N])=>N).join(", ")} \u2014 these are SDK-owned response markers.`),w.mergeMeta(Object.fromEntries(P.filter(([N])=>!Yt.has(N))))},capabilities:{enrichment:L,emailValidation:c,tracking:I},on:w.on,state:w.state,subscribe:w.subscribe,identify:async()=>{let T=await ne({transport:S,environmentId:e,formId:n,source:l,preview:p});return T&&(x=T),T},validateEmail:O.validate,runtimeConfig:g,transport:S,identity:()=>({fingerprint:x?.fingerprint,leadSessionId:x?.leadSessionId??void 0,leadId:x?.leadId??void 0}),preview:p,destroy:()=>_.forEach(T=>T())}}};return sn(yr);})();
|
|
1
|
+
"use strict";var SurfaceFormsSDK=(()=>{var $e=Object.defineProperty;var en=Object.getOwnPropertyDescriptor;var tn=Object.getOwnPropertyNames;var nn=Object.prototype.hasOwnProperty;var rn=(e,n)=>{for(var t in n)$e(e,t,{get:n[t],enumerable:!0})},on=(e,n,t,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let o of tn(n))!nn.call(e,o)&&o!==t&&$e(e,o,{get:()=>n[o],enumerable:!(r=en(n,o))||r.enumerable});return e};var sn=e=>on($e({},"__esModule",{value:!0}),e);var yr={};rn(yr,{DEFAULT_API_BASE_URL:()=>z,DEFAULT_REDIRECT_TIMEOUT_MS:()=>Mt,ENRICHMENT_STATE_ID:()=>Le,IDENTITY_INFO_ANSWER_KEYS:()=>xt,JOURNEY_COOKIE_NAME:()=>re,LEAD_DATA_STORAGE_KEY:()=>te,LEAD_DATA_TTL_MS:()=>Ft,RECENT_VISIT_COOKIE_NAME:()=>oe,SurfaceForms:()=>zt,attachEmailValidation:()=>qe,attachEnrichment:()=>Oe,bindForm:()=>ie,buildIdentifyPayload:()=>Ce,buildRedirectUrl:()=>We,buildResponsesArray:()=>Ke,buildStepTransitionEventBatch:()=>Se,buildUrlData:()=>Te,constructUrlParamsObject:()=>Je,createEmailValidator:()=>ye,createEmitter:()=>be,createFormEngine:()=>Ee,createFormJourneyTracker:()=>Ae,createJourneyTracker:()=>Me,createPushEventClient:()=>ke,createSchedulerClient:()=>fe,createStartedDetector:()=>we,createSubmitResponsePayload:()=>Ie,createTransport:()=>ve,createUpdateResponsePayload:()=>Y,enrichmentSourcesOf:()=>ce,ensureIdentified:()=>ne,fetchRuntimeConfig:()=>de,getBrowserFingerprint:()=>_e,getHash:()=>Ye,hasEnabledEnrichmentProvider:()=>me,identifyLead:()=>xe,mountBookingWidget:()=>ae,mountScheduler:()=>Et,observeDropoff:()=>Re,observeFormView:()=>se,parseCookiesObject:()=>Qe,parsePrefillParams:()=>Ot,parseQuestionId:()=>ze,performRedirect:()=>Lt,readLeadData:()=>G,schedulerQuestionsOf:()=>pe,statefulQuestionIdsOf:()=>it,statefulQuestionsOf:()=>Q,stepsOf:()=>ue,submitResponse:()=>he,toSchedulerAnswerState:()=>vt,updateResponse:()=>ee,writeLeadData:()=>Pe});var se=(e,n)=>{if(typeof IntersectionObserver>"u")return n(),()=>{};let t=!1,r=new IntersectionObserver(o=>{let[a]=o;!a?.isIntersecting||t||(t=!0,r.disconnect(),n())});return r.observe(e),()=>r.disconnect()};var nt="input, select, textarea",an=e=>e.matches(nt)?[e]:Array.from(e.querySelectorAll(nt)).filter(n=>n.closest("[data-question-id]")===e),dn=(e,n,t)=>{let r=e.getAttribute("data-field-name")??n.getAttribute("data-field-name");return r||(t==="Dropdown"&&n instanceof HTMLSelectElement?"selected":n instanceof HTMLInputElement&&n.type==="email"?"email":"input")},rt=(e,n)=>{let t=e.getAttribute("data-question-type")??n.getAttribute("data-question-type");return t||(n instanceof HTMLInputElement&&n.type==="email"?"EmailForm":"ShortInput")},ot=e=>e instanceof HTMLInputElement&&(e.type==="checkbox"||e.type==="radio")&&e.type==="checkbox"?e.checked:e.value,ln=e=>e instanceof HTMLInputElement&&(e.type==="radio"||e.type==="checkbox"),st=e=>{let n=e.findIndex(t=>t.checked);return{value:n===-1?"":e[n].value,index:n}},un={MultipleOptionsQuestion:e=>({choices:e.map((n,t)=>({key:n.value,value:n.checked,index:t}))}),MultipleChoiceQuestion:e=>({choices:e.map(n=>({key:n.value,value:n.checked}))}),MMChoiceQuestion:e=>({choices:e.map(n=>({key:n.value,value:n.checked}))}),GraphicOptions:st,MultipleChoiceSingleAnswer:st},ie=({engine:e,root:n,expectedQuestionIds:t})=>{let r=[],o=new Set,a=(u,c,p)=>{u.addEventListener(c,p),r.push(()=>u.removeEventListener(c,p))};for(let u of Array.from(n.querySelectorAll("[data-question-id]"))){let c=u.getAttribute("data-question-id"),p=an(u);if(p.length===0)continue;o.add(c);let C=rt(u,p[0]),y=un[C],m=p.filter(ln);if(y&&m.length>0){let h=()=>e.setAnswer(c,{type:C,...y(m)});for(let v of m)a(v,"change",h);m.some(v=>v.checked)&&h();continue}for(let h of p){let v=rt(u,h),g=dn(u,h,v),L=()=>e.setAnswer(c,{type:v,[g]:ot(h)});a(h,"input",L),a(h,"change",L);let P=ot(h);P!==""&&P!==!1&&L()}}let i=(t??[]).filter(u=>!o.has(u));i.length>0&&console.warn(`Surface SDK: form record declares questionIds with no bound element: ${i.join(", ")}. Answers for these will never be captured — check data-question-id attributes (validate_form_html catches this at authoring time).`);let s="[data-surface-goto-step], .surface-disqualify-button, .surface-submit-button, .surface-next-button";for(let u of Array.from(n.querySelectorAll(s))){let c=u.getAttribute("data-surface-goto-step"),p=[c!=null?"goto":null,u.classList.contains("surface-disqualify-button")?"disqualify":null,u.classList.contains("surface-submit-button")?"submit":null,u.classList.contains("surface-next-button")?"next":null].filter(y=>y!=null),C=p[0];p.length>1&&console.warn(`Surface SDK: element carries multiple navigation markers (${p.join(", ")}); only "${C}" is bound.`),a(u,"click",y=>{y.preventDefault(),C==="goto"?e.goToStep(c).catch(m=>console.warn(`Surface SDK: ${String(m)}`)):C==="disqualify"?e.disqualify():C==="submit"?e.submit():e.next()})}n instanceof HTMLFormElement&&a(n,"submit",u=>{u.preventDefault(),e.submit()});let d=Array.from(n.querySelectorAll("[data-step-id]")),l=()=>{let{currentStepId:u}=e.state();for(let c of d)c.hidden=c.getAttribute("data-step-id")!==u};return d.length>0&&(l(),r.push(e.on("stepChanged",l))),r.push(se(n,()=>e.markViewed())),()=>r.forEach(u=>u())};var cn=()=>{let e=new Date;return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}`},pn=e=>{let[n,t]=e.split("-").map(Number);return new Date(n,t-1,1).toLocaleDateString(void 0,{month:"long",year:"numeric"})},mn=e=>{let[n,t,r]=e.split("-").map(Number);return new Date(n,t-1,r).toLocaleDateString(void 0,{weekday:"short",month:"short",day:"numeric"})},fn=(e,n)=>{let[t,r]=e.split("-").map(Number),o=new Date(t,r-1+n,1);return`${o.getFullYear()}-${String(o.getMonth()+1).padStart(2,"0")}`},ae=({container:e,scheduler:n,eventTypeId:t,timezone:r=Intl.DateTimeFormat().resolvedOptions().timeZone,duration:o,prefill:a,identity:i,formatters:s,onEvent:d,onComplete:l})=>{let u=s?.month??pn,c=s?.date??mn,p=s?.time??(O=>new Date(O.start).toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit",timeZone:r})),C=document.createElement("div");C.className="surface-booking",e.appendChild(C);let y=cn(),m=!0,h=[],v=null,g=null,L=!1,P=0,k=(O,S,w)=>{let _=document.createElement(O);return _.className=S,w!=null&&(_.textContent=w),_},T=O=>{L||C.replaceChildren(...O)},U=(O,S)=>{let w=k("p","surface-booking-error",O),_=k("button","surface-booking-retry","Try again");_.type="button",_.addEventListener("click",S),T([w,_])},b=async()=>{let O=y,S=++P;T([k("p","surface-booking-loading","Loading availability…")]);let w=await n.getMonthAvailability({eventTypeId:t,month:O,timezone:r,duration:o});if(L||S!==P)return;if(!w.ok){U("Unable to load availability.",()=>{b()});return}h=w.data.data?.dates??[];let _=h.filter(E=>E.slots&&E.slots.length>0);if(m&&(m=!1,_.length===0&&o==null)){let E=await n.getAvailabilitySummary({eventTypeId:t,timezone:r});if(L||S!==P)return;let R=E.ok?E.data.data?.next_available_date:null;if(R&&!R.startsWith(O)){y=R.slice(0,7),b();return}}let q=k("p","surface-booking-month",u(O));q.dataset.value=O;let F=k("div","surface-booking-month-nav");for(let[E,R]of[["Previous month",-1],["Next month",1]]){let D=k("button","surface-booking-month-button",E);D.type="button",D.addEventListener("click",()=>{y=fn(y,R),b()}),F.appendChild(D)}let M=k("ul","surface-booking-dates");for(let E of _){let R=k("li","surface-booking-date"),D=k("button","surface-booking-date-button",c(E.date));D.dataset.value=E.date,D.type="button",D.addEventListener("click",()=>{v=E,d?.({type:"date_selected",date:E.date}),A()}),R.appendChild(D),M.appendChild(R)}M.childElementCount===0&&M.appendChild(k("li","surface-booking-no-dates","No availability this month.")),T([q,F,M])},A=async()=>{if(!v)return;let O=++P,S=v.slots??[];if(S.length===0){let F=await n.getSlots({eventTypeId:t,date:v.date,timezone:r,duration:o});if(L||O!==P)return;if(!F.ok){U("Unable to load times.",()=>{A()});return}S=F.data.data?.slots??[]}let w=k("p","surface-booking-day",c(v.date));w.dataset.value=v.date;let _=k("button","surface-booking-back","Back");_.type="button",_.addEventListener("click",()=>{b()});let q=k("ul","surface-booking-slots");for(let F of S){let M=k("li","surface-booking-slot"),E=k("button","surface-booking-slot-button",p(F));E.dataset.value=F.start,E.type="button",E.addEventListener("click",()=>{g=F,d?.({type:"slot_selected",slot:F}),x()}),M.appendChild(E),q.appendChild(M)}T([w,_,q])},x=O=>{if(!g)return;O==null&&d?.({type:"form_opened"});let S=k("form","surface-booking-form"),w=k("input","surface-booking-name");w.name="name",w.placeholder="Name",w.value=a?.name??"";let _=k("input","surface-booking-email");_.type="email",_.name="email",_.placeholder="Email",_.value=a?.email??"";let q=k("button","surface-booking-submit","Book");q.type="submit",S.append(w,_,q),O&&S.appendChild(k("p","surface-booking-error",O)),S.addEventListener("submit",F=>{F.preventDefault(),(async()=>{q.disabled=!0;let M=typeof i=="function"?await i():i,E=await n.book({eventTypeId:t,startTime:g.start,endTime:g.end,timezone:r,inviteeName:w.value,inviteeEmail:_.value,duration:o,...M});if(!L){if(!E.ok){x("Booking failed. Please try again.");return}T([k("p","surface-booking-booked","Booked!")]),d?.({type:"booking_confirmed",booking:E.data}),l(E.data)}})()}),T([S])};return d?.({type:"viewed"}),b(),()=>{L=!0,C.remove()}};var de=(e,n,{preview:t=!1,previewToken:r}={})=>e.get(`/api/v1/public/forms/${n}/runtime-config${t?`?preview=1${r?`&pt=${encodeURIComponent(r)}`:""}`:""}`),le=e=>{let n=e.components;if(Array.isArray(n))return n;let t=n?.layout;return Array.isArray(t)?t.flatMap(r=>{let o=r.row;return Array.isArray(o)?o.map(a=>a.type==="GridLayoutRowItem"?a.component:a):[]}):[]},ue=e=>(e.steps??[]).map(n=>({id:n.id,...n.endStepKind!==void 0&&{endStepKind:n.endStepKind}})),Q=e=>(e.steps??[]).flatMap(le).flatMap(n=>{let t=n;return typeof t?.state?.questionId!="string"?[]:[{questionId:t.state.questionId,...typeof t.type=="string"&&{componentType:t.type}}]}),it=e=>Q(e).map(n=>n.questionId),ce=e=>(e.steps??[]).flatMap(le).flatMap(n=>{let t=n;if(typeof t?.state?.questionId!="string")return[];if(t.type==="IdentityInfo"){let r=typeof t.content?.enrichmentSourceField=="string"?t.content.enrichmentSourceField:"emailAddress";return[{questionId:t.state.questionId,fieldNames:[...new Set([r,"websiteUrl"])]}]}return t.type==="EmailForm"?[{questionId:t.state.questionId,fieldNames:["email"]}]:[]}),at=e=>{let n=e;return typeof n?.stepId=="string"&&typeof n?.questionId=="string"?{stepId:n.stepId,questionId:n.questionId}:void 0},gn=e=>{let n=at(e),t=e?.variable;return n&&typeof t=="string"?{...n,variable:t}:void 0},pe=e=>(e.steps??[]).flatMap(n=>le(n).flatMap(t=>{let r=t;if(r?.type!=="CalendlyScreen"&&r?.type!=="DynamicScheduler")return[];if(typeof r.state?.questionId!="string")return[];let o=r.content??{},a={};for(let s of["dataUrl","eventTypeId","savvyCalLinkId","revenueHeroRouterId"])typeof o[s]=="string"&&(a[s]=o[s]);for(let s of["addSchedulerQueryParams","skipFormIfPrefilled"])typeof o[s]=="boolean"&&(a[s]=o[s]);for(let s of["linkNameToStep","linkLastNameToStep","linkEmailToStep"]){let d=at(o[s]);d&&(a[s]=d)}let i=Object.entries(o.dataUrlParams??{}).flatMap(([s,d])=>{let l=gn(d);return l?[[s,l]]:[]});return i.length>0&&(a.dataUrlParams=Object.fromEntries(i)),Array.isArray(o.calendars)&&(a.calendars=o.calendars),o.defaultCalendar!=null&&(a.defaultCalendar=o.defaultCalendar),[{questionId:r.state.questionId,stepId:n.id,componentType:r.type,calendarType:typeof o.calendarType=="string"?o.calendarType:"Calendly",content:a}]})),dt=e=>(e.steps??[]).flatMap(le).some(n=>typeof n?.content?.enrichmentSourceField=="string"),me=e=>{let n=e?.enrichment;return n?.version!==2||!Array.isArray(n.providers)?!1:n.providers.some(t=>t?.enabled===!0&&Array.isArray(t.enabledFields)&&t.enabledFields.length>0)};var X=e=>/^[a-z][a-z0-9+.-]*:\/\//i.test(e)?e:`https://${e}`,B=(e,n)=>{let t;try{t=new URL(X(e))}catch{return null}for(let[r,o]of Object.entries(n))o!=null&&!t.searchParams.has(r)&&t.searchParams.set(r,o);return t.toString()},yn=(e,n)=>{let t=document.createElement("iframe");return t.className="surface-scheduler-frame",t.src=n,t.style.width="100%",t.style.height="100%",t.style.border="0",e.appendChild(t),t},W=e=>new Promise((n,t)=>{let r=document.querySelector(`script[src="${e}"]`);if(r){if(r.dataset.surfaceLoaded==="true")return n();r.addEventListener("load",()=>n()),r.addEventListener("error",()=>t(new Error(`Failed to load ${e}`)));return}let o=document.createElement("script");o.src=e,o.async=!0,o.addEventListener("load",()=>{o.dataset.surfaceLoaded="true",n()}),o.addEventListener("error",()=>{o.remove(),t(new Error(`Failed to load ${e}`))}),document.head.appendChild(o)}),hn=(e,n)=>{let t;try{t=new URL(e)}catch{return!1}return n.some(r=>"exact"in r?e===r.exact:t.protocol!=="https:"?!1:"hostRegex"in r?r.hostRegex.test(t.hostname):t.hostname===r.hostSuffix||t.hostname.endsWith(`.${r.hostSuffix}`))},N=(e,n)=>(console.warn(`Surface SDK: scheduler question "${e.questionId}" is missing ${n} on the record.`),()=>{}),j=e=>{let n=!1,t;return e().then(r=>{n?r?.():t=r}).catch(r=>console.warn("Surface SDK: scheduler embed failed",r)),()=>{n=!0,t?.()}},Z=(e,n)=>{let t=r=>{if(hn(r.origin,e))try{n(r.data)}catch(o){console.warn("Surface SDK: scheduler message handler failed",o)}};return window.addEventListener("message",t),()=>window.removeEventListener("message",t)},V=(e,{needsResponseId:n=!1,build:t})=>j(async()=>{let r=n?await e.ensureResponseId():null,o=t(r);if(o.src==null)return;let a=yn(e.container,o.src),i=o.origins&&o.onMessage?Z(o.origins,o.onMessage):void 0,s=o.poll&&r!=null?vn({transport:e.form.transport,...o.poll}):void 0;return()=>{i?.(),s?.(),a.remove()}}),vn=({transport:e,path:n,onResult:t,intervalMs:r=2e3,timeoutMs:o=3e5})=>{let a=Date.now(),i=!1,s=null,d=()=>{i=!0,s!=null&&clearInterval(s),s=null},l=async()=>{if(i)return;if(Date.now()-a>o)return d();let u=await e.get(n);i||!u.ok||t(u.data)==="stop"&&d()};return l(),s=setInterval(()=>{l()},r),d};var lt=e=>{let n=e.content.dataUrl;if(!n)return N(e.question,"dataUrl");let t=X(n),r=t.split("/").pop()?.split("?")[0]??"surface",o=t.replace(/^https?:\/\/(app\.)?cal\.com\//,""),a=`surface-cal-${e.question.questionId}`,i=document.createElement("div");i.id=a,e.container.appendChild(i);let s=l=>{let u=l.detail?.data?.booking?.uid;e.confirmBooking({uri:u?`https://app.cal.com/booking/${u}`:"",raw:l.detail})};window.addEventListener(`CAL:${r}:bookingSuccessful`,s);let d=j(async()=>{await W("https://app.cal.com/embed/embed.js");let l=window.Cal;l&&(l("init",r,{origin:"https://cal.com"}),l.ns?.[r]?.("inline",{elementOrSelector:`#${a}`,calLink:o,config:{...e.prefill.name&&{name:e.prefill.name},...e.prefill.email&&{email:e.prefill.email}}}))});return()=>{window.removeEventListener(`CAL:${r}:bookingSuccessful`,s),d(),i.remove()}};var ut=e=>{let n=e.content.dataUrl;if(!n)return N(e.question,"dataUrl");let t=!1,r=(a,i)=>{t||(t=!0,e.confirmBooking({uri:a,raw:i}))},o=e.content.addSchedulerQueryParams!==!1;return V(e,{needsResponseId:!0,build:a=>({src:B(n,{embed_domain:"1",embed_type:"Inline",...o&&{hide_event_type_details:"1",hide_gdpr_banner:"1"},...Object.keys(e.urlParams).length>0?e.urlParams:{name:e.prefill.name,email:e.prefill.email},...a!=null&&{utm_source:`surface-${a}`}}),origins:[{exact:"https://calendly.com"}],onMessage:i=>{let s=i;typeof s?.event!="string"||!s.event.startsWith("calendly.")||(s.event==="calendly.event_type_viewed"&&e.emit({type:"viewed"}),s.event==="calendly.date_and_time_selected"&&e.emit({type:"slot_selected"}),s.event==="calendly.event_scheduled"&&r(s.payload?.invitee?.uri??"",i))},poll:{path:`/api/v1/calendly/check-event/${a}`,onResult:i=>i.status==="pending"?"continue":i.status==="canceled"?(t&&e.cancelBooking(),"stop"):typeof i.url=="string"&&i.url&&i.responseId===a?(r(i.url,i),"stop"):t?"stop":"continue"}})})};var ct=e=>{let n=e.content.dataUrl;return n?V(e,{build:()=>({src:B(n,{embed:"true",...e.urlParams}),origins:[{hostSuffix:"chilipiper.com"}],onMessage:t=>{let r=t;r?.action==="booking-confirmed"&&e.confirmBooking({uri:r.args?.eventId??"",raw:t})}})}):N(e.question,"dataUrl")};var pt=e=>{let n=e.content.dataUrl;return n?V(e,{build:()=>({src:B(n,{embed:"true",...e.urlParams})})}):N(e.question,"dataUrl")};var mt=e=>{let n=e.content.dataUrl;if(!n)return N(e.question,"dataUrl");let t=B(n,{embed:"true",...e.urlParams});if(t==null)return()=>{};let r=`surface-hubspot-${e.question.questionId}`,o=document.createElement("div");o.id=r,o.className="meetings-iframe-container",o.dataset.src=t,e.container.appendChild(o);let a=Z([{exact:"https://meetings.hubspot.com"},{hostRegex:/^meetings-[a-z0-9]+\.hubspot\.com$/}],s=>{s?.meetingBookSucceeded===!0&&e.confirmBooking({uri:" ",raw:s})}),i=j(async()=>{await W("https://static.hsappstatic.net/MeetingsEmbed/ex/MeetingsEmbedCode.js"),window.MeetingsEmbedCode?.createMeetingsIframe(`#${r}`)});return()=>{a(),i(),o.remove()}};var bn=["reclaim.ai","reclaim.com","reclaimai.com"],ft=e=>{let n=e.content.dataUrl,t=(()=>{try{return new URL(X(n??"")).hostname}catch{return null}})(),r=t!=null&&bn.some(o=>t===o||t.endsWith(`.${o}`));return!n||!r?N(e.question,"a valid reclaim.ai dataUrl"):V(e,{needsResponseId:!0,build:o=>({src:B(n,{...o!=null&&{"data-responseId":o},...e.urlParams}),poll:{path:`/api/v1/reclaimai/check-event/${o}`,onResult:a=>{if(a.status==="pending")return"continue";if(a.meetingId!=null&&a.responseId===o){let i=[a.schedulingLinkId,a.meetingId].find(s=>typeof s=="string"&&s.length>0);return e.confirmBooking({uri:i??"",raw:a}),"stop"}return"continue"}}})})};var gt=e=>{let n=e.content.revenueHeroRouterId;if(!n)return N(e.question,"revenueHeroRouterId");let t=`surface-revenuehero-${e.question.questionId}`,r=document.createElement("div");r.id=t,e.container.appendChild(r);let o=Z([{hostSuffix:"revenuehero.io"}],i=>{let s=i;s?.type!=="MEETING_BOOKED"||s.meeting==null||e.confirmBooking({uri:s.meeting.id??"",...s.meeting.attributes?.meeting_time!=null&&{meetingTime:s.meeting.attributes.meeting_time},raw:i})}),a=j(async()=>{await W("https://assets.revenuehero.io/scheduler.min.js");let i=window.RevenueHero;if(!i)return;let s=new i({routerId:n,showLoader:!1}),d={...e.urlParams,...e.prefill.email&&{email:e.prefill.email},...e.prefill.name&&{name:e.prefill.name}},l=await s.submit(d);s.dialog.setEmbedTarget(`#${t}`),s.dialog.open(l)});return()=>{o(),a(),r.remove()}};var yt=e=>{let n=e.content.savvyCalLinkId;if(!n)return N(e.question,"savvyCalLinkId");let t=`surface-savvycal-${e.question.questionId}`,r=document.createElement("div");r.id=t,e.container.appendChild(r);let o=i=>{let s=i.detail;s&&e.confirmBooking({uri:s.url??"",raw:s})};window.addEventListener("savvycal.scheduled",o);let a=j(async()=>{await W("https://embed.savvycal.com/v1/embed.js");let i=window.SavvyCal;if(!i)return;i("init");let s=[e.prefill.name,e.prefill.lastName].filter(Boolean).join(" ");i("inline",{link:n,selector:`#${t}`,...s&&{displayName:s},...e.prefill.email&&{email:e.prefill.email}})});return()=>{window.removeEventListener("savvycal.scheduled",o),a(),r.remove()}};var ht=e=>new URLSearchParams(Object.fromEntries(Object.entries(e).filter(([,n])=>n!=null))),fe=({transport:e,preview:n=!1})=>{let t=n?"true":void 0,r=o=>{if(!o.ok)return o;let a=o.data.data;return a?.id?{ok:!0,data:a}:{ok:!1,error:{kind:"http",status:200,body:o.data}}};return{getPublicEventType:o=>e.get(`/api/v1/scheduler/event-types/${o}/public`),getAvailabilitySummary:({eventTypeId:o,timezone:a})=>{let i=new URLSearchParams({eventTypeId:o,timezone:a??Intl.DateTimeFormat().resolvedOptions().timeZone});return e.get(`/api/v1/scheduler/availability-summary?${i}`)},getMonthAvailability:({eventTypeId:o,month:a,timezone:i,duration:s,hostId:d,ownerEmail:l})=>{let[u,c]=a.split("-").map(Number),p=ht({eventTypeId:o,month:String(c),year:String(u),timezone:i,duration:s?String(s):void 0,preview:t,hostId:d,ownerEmail:l});return e.get(`/api/v1/scheduler/availability?${p}`)},getSlots:({eventTypeId:o,date:a,timezone:i,duration:s,hostId:d,ownerEmail:l})=>{let u=ht({eventTypeId:o,date:a,timezone:i,duration:s?String(s):void 0,preview:t,hostId:d,ownerEmail:l});return e.get(`/api/v1/scheduler/slots?${u}`)},book:async({eventTypeId:o,startTime:a,endTime:i,timezone:s,inviteeName:d,inviteeEmail:l,duration:u,intakeResponses:c,guestEmails:p,captchaToken:C,responseId:y,leadSessionId:m,fingerprint:h,hostRouting:v})=>{if(n)return{ok:!0,data:{id:"preview-booking-"+Date.now(),startTime:a,endTime:i,timezone:s,inviteeName:d||"Test User",inviteeEmail:l||"test@example.com",meetingJoinLink:null,cancelToken:"preview-cancel-"+Date.now(),rescheduleToken:"preview-reschedule-"+Date.now(),attendees:[{name:"Host",email:"host@example.com",isHost:!0}]}};let g=await e.post("/api/v1/scheduler/book",{eventTypeId:o,startTime:a,timezone:s,inviteeName:d,inviteeEmail:l.trim(),...u?{duration:u}:{},...c&&Object.keys(c).length>0?{intakeResponses:c}:{},...p&&p.length>0?{guestEmails:p}:{},...C?{captchaToken:C}:{},meta:{source:"form",...y?{responseId:y}:{},...m?{leadSessionId:m}:{},...h?{fingerprint:h}:{},...v?{hostRouting:v}:{}}});return r(g)},reschedule:async({bookingId:o,rescheduleToken:a,newStartTime:i,timezone:s})=>{let d=await e.post(`/api/v1/scheduler/bookings/${o}/reschedule`,{rescheduleToken:a,newStartTime:i,timezone:s});return r(d)}}},vt=e=>{let n=e.attendees?.find(t=>t.isHost);return{type:"DynamicScheduler",eventScheduled:!0,uri:e.id,meetingTime:e.startTime,meetingEndTime:e.endTime,ownerEmails:n?.email??"",guestEmails:e.inviteeEmail,inviteeName:e.inviteeName,googleMeetLink:e.meetingJoinLink??""}};var bt=e=>{let n=e.content.eventTypeId;if(!n)throw new Error(`mountScheduler: Surface scheduler question "${e.question.questionId}" has no eventTypeId on the record.`);let t=fe({transport:e.form.transport,preview:e.form.preview}),r=[e.prefill.name,e.prefill.lastName].filter(Boolean).join(" ");return e.mergeAnswer({eventScheduled:!1,uri:"",schedulerSubStep:"date"}),ae({container:e.container,scheduler:t,eventTypeId:n,prefill:{...r&&{name:r},...e.prefill.email&&{email:e.prefill.email}},formatters:e.formatters,identity:async()=>{let o=await e.ensureResponseId(),a=e.form.identity();return{...o!=null&&{responseId:o},...a.leadSessionId!=null&&{leadSessionId:a.leadSessionId},...a.fingerprint!=null&&{fingerprint:a.fingerprint}}},onEvent:o=>{if(o.type==="booking_confirmed"){let{booking:i}=o,s=i.attendees?.find(d=>d.isHost);e.confirmBooking({uri:i.id,meetingTime:i.startTime,meetingEndTime:i.endTime,inviteeName:i.inviteeName,guestEmails:i.inviteeEmail,ownerEmails:s?.email??"",joinLink:i.meetingJoinLink??"",raw:i},{schedulerSubStep:"booked"});return}let a={date_selected:"time",form_opened:"form"}[o.type];a&&e.mergeAnswer({schedulerSubStep:a}),e.emit(o)},onComplete:()=>{}})};var Sn={hostEmail:"ownerEmails",startTime:"meetingTime",endTime:"meetingEndTime",joinUrl:"googleMeetLink",duration:"durationMinutes",timezone:"hostTimezone"},St=e=>{let n=e.content.dataUrl;if(!n)return N(e.question,"dataUrl");let[t,...r]=(e.prefill.name??"").split(/\s+/),o=e.prefill.lastName??(r.length>0?r.join(" "):void 0);return V(e,{needsResponseId:!0,build:a=>({src:B(n,{embed:"true",origin:window.location.origin,...t&&{firstname:t},...o&&{lastname:o},...e.prefill.email&&{email:e.prefill.email},...a!=null&&{utm_source:`surface-${a}`},...e.urlParams}),origins:[{exact:"https://scheduler.zoom.us"}],onMessage:i=>{let s=i;if(s?.type!=="bookingForm")return;let d=s.payload??{},l=[d.bookerFirstName,d.bookerLastName].filter(Boolean).join(" ");e.confirmBooking({uri:d.scheduledEventId??"",guestEmails:d.bookerEmail??"",...l&&{inviteeName:l},raw:i})},poll:{path:`/api/v1/zoom/check-event/${a}`,onResult:i=>{if(i.status==="pending"||i.hostEmail==null&&i.startTime==null)return"continue";let s={};for(let[d,l]of Object.entries(Sn))typeof i[d]=="string"&&(s[l]=i[d]);return e.mergeAnswer(s,{save:!0}),"stop"}}})})};var kt={Surface:bt,Calendly:ut,Cal:lt,SavvyCal:yt,ChiliCal:ct,Hubspot:mt,RevenueHero:gt,Zoom:St,ReclaimAI:ft,Clari:pt};var wt="surface-scheduler-styles",kn=`\n\${--surface-scheduler-accent:#2563eb;--surface-scheduler-border:#e2e8f0;--surface-scheduler-text:#0f172a;--surface-scheduler-muted:#64748b;--surface-scheduler-radius:8px;font-family:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;color:var(--surface-scheduler-text)}\n%{display:flex;flex-direction:column;gap:12px;max-width:26rem;padding:16px;border:1px solid var(--surface-scheduler-border);border-radius:var(--surface-scheduler-radius)}\n%-month,%-day{margin:0;font-size:1rem;font-weight:600}\n%-month-nav{display:flex;gap:8px}\n$ button{font:inherit;cursor:pointer;border-radius:calc(var(--surface-scheduler-radius) - 2px)}\n%-month-button,%-back,%-retry{padding:4px 10px;border:1px solid var(--surface-scheduler-border);background:transparent;color:var(--surface-scheduler-muted)}\n%-month-button:hover,%-back:hover{color:var(--surface-scheduler-text)}\n%-dates,%-slots{display:grid;grid-template-columns:repeat(auto-fill,minmax(7.5rem,1fr));gap:8px;margin:0;padding:0;list-style:none}\n%-date-button,%-slot-button{width:100%;padding:8px 6px;border:1px solid var(--surface-scheduler-border);background:transparent;color:var(--surface-scheduler-text)}\n%-date-button:hover,%-slot-button:hover{border-color:var(--surface-scheduler-accent);color:var(--surface-scheduler-accent)}\n%-form{display:flex;flex-direction:column;gap:8px}\n%-name,%-email{font:inherit;padding:8px 10px;border:1px solid var(--surface-scheduler-border);border-radius:calc(var(--surface-scheduler-radius) - 2px)}\n%-name:focus,%-email:focus{outline:2px solid var(--surface-scheduler-accent);outline-offset:-1px}\n%-submit{padding:8px 14px;border:0;background:var(--surface-scheduler-accent);color:#fff}\n%-submit:disabled{opacity:.6;cursor:default}\n%-loading,%-no-dates{color:var(--surface-scheduler-muted)}\n%-error{color:#b91c1c;margin:0}\n%-booked{font-weight:600;color:var(--surface-scheduler-accent)}\n.surface-scheduler-frame{display:block;min-height:640px}\n`,It=()=>{if(document.getElementById(wt))return;let e=document.createElement("style");e.id=wt,e.textContent=kn.replace(/%/g,"$ .surface-booking").replace(/\$/g,".surface-scheduler"),document.head.appendChild(e)};var ge=(e,n)=>{for(let t of Object.values(e.state().answers))if(t[n]!=null)return t[n]},Be=(e,n)=>{for(let t of n){let r=e?.[t];if(typeof r=="string"&&r.length>0)return r}},wn=(e,n,t)=>({name:t?.name??Be(n.linkNameToStep&&ge(e,n.linkNameToStep.questionId),["fullName","firstName","input"]),lastName:t?.lastName??Be(n.linkLastNameToStep&&ge(e,n.linkLastNameToStep.questionId),["lastName","input"]),email:t?.email??Be(n.linkEmailToStep&&ge(e,n.linkEmailToStep.questionId),["email","emailAddress","workEmailAddress","input"])}),In=(e,n)=>{let{content:t}=e;if(e.componentType!=="DynamicScheduler")return t;let r=t.calendars??[],o;if(n!=null){if(o=r.find(s=>s.name===n),!o){let s=r.map(d=>String(d.name)).join(", ")||"(none)";throw new Error(`mountScheduler: no calendar named "${n}" on question "${e.questionId}" — available: ${s}.`)}}else if(o=t.defaultCalendar??void 0,!o&&r.length===1&&(o=r[0]),!o)throw new Error(`mountScheduler: question "${e.questionId}" routes between ${r.length} calendars with no default — pass calendarId to choose one (condition evaluation is the caller's own routing).`);let a={...t},i=[o.dataUrl,o.url].find(s=>typeof s=="string"&&s.length>0);i!=null&&(a.dataUrl=i);for(let s of["eventTypeId","savvyCalLinkId","revenueHeroRouterId"])typeof o[s]=="string"&&(a[s]=o[s]);return a},En=(e,{questionId:n,stepId:t})=>{if(!e.runtimeConfig)throw new Error("mountScheduler: no record to read scheduler config from (the form was booted with caller-provided steps) — init without `steps`, or mount the widget manually.");let r=pe(e.runtimeConfig.config),o=r.filter(i=>(n==null||i.questionId===n)&&(t==null||i.stepId===t));if(o.length===1)return o[0];let a=r.map(i=>`"${i.questionId}" (${i.calendarType}, step "${i.stepId}")`).join(", ");throw new Error(o.length===0?`mountScheduler: no scheduler question${n?` "${n}"`:""}${t?` on step "${t}"`:""} — the record has: ${a||"none"}.`:`mountScheduler: ${o.length} scheduler questions match — pass questionId. Candidates: ${a}.`)},Et=({form:e,container:n,questionId:t,stepId:r,styled:o=!0,persist:a=!0,prefill:i,formatters:s,calendarId:d,onEvent:l,onComplete:u})=>{let c=En(e,{questionId:t,stepId:r}),p=c.calendarType,C=kt[p];if(!C)throw new Error(`mountScheduler: unsupported provider "${c.calendarType}" on question "${c.questionId}".`);let y=In(c,d),m=!1,h=!1,v=b=>{if(m)return;if(b.type==="viewed"){if(h)return;h=!0}let A={...b,questionId:c.questionId,stepId:c.stepId,provider:p};e.notifyScheduler(A);try{l?.(A)}catch(x){console.warn("Surface SDK: mountScheduler onEvent handler failed",x)}},g=(b,A)=>{a&&(e.setAnswer(c.questionId,{type:c.componentType,...b}),A?.save&&!e.state().finished&&e.savePartial())},L=(b,A)=>{let x={...b,provider:p},O={eventScheduled:!0,uri:x.uri},S={meetingTime:x.meetingTime,meetingEndTime:x.meetingEndTime,ownerEmails:x.ownerEmails,guestEmails:x.guestEmails,inviteeName:x.inviteeName,googleMeetLink:x.joinLink};for(let[w,_]of Object.entries(S))_!==void 0&&(O[w]=_);g({...O,...A},{save:!0}),v({type:"booking_confirmed",booking:x});try{u?.(x)}catch(w){console.warn("Surface SDK: mountScheduler onComplete handler failed",w)}},P=b=>{g({eventScheduled:!1,eventCancelled:!0,...b!=null&&{cancelReason:b}},{save:!0}),v({type:"booking_cancelled",...b!=null&&{reason:b}})},k=async()=>e.preview?null:(e.state().responseId==null&&a&&await e.savePartial(),e.state().responseId);o&&(It(),n.classList.add("surface-scheduler"));let T=Object.fromEntries(Object.entries(y.dataUrlParams??{}).flatMap(([b,A])=>{let x=ge(e,A.questionId)?.[A.variable];return typeof x=="string"&&x.length>0?[[b,x]]:[]})),U=C({form:e,container:n,question:c,content:y,prefill:wn(e,y,i),urlParams:T,formatters:s,styled:o,emit:v,confirmBooking:L,cancelBooking:P,mergeAnswer:g,ensureResponseId:k});return v({type:"viewed"}),()=>{m||(m=!0,o&&n.classList.remove("surface-scheduler"),U())}};var Tn="/api/v1/edge/emailValidation",Tt=e=>({email:e,isValid:!0,status:"unknown",reason:"validation_failed",failed:!0}),Rn=(e,n)=>!n||typeof n.isValid!="boolean"?Tt(e):{email:e,isValid:n.isValid,status:n.status,reason:n.reason,...n.blacklistEntryIds?.length?{blacklistEntryIds:n.blacklistEntryIds}:{},...n.validationSuccessfullyRan===!1?{failed:!0}:{}},ye=({transport:e,environmentId:n,preview:t=!1})=>{let r=new Map,o=a=>{let i=[...new Set(a.map(d=>d.trim()).filter(d=>d!==""))];if(t)for(let d of i)r.has(d)||r.set(d,Promise.resolve({email:d,isValid:!0,status:"preview"}));let s=i.filter(d=>!r.has(d));if(s.length>0){let d=e.post(Tn,{emails:s,environmentId:n}).then(l=>l.ok?l.data.data??{}:{}).catch(()=>({}));for(let l of s)r.set(l,d.then(u=>Rn(l,u[l])))}return Promise.all(i.map(d=>r.get(d)))};return{validateBatch:o,validate:async a=>{let[i]=await o([a]);return i??Tt(a.trim())}}};var An="/api/v1/responses/",Rt="/api/v1/responses/update",_n="/api/v1/responses/getResponse",he=async(e,n)=>{let t=await e.post(An,n,{credentials:!0});if(!t.ok)return t;let r=t.data.data?.id;return r?{ok:!0,data:{responseId:r,leadId:t.data.data?.meta?.leadId??null,resumeToken:t.data.data?.resumeToken??null}}:{ok:!1,error:{kind:"http",status:200,body:t.data}}},ee=(e,n)=>{e.beacon(Rt,n)},At=(e,n)=>e.post(Rt,n,{keepalive:!0,credentials:!0}),Cn=e=>typeof e?.questionId=="string"&&typeof e?.response=="object"&&e.response!==null,_t=async(e,{responseId:n,resumeToken:t})=>{let r=await e.get(`${_n}?rid=${encodeURIComponent(n)}&rt=${encodeURIComponent(t)}`);return r.ok?{ok:!0,data:{answers:(Array.isArray(r.data.data?.data)?r.data.data.data:[]).filter(Cn).filter(a=>a.response.type!=="URL_DATA")}}:r};var z="https://forms.withsurface.com",Ct="0.1.0",Ve=(e={})=>({...e,"X-Surface-Sdk-Version":Ct}),xn=e=>`${e}${e.includes("?")?"&":"?"}sdv=${Ct}`,ve=({apiBaseUrl:e=z}={})=>{let n=e.replace(/\/$/,""),t=i=>`${n}${i}`;return{get:async i=>{try{let s=await fetch(t(i),{headers:Ve()});if(!s.ok){let d=await s.json().catch(()=>{});return{ok:!1,error:{kind:"http",status:s.status,body:d}}}return{ok:!0,data:await s.json()}}catch(s){return{ok:!1,error:{kind:"network",cause:s}}}},post:async(i,s,d)=>{try{let l=await fetch(t(i),{method:"POST",headers:Ve({"Content-Type":"application/json"}),body:JSON.stringify(s),...d?.keepalive?{keepalive:!0}:{},...d?.credentials?{credentials:"include"}:{}});if(!l.ok){let u=await l.json().catch(()=>{});return{ok:!1,error:{kind:"http",status:l.status,body:u}}}return{ok:!0,data:await l.json()}}catch(l){return{ok:!1,error:{kind:"network",cause:l}}}},beacon:(i,s)=>{let d;try{d=JSON.stringify(s)}catch{return!1}let l=xn(t(i));try{if(typeof navigator<"u"&&typeof navigator.sendBeacon=="function"&&navigator.sendBeacon(l,new Blob([d],{type:"application/json"})))return!0}catch{}try{fetch(l,{method:"POST",keepalive:!0,credentials:"include",headers:Ve({"Content-Type":"application/json"}),body:d}).catch(()=>{})}catch{}return!1}}};var xt=["firstName","lastName","fullName","emailAddress","workEmailAddress","phoneNumber","companyName","numberOfEmployees","websiteUrl","title","streetAddress","aptSuiteEtc","city","state","country","zipCode","companyRevenue","profilePictureUrl"];var be=()=>{let e=new Map;return{on:(n,t)=>{let r=e.get(n)??new Set;return r.add(t),e.set(n,r),()=>{r.delete(t)}},emit:(n,t)=>{e.get(n)?.forEach(r=>{try{r(t)}catch(o){console.error(`Surface SDK: "${String(n)}" handler threw`,o)}})}}};var Pn="/api/v1/pushEvent",Mn=/bot|crawl|spider|slurp|baidu|bingpreview|googlebot|yandex|duckduck|ahrefs|semrush|facebookexternalhit|embedly|quora link preview|pinterest|twitterbot|linkedinbot|whatsapp|telegram|discord|headless|lighthouse|pagespeed/i,Ln=()=>{let e=navigator.userAgent;return e?Mn.test(e):!1},On=e=>!!(e?.type&&e?.entityType&&e?.entityId),Se=({sessionId:e,formId:n,currentStepId:t,nextStepId:r,stepCompletionTime:o})=>({events:[{type:"form_step_submitted",entityType:"form_step",entityId:n,stepId:t,leadSessionId:e,properties:[{key:"stepCompletionTime",value:o}]},{type:"form_step_viewed",entityType:"form_step",entityId:n,stepId:r,leadSessionId:e,properties:[]}]}),ke=({transport:e,preview:n=!1})=>({push:t=>{if(n||typeof navigator>"u")return;let r="events"in t?t.events:[t];Ln()||r.some(o=>!On(o))||e.beacon(Pn,t)}});var we=e=>{let n=je(e),t=!1;return r=>t||He(n,r)?!1:(t=!0,!0)},je=e=>{if(Array.isArray(e))return e.map(je);if(e!==null&&typeof e=="object"){let n={};for(let[t,r]of Object.entries(e))n[t]=je(r);return n}return e},He=(e,n)=>{if(Object.is(e,n))return!0;if(Array.isArray(e)||Array.isArray(n))return!Array.isArray(e)||!Array.isArray(n)||e.length!==n.length?!1:e.every((t,r)=>He(t,n[r]));if(e!==null&&n!==null&&typeof e=="object"&&typeof n=="object"){let t=Object.keys(e),r=Object.keys(n);return t.length!==r.length?!1:t.every(o=>He(e[o],n[o]))}return!1};var Ke=(e,n)=>{let t=[],r={},o;for(let a in e){let i=e[a];for(let s in i){let d=i[s];!o&&d?.eventScheduled===!0&&typeof d.uri=="string"&&d.uri.length>0&&!d.uri.includes("calendly.com")&&!d.uri.includes("cal.com")&&(o=d.uri),t.push({questionId:s,response:{...i[s]}})}}for(let a in n){let i=n[a];i.type!=="SCHEDULER_AVAILABILITY_DATA"&&(t.push({questionId:a,response:{...i}}),i.type==="APOLLO_EMAIL_ENRICHMENT"&&i.processed&&(r=i.data??{}))}return{responses:t,enrichedFields:r,bookingId:o}},Pt=({formId:e,answers:n,externalStates:t,submittingOnStepId:r,finished:o,invalidResponse:a,trackCookies:i,meta:s={},personAttributeEnrichedFields:d,fingerprint:l,leadSessionId:u})=>{let{responses:c,enrichedFields:p,bookingId:C}=Ke(n,t),y=i?s:Object.fromEntries(Object.entries(s).filter(([m])=>m!=="cookies"));return{responses:c,enrichedFields:d??p??{},formId:e,finished:o,invalidResponse:a,stepId:r,fingerprint:l,leadSessionId:u,meta:C?{...y,bookingId:C}:y}},Ie=e=>({...Pt(e),responseShapeVersion:"2.0"}),Y=e=>({...Pt(e),responseId:e.responseId});var Ee=({formId:e,environmentId:n,steps:t,transport:r,resolveNextStep:o,trackPartialResponses:a=!0,trackCookies:i=!1,externalStates:s={},meta:d={},identity:l,pushEvents:u,formJourney:c,preview:p=!1,resume:C})=>{if(t.length===0)throw new Error("createFormEngine requires at least one step");let y=o??(f=>{let I=t.findIndex(H=>H.id===f),$=t[I+1];return $?{stepId:$.id,reason:"linear"}:"END"}),m=be(),h=new Set,v=!0,g,L=()=>{v=!0,h.forEach(f=>f())},P=()=>l?.()??{},k={},T=t[0].id,U=C?.responseId??null,b=null;if(C?.answers){let f={};for(let[I,$]of Object.entries(C.answers))f[I]={...$};k[T]=f}let A=!1,x=null,O=!1,S=Date.now(),w=[],_=we(k);c?.setFormId(e),U!=null&&c?.setResponseId(U),c?.recordEntry(T);let q=async(f,I,$)=>{if(p)return;let H={formId:e,answers:k,externalStates:s,submittingOnStepId:f,finished:I,invalidResponse:$,trackCookies:i,meta:d,fingerprint:P().fingerprint,leadSessionId:P().leadSessionId};if(U==null){let K=await he(r,Ie(H));if(!K.ok){K.error.kind==="network"&&u?.push({type:"response_submission_error",entityType:"response",entityId:e,stepId:f,leadSessionId:P().leadSessionId,properties:[{key:"error",value:"network"}]}),m.emit("error",{scope:"submit",error:K.error});return}U=K.data.responseId,b=K.data.resumeToken,c?.setResponseId(U),u?.push({type:"response_submission_created",entityType:"response",entityId:e,stepId:f,leadSessionId:P().leadSessionId,properties:[{key:"responseId",value:U}]})}else if(I){let K=await At(r,Y({...H,responseId:U}));if(!K.ok){ee(r,Y({...H,responseId:U})),m.emit("error",{scope:"submit",error:K.error});return}}else ee(r,Y({...H,responseId:U}));L(),m.emit("saved",{responseId:U,finished:I,resumeToken:b})},F=Promise.resolve(),M=f=>{let I=F.then(()=>A?void 0:f());return F=I.catch(()=>{}),I},E=()=>{if(!A||x==null)return;let f=x;F=F.then(()=>{if(U!=null)return q(f.stepId,!0,f.invalid)}).catch(()=>{})},R=null,D=f=>{if(A)return Promise.resolve();if(R)return R;let I=M(()=>Zt(f)).finally(()=>{R===I&&(R=null)});return R=I,I},J=f=>{if(A||R)return R??Promise.resolve();let I=y(T,k),$=f||I==="END"||I==="INVALID"||I==null;return m.emit("stepCompleted",{stepId:T}),$?D(I==="INVALID"):(tt(I),Promise.resolve())},Ne=f=>{let I=T;for(;w.length>0&&T!==f;)T=w.pop();L(),c?.recordTransition({fromStepId:I,toStepId:T,reason:"back_nav"}),m.emit("stepChanged",{fromStepId:I,toStepId:T})},Yt=f=>t.some(I=>I.id===f)?A||R?R??Promise.resolve():f===T?Promise.resolve():w.includes(f)?(Ne(f),Promise.resolve()):(m.emit("stepCompleted",{stepId:T}),tt({stepId:f,reason:"conditional_match"}),Promise.resolve()):Promise.reject(new Error(`goToStep: no step with id "${f}"`)),Gt=()=>A||R?R??Promise.resolve():(m.emit("stepCompleted",{stepId:T}),D(!0)),tt=f=>{let I=T;u?.push(Se({sessionId:P().leadSessionId,formId:e,currentStepId:I,nextStepId:f.stepId,stepCompletionTime:(Date.now()-S)/1e3})),c?.recordTransition({fromStepId:I,toStepId:f.stepId,reason:f.reason??"linear"}),w.push(I),T=f.stepId,L(),m.emit("stepChanged",{fromStepId:I,toStepId:T}),a&&M(()=>q(I,!1,!1))},Xt=f=>{let I=t.find(H=>H.endStepKind===f);if(!I||I.id===T)return;let $=T;w.push($),T=I.id,L(),m.emit("stepChanged",{fromStepId:$,toStepId:T})},Zt=async f=>{let I=T;A=!0,x={stepId:I,invalid:f},await q(I,!0,f),Xt(f?"disqualified":"thank_you"),f?(c?.recordTerminal({outcome:"disqualified",disqualification:{reason:"conditional_match",atStepId:I}}),m.emit("disqualified",{stepId:I})):(c?.recordTerminal({outcome:"completed"}),u?.push({type:"form_completed",entityType:"form",entityId:e,stepId:null,leadSessionId:P().leadSessionId,properties:[],environmentId:n,leadId:P().leadId}),m.emit("completed",{formId:e})),L()};return{setAnswer:(f,I)=>{let $=k[T]??(k[T]={});$[f]={...$[f],...I},_(k)&&(u?.push({type:"form_started",entityType:"form",entityId:e,stepId:null,leadSessionId:P().leadSessionId,properties:[]}),m.emit("started",{formId:e})),L(),E()},setExternalState:(f,I)=>{s[f]=I,L(),E()},mergeMeta:f=>{Object.assign(d,f),E()},next:()=>J(!1),goToStep:Yt,submit:()=>J(!0),disqualify:Gt,back:()=>{if(A||R)return;let f=w.pop();if(f==null)return;let I=T;T=f,L(),c?.recordTransition({fromStepId:I,toStepId:f,reason:"back_nav"}),m.emit("stepChanged",{fromStepId:I,toStepId:f})},savePartial:()=>{let f=T;return M(()=>q(f,!1,!1))},notifyScheduler:f=>m.emit("scheduler",f),flush:()=>F.then(()=>{}),markViewed:()=>{O||(O=!0,u?.push({type:"form_viewed",entityType:"form",entityId:e,stepId:null,leadSessionId:P().leadSessionId,properties:[],environmentId:n,leadId:P().leadId}),u?.push({type:"form_step_viewed",entityType:"form_step",entityId:e,stepId:t[0].id,leadSessionId:P().leadSessionId,properties:[]}),m.emit("viewed",{formId:e}))},on:m.on,state:()=>(v&&(g={currentStepId:T,answers:k,externalStates:s,responseId:U,resumeToken:b,finished:A},v=!1),g),subscribe:f=>(h.add(f),()=>h.delete(f))}};var Mt=400,Fn=(e,n="https")=>!e||e.startsWith(n)?e:`${n}://${e}`,We=(e,{leadId:n,sessionId:t}={})=>{if(!e||!e.trim())return"";try{let r=new URL(Fn(e));return n&&r.searchParams.set("leadId",n),t&&r.searchParams.set("sessionId",t),r.toString()}catch{return e}},Lt=({url:e,redirectType:n="CurrentWindow",leadId:t,sessionId:r,preview:o=!1})=>{if(!e||o||typeof window>"u")return;let a=We(e,{leadId:t,sessionId:r});a&&(n==="CurrentWindow"?window.location.href=a:n==="NewTab"&&window.open(a,"_blank"))};var Je=e=>{let n=new URL(e);if(!n.search)return{};let t={};return new URLSearchParams(n.search).forEach((r,o)=>{t[o]=r}),t},Qe=e=>{let n={};for(let t of e.split(";")){let r=t.trim(),o=r.indexOf("=");if(o<=0)continue;let a=r.substring(o+1);try{n[r.substring(0,o)]=decodeURIComponent(a)}catch{n[r.substring(0,o)]=a}}return n},Te=({defaultUrl:e,trackCookies:n=!1}={})=>{let t=typeof window<"u",r={type:"URL_DATA",fullUrl:e??(t?window.location.href:void 0),referrer:t&&typeof document<"u"?document.referrer||"":void 0};if(r.fullUrl)try{r.params=Je(r.fullUrl)}catch{}return n?r.cookies=t&&typeof document<"u"?Qe(document.cookie):{}:r.cookies={},r};var ze=e=>{let n=e.indexOf("_");return{originalId:e,questionId:n>=0?e.slice(0,n).trim():e,fieldName:n>=0?e.slice(n+1).trim():null}},Dn=new Set(["url","referrer","cookies"]),Ot=e=>{let n=typeof e=="string"?new URLSearchParams(e):e,t=null;for(let r of n.keys()){if(Dn.has(r))continue;let{originalId:o,questionId:a,fieldName:i}=ze(r);if(i==null)continue;let s={originalId:o,questionId:a,fieldName:i,value:n.get(r)};t??(t=Object.create(null)),t[a]=[...t[a]??[],s]}return t};var Re=(e,n)=>{if(typeof window>"u")return()=>{};let t=r=>{let{started:o,formId:a,stepId:i,sessionId:s}=n();!o||r.persisted||e.push({type:"form_step_dropoff",entityType:"form_step",entityId:a,stepId:i,leadSessionId:s,properties:[]})};return window.addEventListener("pagehide",t),()=>window.removeEventListener("pagehide",t)};var Un="/api/v1/form-journey/track";var qn=new Set(["completed","disqualified","dropped_off","partial"]),Ae=({transport:e,preview:n=!1})=>{let t={responseId:null,formId:null,nextOrdinal:1,enteredAt:new Map,pendingClose:null,visits:[],truncated:!1,terminal:{},frozen:!1,flushScheduled:!1},r=()=>{t.flushScheduled=!1,!n&&(!t.responseId||!t.formId||t.visits.length===0&&!t.terminal.outcome||(e.beacon(Un,{responseId:t.responseId,formId:t.formId,events:t.visits,...t.terminal}),t.terminal={}))},o=()=>{t.flushScheduled||(t.flushScheduled=!0,queueMicrotask(()=>{t.flushScheduled&&r()}))},a=s=>{if(!t.pendingClose)return;let{ordinal:d,stepId:l}=t.pendingClose,u=t.enteredAt.get(d),c=t.visits.find(C=>C.ordinal===d),p=u?Date.parse(s)-Date.parse(u):null;c?(c.exitedAt=s,c.durationMs=p):t.visits.push({ordinal:d,stepId:l,enteredAt:u??s,exitedAt:s,durationMs:p,fromStepId:null,transitionReason:"initial"}),t.pendingClose=null},i=s=>t.visits.length>=50?(t.truncated=!0,!1):(t.visits.push(s),!0);return{hasRecordedTransition:()=>t.nextOrdinal>1,setResponseId:s=>{t.responseId=s,o()},setFormId:s=>{t.formId=s,o()},recordEntry:s=>{if(t.frozen||t.truncated)return;let d=(new Date).toISOString();t.nextOrdinal===1&&(t.enteredAt.set(1,d),t.pendingClose={ordinal:1,stepId:s},t.nextOrdinal=2)},recordTransition:({fromStepId:s,toStepId:d,reason:l,transitionMeta:u})=>{if(t.frozen||t.truncated)return;let c=(new Date).toISOString();a(c);let p=t.nextOrdinal++;t.enteredAt.set(p,c);let C=i({ordinal:p,stepId:d,enteredAt:c,exitedAt:null,durationMs:null,fromStepId:s,transitionReason:l,transitionMeta:u??null});t.pendingClose=C?{ordinal:p,stepId:d}:null,o()},recordTerminal:({outcome:s,disqualification:d})=>{if(t.frozen)return;let l=(new Date).toISOString();a(l),t.terminal={outcome:s,disqualification:d?{reason:d.reason,matched:d.matched}:void 0,disqualifiedAtStepId:d?.atStepId,disqualifiedTriggerStepId:d?.triggerStepId},qn.has(s)&&(t.frozen=!0),s==="in_progress"?r():o()}}};async function Ye(e){let n=(new TextEncoder).encode(e),t=await crypto.subtle.digest("SHA-256",n);return Array.from(new Uint8Array(t)).map(r=>r.toString(16).padStart(2,"0")).join("")}var _e=async e=>{let n=navigator.userAgentData||{},t={deviceType:/Mobi|Android/i.test(navigator.userAgent)?"Mobile":"Desktop",screen:{width:screen.width,height:screen.height,colorDepth:screen.colorDepth},userAgent:navigator.userAgent,browser:n.brands||n.uaList||[{brand:"unknown",version:"unknown"}],os:n.platform||"unknown",language:navigator.language,...navigator.plugins!=null?{plugins:Array.from(navigator.plugins).map(r=>r.name)}:{},timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,environmentId:e};return{...t,id:await Ye(JSON.stringify(t))}};var Nn="/api/v1/lead/identify",Ce=({environmentId:e,fingerprintId:n,pageUrl:t,source:r="sdkForm",formId:o,leadId:a=null,sessionIdFromParams:i=null,referrer:s})=>{let d=new URL(t);return{environmentId:e,source:r,sourceURL:d.href.replace(/\/$/,""),sourceURLDomain:d.hostname,sourceURLPath:d.pathname.replace(/\/$/,""),sourceUrlSearchParams:d.search,fingerprint:n,formId:o,leadId:a,sessionIdFromParams:i,...s!=null?{referrer:s}:{}}},xe=async(e,n)=>{let t=await e.post(Nn,n,{keepalive:!0,credentials:!0});if(!t.ok)return null;let r=t.data.data?.data;return!r?.leadId||!r?.sessionId?null:{leadId:r.leadId,sessionId:r.sessionId,existing:r.existing,leadHasExistingBookingAttr:r.leadHasExistingBookingAttr,leadHasExistingEmailAttr:r.leadHasExistingEmailAttr}};var te="surfaceLeadData",Ft=6e5,G=()=>{if(typeof localStorage>"u")return null;try{let e=localStorage.getItem(te);if(!e)return null;let n=JSON.parse(e);return Date.now()>(n.expiry??0)?(localStorage.removeItem(te),null):{leadId:n.leadId,leadSessionId:n.leadSessionId,fingerprint:n.fingerprint,landingPageUrl:n.landingPageUrl,expiry:n.expiry}}catch{return null}},Pe=e=>{if(!(typeof localStorage>"u"))try{localStorage.setItem(te,JSON.stringify({...e,expiry:Date.now()+6e5}))}catch{}};var ne=async({transport:e,environmentId:n,formId:t,pageUrl:r,source:o,preview:a=!1})=>{if(a||typeof window>"u")return null;let i=G();if(i?.leadSessionId&&i?.fingerprint)return i;let s=r??window.location.href,d=await _e(n),l=await xe(e,Ce({environmentId:n,fingerprintId:d.id,pageUrl:s,formId:t,source:o,leadId:i?.leadId??null,sessionIdFromParams:i?.leadSessionId??null}));if(l==null)return null;let u={leadId:l.leadId,leadSessionId:l.sessionId,fingerprint:d.id,landingPageUrl:s};return Pe(u),u};var re="surface_journey_id",oe="surface_recent_visit",$n=5184e3,Bn=86400,Dt="/api/v1/lead/track",Ut=e=>{if(typeof document>"u")return null;for(let n of document.cookie.split(";")){let t=n.trim(),r=t.indexOf("=");if(r===-1||t.substring(0,r)!==e)continue;let o=t.substring(r+1);try{return decodeURIComponent(o)}catch{return o}}return null},qt=(e,n,t,r)=>{if(typeof document>"u")return;let o=r?`; domain=${r}`:"";document.cookie=`${e}=${encodeURIComponent(n)}; path=/; max-age=${t}; samesite=lax${o}`},Ge=()=>{let e=typeof window>"u"?"":window.location?.hostname??"";if(!e||!e.includes("."))return;let n=e.split(".");return"."+(n.length===2?e:n.slice(1).join("."))},Me=({transport:e,environmentId:n})=>{let t=Ut(re),r=()=>{t&&qt(re,t,$n,Ge())},o=d=>{let l=G();return{...t?{id:t}:{},data:{type:"page_view",payload:{url:d,timestamp:(new Date).toISOString(),referrer:typeof document>"u"?"":document.referrer||""}},metadata:{environmentId:n,...l?{...l.leadId?{leadId:l.leadId}:{},...l.leadSessionId?{leadSessionId:l.leadSessionId}:{},fingerprint:l.fingerprint,...l.landingPageUrl?{landingPageUrl:l.landingPageUrl}:{}}:{}}}},a=async d=>{if(typeof window>"u")return;let l=d??window.location.href;if(Ut(oe)===l)return;let u=o(l);if(t&&e.beacon(Dt,u))r();else{let c=await e.post(Dt,u);c.ok&&c.data.data?.id&&(t=c.data.data.id),r()}qt(oe,l,Bn,Ge())};return{trackPageView:a,observeRouteChanges:()=>{if(typeof window>"u")return()=>{};let d=window.location.href,l=()=>{let p=window.location.href;p!==d&&(d=p,a(p))};window.addEventListener("popstate",l);let u=history.pushState,c=history.replaceState;return history.pushState=function(...p){u.apply(history,p),setTimeout(l,0)},history.replaceState=function(...p){c.apply(history,p),setTimeout(l,0)},()=>{window.removeEventListener("popstate",l),history.pushState=u,history.replaceState=c}},clear:()=>{let d=Ge(),l=d?`; domain=${d}`:"";typeof document>"u"||(document.cookie=`${re}=; path=/; max-age=0; samesite=lax${l}`,document.cookie=`${oe}=; path=/; max-age=0; samesite=lax${l}`,t=null)}}};var Vn="/api/v1/services/enrichment/realtime",Le="selfServeEnrichment";var jn=/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/,Hn=/^(?:https?:\/\/)?(?:www\.)?([a-z0-9-]+(?:\.[a-z0-9-]+)+)/i,Nt=e=>{let n=e.trim();if(jn.test(n))return{email:n};let t=n.match(Hn)?.[1];return t?{domain:t}:null},Oe=({engine:e,transport:n,formId:t,sources:r})=>{let o=new Set,a=new Set,i,s,d=!1,l=async y=>{let m=Nt(y);if(!m)return;let h=m.email??m.domain;if(!(o.has(h)||a.has(h))){a.add(h);try{let v=await n.post(Vn,{formId:t,...m});if(d||!v.ok)return;let g=v.data.data??{};if(Object.keys(g).length===0)return;o.add(h);let L=e.state().externalStates[Le],P=L?.type==="APOLLO_EMAIL_ENRICHMENT"?L.data??{}:{};e.setExternalState(Le,{type:"APOLLO_EMAIL_ENRICHMENT",processed:!0,data:{...g,...P}})}finally{a.delete(h)}}},u=()=>{let y=[],m={};for(let h of Object.values(e.state().answers))Object.assign(m,h);for(let{questionId:h,fieldNames:v}of r){let g=m[h];if(g)for(let L of v){let P=g[L];typeof P=="string"&&P.trim().length>0&&y.push(P)}}return y},c=()=>{let y=u().find(m=>{let h=Nt(m);return h!=null&&!o.has(h.email??h.domain)});y===void 0||y===s||(s=y,clearTimeout(i),i=setTimeout(()=>{s=void 0,l(y)},1e3))},p=()=>{if(s===void 0)return;clearTimeout(i);let y=s;s=void 0,l(y)},C=[e.subscribe(c),e.on("stepCompleted",p),e.on("completed",p)];return()=>{d=!0,clearTimeout(i),C.forEach(y=>y())}};var Kn=new Set(["MultipleOptionsQuestion","MultipleChoiceQuestion","MMChoiceQuestion"]),Wn=(e,n)=>typeof e=="object"&&e!==null&&typeof e.key=="string"&&typeof e.value=="boolean"&&(!n||typeof e.index=="number"),$t=({questions:e,questionId:n,merged:t})=>{let r=`Surface SDK [debug]: setAnswer("${n}")`,o=e.size>0?e.get(n):void 0;if(e.size>0&&!o){console.warn(`${r} — the record has no stateful question with this id; the answer will be dropped.`),console.debug(`Surface SDK [debug]: answer ${n}`,t);return}t.type===void 0?console.warn(`${r} — state has no "type" discriminator; the wire schema rejects untyped states. Include type: "${o?.componentType??"<ComponentType>"}".`):o?.componentType!==void 0&&t.type!==o.componentType&&console.warn(`${r} — state type "${String(t.type)}" but the record's component is ${o.componentType}.`);let a=o?.componentType??t.type;if(typeof a=="string"&&Kn.has(a)){let i=a==="MultipleOptionsQuestion";(!Array.isArray(t.choices)||t.choices.some(d=>!Wn(d,i)))&&console.warn(`${r} — ${a} answers need the ENTIRE option list under "choices" as {key, value${i?", index":""}} objects, not ${JSON.stringify(t.choices??t)}. See get_sdk_binding_map's answerShape.`)}console.debug(`Surface SDK [debug]: answer ${n}`,t)};var Jn="Lead",Qn="generate_lead",zn="lead_created",jt=/^tw-([a-z0-9]+)-([a-z0-9]+)$/i,Yn=e=>{let n=e?.trim().match(jt);return n?n[1]:null},Bt=e=>/^\d+$/.test(e?.trim()??""),Gn=e=>{if(e.enabled===!1||(e.trigger??"reached_qualified")==="reached_step"&&!e.triggerStepId?.trim())return!1;switch(e.provider){case"x":return jt.test(e.eventId?.trim()??"");case"meta":case"openai":return!!e.pixelId?.trim();case"ga4":return!!e.measurementId?.trim();case"linkedin":return Bt(e.partnerId)&&Bt(e.conversionId);default:return!1}},Xn=(e,n)=>{let t=n.toLowerCase();for(let[r,o]of Object.entries(e))if(r.toLowerCase()===t)return o},Vt=(e,n)=>{let t=Xn(n,e.param)?.trim()??"",r=e.values??[];switch(e.operator){case"is_present":return t.length>0;case"equals_any":return r.some(o=>o.trim().toLowerCase()===t.toLowerCase());case"contains":return t.length>0&&r.some(o=>t.toLowerCase().includes(o.trim().toLowerCase()));default:return!1}},Zn=(e,n,t="and")=>e.length===0?!0:t==="or"?e.some(r=>Vt(r,n)):e.every(r=>Vt(r,n)),er=e=>{if(!Gn(e))return null;switch(e.provider){case"x":{let n=Yn(e.eventId);return n?{provider:"x",event:{event_id:e.eventId.trim(),pixel_id:n}}:null}case"meta":return{provider:"meta",event:{pixel_id:e.pixelId.trim(),event_name:e.eventName?.trim()||Jn}};case"openai":return{provider:"openai",event:{pixel_id:e.pixelId.trim(),event_name:e.eventName?.trim()||zn}};case"ga4":return{provider:"ga4",event:{measurement_id:e.measurementId.trim(),event_name:e.eventName?.trim()||Qn}};case"linkedin":return{provider:"linkedin",event:{partner_id:e.partnerId.trim(),conversion_id:e.conversionId.trim()}};default:return null}},Fe=(e,n,t,r)=>{let o=[];for(let a of e){if((a.trigger??"reached_qualified")!==n||n==="reached_step"&&(!r||a.triggerStepId!==r)||!Zn(a.conditions??[],t,a.conditionsOperator??"and"))continue;let i=er(a);i&&o.push({rule:a,conversion:i})}return o},tr=(e,n)=>{if(!e.twq){let t=e.twq=function(...o){t.exe?t.exe.apply(t,o):t.queue.push(o)};t.version="1.1",t.queue=[];let r=e.document.createElement("script");r.async=!0,r.src="https://static.ads-twitter.com/uwt.js",e.document.head.appendChild(r)}e.twq("config",n)},nr=(e,n)=>{if(!e.fbq){let t=e.fbq=function(...o){t.callMethod?t.callMethod.apply(t,o):t.queue.push(o)};e._fbq||(e._fbq=t),t.push=t,t.loaded=!0,t.version="2.0",t.queue=[];let r=e.document.createElement("script");r.async=!0,r.src="https://connect.facebook.net/en_US/fbevents.js",e.document.head.appendChild(r)}e.fbq("init",n)},rr=(e,n)=>{if(!e.oaiq){let t=e.oaiq=function(...o){t.q.push(o)};t.q=[];let r=e.document.createElement("script");r.async=!0,r.src="https://bzrcdn.openai.com/sdk/oaiq.min.js",e.document.head.appendChild(r)}e.oaiq("init",{pixelId:n})},or=(e,n)=>{if(!e.gtag){e.dataLayer=e.dataLayer||[],e.gtag=function(...r){e.dataLayer.push(r)};let t=e.document.createElement("script");t.async=!0,t.src=`https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(n)}`,e.document.head.appendChild(t),e.gtag("js",new Date)}e.gtag("config",n,{send_page_view:!1})},sr=(e,n)=>{if(!e.lintrk){e._linkedin_partner_id=n;let t=e.lintrk=function(o,a){t.q.push([o,a])};t.q=[];let r=e.document.createElement("script");r.async=!0,r.src="https://snap.licdn.com/li.lms-analytics/insight.min.js",e.document.head.appendChild(r)}e._linkedin_data_partner_ids=e._linkedin_data_partner_ids||[],e._linkedin_data_partner_ids.includes(n)||e._linkedin_data_partner_ids.push(n)},Ht=(e,n,t)=>{let r=e;try{switch(n.provider){case"x":return tr(r,n.event.pixel_id),r.twq("event",n.event.event_id,{conversion_id:t.responseId,...t.twclid?{twclid:t.twclid}:{},...t.email?{email_address:t.email}:{}}),!0;case"meta":return nr(r,n.event.pixel_id),r.fbq("track",n.event.event_name,{},{eventID:t.responseId}),!0;case"openai":return rr(r,n.event.pixel_id),r.oaiq("measure",n.event.event_name,{type:"customer_action"},{event_id:t.responseId}),!0;case"ga4":return or(r,n.event.measurement_id),r.gtag("event",n.event.event_name,{transaction_id:t.responseId,send_to:n.event.measurement_id}),!0;case"linkedin":return sr(r,n.event.partner_id),r.lintrk("track",{conversion_id:n.event.conversion_id}),!0;default:return!1}}catch{return!1}};var Xe=(e,n)=>e.document.querySelector(`script[src="${n}"]`)!=null,De=(e,n,t,r)=>{if(Xe(e,n))return;let o=e.document.createElement("script");o.async=!0,o.src=n,r&&(o.id=r),e.document[t].appendChild(o)},ir=(e,n)=>{let t=`https://www.googletagmanager.com/gtm.js?id=${encodeURIComponent(n)}`;Xe(e,t)||(e.dataLayer=e.dataLayer||[],e.dataLayer.push({"gtm.start":(new Date).getTime(),event:"gtm.js"}),De(e,t,"head"))},ar=(e,n)=>{let t=`https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(n)}`;if(Xe(e,t))return;e.dataLayer=e.dataLayer||[],e.gtag||(e.gtag=function(){e.dataLayer.push(arguments)},e.gtag("js",new Date)),De(e,t,"head");let r=e.self!==e.top;e.gtag("config",n,{...r&&{cookie_flags:"SameSite=None;Secure;Partitioned"}})},dr=(e,n)=>{if(!e.fbq){let t=e.fbq=function(...r){t.callMethod?t.callMethod.apply(t,r):t.queue.push(r)};e._fbq||(e._fbq=t),t.push=t,t.loaded=!0,t.version="2.0",t.queue=[],De(e,"https://connect.facebook.net/en_US/fbevents.js","head")}e.fbq("init",n)},lr=(e,n)=>{De(e,`https://js.hs-scripts.com/${n}.js`,"body","hs-script-loader")},Kt=(e,n)=>{let t=e;n.gtmId&&ir(t,n.gtmId),n.gaMeasurementId&&ar(t,n.gaMeasurementId),n.metaPixelId&&dr(t,n.metaPixelId),n.hubspotTracking?.trackingId&&lr(t,n.hubspotTracking.trackingId);let r=i=>{n.gtmId&&(t.dataLayer=t.dataLayer||[],t.dataLayer.push(i))},o=(i,s)=>{n.gaMeasurementId&&t.gtag?.("event",i,s)},a=(i,s)=>{n.metaPixelId&&t.fbq?.("trackCustom",i,s)};return{formStarted:(i,s)=>{r({event:"SurfaceFormStarted",formId:i,...s}),a("SurfaceFormStarted",{formId:i,...s}),o("SurfaceFormStarted",{formId:i,...s})},stepSubmitted:i=>{r({event:"SurfaceFormStepSubmitted",...i}),a("SurfaceFormStepSubmitted",i),o("SurfaceFormStepSubmitted",i)},formCompleted:(i,s)=>{r({event:"SurfaceFormSubmitEvent",formId:i,...s}),a("SurfaceFormCompleted",{formId:i,...s}),o("SurfaceFormCompleted",{formId:i,...s})}}};var ur=e=>{try{return Object.fromEntries(new URLSearchParams(e.location.search).entries())}catch{return{}}},Ue=(e,n)=>{let t=n.toLowerCase();for(let[r,o]of Object.entries(e))if(r.toLowerCase()===t)return o?.trim()||void 0},cr=e=>({twclid:Ue(e,"twclid"),fbclid:Ue(e,"fbclid"),gclid:Ue(e,"gclid"),li_fat_id:Ue(e,"li_fat_id")}),pr=["email","emailAddress","workEmailAddress"],Ze=e=>{for(let n of Object.values(e))for(let t of pr){let r=n[t];if(typeof r=="string"&&r.trim().length>0)return r.trim()}},Wt=e=>Object.values(e).some(n=>n.eventScheduled===!0),et=e=>{let n={};for(let t of Object.values(e.state().answers))Object.assign(n,t);return n},Jt=({engine:e,formId:n,settings:t,win:r})=>{let o=r??window,a=Kt(o,t),i=t.adsConversions??[],s=ur(o),d={url:o.location.href,urlParams:s},l=new Set,u=new Set,c=new Set,p=new Set,C=!1,y=!1,m=!1,h=!1,v=!1,g=e.state().responseId==null,L=!g,P=(S,w)=>{let _=S.filter(({rule:F})=>!l.has(F.id));if(_.length===0)return;_.forEach(({rule:F})=>l.add(F.id));let q={responseId:w,email:Ze(et(e)),...cr(s)};_.forEach(({conversion:F})=>Ht(o,F,q))},k=(S,w)=>{if(!w){p.add(S);return}P(Fe(i,S,s),w)},T=(S,w)=>{if(!w){c.add(S);return}P(Fe(i,"reached_step",s,S),w)},U=S=>{if(!S){C=!0;return}y=!0,C=!1;let w=new Map;for(let _ of["reached_qualified","form_submitted"])for(let q of Fe(i,_,s))w.set(q.rule.id,q);P(Array.from(w.values()),S)},b=()=>{let S=et(e);!h&&g&&Ze(S)!==void 0&&(h=!0,k("email_provided",e.state().responseId)),!v&&g&&Wt(S)&&(v=!0,k("meeting_booked",e.state().responseId))},A=[];A.push(e.on("started",()=>{a.formStarted(n,d)}));let x;A.push(e.on("stepCompleted",({stepId:S})=>{let w=et(e);x={stepId:S,formId:n,emailProvided:Ze(w)!==void 0,meetingBooked:Wt(w),...d},!m&&g&&(m=!0,k("step_submitted",e.state().responseId))})),A.push(e.on("stepChanged",({toStepId:S})=>{x&&(e.state().finished||a.stepSubmitted(x),x=void 0),!u.has(S)&&(u.add(S),T(S,e.state().responseId))})),A.push(e.on("completed",()=>{x=void 0,a.formCompleted(n,d),y||U(e.state().responseId)})),A.push(e.on("saved",({responseId:S})=>{if(L||(L=!0,k("form_started",S)),C&&U(S),c.size>0){let w=Array.from(c);c.clear(),w.forEach(_=>T(_,S))}if(p.size>0){let w=Array.from(p);p.clear(),w.forEach(_=>k(_,S))}})),A.push(e.subscribe(b));let O=e.state().currentStepId;return u.add(O),T(O,e.state().responseId),b(),()=>A.forEach(S=>S())};var mr=["email","emailAddress","workEmailAddress"],fr=/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/,qe=({engine:e,validator:n})=>{let t=new Set,r=new Map,o,a=!1,i,s=!1,d=()=>{let y=[];for(let m of Object.values(e.state().answers))for(let h of Object.values(m))for(let v of mr){let g=h[v];typeof g=="string"&&fr.test(g.trim())&&y.push(g.trim())}return y},l=()=>{let y=new Set(d()),m=[...r.values()].filter(g=>y.has(g.email));if(m.length===0)return;let h=JSON.stringify(m.map(g=>[g.email,g.isValid,g.failed===!0]));if(h===i)return;i=h;let v=m.find(g=>g.status&&g.reason);e.mergeMeta({isEmailValid:m.some(g=>g.isValid),emailValidation:v?{status:v.status,reason:v.reason,...v.blacklistEntryIds?.length&&{blacklistEntryIds:v.blacklistEntryIds}}:void 0,emailValidationFailed:m.some(g=>g.failed===!0)})},u=async()=>{let y=d().filter(h=>!t.has(h));if(y.length===0)return;y.forEach(h=>t.add(h));let m=await n.validateBatch(y);s||(m.forEach(h=>r.set(h.email,h)),l())},c=()=>{if(!d().some(y=>!t.has(y))){l();return}a=!0,clearTimeout(o),o=setTimeout(()=>{a=!1,u()},300)},p=()=>{a&&(a=!1,clearTimeout(o),u())},C=[e.subscribe(c),e.on("stepCompleted",p),e.on("completed",p)];return()=>{s=!0,clearTimeout(o),C.forEach(y=>y())}};var Qt=new Set(["surfaceTagStatus","isEmailValid","emailValidation","emailValidationFailed"]),gr=new Set(["CalendlyScreen","DynamicScheduler","FileUploader"]),zt={init:async({environmentId:e,formId:n,steps:t,settings:r={},apiBaseUrl:o,container:a,expectedQuestionIds:i,resolveNextStep:s,urlDataStateId:d,source:l,journey:u=!1,emailValidation:c=!1,preview:p=!1,previewToken:C,debug:y=!1,resume:m,meta:h})=>{let v=ve({apiBaseUrl:o}),g;if(!t){let M=await de(v,n,{preview:p,previewToken:C});if(!M.ok||!M.data.data){let R=(o??z).replace(/\/$/,""),D=M.ok?"empty response":M.error.kind==="http"?`HTTP ${M.error.status}`:"network error";throw new Error(`SurfaceForms.init: could not fetch runtime config for form "${n}" (${D} from ${R}/api/v1/public/forms/${n}/runtime-config). If this environment is not served from ${z}, pass apiBaseUrl — the get_sdk_binding_map MCP tool returns the correct value.`)}g=M.data.data,t=ue(g.config),i=i??Q(g.config).filter(R=>!gr.has(R.componentType??"")).map(R=>R.questionId);let E=g.settings??{};r={trackPartialResponses:E.trackPartialResponses,trackCookies:E.trackCookie,gtmId:E.gtmId,gaMeasurementId:E.gaMeasurementId,metaPixelId:E.metaPixelId,hubspotTracking:E.hubspotTracking,adsConversions:E.adsConversions,...r}}let L=r.trackCookies??!1,P;if(m&&!p){let M=await _t(v,m);M.ok?P={responseId:m.responseId,answers:Object.fromEntries(M.data.answers.map(E=>[E.questionId,E.response]))}:console.warn(`Surface SDK: resume fetch for response "${m.responseId}" failed — starting a fresh session.`)}let k=await ne({transport:v,environmentId:e,formId:n,source:l,preview:p}),T=ke({transport:v,preview:p}),U=Ae({transport:v,preview:p}),b=Ee({formId:n,environmentId:e,steps:t,transport:v,resolveNextStep:s,trackPartialResponses:r.trackPartialResponses??!0,trackCookies:L,externalStates:d?{[d]:Te({trackCookies:L})}:{},meta:{...h,surfaceTagStatus:"sdk"},identity:()=>({fingerprint:k?.fingerprint,leadSessionId:k?.leadSessionId??void 0,leadId:k?.leadId??void 0}),pushEvents:T,formJourney:U,preview:p,resume:P}),A=[],x=b;if(y){let M=new Map((g?Q(g.config):[]).map(R=>[R.questionId,R])),E=(R,D)=>(...J)=>(console.debug(`Surface SDK [debug]: ${R} requested from step ${b.state().currentStepId}`),D(...J));x={...b,setAnswer:(R,D)=>{let J=b.state().currentStepId;b.setAnswer(R,D);let Ne=b.state().answers[J]?.[R]??D;$t({questions:M,questionId:R,merged:Ne})},next:E("next",b.next),back:E("back",b.back),goToStep:E("goToStep",b.goToStep),submit:E("submit",b.submit),disqualify:E("disqualify",b.disqualify)};for(let R of["viewed","started","stepChanged","stepCompleted","completed","disqualified","saved","error","scheduler"])A.push(b.on(R,D=>console.debug(`Surface SDK [debug]: ${R}`,D)))}let O=!1;A.push(b.on("started",()=>{O=!0})),A.push(Re(T,()=>({started:O,formId:n,stepId:b.state().currentStepId,sessionId:k?.leadSessionId??void 0}))),a&&A.push(ie({engine:x,root:a,expectedQuestionIds:i}));let S=!!r.gtmId||!!r.gaMeasurementId||!!r.metaPixelId||!!r.hubspotTracking?.trackingId||(r.adsConversions?.length??0)>0;S&&!p&&typeof window<"u"&&A.push(Jt({engine:b,formId:n,settings:r}));let w=g?ce(g.config):[],_=g!=null&&w.length>0&&me(g.settings);_&&!p?A.push(Oe({engine:b,transport:v,formId:n,sources:w})):y&&g&&!_&&dt(g.config)&&console.warn("Surface SDK: the record declares an enrichmentSourceField, but this environment has no enabled enrichment provider — no enrichment will run (capabilities.enrichment is false).");let q=ye({transport:v,environmentId:e,preview:p});c&&!p&&A.push(qe({engine:b,validator:q}));let F;return u&&!p&&(F=Me({transport:v,environmentId:e}),F.trackPageView(),A.push(F.observeRouteChanges())),{setAnswer:x.setAnswer,setExternalState:b.setExternalState,next:x.next,back:x.back,goToStep:x.goToStep,submit:x.submit,disqualify:x.disqualify,savePartial:b.savePartial,notifyScheduler:b.notifyScheduler,flush:b.flush,markViewed:b.markViewed,mergeMeta:M=>{let E=Object.entries(M),R=E.filter(([D])=>Qt.has(D));R.length>0&&console.warn(`Surface SDK: mergeMeta dropped reserved key(s) ${R.map(([D])=>D).join(", ")} — these are SDK-owned response markers.`),b.mergeMeta(Object.fromEntries(E.filter(([D])=>!Qt.has(D))))},capabilities:{enrichment:_,emailValidation:c,tracking:S},on:b.on,state:b.state,subscribe:b.subscribe,identify:async()=>{let M=await ne({transport:v,environmentId:e,formId:n,source:l,preview:p});return M&&(k=M),M},validateEmail:q.validate,runtimeConfig:g,transport:v,identity:()=>({fingerprint:k?.fingerprint,leadSessionId:k?.leadSessionId??void 0,leadId:k?.leadId??void 0}),preview:p,destroy:()=>A.forEach(M=>M())}}};return sn(yr)})();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Transport } from "../../core/client/transport";
|
|
2
2
|
import type { ProviderContext } from "./types";
|
|
3
3
|
|
|
4
|
+
|
|
4
5
|
export declare const withProtocol: (url: string) => string;
|
|
5
6
|
|
|
6
7
|
export declare const buildEmbedUrl: (dataUrl: string, params: Record<string, string | undefined>) => string | null;
|
|
@@ -59,10 +59,12 @@ export type FormEngine = {
|
|
|
59
59
|
} & Record<string, unknown>) => void;
|
|
60
60
|
|
|
61
61
|
mergeMeta: (partial: Record<string, unknown>) => void;
|
|
62
|
+
|
|
62
63
|
next: () => Promise<void>;
|
|
63
64
|
back: () => void;
|
|
64
65
|
|
|
65
66
|
goToStep: (stepId: string) => Promise<void>;
|
|
67
|
+
|
|
66
68
|
submit: () => Promise<void>;
|
|
67
69
|
|
|
68
70
|
disqualify: () => Promise<void>;
|
package/docs/api.md
CHANGED
|
@@ -64,7 +64,7 @@ Full method semantics, event payloads, and delivery guarantees:
|
|
|
64
64
|
| Member | Signature | Semantics |
|
|
65
65
|
| ------------------------------------ | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
66
66
|
| `setAnswer` | `(questionId, state) => void` | Merges a partial state into the question's answer. Use the typed answer states (§6) — wrong shapes are the classic production 400. |
|
|
67
|
-
| `next` / `back` | `() => Promise<void>` / `() => void` | Linear advance
|
|
67
|
+
| `next` / `back` | `() => Promise<void>` / `() => void` | Linear advance — switches the step immediately and resolves on the step change; the partial save (stamped with the step being LEFT) lands behind it / rewind (never writes). |
|
|
68
68
|
| `goToStep` | `(stepId) => Promise<void>` | Customer-owned routing: forward jumps save like `next()`; jumps to a visited step rewind like `back()`. Rejects unknown ids. |
|
|
69
69
|
| `submit` | `() => Promise<void>` | Finishes the form. **The terminal write is awaited** — when this resolves (and `saved` fires with `finished: true`), the server has the finished response; a delivery failure emits `error` instead. Then reveals the record's `thank_you` step. |
|
|
70
70
|
| `disqualify` | `() => Promise<void>` | Finishes as disqualified (`invalidResponse: true`); reveals the `disqualified` ending. |
|
|
@@ -186,9 +186,12 @@ Semantics that matter:
|
|
|
186
186
|
|
|
187
187
|
- Partial saves happen on forward movement only, stamped with the step being
|
|
188
188
|
left; the first forward move creates the response, later moves update it.
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
189
|
+
They run BEHIND the step change — `next()`/`goToStep()` never wait on the
|
|
190
|
+
network.
|
|
191
|
+
- Every write runs through one queue (the first move's create settles the
|
|
192
|
+
responseId before any update needs it). Finishing is the only navigation
|
|
193
|
+
that waits; a re-entrant `submit()`/`next()`/`disqualify()` while a finish
|
|
194
|
+
is pending joins it, and nothing writes after the finishing submit.
|
|
192
195
|
- The FINISHING write is an awaited `fetch(keepalive)`; partial updates are
|
|
193
196
|
beacons. A failed terminal write emits `error` (with a best-effort beacon
|
|
194
197
|
fallback) and never fires `saved`.
|
|
@@ -315,7 +318,8 @@ dependency; the main entry is React-free.
|
|
|
315
318
|
throwing; event-handler exceptions are isolated.
|
|
316
319
|
- **Preview writes nothing**: identify, responses, events, journey, enrichment,
|
|
317
320
|
tracking, and email validation (synthetic verdicts) are all blocked.
|
|
318
|
-
- **Delivery**:
|
|
321
|
+
- **Delivery**: the finishing update is awaited; the create and mid-form
|
|
322
|
+
updates run behind the step change (navigation never waits on the network)
|
|
319
323
|
and analytics are beacon-first fire-and-forget. `flush()` before
|
|
320
324
|
programmatic teardown.
|
|
321
325
|
- Send `X-Surface-Sdk-Version` on everything — visible server-side for rate
|
package/docs/reference/engine.md
CHANGED
|
@@ -85,12 +85,15 @@ resumeToken, finished}`. The snapshot is cached until the next mutation, so it i
|
|
|
85
85
|
|
|
86
86
|
### Write serialization + delivery
|
|
87
87
|
|
|
88
|
-
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
-
|
|
93
|
-
|
|
88
|
+
- Navigation is synchronous: `next()`/`goToStep()` switch the step and resolve immediately; the
|
|
89
|
+
partial save is queued behind the transition. Finishing is the only navigation that waits, and
|
|
90
|
+
a re-entrant `submit()`/`next()`/`disqualify()` while a finish is pending joins it (a
|
|
91
|
+
double-clicked submit finishes once; submit intent never dropped).
|
|
92
|
+
- One queue serializes every write; queued writes re-check `finished` when they run, so nothing
|
|
93
|
+
writes after the finishing submit.
|
|
94
|
+
- First forward write CREATES the response (`POST /api/v1/responses/`, credentialed, settled
|
|
95
|
+
before any later write runs); later writes UPDATE it. Every write resends the FULL answer set +
|
|
96
|
+
external states.
|
|
94
97
|
- A failed create: `error` event; `response_submission_error` pushEvent only for network-kind
|
|
95
98
|
failures (the server logs HTTP-level ones itself); the responseId stays null (the next write
|
|
96
99
|
retries the create).
|
package/llms.txt
CHANGED
|
@@ -136,9 +136,18 @@ Markers, most specific wins, ONE per element:
|
|
|
136
136
|
|
|
137
137
|
A `<form>` container's native submit also finishes. Conditional branching =
|
|
138
138
|
your JS choosing which goto button to show, or calling the API below. Driving
|
|
139
|
-
navigation/submit entirely from JS (
|
|
140
|
-
Put `data-surface-nav="js"` on any element — it tells
|
|
141
|
-
the page submits in code, silencing its advance/submit
|
|
139
|
+
navigation/submit entirely from JS (custom branching, an owner-requested
|
|
140
|
+
gate)? Put `data-surface-nav="js"` on any element — it tells
|
|
141
|
+
`validate_form_html` the page submits in code, silencing its advance/submit
|
|
142
|
+
warnings.
|
|
143
|
+
|
|
144
|
+
Timing: `next()`/`goToStep()` switch the step IMMEDIATELY and resolve on the
|
|
145
|
+
step change — the partial save runs behind it (`saved`/`error` report it). A
|
|
146
|
+
visitor never waits on a partial save, so don't disable the CTA for one, and
|
|
147
|
+
don't put async work of your own in front of the step change unless the form
|
|
148
|
+
owner asked for a gate (see Email validation). `submit()`/`disqualify()` are
|
|
149
|
+
the one wait: they await the finishing write before the ending step shows —
|
|
150
|
+
disable that button while the promise is pending.
|
|
142
151
|
|
|
143
152
|
Finishing reveals the record's matching ending step: after the terminal write,
|
|
144
153
|
`submit()` moves to the step with `endStepKind: "thank_you"` and `disqualify()`
|
|
@@ -166,10 +175,12 @@ answer (booking prefill, a summary screen) indexes by that step's id:
|
|
|
166
175
|
|
|
167
176
|
Delivery guarantees: the FINISHING write is awaited — when `submit()` resolves
|
|
168
177
|
(and `saved` fires with `finished: true`) the server has the finished response;
|
|
169
|
-
a failure emits `error` instead of lying.
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
178
|
+
a failure emits `error` instead of lying. Partial saves never block: `next()`
|
|
179
|
+
resolves on the step change and the write lands behind it — the first one
|
|
180
|
+
creates the response and settles `responseId` (later writes queue behind it),
|
|
181
|
+
the rest are fire-and-forget beacons reconciled server-side. `await
|
|
182
|
+
form.flush()` before tearing the page down programmatically (SPA unmount, test
|
|
183
|
+
harness closing the browser) so no queued write is cut off.
|
|
173
184
|
|
|
174
185
|
`mergeMeta(partial)` records caller-computed values (a qualification score, an
|
|
175
186
|
experiment bucket) onto the response `meta` — they ride the next save, or amend
|
|
@@ -210,31 +221,38 @@ wire shapes; during development, `debug: true` audits them at runtime too.
|
|
|
210
221
|
|
|
211
222
|
## Email validation
|
|
212
223
|
|
|
224
|
+
Two mechanisms share one per-address verdict cache (an address is billed once
|
|
225
|
+
no matter which path asks). Automatic mode — `emailValidation: true` on
|
|
226
|
+
`init` — validates email answers as they're captured (debounced) and writes
|
|
227
|
+
the same `meta` verdict keys native forms write (`isEmailValid`,
|
|
228
|
+
`emailValidation`, `emailValidationFailed`) for dashboards and workflows.
|
|
213
229
|
`form.validateEmail(email)` resolves the server-side deliverability verdict
|
|
214
230
|
(provider waterfall + the environment's spam blacklist; keys stay
|
|
215
|
-
server-side): `{ isValid, status, reason, failed? }`.
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
`
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
231
|
+
server-side) on demand: `{ isValid, status, reason, failed? }`.
|
|
232
|
+
|
|
233
|
+
**What happens on an invalid address is the form owner's decision — ask
|
|
234
|
+
before authoring, never assume.** The default is ANNOTATE ONLY: pass
|
|
235
|
+
`emailValidation: true`, let the visitor continue, and the response carries
|
|
236
|
+
`isEmailValid: false` for the owner's workflows and lead scoring to act on.
|
|
237
|
+
Automatic mode never blocks navigation or submission, and the visitor never
|
|
238
|
+
waits on a verdict. Only when the owner explicitly wants a gate do you call
|
|
239
|
+
`validateEmail` in your own navigation:
|
|
223
240
|
|
|
224
241
|
```js
|
|
242
|
+
// Owner chose BLOCK: keep the visitor on the step with a message.
|
|
225
243
|
const { isValid, reason, failed } = await form.validateEmail(emailInput.value);
|
|
226
244
|
if (isValid) form.next();
|
|
227
245
|
else showError(`Email rejected: ${reason}`);
|
|
246
|
+
// Owner chose DISQUALIFY: form.disqualify() instead of showError.
|
|
228
247
|
```
|
|
229
248
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
`validateEmail` in your own navigation as above. Preview resolves synthetic valid verdicts with no
|
|
249
|
+
Verdicts FAIL OPEN: when no validator can run, the result is
|
|
250
|
+
`{ isValid: true, failed: true, status: "unknown" }` — never lock a visitor
|
|
251
|
+
out on a vendor outage. Two consequences to design for: (1) check `failed` if
|
|
252
|
+
you want to soft-warn instead of hard-block; (2) the same address can be
|
|
253
|
+
accepted today (fail-open) and return a definitive `invalid` tomorrow — that's
|
|
254
|
+
the waterfall resolving, not a bug; don't write tests that assume a fixed
|
|
255
|
+
verdict for a fresh domain. Preview resolves synthetic valid verdicts with no
|
|
238
256
|
network. Offline callers wire it themselves: `createEmailValidator({
|
|
239
257
|
transport, environmentId })` and optionally `attachEmailValidation({ engine,
|
|
240
258
|
validator })`.
|
package/package.json
CHANGED