@lockerverse/react 0.2.154-dev.1 → 0.2.155

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.
@@ -1,6 +1,6 @@
1
1
  import { i as LockerversePaymentProps } from "./types.js";
2
- import "react";
3
- import { LockerverseCatalog, LockerverseCheckoutClient } from "@lockerverse/sdk/checkout";
2
+ import { RefObject } from "react";
3
+ import { LockerverseCatalog, LockerverseCheckoutClient, LockerverseCheckoutEstimate, LockerverseCheckoutItem, LockerversePreparedCheckout } from "@lockerverse/sdk/checkout";
4
4
  //#region src/lockerverse-payment.d.ts
5
5
  declare function LockerversePayment({ widget, ...viewProps }: LockerversePaymentProps): import("react").JSX.Element;
6
6
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"payment-form.d.ts","names":[],"sources":["../src/lockerverse-payment.tsx","../src/payment-form.tsx"],"mappings":";;;;iBAgYgB,qBACd,WACG,aACF,0CAAuB,IAAA;;;iBCxUV,0BACd,SAAS,KAAK,iCAA8B,oCAAA"}
1
+ {"version":3,"file":"payment-form.d.ts","names":[],"sources":["../src/lockerverse-payment.tsx","../src/payment-form.tsx"],"mappings":";;;;iBAmYgB,qBACd,WACG,aACF,0CAAuB,IAAA;;;iBC1UV,0BACd,SAAS,KAAK,iCAA8B,oCAAA"}
@@ -0,0 +1,113 @@
1
+ import { a as createCustomFieldValues, c as validateCustomFields, i as buildCustomFieldAnswers, n as CustomFieldValues, o as getCheckoutCustomFields, r as CustomFields, s as reconcileCustomFieldValues, t as CustomField } from "./custom-fields.js";
2
+ import { ComponentProps, ReactNode, RefObject } from "react";
3
+ import { LockerverseCheckoutEstimate, LockerversePreparedCheckout } from "@lockerverse/sdk/checkout";
4
+ //#region src/form-field.d.ts
5
+ declare function FieldError({ className, error, id }: {
6
+ className?: string;
7
+ error: string | undefined;
8
+ id: string;
9
+ }): import("react").JSX.Element | null;
10
+ declare function FormField({ children, error, errorId, id, label }: {
11
+ children: ReactNode;
12
+ error?: string | undefined;
13
+ errorId?: string | undefined;
14
+ id: string;
15
+ label: string;
16
+ }): import("react").JSX.Element;
17
+ type TextFieldProps$1 = ComponentProps<"input"> & {
18
+ error?: string | undefined;
19
+ errorId?: string | undefined;
20
+ id: string;
21
+ label: string;
22
+ };
23
+ declare function TextField({ className, error, errorId, id, label, ...inputProps }: TextFieldProps$1): import("react").JSX.Element;
24
+ declare function EmailField(props: Omit<TextFieldProps$1, "type">): import("react").JSX.Element;
25
+ /** Native checkbox semantics with the shared SDK control appearance. */
26
+ declare function Checkbox({ className, ...props }: Omit<ComponentProps<"input">, "type">): import("react").JSX.Element;
27
+ //#endregion
28
+ //#region src/payment-summary.d.ts
29
+ declare function PaymentSummary({ quote, displayedTipCents, displayedTotalCents, displayedBaseCents }: {
30
+ displayedBaseCents?: number;
31
+ displayedTipCents?: number;
32
+ displayedTotalCents?: number;
33
+ quote: LockerverseCheckoutEstimate | LockerversePreparedCheckout;
34
+ }): import("react").JSX.Element;
35
+ //#endregion
36
+ //#region src/phone.d.ts
37
+ declare const PHONE_COUNTRIES: readonly [{
38
+ readonly callingCode: "+1";
39
+ readonly label: "🇺🇸 +1";
40
+ readonly value: "US";
41
+ }, {
42
+ readonly callingCode: "+52";
43
+ readonly label: "🇲🇽 +52";
44
+ readonly value: "MX";
45
+ }, {
46
+ readonly callingCode: "+380";
47
+ readonly label: "🇺🇦 +380";
48
+ readonly value: "UA";
49
+ }, {
50
+ readonly callingCode: "+48";
51
+ readonly label: "🇵🇱 +48";
52
+ readonly value: "PL";
53
+ }, {
54
+ readonly callingCode: "+1";
55
+ readonly label: "🇨🇦 +1";
56
+ readonly value: "CA";
57
+ }, {
58
+ readonly callingCode: "+49";
59
+ readonly label: "🇩🇪 +49";
60
+ readonly value: "DE";
61
+ }, {
62
+ readonly callingCode: "+44";
63
+ readonly label: "🇬🇧 +44";
64
+ readonly value: "GB";
65
+ }, {
66
+ readonly callingCode: "+46";
67
+ readonly label: "🇸🇪 +46";
68
+ readonly value: "SE";
69
+ }, {
70
+ readonly callingCode: "+358";
71
+ readonly label: "🇫🇮 +358";
72
+ readonly value: "FI";
73
+ }, {
74
+ readonly callingCode: "+1";
75
+ readonly label: "🇵🇷 +1";
76
+ readonly value: "PR";
77
+ }];
78
+ type PhoneCountry = (typeof PHONE_COUNTRIES)[number]["value"];
79
+ declare function getInternationalPhone(phone: string, country: string): string;
80
+ //#endregion
81
+ //#region src/phone-field.d.ts
82
+ type PhoneInputValue = {
83
+ value: string;
84
+ country: string;
85
+ };
86
+ type PhoneInputProps = {
87
+ country: string;
88
+ disabled?: boolean | undefined;
89
+ error?: string | boolean | undefined;
90
+ errorId?: string | undefined;
91
+ id: string;
92
+ inputRef?: RefObject<HTMLInputElement | null> | undefined;
93
+ name?: string | undefined;
94
+ onChange: (value: PhoneInputValue) => void;
95
+ placeholder?: string | undefined;
96
+ required?: boolean | undefined;
97
+ value: string;
98
+ };
99
+ /** Controlled raw input. The caller validates and normalizes it on submission. */
100
+ declare function PhoneInput({ id, name, value, onChange, country, required, disabled, inputRef, error, errorId, placeholder }: PhoneInputProps): import("react").JSX.Element;
101
+ //#endregion
102
+ //#region src/payment-primitives-entry.d.ts
103
+ type CheckboxProps = ComponentProps<typeof Checkbox>;
104
+ type CustomFieldProps = ComponentProps<typeof CustomField>;
105
+ type CustomFieldsProps = ComponentProps<typeof CustomFields>;
106
+ type EmailFieldProps = ComponentProps<typeof EmailField>;
107
+ type FieldErrorProps = ComponentProps<typeof FieldError>;
108
+ type FormFieldProps = ComponentProps<typeof FormField>;
109
+ type PaymentSummaryProps = ComponentProps<typeof PaymentSummary>;
110
+ type TextFieldProps = ComponentProps<typeof TextField>;
111
+ //#endregion
112
+ export { Checkbox, CheckboxProps, CustomField, CustomFieldProps, type CustomFieldValues, CustomFields, CustomFieldsProps, EmailField, EmailFieldProps, FieldError, FieldErrorProps, FormField, FormFieldProps, PaymentSummary, PaymentSummaryProps, type PhoneCountry, PhoneInput, type PhoneInputProps, type PhoneInputValue, TextField, TextFieldProps, buildCustomFieldAnswers, createCustomFieldValues, getCheckoutCustomFields, getInternationalPhone, reconcileCustomFieldValues, validateCustomFields };
113
+ //# sourceMappingURL=payment-primitives.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payment-primitives.d.ts","names":[],"sources":["../src/form-field.tsx","../src/payment-summary.tsx","../src/phone.ts","../src/phone-field.tsx","../src/payment-primitives-entry.ts"],"mappings":";;;;iBAEgB,aACd,WACA,OACA;EAEA;EACA;EACA;oBACD,IAAA;iBAYe,YACd,UACA,OACA,SACA,IACA;EAEA,UAAU;EACV;EACA;EACA;EACA;oBACD,IAAA;KAUI,mBAAiB;EACpB;EACA;EACA;EACA;;iBAGc,YACd,WACA,OACA,SACA,IACA,UACG,cACF,mCAAc,IAAA;iBAeD,WAAW,OAAO,KAAK,4CAAuB,IAAA;;iBAY9C,WACd,cACG,SACF,KAAK,mDAAgC,IAAA;;;iBClFxB,iBACd,OACA,mBACA,qBACA;EAEA;EACA;EACA;EACA,OAAO,8BAA8B;oBACtC,IAAA;;;cCdY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAqDD,uBAAuB;iBAkBnB,sBAAsB,eAAe;;;KCjEzC;EAAoB;EAAe;;KAEnC;EACV;EACA;EACA;EACA;EACA;EACA,WAAW,UAAU;EACrB;EACA,WAAW,OAAO;EAClB;EACA;EACA;;;iBAIc,aACd,IACA,MACA,OACA,UACA,SACA,UACA,UACA,UACA,OACA,SACA,eACC,kCAAe,IAAA;;;KCAN,gBAAgB,sBAAsB;KACtC,mBAAmB,sBAAsB;KACzC,oBAAoB,sBAAsB;KAC1C,kBAAkB,sBAAsB;KACxC,kBAAkB,sBAAsB;KACxC,iBAAiB,sBAAsB;KACvC,sBAAsB,sBAAsB;KAC5C,iBAAiB,sBAAsB"}
@@ -0,0 +1 @@
1
+ import{d as e,f as t,m as n,n as r,p as i,t as a,u as o}from"./phone-field.js";import{a as s,i as c,n as l,o as u,r as d,s as f,t as p}from"./custom-fields.js";import{t as m}from"./payment-summary.js";export{o as Checkbox,p as CustomField,l as CustomFields,e as EmailField,t as FieldError,i as FormField,m as PaymentSummary,a as PhoneInput,n as TextField,d as buildCustomFieldAnswers,c as createCustomFieldValues,s as getCheckoutCustomFields,r as getInternationalPhone,u as reconcileCustomFieldValues,f as validateCustomFields};
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./format-money.js";import{Fragment as t,jsx as n,jsxs as r}from"react/jsx-runtime";function i({quote:i,displayedTipCents:a=i.tipCents,displayedTotalCents:o=i.totalCents,displayedBaseCents:s=o-a}){let c=null;i.paymentOption===`monthly`?c={label:`Monthly`}:i.paymentOption===`annually`&&(c={label:`Annual`});let l=Math.max(0,s-i.subtotalCents+i.discountCents);return r(`section`,{"aria-label":`Payment summary`,className:`lockerverse-payment__payment-summary`,children:[n(`h2`,{children:`Order summary`}),n(`div`,{className:`lockerverse-payment__payment-summary-items`,children:i.lineItems.map(i=>r(`div`,{className:`lockerverse-payment__payment-summary-row`,children:[r(`span`,{children:[i.productName,i.quantity>1?r(t,{children:[` `,r(`small`,{children:[`× `,i.quantity]})]}):null,i.paymentOption===`monthly`?n(`small`,{children:` · Monthly`}):null,i.paymentOption===`annually`?n(`small`,{children:` · Annual`}):null]}),n(`strong`,{children:e(i.subtotalCents)})]},i.listingId))}),r(`div`,{className:`lockerverse-payment__payment-summary-totals`,children:[l>0?r(`div`,{className:`lockerverse-payment__payment-summary-row lockerverse-payment__payment-summary-detail`,children:[n(`span`,{children:`Service fee`}),n(`strong`,{children:e(l)})]}):null,i.discountCents>0&&i.appliedDiscount?r(`div`,{className:`lockerverse-payment__payment-summary-row lockerverse-payment__payment-summary-discount`,children:[r(`span`,{children:[i.appliedDiscount.source===`email_list`?`Email discount`:`Promo code discount`,` `,`(`,i.appliedDiscount.percentageOff,`% off)`]}),r(`strong`,{children:[`-`,e(i.discountCents)]})]}):null,a>0?r(`div`,{className:`lockerverse-payment__payment-summary-row lockerverse-payment__payment-summary-detail lockerverse-payment__payment-summary-tip`,children:[n(`span`,{children:`Tip`}),n(`strong`,{children:e(a)})]}):null,r(`div`,{className:`lockerverse-payment__payment-summary-row lockerverse-payment__payment-summary-total`,children:[n(`span`,{children:c?`${c.label} total`:`Total`}),n(`strong`,{children:e(o)})]})]})]})}export{i as t};
2
+ //# sourceMappingURL=payment-summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payment-summary.js","names":[],"sources":["../src/payment-summary.tsx"],"sourcesContent":["import type {\n LockerverseCheckoutEstimate,\n LockerversePreparedCheckout,\n} from \"@lockerverse/sdk/checkout\";\nimport { formatMoney } from \"./format-money.ts\";\n\nexport function PaymentSummary({\n quote,\n displayedTipCents = quote.tipCents,\n displayedTotalCents = quote.totalCents,\n displayedBaseCents = displayedTotalCents - displayedTipCents,\n}: {\n displayedBaseCents?: number;\n displayedTipCents?: number;\n displayedTotalCents?: number;\n quote: LockerverseCheckoutEstimate | LockerversePreparedCheckout;\n}) {\n let cadence: { label: string } | null = null;\n if (quote.paymentOption === \"monthly\") {\n cadence = { label: \"Monthly\" };\n } else if (quote.paymentOption === \"annually\") {\n cadence = { label: \"Annual\" };\n }\n const displayedServiceFeeCents = Math.max(\n 0,\n displayedBaseCents - quote.subtotalCents + quote.discountCents\n );\n return (\n <section\n aria-label=\"Payment summary\"\n className=\"lockerverse-payment__payment-summary\"\n >\n <h2>Order summary</h2>\n <div className=\"lockerverse-payment__payment-summary-items\">\n {quote.lineItems.map((item) => (\n <div\n className=\"lockerverse-payment__payment-summary-row\"\n key={item.listingId}\n >\n <span>\n {item.productName}\n {item.quantity > 1 ? (\n <>\n {\" \"}\n <small>× {item.quantity}</small>\n </>\n ) : null}\n {item.paymentOption === \"monthly\" ? (\n <small> · Monthly</small>\n ) : null}\n {item.paymentOption === \"annually\" ? (\n <small> · Annual</small>\n ) : null}\n </span>\n <strong>{formatMoney(item.subtotalCents)}</strong>\n </div>\n ))}\n </div>\n <div className=\"lockerverse-payment__payment-summary-totals\">\n {displayedServiceFeeCents > 0 ? (\n <div className=\"lockerverse-payment__payment-summary-row lockerverse-payment__payment-summary-detail\">\n <span>Service fee</span>\n <strong>{formatMoney(displayedServiceFeeCents)}</strong>\n </div>\n ) : null}\n {quote.discountCents > 0 && quote.appliedDiscount ? (\n <div className=\"lockerverse-payment__payment-summary-row lockerverse-payment__payment-summary-discount\">\n <span>\n {quote.appliedDiscount.source === \"email_list\"\n ? \"Email discount\"\n : \"Promo code discount\"}{\" \"}\n ({quote.appliedDiscount.percentageOff}% off)\n </span>\n <strong>-{formatMoney(quote.discountCents)}</strong>\n </div>\n ) : null}\n {displayedTipCents > 0 ? (\n <div className=\"lockerverse-payment__payment-summary-row lockerverse-payment__payment-summary-detail lockerverse-payment__payment-summary-tip\">\n <span>Tip</span>\n <strong>{formatMoney(displayedTipCents)}</strong>\n </div>\n ) : null}\n <div className=\"lockerverse-payment__payment-summary-row lockerverse-payment__payment-summary-total\">\n <span>{cadence ? `${cadence.label} total` : \"Total\"}</span>\n <strong>{formatMoney(displayedTotalCents)}</strong>\n </div>\n </div>\n </section>\n );\n}\n"],"mappings":"sGAMA,SAAgB,EAAe,CAC7B,QACA,oBAAoB,EAAM,SAC1B,sBAAsB,EAAM,WAC5B,qBAAqB,EAAsB,GAM1C,CACD,IAAI,EAAoC,KACpC,EAAM,gBAAkB,UAC1B,EAAU,CAAE,MAAO,SAAU,EACpB,EAAM,gBAAkB,aACjC,EAAU,CAAE,MAAO,QAAS,GAE9B,IAAM,EAA2B,KAAK,IACpC,EACA,EAAqB,EAAM,cAAgB,EAAM,aACnD,EACA,OACE,EAAC,UAAD,CACE,aAAW,kBACX,UAAU,uCAFZ,SAAA,CAIE,EAAC,KAAD,CAAA,SAAI,eAAiB,CAAA,EACrB,EAAC,MAAD,CAAK,UAAU,6CACZ,SAAA,EAAM,UAAU,IAAK,GACpB,EAAC,MAAD,CACE,UAAU,2CADZ,SAAA,CAIE,EAAC,OAAD,CAAA,SAAA,CACG,EAAK,YACL,EAAK,SAAW,EACf,EAAA,EAAA,CAAA,SAAA,CACG,IACD,EAAC,QAAD,CAAA,SAAA,CAAO,KAAG,EAAK,QAAgB,CAAA,CAAA,CAC/B,CAAA,CAAA,EACA,KACH,EAAK,gBAAkB,UACtB,EAAC,QAAD,CAAA,SAAO,YAAiB,CAAA,EACtB,KACH,EAAK,gBAAkB,WACtB,EAAC,QAAD,CAAA,SAAO,WAAgB,CAAA,EACrB,IACA,CAAA,CAAA,EACN,EAAC,SAAD,CAAA,SAAS,EAAY,EAAK,aAAa,CAAU,CAAA,CAC9C,CAlBE,EAAA,EAAK,SAkBP,CACN,CACE,CAAA,EACL,EAAC,MAAD,CAAK,UAAU,8CAAf,SAAA,CACG,EAA2B,EAC1B,EAAC,MAAD,CAAK,UAAU,uFAAf,SAAA,CACE,EAAC,OAAD,CAAA,SAAM,aAAiB,CAAA,EACvB,EAAC,SAAD,CAAA,SAAS,EAAY,CAAwB,CAAU,CAAA,CACpD,CACH,CAAA,EAAA,KACH,EAAM,cAAgB,GAAK,EAAM,gBAChC,EAAC,MAAD,CAAK,UAAU,yFAAf,SAAA,CACE,EAAC,OAAD,CAAA,SAAA,CACG,EAAM,gBAAgB,SAAW,aAC9B,iBACA,sBAAuB,IAAI,IAC7B,EAAM,gBAAgB,cAAc,QAClC,CAAA,CAAA,EACN,EAAC,SAAD,CAAA,SAAA,CAAQ,IAAE,EAAY,EAAM,aAAa,CAAU,CAAA,CAAA,CAChD,CACH,CAAA,EAAA,KACH,EAAoB,EACnB,EAAC,MAAD,CAAK,UAAU,gIAAf,SAAA,CACE,EAAC,OAAD,CAAA,SAAM,KAAS,CAAA,EACf,EAAC,SAAD,CAAA,SAAS,EAAY,CAAiB,CAAU,CAAA,CAC7C,CACH,CAAA,EAAA,KACJ,EAAC,MAAD,CAAK,UAAU,sFAAf,SAAA,CACE,EAAC,OAAD,CAAA,SAAO,EAAU,GAAG,EAAQ,MAAM,QAAU,OAAc,CAAA,EAC1D,EAAC,SAAD,CAAA,SAAS,EAAY,CAAmB,CAAU,CAAA,CAC/C,GACF,GACE,GAEb"}
package/dist/payment.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { n as LockerverseTheme, t as LockerverseStyle } from "./theme.js";
2
+ import { n as CustomFieldValues } from "./custom-fields.js";
2
3
  import { a as LockerversePaymentRecovery, c as LockerversePaymentTheme, i as LockerversePaymentProps, l as LockerversePaymentUncertain, o as LockerversePaymentSelectionItem, r as LockerversePaymentBranding, s as LockerversePaymentStyle, u as LockerverseStripeLoader } from "./types.js";
3
4
  import { n as LockerversePayment, t as preloadLockerversePayment } from "./payment-form.js";
4
5
  import { LockerversePaymentCompletion } from "@lockerverse/sdk/checkout";
5
- export { LockerversePayment, type LockerversePaymentBranding, type LockerversePaymentCompletion, type LockerversePaymentProps, type LockerversePaymentRecovery, type LockerversePaymentSelectionItem, type LockerversePaymentStyle, type LockerversePaymentTheme, type LockerversePaymentUncertain, type LockerverseStripeLoader, type LockerverseStyle, type LockerverseTheme, preloadLockerversePayment };
6
+ export { type CustomFieldValues, LockerversePayment, type LockerversePaymentBranding, type LockerversePaymentCompletion, type LockerversePaymentProps, type LockerversePaymentRecovery, type LockerversePaymentSelectionItem, type LockerversePaymentStyle, type LockerversePaymentTheme, type LockerversePaymentUncertain, type LockerverseStripeLoader, type LockerverseStyle, type LockerverseTheme, preloadLockerversePayment };
@@ -0,0 +1,2 @@
1
+ import{ChevronDown as e}from"lucide-react";import{useRef as t}from"react";import{jsx as n,jsxs as r}from"react/jsx-runtime";import{check as i,email as a,nonEmpty as o,pipe as s,regex as c,string as l,transform as u,trim as d}from"valibot";function f({className:e,error:t,id:r}){return t?n(`span`,{className:`lockerverse-form__error ${e??``}`,id:r,role:`alert`,children:t}):null}function p({children:e,error:t,errorId:i,id:a,label:o}){return r(`div`,{className:`lockerverse-form__field`,children:[n(`label`,{htmlFor:a,children:o}),e,n(f,{error:t,id:i??`${a}-error`})]})}function m({className:e,error:t,errorId:r,id:i,label:a,...o}){let s=r??`${i}-error`;return n(p,{error:t,errorId:s,id:i,label:a,children:n(`input`,{...o,"aria-describedby":t?s:o[`aria-describedby`],"aria-invalid":t?`true`:o[`aria-invalid`],className:`lockerverse-form__control ${e??``}`,id:i})})}function h(e){return n(m,{autoComplete:`email`,placeholder:`name@example.com`,...e,type:`email`})}function g({className:e,...t}){return n(`input`,{...t,className:[`lockerverse-form__checkbox`,e].filter(Boolean).join(` `),type:`checkbox`})}const _=`Enter a valid email address.`,v=`Phone is required.`,y=`Enter a valid phone number.`,b=/^(?:$|[^\s@]+@[^\s@]+\.[^\s@]+)$/,x=/^\+[1-9]\d{6,14}$/;function S(e){return x.test(e)}function C(e){return e.trim().replace(/[().\s-]/g,``)}const w=s(l(),d(),c(b,_)),T=s(l(),d(),o(`Email is required.`),a(_)),E=s(l(),d(),i(e=>e===``||C(e)!==``,y),u(C),i(e=>e===``||S(e),y)),D=s(l(),d(),o(v),u(C),i(S,y));function O(e){if(e===`PAYMENT_WIDGET_PHONE_REQUIRED`||e===`SIGN_UP_WIDGET_PHONE_REQUIRED`)return v;if(e===`PAYMENT_WIDGET_PHONE_INVALID`||e===`SIGN_UP_WIDGET_PHONE_INVALID`)return y}const k=[{callingCode:`+1`,label:`🇺🇸 +1`,value:`US`},{callingCode:`+52`,label:`🇲🇽 +52`,value:`MX`},{callingCode:`+380`,label:`🇺🇦 +380`,value:`UA`},{callingCode:`+48`,label:`🇵🇱 +48`,value:`PL`},{callingCode:`+1`,label:`🇨🇦 +1`,value:`CA`},{callingCode:`+49`,label:`🇩🇪 +49`,value:`DE`},{callingCode:`+44`,label:`🇬🇧 +44`,value:`GB`},{callingCode:`+46`,label:`🇸🇪 +46`,value:`SE`},{callingCode:`+358`,label:`🇫🇮 +358`,value:`FI`},{callingCode:`+1`,label:`🇵🇷 +1`,value:`PR`}];function A(e){return k.find(t=>t.value===e)??k[0]}function j(e,t){let n=`${t}${t}`,r=e;for(;r.startsWith(n);)r=`${t}${r.slice(n.length)}`;return r}function M(e,t){let n=C(e);if(!n)return``;let r=A(t),i=j(n,r.callingCode);return i.startsWith(`+`)?i:`${r.callingCode}${i}`}function N(e,t=`US`){let n=C(e),r=A(t);return n.startsWith(`+`)&&!n.startsWith(r.callingCode)?k.find(e=>n.startsWith(e.callingCode))?.value??r.value:r.value}function P({id:i,name:a,value:o,onChange:s,country:c,required:l,disabled:u,inputRef:d,error:f,errorId:p,placeholder:m=`(201) 555-0123`}){let h=t(null),g=A(c);return r(`div`,{className:`lockerverse-form__phone`,dir:`ltr`,children:[r(`div`,{className:`lockerverse-form__phone-country`,children:[r(`span`,{"aria-hidden":`true`,children:[n(`span`,{className:`lockerverse-form__phone-flag`,children:g.label.split(` `)[0]}),g.callingCode,n(e,{"aria-hidden":`true`,size:14})]}),n(`select`,{"aria-label":`Phone number country`,disabled:u,name:`phoneCountry`,onChange:e=>{s({country:A(e.target.value).value,value:o}),h.current?.focus()},value:g.value,children:k.map(e=>n(`option`,{value:e.value,children:e.label},e.value))})]}),n(`input`,{"aria-describedby":f?p:void 0,"aria-invalid":f?!0:void 0,autoComplete:`tel-national`,disabled:u,id:i,name:a,onChange:e=>{let t=e.target.value;s({country:N(t,c),value:t})},placeholder:m,ref:e=>{h.current=e,d&&(d.current=e)},required:l,type:`tel`,value:o})]})}export{C as a,T as c,h as d,f,O as i,D as l,m,M as n,w as o,p,N as r,E as s,P as t,g as u};
2
+ //# sourceMappingURL=phone-field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phone-field.js","names":[],"sources":["../src/form-field.tsx","../src/contact-validation.ts","../src/phone.ts","../src/phone-field.tsx"],"sourcesContent":["import type { ComponentProps, ReactNode } from \"react\";\n\nexport function FieldError({\n className,\n error,\n id,\n}: {\n className?: string;\n error: string | undefined;\n id: string;\n}) {\n return error ? (\n <span\n className={`lockerverse-form__error ${className ?? \"\"}`}\n id={id}\n role=\"alert\"\n >\n {error}\n </span>\n ) : null;\n}\n\nexport function FormField({\n children,\n error,\n errorId,\n id,\n label,\n}: {\n children: ReactNode;\n error?: string | undefined;\n errorId?: string | undefined;\n id: string;\n label: string;\n}) {\n return (\n <div className=\"lockerverse-form__field\">\n <label htmlFor={id}>{label}</label>\n {children}\n <FieldError error={error} id={errorId ?? `${id}-error`} />\n </div>\n );\n}\n\ntype TextFieldProps = ComponentProps<\"input\"> & {\n error?: string | undefined;\n errorId?: string | undefined;\n id: string;\n label: string;\n};\n\nexport function TextField({\n className,\n error,\n errorId,\n id,\n label,\n ...inputProps\n}: TextFieldProps) {\n const messageId = errorId ?? `${id}-error`;\n return (\n <FormField error={error} errorId={messageId} id={id} label={label}>\n <input\n {...inputProps}\n aria-describedby={error ? messageId : inputProps[\"aria-describedby\"]}\n aria-invalid={error ? \"true\" : inputProps[\"aria-invalid\"]}\n className={`lockerverse-form__control ${className ?? \"\"}`}\n id={id}\n />\n </FormField>\n );\n}\n\nexport function EmailField(props: Omit<TextFieldProps, \"type\">) {\n return (\n <TextField\n autoComplete=\"email\"\n placeholder=\"name@example.com\"\n {...props}\n type=\"email\"\n />\n );\n}\n\n/** Native checkbox semantics with the shared SDK control appearance. */\nexport function Checkbox({\n className,\n ...props\n}: Omit<ComponentProps<\"input\">, \"type\">) {\n return (\n <input\n {...props}\n className={[\"lockerverse-form__checkbox\", className]\n .filter(Boolean)\n .join(\" \")}\n type=\"checkbox\"\n />\n );\n}\n","import {\n check,\n email,\n nonEmpty,\n pipe,\n regex,\n string,\n transform,\n trim,\n} from \"valibot\";\n\nexport const EMAIL_REQUIRED_MESSAGE = \"Email is required.\";\nexport const EMAIL_INVALID_MESSAGE = \"Enter a valid email address.\";\nexport const PHONE_REQUIRED_MESSAGE = \"Phone is required.\";\nexport const PHONE_INVALID_MESSAGE = \"Enter a valid phone number.\";\n\nconst OPTIONAL_EMAIL_PATTERN = /^(?:$|[^\\s@]+@[^\\s@]+\\.[^\\s@]+)$/;\nconst INTERNATIONAL_PHONE_PATTERN = /^\\+[1-9]\\d{6,14}$/;\n\nfunction isValidInternationalPhone(value: string) {\n return INTERNATIONAL_PHONE_PATTERN.test(value);\n}\n\nexport function normalizePhone(input: string) {\n return input.trim().replace(/[().\\s-]/g, \"\");\n}\n\nexport const optionalEmailSchema = pipe(\n string(),\n trim(),\n regex(OPTIONAL_EMAIL_PATTERN, EMAIL_INVALID_MESSAGE)\n);\n\nexport const requiredEmailSchema = pipe(\n string(),\n trim(),\n nonEmpty(EMAIL_REQUIRED_MESSAGE),\n email(EMAIL_INVALID_MESSAGE)\n);\n\nexport const optionalPhoneSchema = pipe(\n string(),\n trim(),\n check(\n (value) => value === \"\" || normalizePhone(value) !== \"\",\n PHONE_INVALID_MESSAGE\n ),\n transform(normalizePhone),\n check(\n (value) => value === \"\" || isValidInternationalPhone(value),\n PHONE_INVALID_MESSAGE\n )\n);\n\nexport const requiredPhoneSchema = pipe(\n string(),\n trim(),\n nonEmpty(PHONE_REQUIRED_MESSAGE),\n transform(normalizePhone),\n check(isValidInternationalPhone, PHONE_INVALID_MESSAGE)\n);\n\nexport function getPhoneServerError(serverCode: string | undefined) {\n if (\n serverCode === \"PAYMENT_WIDGET_PHONE_REQUIRED\" ||\n serverCode === \"SIGN_UP_WIDGET_PHONE_REQUIRED\"\n ) {\n return PHONE_REQUIRED_MESSAGE;\n }\n if (\n serverCode === \"PAYMENT_WIDGET_PHONE_INVALID\" ||\n serverCode === \"SIGN_UP_WIDGET_PHONE_INVALID\"\n ) {\n return PHONE_INVALID_MESSAGE;\n }\n}\n","import { normalizePhone } from \"./contact-validation.ts\";\n\nexport const PHONE_COUNTRIES = [\n {\n callingCode: \"+1\",\n label: \"🇺🇸 +1\",\n value: \"US\",\n },\n {\n callingCode: \"+52\",\n label: \"🇲🇽 +52\",\n value: \"MX\",\n },\n {\n callingCode: \"+380\",\n label: \"🇺🇦 +380\",\n value: \"UA\",\n },\n {\n callingCode: \"+48\",\n label: \"🇵🇱 +48\",\n value: \"PL\",\n },\n {\n callingCode: \"+1\",\n label: \"🇨🇦 +1\",\n value: \"CA\",\n },\n {\n callingCode: \"+49\",\n label: \"🇩🇪 +49\",\n value: \"DE\",\n },\n {\n callingCode: \"+44\",\n label: \"🇬🇧 +44\",\n value: \"GB\",\n },\n {\n callingCode: \"+46\",\n label: \"🇸🇪 +46\",\n value: \"SE\",\n },\n {\n callingCode: \"+358\",\n label: \"🇫🇮 +358\",\n value: \"FI\",\n },\n {\n callingCode: \"+1\",\n label: \"🇵🇷 +1\",\n value: \"PR\",\n },\n] as const;\n\nexport type PhoneCountry = (typeof PHONE_COUNTRIES)[number][\"value\"];\n\nexport function getPhoneCountry(country: string) {\n return (\n PHONE_COUNTRIES.find((option) => option.value === country) ??\n PHONE_COUNTRIES[0]\n );\n}\n\nfunction removeRepeatedCallingCode(phone: string, callingCode: string) {\n const repeatedCallingCode = `${callingCode}${callingCode}`;\n let normalizedPhone = phone;\n while (normalizedPhone.startsWith(repeatedCallingCode)) {\n normalizedPhone = `${callingCode}${normalizedPhone.slice(repeatedCallingCode.length)}`;\n }\n return normalizedPhone;\n}\n\nexport function getInternationalPhone(phone: string, country: string) {\n const normalizedPhone = normalizePhone(phone);\n if (!normalizedPhone) {\n return \"\";\n }\n\n const selectedCountry = getPhoneCountry(country);\n const phoneWithOneCallingCode = removeRepeatedCallingCode(\n normalizedPhone,\n selectedCountry.callingCode\n );\n\n return phoneWithOneCallingCode.startsWith(\"+\")\n ? phoneWithOneCallingCode\n : `${selectedCountry.callingCode}${phoneWithOneCallingCode}`;\n}\n\nexport function resolvePhoneCountry(phone: string, country = \"US\") {\n const normalized = normalizePhone(phone);\n const current = getPhoneCountry(country);\n return normalized.startsWith(\"+\") &&\n !normalized.startsWith(current.callingCode)\n ? (PHONE_COUNTRIES.find((option) =>\n normalized.startsWith(option.callingCode)\n )?.value ?? current.value)\n : current.value;\n}\n","import { ChevronDown } from \"lucide-react\";\nimport { type RefObject, useRef } from \"react\";\nimport {\n getPhoneCountry,\n PHONE_COUNTRIES,\n resolvePhoneCountry,\n} from \"./phone.ts\";\n\nexport type PhoneInputValue = { value: string; country: string };\n\nexport type PhoneInputProps = {\n country: string;\n disabled?: boolean | undefined;\n error?: string | boolean | undefined;\n errorId?: string | undefined;\n id: string;\n inputRef?: RefObject<HTMLInputElement | null> | undefined;\n name?: string | undefined;\n onChange: (value: PhoneInputValue) => void;\n placeholder?: string | undefined;\n required?: boolean | undefined;\n value: string;\n};\n\n/** Controlled raw input. The caller validates and normalizes it on submission. */\nexport function PhoneInput({\n id,\n name,\n value,\n onChange,\n country,\n required,\n disabled,\n inputRef,\n error,\n errorId,\n placeholder = \"(201) 555-0123\",\n}: PhoneInputProps) {\n const input = useRef<HTMLInputElement>(null);\n const selectedCountry = getPhoneCountry(country);\n\n return (\n <div className=\"lockerverse-form__phone\" dir=\"ltr\">\n <div className=\"lockerverse-form__phone-country\">\n <span aria-hidden=\"true\">\n <span className=\"lockerverse-form__phone-flag\">\n {selectedCountry.label.split(\" \")[0]}\n </span>\n {selectedCountry.callingCode}\n <ChevronDown aria-hidden=\"true\" size={14} />\n </span>\n <select\n aria-label=\"Phone number country\"\n disabled={disabled}\n name=\"phoneCountry\"\n onChange={(event) => {\n const nextCountry = getPhoneCountry(event.target.value);\n onChange({ country: nextCountry.value, value });\n input.current?.focus();\n }}\n value={selectedCountry.value}\n >\n {PHONE_COUNTRIES.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n </div>\n <input\n aria-describedby={error ? errorId : undefined}\n aria-invalid={error ? true : undefined}\n autoComplete=\"tel-national\"\n disabled={disabled}\n id={id}\n name={name}\n onChange={(event) => {\n const raw = event.target.value;\n onChange({ country: resolvePhoneCountry(raw, country), value: raw });\n }}\n placeholder={placeholder}\n ref={(element) => {\n input.current = element;\n if (inputRef) {\n inputRef.current = element;\n }\n }}\n required={required}\n type=\"tel\"\n value={value}\n />\n </div>\n );\n}\n"],"mappings":"+OAEA,SAAgB,EAAW,CACzB,YACA,QACA,MAKC,CACD,OAAO,EACL,EAAC,OAAD,CACE,UAAW,2BAA2B,GAAa,KAC/C,KACJ,KAAK,QAEJ,SAAA,CACG,CAAA,EACJ,IACN,CAEA,SAAgB,EAAU,CACxB,WACA,QACA,UACA,KACA,SAOC,CACD,OACE,EAAC,MAAD,CAAK,UAAU,0BAAf,SAAA,CACE,EAAC,QAAD,CAAO,QAAS,EAAK,SAAA,CAAa,CAAA,EACjC,EACD,EAAC,EAAD,CAAmB,QAAO,GAAI,GAAW,GAAG,EAAG,OAAU,CAAA,CACtD,GAET,CASA,SAAgB,EAAU,CACxB,YACA,QACA,UACA,KACA,QACA,GAAG,GACc,CACjB,IAAM,EAAY,GAAW,GAAG,EAAG,QACnC,OACE,EAAC,EAAD,CAAkB,QAAO,QAAS,EAAe,KAAW,QAC1D,SAAA,EAAC,QAAD,CACE,GAAI,EACJ,mBAAkB,EAAQ,EAAY,EAAW,oBACjD,eAAc,EAAQ,OAAS,EAAW,gBAC1C,UAAW,6BAA6B,GAAa,KACjD,IACL,CAAA,CACQ,CAAA,CAEf,CAEA,SAAgB,EAAW,EAAqC,CAC9D,OACE,EAAC,EAAD,CACE,aAAa,QACb,YAAY,mBACZ,GAAI,EACJ,KAAK,OACN,CAAA,CAEL,CAGA,SAAgB,EAAS,CACvB,YACA,GAAG,GACqC,CACxC,OACE,EAAC,QAAD,CACE,GAAI,EACJ,UAAW,CAAC,6BAA8B,CAAS,CAAC,CACjD,OAAO,OAAO,CAAC,CACf,KAAK,GAAG,EACX,KAAK,UACN,CAAA,CAEL,CCvFA,MACa,EAAwB,+BACxB,EAAyB,qBACzB,EAAwB,8BAE/B,EAAyB,mCACzB,EAA8B,oBAEpC,SAAS,EAA0B,EAAe,CAChD,OAAO,EAA4B,KAAK,CAAK,CAC/C,CAEA,SAAgB,EAAe,EAAe,CAC5C,OAAO,EAAM,KAAK,CAAC,CAAC,QAAQ,YAAa,EAAE,CAC7C,CAEA,MAAa,EAAsB,EACjC,EAAO,EACP,EAAK,EACL,EAAM,EAAwB,CAAqB,CACrD,EAEa,EAAsB,EACjC,EAAO,EACP,EAAK,EACL,EAAS,oBAAsB,EAC/B,EAAM,CAAqB,CAC7B,EAEa,EAAsB,EACjC,EAAO,EACP,EAAK,EACL,EACG,GAAU,IAAU,IAAM,EAAe,CAAK,IAAM,GACrD,CACF,EACA,EAAU,CAAc,EACxB,EACG,GAAU,IAAU,IAAM,EAA0B,CAAK,EAC1D,CACF,CACF,EAEa,EAAsB,EACjC,EAAO,EACP,EAAK,EACL,EAAS,CAAsB,EAC/B,EAAU,CAAc,EACxB,EAAM,EAA2B,CAAqB,CACxD,EAEA,SAAgB,EAAoB,EAAgC,CAClE,GACE,IAAe,iCACf,IAAe,gCAEf,OAAO,EAET,GACE,IAAe,gCACf,IAAe,+BAEf,OAAO,CAEX,CCzEA,MAAa,EAAkB,CAC7B,CACE,YAAa,KACb,MAAO,UACP,MAAO,IACT,EACA,CACE,YAAa,MACb,MAAO,WACP,MAAO,IACT,EACA,CACE,YAAa,OACb,MAAO,YACP,MAAO,IACT,EACA,CACE,YAAa,MACb,MAAO,WACP,MAAO,IACT,EACA,CACE,YAAa,KACb,MAAO,UACP,MAAO,IACT,EACA,CACE,YAAa,MACb,MAAO,WACP,MAAO,IACT,EACA,CACE,YAAa,MACb,MAAO,WACP,MAAO,IACT,EACA,CACE,YAAa,MACb,MAAO,WACP,MAAO,IACT,EACA,CACE,YAAa,OACb,MAAO,YACP,MAAO,IACT,EACA,CACE,YAAa,KACb,MAAO,UACP,MAAO,IACT,CACF,EAIA,SAAgB,EAAgB,EAAiB,CAC/C,OACE,EAAgB,KAAM,GAAW,EAAO,QAAU,CAAO,GACzD,EAAgB,EAEpB,CAEA,SAAS,EAA0B,EAAe,EAAqB,CACrE,IAAM,EAAsB,GAAG,IAAc,IACzC,EAAkB,EACtB,KAAO,EAAgB,WAAW,CAAmB,GACnD,EAAkB,GAAG,IAAc,EAAgB,MAAM,EAAoB,MAAM,IAErF,OAAO,CACT,CAEA,SAAgB,EAAsB,EAAe,EAAiB,CACpE,IAAM,EAAkB,EAAe,CAAK,EAC5C,GAAI,CAAC,EACH,MAAO,GAGT,IAAM,EAAkB,EAAgB,CAAO,EACzC,EAA0B,EAC9B,EACA,EAAgB,WAClB,EAEA,OAAO,EAAwB,WAAW,GAAG,EACzC,EACA,GAAG,EAAgB,cAAc,GACvC,CAEA,SAAgB,EAAoB,EAAe,EAAU,KAAM,CACjE,IAAM,EAAa,EAAe,CAAK,EACjC,EAAU,EAAgB,CAAO,EACvC,OAAO,EAAW,WAAW,GAAG,GAC9B,CAAC,EAAW,WAAW,EAAQ,WAAW,EACvC,EAAgB,KAAM,GACrB,EAAW,WAAW,EAAO,WAAW,CAC1C,CAAC,EAAE,OAAS,EAAQ,MACpB,EAAQ,KACd,CC1EA,SAAgB,EAAW,CACzB,KACA,OACA,QACA,WACA,UACA,WACA,WACA,WACA,QACA,UACA,cAAc,kBACI,CAClB,IAAM,EAAQ,EAAyB,IAAI,EACrC,EAAkB,EAAgB,CAAO,EAE/C,OACE,EAAC,MAAD,CAAK,UAAU,0BAA0B,IAAI,MAA7C,SAAA,CACE,EAAC,MAAD,CAAK,UAAU,kCAAf,SAAA,CACE,EAAC,OAAD,CAAM,cAAY,OAAlB,SAAA,CACE,EAAC,OAAD,CAAM,UAAU,+BACb,SAAA,EAAgB,MAAM,MAAM,GAAG,CAAC,CAAC,EAC9B,CAAA,EACL,EAAgB,YACjB,EAAC,EAAD,CAAa,cAAY,OAAO,KAAM,EAAK,CAAA,CACvC,CACN,CAAA,EAAA,EAAC,SAAD,CACE,aAAW,uBACD,WACV,KAAK,eACL,SAAW,GAAU,CAEnB,EAAS,CAAE,QADS,EAAgB,EAAM,OAAO,KACnB,CAAC,CAAC,MAAO,OAAM,CAAC,EAC9C,EAAM,SAAS,MAAM,CACvB,EACA,MAAO,EAAgB,MAEtB,SAAA,EAAgB,IAAK,GACpB,EAAC,SAAD,CAA2B,MAAO,EAAO,MACtC,SAAA,EAAO,KACF,EAFK,EAAO,KAEZ,CACT,CACK,CAAA,CACL,CACL,CAAA,EAAA,EAAC,QAAD,CACE,mBAAkB,EAAQ,EAAU,IAAA,GACpC,eAAc,EAAQ,GAAO,IAAA,GAC7B,aAAa,eACH,WACN,KACE,OACN,SAAW,GAAU,CACnB,IAAM,EAAM,EAAM,OAAO,MACzB,EAAS,CAAE,QAAS,EAAoB,EAAK,CAAO,EAAG,MAAO,CAAI,CAAC,CACrE,EACa,cACb,IAAM,GAAY,CAChB,EAAM,QAAU,EACZ,IACF,EAAS,QAAU,EAEvB,EACU,WACV,KAAK,MACE,OACR,CAAA,CACE,GAET"}
package/dist/signup.js CHANGED
@@ -1,2 +1,2 @@
1
- import{t as e}from"./immutable-resource-identity.js";import{a as t,c as n,f as r,l as i,m as a,n as o,p as s,r as c,s as l,t as u,u as d}from"./host-callback.js";import{n as f,t as p}from"./accent-contrast.js";import{i as m,n as h,o as g,r as _,s as v,t as y}from"./form-skeleton.js";import{useCallback as b,useEffect as x,useId as S,useRef as C,useState as w}from"react";import{jsx as T,jsxs as E}from"react/jsx-runtime";import{check as D,nonEmpty as O,nullable as k,object as A,pipe as j,regex as M,safeParse as N,string as P,transform as F,trim as I}from"valibot";import{createLockerverseSignupClient as L}from"@lockerverse/sdk/signup";const R=`lockerverse-signup-google-places`,z=[`premise`,`subpremise`,`street_address`,`route`];let B=null;function ee(e){let t=window;if(t.google?.maps?.importLibrary)return;t.google||={};let n=t.google;n.maps||={};let r=n.maps,i=null;r.importLibrary=n=>(i||=new Promise((t,i)=>{let a=document.getElementById(R);if(r.__lockerverseSignupReady=t,a){a.addEventListener(`error`,()=>i(Error(`Unable to load Google Places.`)),{once:!0});return}let o=document.createElement(`script`),s=new URLSearchParams({callback:`google.maps.__lockerverseSignupReady`,key:e,libraries:n,v:`weekly`});o.async=!0,o.id=R,o.src=`https://maps.googleapis.com/maps/api/js?${s}`,o.onerror=()=>i(Error(`Unable to load Google Places.`)),document.head.append(o)}),i.then(()=>{let e=t.google?.maps?.importLibrary;if(!e)throw Error(`Unable to load Google Places.`);return e(n)}).catch(e=>{throw i=null,document.getElementById(R)?.remove(),e}))}function V(e){return B||=(async()=>{try{ee(e);let t=window.google?.maps?.importLibrary;if(!t)throw Error(`Unable to load Google Places.`);return await t(`places`)}catch(e){throw B=null,e}})(),B}function H(e,t,n=`longText`){return e.find(e=>e.types.includes(t))?.[n]??``}function te(e,t){let n=t.addressComponents??[],r=[H(n,`street_number`),H(n,`route`)].filter(Boolean).join(` `);return{...e,city:H(n,`locality`)||H(n,`postal_town`)||H(n,`sublocality_level_1`),country:H(n,`country`,`shortText`)||`US`,line1:r||t.formattedAddress?.split(`,`)[0]||``,line2:H(n,`subpremise`),postalCode:[H(n,`postal_code`),H(n,`postal_code_suffix`)].filter(Boolean).join(`-`),state:H(n,`administrative_area_level_1`,`shortText`)}}function ne({apiKey:e,errorId:t,invalid:n,onChange:r,required:i,value:a}){let o=S(),s=`${o}-suggestions`,[c,l]=w(-1),[u,d]=w(!1),[f,p]=w(!1),[m,h]=w([]),g=C(0),_=C(0),v=C(null);x(()=>()=>{g.current+=1},[]),x(()=>{let t=_.current+1;_.current=t;let n=a.line1.trim();if(l(-1),p(!1),!(e&&u&&n.length>=3)){h([]);return}let r=window.setTimeout(async()=>{if(t===_.current){p(!0);try{let{AutocompleteSessionToken:r,AutocompleteSuggestion:i}=await V(e);v.current??=new r;let a=await i.fetchAutocompleteSuggestions({includedPrimaryTypes:z,includedRegionCodes:[`US`],input:n,region:`US`,sessionToken:v.current});t===_.current&&h(a.suggestions.flatMap(({placePrediction:e})=>e?[{id:e.placeId,label:e.mainText?.text??e.text.text,prediction:e,secondaryLabel:e.secondaryText?.text??``}]:[]))}catch{t===_.current&&h([])}finally{t===_.current&&p(!1)}}},250);return()=>{window.clearTimeout(r)}},[e,u,a.line1]);let y=e=>{g.current+=1,r({...a,...e})},b=async e=>{let t=g.current+1;g.current=t;let n=e.prediction.toPlace();try{if(await n.fetchFields({fields:[`addressComponents`,`formattedAddress`]}),t!==g.current)return;r(te(a,n)),v.current=null,h([]),l(-1),d(!1)}catch{if(t!==g.current)return;h([]),l(-1)}},D=e=>{if(e.key===`Escape`){e.preventDefault(),h([]),l(-1);return}if(m.length===0)return;if(e.key===`ArrowDown`){e.preventDefault(),l(e=>e<m.length-1?e+1:0);return}if(e.key===`ArrowUp`){e.preventDefault(),l(e=>e>0?e-1:m.length-1);return}let t=m[c];e.key===`Enter`&&t&&(e.preventDefault(),b(t).catch(()=>void 0))},O=e=>{e.currentTarget.closest(`.lockerverse-signup__address-search`)?.contains(e.relatedTarget)||window.setTimeout(()=>d(!1),120)};return E(`fieldset`,{"aria-describedby":n?t:void 0,"aria-invalid":n?`true`:void 0,className:`lockerverse-signup__address`,children:[T(`legend`,{children:`Address`}),E(`label`,{htmlFor:`${o}-line1`,children:[T(`span`,{children:`Street address`}),E(`div`,{className:`lockerverse-signup__address-search`,children:[T(`input`,{"aria-activedescendant":c>=0?`${o}-suggestion-${c}`:void 0,"aria-autocomplete":`list`,"aria-controls":s,"aria-describedby":n?t:void 0,"aria-expanded":u&&m.length>0,"aria-invalid":n?`true`:void 0,autoComplete:`street-address`,id:`${o}-line1`,name:`address.line1`,onBlur:O,onChange:e=>y({line1:e.currentTarget.value}),onFocus:()=>d(!0),onKeyDown:D,required:i,role:`combobox`,value:a.line1}),f?T(`span`,{className:`lockerverse-signup__address-loading`,children:`Searching…`}):null,m.length>0?T(`div`,{className:`lockerverse-signup__address-suggestions`,id:s,role:`listbox`,children:m.map((e,t)=>E(`button`,{"aria-selected":c===t,id:`${o}-suggestion-${t}`,onBlur:O,onClick:t=>{t.detail===0&&b(e).catch(()=>void 0)},onMouseDown:t=>{t.preventDefault(),b(e).catch(()=>void 0)},role:`option`,type:`button`,children:[T(`strong`,{children:e.label}),e.secondaryLabel?T(`span`,{children:e.secondaryLabel}):null]},e.id))}):null]})]}),E(`label`,{htmlFor:`${o}-line2`,children:[T(`span`,{children:`Apartment, suite, or unit`}),T(`input`,{autoComplete:`address-line2`,id:`${o}-line2`,onChange:e=>y({line2:e.currentTarget.value}),placeholder:`Optional`,value:a.line2??``})]}),E(`div`,{className:`lockerverse-signup__address-row`,children:[E(`label`,{htmlFor:`${o}-city`,children:[T(`span`,{children:`City`}),T(`input`,{autoComplete:`address-level2`,id:`${o}-city`,onChange:e=>y({city:e.currentTarget.value}),required:i,value:a.city})]}),E(`label`,{htmlFor:`${o}-state`,children:[T(`span`,{children:`State`}),T(`input`,{autoComplete:`address-level1`,id:`${o}-state`,onChange:e=>y({state:e.currentTarget.value}),required:i,value:a.state})]})]}),E(`div`,{className:`lockerverse-signup__address-row`,children:[E(`label`,{htmlFor:`${o}-postal`,children:[T(`span`,{children:`Postal code`}),T(`input`,{autoComplete:`postal-code`,id:`${o}-postal`,onChange:e=>y({postalCode:e.currentTarget.value}),required:i,value:a.postalCode})]}),E(`label`,{htmlFor:`${o}-country`,children:[T(`span`,{children:`Country`}),T(`input`,{autoComplete:`country`,id:`${o}-country`,maxLength:2,onChange:e=>y({country:e.currentTarget.value.toUpperCase()}),required:i,value:a.country})]})]})]})}const re=/^[1-9]\d*$/,ie=/^(?:$|[1-9]\d*)$/,ae=j(P(),I(),O(`Name is required.`)),U=j(P(),I(),M(ie,`Guest count must be a positive whole number.`),F(e=>e?Number(e):null),D(e=>e===null||Number.isSafeInteger(e),`Guest count must be a positive whole number.`)),W=j(P(),I(),O(`Guest count is required.`),M(re,`Guest count must be a positive whole number.`),F(Number),D(e=>Number.isSafeInteger(e),`Guest count must be a positive whole number.`)),G=A({city:P(),country:P(),line1:P(),line2:k(P()),postalCode:P(),state:P()}),K=j(G,D(Y,`Complete the address.`)),q={city:``,country:`US`,line1:``,line2:null,postalCode:``,state:``},oe=j(G,D(e=>J(e)||Y(e),`Complete the address or leave it blank.`));function J(e){return![e.city,e.line1,e.line2,e.postalCode,e.state].some(e=>e?.trim())}function Y(e){return[e.city,e.country,e.line1,e.postalCode,e.state].every(e=>e.trim())}function se(e,t){let r={...t,address:e.fields.address.enabled?t.address:q,customFields:g(e.customFields,t.customFields),email:e.fields.email.enabled?t.email:``,participantCount:e.fields.participantCount.enabled?t.participantCount:``,phone:e.fields.phone.enabled?t.phone:``},a=A({address:e.fields.address.enabled&&e.fields.address.required?K:oe,email:e.fields.email.enabled&&e.fields.email.required?i:l,name:ae,participantCount:e.fields.participantCount.enabled&&e.fields.participantCount.required?W:U,phone:e.fields.phone.enabled&&e.fields.phone.required?d:n}),o=N(a,r),s=v(e.customFields,r.customFields);if(!o.success)for(let e of o.issues){let t=e.path?.[0]?.key,n=[`address`,`email`,`name`,`participantCount`,`phone`].find(e=>e===t);n&&!s[n]&&(s[n]=e.message)}return o.success?{errors:s,value:{...r,...o.output}}:{errors:s,value:null}}const ce={city:``,country:`US`,line1:``,line2:``,postalCode:``,state:``};function le(e){return{address:ce,customFields:m(e.customFields),email:``,honeypot:``,name:``,participantCount:``,phone:``,phoneCountry:`US`}}function X(e,t){let n=e.elements.namedItem(t);if(n instanceof HTMLElement)return!n.matches(`:disabled`)&&(n.focus(),!0);if(n instanceof RadioNodeList){let e=Array.from(n).find(e=>e instanceof HTMLElement&&!e.matches(`:disabled`));return e?.focus(),!!e}return!1}function Z(e,t){let n=[[`name`,`name`],[`email`,`email`],[`phone`,`phone`],[`participantCount`,`participantCount`],[`address`,`address.line1`]];for(let[r,i]of n)if(t[r]&&X(e,i))return;let r=new Set(n.map(([e])=>e)),i=Object.keys(t).find(e=>!r.has(e));i&&X(e,`custom:${i}`)}function Q({children:e,loading:t=!1,status:n=!1,viewProps:r}){let{branding:i,className:a,googlePlacesApiKey:o,onSignupComplete:s,style:c,theme:l=`dark`,...u}=r,d=f(c?.[`--lockerverse-accent`]??c?.[`--lockerverse-signup-accent`]??i?.accentColor??`#5751f2`),m={...c};if((c?.[`--lockerverse-accent`]!==void 0||c?.[`--lockerverse-signup-accent`]!==void 0||i?.accentColor)&&(m[`--lockerverse-accent`]=d),c?.[`--lockerverse-accent-contrast`]===void 0&&c?.[`--lockerverse-signup-accent-contrast`]===void 0){let e=p(d);e&&(m[`--lockerverse-accent-contrast`]=e)}return T(`section`,{...u,...t?{"aria-busy":!0}:{},className:[`lockerverse-signup`,n?`lockerverse-signup__status`:null,a].filter(Boolean).join(` `),"data-lockerverse-theme":l,style:m,children:e})}function ue({client:e,loadError:n,onRetry:i,signup:l,...d}){let{branding:f,googlePlacesApiKey:p,onSignupComplete:m}=d,v=S(),y=C(!0),b=C(null),D=C(!1),[O,k]=w({phase:`idle`}),[A,j]=w(()=>le(l)),[M,N]=w({}),[P,F]=w(),I=g(l.customFields,A.customFields);if(x(()=>{I!==A.customFields&&j(e=>({...e,customFields:g(l.customFields,e.customFields)}))},[I,l.customFields,A.customFields]),x(()=>(y.current=!0,()=>{y.current=!1}),[]),x(()=>{O.phase!==`submitting`&&M.phone&&b.current?.focus()},[M.phone,O.phase]),!l.isActive)return E(Q,{status:!0,viewProps:d,children:[T(`h1`,{children:`Signup closed`}),T(`p`,{children:`This signup is not accepting submissions.`})]});if(O.phase===`submitted`)return E(Q,{status:!0,viewProps:d,children:[f?T($,{branding:f}):null,T(`span`,{"aria-hidden":`true`,className:`lockerverse-signup__success`,children:`✓`}),T(`h1`,{children:`Thank you`}),T(`p`,{children:`Your signup has been received.`})]});let L=e=>j(t=>({...t,...e})),R=O.phase===`submitting`,z=O.phase===`submit_error`?O.error.message:void 0;return E(Q,{viewProps:d,children:[l.coverImageUrl?T(`img`,{alt:``,className:`lockerverse-signup__cover`,height:192,src:l.coverImageUrl,width:440}):null,f?T($,{branding:f}):null,E(`header`,{children:[l.title?.trim()?T(`h1`,{children:l.title}):null,l.description?T(`p`,{children:l.description}):null]}),n?E(`div`,{role:`alert`,children:[T(`p`,{children:n.message}),T(`button`,{onClick:i,type:`button`,children:`Retry`})]}):null,E(`form`,{noValidate:!0,onSubmit:async n=>{if(n.preventDefault(),D.current)return;let r=se(l,{...A,customFields:I,phone:l.fields.phone.enabled?c(A.phone,A.phoneCountry):``});if(N(r.errors),Object.keys(r.errors).length>0||!r.value){let e=n.currentTarget;queueMicrotask(()=>Z(e,r.errors));return}let i=r.value,a={address:l.fields.address.enabled&&!J(i.address)?i.address:null,answers:_(l.customFields,i.customFields),email:l.fields.email.enabled&&i.email||null,honeypot:i.honeypot,name:i.name,participantCount:l.fields.participantCount.enabled?i.participantCount:null,phone:l.fields.phone.enabled&&i.phone||null},o=JSON.stringify(a),s=P?.payloadKey===o?P.reference:globalThis.crypto.randomUUID(),d;D.current=!0,k({phase:`submitting`});try{d=await e.submit(a,{submissionReference:s})}catch(e){if(!y.current)return;let n=e,r=t(n.serverCode);if(r){N(e=>({...e,phone:r})),k({phase:`idle`}),F(void 0);return}k({error:n,phase:`submit_error`}),n.recoveryRecommended?F({payloadKey:o,reference:s}):F(void 0);return}finally{D.current=!1}y.current&&(F(void 0),k({phase:`submitted`}),u(m,d))},children:[T(`input`,{"aria-hidden":`true`,autoComplete:`off`,className:`lockerverse-signup__honeypot`,onChange:e=>L({honeypot:e.currentTarget.value}),tabIndex:-1,value:A.honeypot}),E(`div`,{className:`lockerverse-signup__fields`,children:[E(`label`,{htmlFor:`${v}-name`,children:[T(`span`,{children:`Name`}),T(`input`,{"aria-describedby":M.name?`${v}-name-error`:void 0,"aria-invalid":M.name?`true`:void 0,autoComplete:`name`,id:`${v}-name`,name:`name`,onChange:e=>L({name:e.currentTarget.value}),required:!0,value:A.name}),T(s,{error:M.name,id:`${v}-name-error`})]}),l.fields.email.enabled?T(r,{error:M.email,id:`${v}-email`,label:`Email`,name:`email`,onChange:e=>L({email:e.currentTarget.value}),required:l.fields.email.required,value:A.email}):null,l.fields.phone.enabled?T(a,{error:M.phone,id:`${v}-phone`,label:`Phone`,children:T(o,{country:A.phoneCountry,error:M.phone,errorId:`${v}-phone-error`,id:`${v}-phone`,inputRef:b,name:`phone`,onChange:({value:e,country:t})=>L({phone:e,phoneCountry:t}),required:l.fields.phone.required,value:A.phone})}):null,l.fields.participantCount.enabled?E(`label`,{htmlFor:`${v}-participant-count`,children:[T(`span`,{children:`Guest count`}),T(`input`,{"aria-describedby":M.participantCount?`${v}-participant-count-error`:void 0,"aria-invalid":M.participantCount?`true`:void 0,id:`${v}-participant-count`,min:1,name:`participantCount`,onChange:e=>L({participantCount:e.currentTarget.value}),required:l.fields.participantCount.required,type:`number`,value:A.participantCount}),T(s,{error:M.participantCount,id:`${v}-participant-count-error`})]}):null,l.fields.address.enabled?E(`div`,{className:`lockerverse-signup__field-group`,children:[T(ne,{apiKey:p,errorId:M.address?`${v}-address-error`:void 0,invalid:!!M.address,onChange:e=>L({address:e}),required:l.fields.address.required,value:A.address}),T(s,{error:M.address,id:`${v}-address-error`})]}):null,T(h,{choiceClassName:`lockerverse-signup__choice`,errorClassName:`lockerverse-signup__field-error`,errors:M,fields:l.customFields,idPrefix:v,onChange:e=>L({customFields:e}),values:I})]}),z?E(`p`,{className:`lockerverse-signup__submit-error`,role:`alert`,children:[z,` Try again.`]}):null,T(`button`,{className:`lockerverse-signup__submit`,disabled:R,type:`submit`,children:R?`Submitting…`:`Submit`})]})]})}function de({widget:e,...t}){return e.error&&!e.signup?E(Q,{status:!0,viewProps:t,children:[T(`h1`,{children:`Signup unavailable`}),T(`p`,{role:`alert`,children:e.error.message}),T(`button`,{onClick:e.refresh,type:`button`,children:`Retry`})]}):e.signup?T(ue,{client:e.client,loadError:e.error,onRetry:e.refresh,signup:e.signup,...t}):T(Q,{loading:!0,viewProps:t,children:T(y,{fieldCount:4,label:`Loading signup…`})})}function $({branding:e}){return E(`div`,{className:`lockerverse-signup__branding`,children:[e.imageUrl?T(`img`,{alt:``,height:48,src:e.imageUrl,width:48}):null,T(`strong`,{children:e.name})]})}function fe(t,{initialSignup:n}={}){let{onError:r}=t;e(`signup`,{apiBaseUrl:t.apiBaseUrl,communitySlug:t.communitySlug,environment:t.environment,slug:t.signupSlug});let i=C(r);i.current=r;let[a]=w(()=>{let e={...t,onError:e=>i.current?.(e)};return L(e)}),[o,s]=w(0),[c,l]=w(()=>({error:null,loading:!0,signup:n??null}));x(()=>{let e=!0;return a.load().then(t=>{e&&l({error:null,loading:!1,signup:t})},t=>{e&&l(e=>({...e,error:t,loading:!1}))}),()=>{e=!1}},[a,o]);let u=b(()=>{l(e=>({...e,error:null,loading:!0})),s(e=>e+1)},[]);return{client:a,error:c.error,loading:c.loading,refresh:u,signup:c.signup}}export{de as LockerverseSignup,fe as useLockerverseSignup};
1
+ import{t as e}from"./immutable-resource-identity.js";import{c as t,d as n,f as r,i,l as a,n as o,o as s,p as c,s as l,t as u}from"./phone-field.js";import{t as d}from"./host-callback.js";import{n as f,t as p}from"./accent-contrast.js";import{i as m,n as h,o as g,r as _,s as v}from"./custom-fields.js";import{t as y}from"./form-skeleton.js";import{useCallback as b,useEffect as x,useId as S,useRef as C,useState as w}from"react";import{jsx as T,jsxs as E}from"react/jsx-runtime";import{check as D,nonEmpty as O,nullable as k,object as A,pipe as j,regex as M,safeParse as N,string as P,transform as F,trim as I}from"valibot";import{createLockerverseSignupClient as L}from"@lockerverse/sdk/signup";const R=`lockerverse-signup-google-places`,z=[`premise`,`subpremise`,`street_address`,`route`];let B=null;function ee(e){let t=window;if(t.google?.maps?.importLibrary)return;t.google||={};let n=t.google;n.maps||={};let r=n.maps,i=null;r.importLibrary=n=>(i||=new Promise((t,i)=>{let a=document.getElementById(R);if(r.__lockerverseSignupReady=t,a){a.addEventListener(`error`,()=>i(Error(`Unable to load Google Places.`)),{once:!0});return}let o=document.createElement(`script`),s=new URLSearchParams({callback:`google.maps.__lockerverseSignupReady`,key:e,libraries:n,v:`weekly`});o.async=!0,o.id=R,o.src=`https://maps.googleapis.com/maps/api/js?${s}`,o.onerror=()=>i(Error(`Unable to load Google Places.`)),document.head.append(o)}),i.then(()=>{let e=t.google?.maps?.importLibrary;if(!e)throw Error(`Unable to load Google Places.`);return e(n)}).catch(e=>{throw i=null,document.getElementById(R)?.remove(),e}))}function V(e){return B||=(async()=>{try{ee(e);let t=window.google?.maps?.importLibrary;if(!t)throw Error(`Unable to load Google Places.`);return await t(`places`)}catch(e){throw B=null,e}})(),B}function H(e,t,n=`longText`){return e.find(e=>e.types.includes(t))?.[n]??``}function te(e,t){let n=t.addressComponents??[],r=[H(n,`street_number`),H(n,`route`)].filter(Boolean).join(` `);return{...e,city:H(n,`locality`)||H(n,`postal_town`)||H(n,`sublocality_level_1`),country:H(n,`country`,`shortText`)||`US`,line1:r||t.formattedAddress?.split(`,`)[0]||``,line2:H(n,`subpremise`),postalCode:[H(n,`postal_code`),H(n,`postal_code_suffix`)].filter(Boolean).join(`-`),state:H(n,`administrative_area_level_1`,`shortText`)}}function ne({apiKey:e,errorId:t,invalid:n,onChange:r,required:i,value:a}){let o=S(),s=`${o}-suggestions`,[c,l]=w(-1),[u,d]=w(!1),[f,p]=w(!1),[m,h]=w([]),g=C(0),_=C(0),v=C(null);x(()=>()=>{g.current+=1},[]),x(()=>{let t=_.current+1;_.current=t;let n=a.line1.trim();if(l(-1),p(!1),!(e&&u&&n.length>=3)){h([]);return}let r=window.setTimeout(async()=>{if(t===_.current){p(!0);try{let{AutocompleteSessionToken:r,AutocompleteSuggestion:i}=await V(e);v.current??=new r;let a=await i.fetchAutocompleteSuggestions({includedPrimaryTypes:z,includedRegionCodes:[`US`],input:n,region:`US`,sessionToken:v.current});t===_.current&&h(a.suggestions.flatMap(({placePrediction:e})=>e?[{id:e.placeId,label:e.mainText?.text??e.text.text,prediction:e,secondaryLabel:e.secondaryText?.text??``}]:[]))}catch{t===_.current&&h([])}finally{t===_.current&&p(!1)}}},250);return()=>{window.clearTimeout(r)}},[e,u,a.line1]);let y=e=>{g.current+=1,r({...a,...e})},b=async e=>{let t=g.current+1;g.current=t;let n=e.prediction.toPlace();try{if(await n.fetchFields({fields:[`addressComponents`,`formattedAddress`]}),t!==g.current)return;r(te(a,n)),v.current=null,h([]),l(-1),d(!1)}catch{if(t!==g.current)return;h([]),l(-1)}},D=e=>{if(e.key===`Escape`){e.preventDefault(),h([]),l(-1);return}if(m.length===0)return;if(e.key===`ArrowDown`){e.preventDefault(),l(e=>e<m.length-1?e+1:0);return}if(e.key===`ArrowUp`){e.preventDefault(),l(e=>e>0?e-1:m.length-1);return}let t=m[c];e.key===`Enter`&&t&&(e.preventDefault(),b(t).catch(()=>void 0))},O=e=>{e.currentTarget.closest(`.lockerverse-signup__address-search`)?.contains(e.relatedTarget)||window.setTimeout(()=>d(!1),120)};return E(`fieldset`,{"aria-describedby":n?t:void 0,"aria-invalid":n?`true`:void 0,className:`lockerverse-signup__address`,children:[T(`legend`,{children:`Address`}),E(`label`,{htmlFor:`${o}-line1`,children:[T(`span`,{children:`Street address`}),E(`div`,{className:`lockerverse-signup__address-search`,children:[T(`input`,{"aria-activedescendant":c>=0?`${o}-suggestion-${c}`:void 0,"aria-autocomplete":`list`,"aria-controls":s,"aria-describedby":n?t:void 0,"aria-expanded":u&&m.length>0,"aria-invalid":n?`true`:void 0,autoComplete:`street-address`,id:`${o}-line1`,name:`address.line1`,onBlur:O,onChange:e=>y({line1:e.currentTarget.value}),onFocus:()=>d(!0),onKeyDown:D,required:i,role:`combobox`,value:a.line1}),f?T(`span`,{className:`lockerverse-signup__address-loading`,children:`Searching…`}):null,m.length>0?T(`div`,{className:`lockerverse-signup__address-suggestions`,id:s,role:`listbox`,children:m.map((e,t)=>E(`button`,{"aria-selected":c===t,id:`${o}-suggestion-${t}`,onBlur:O,onClick:t=>{t.detail===0&&b(e).catch(()=>void 0)},onMouseDown:t=>{t.preventDefault(),b(e).catch(()=>void 0)},role:`option`,type:`button`,children:[T(`strong`,{children:e.label}),e.secondaryLabel?T(`span`,{children:e.secondaryLabel}):null]},e.id))}):null]})]}),E(`label`,{htmlFor:`${o}-line2`,children:[T(`span`,{children:`Apartment, suite, or unit`}),T(`input`,{autoComplete:`address-line2`,id:`${o}-line2`,onChange:e=>y({line2:e.currentTarget.value}),placeholder:`Optional`,value:a.line2??``})]}),E(`div`,{className:`lockerverse-signup__address-row`,children:[E(`label`,{htmlFor:`${o}-city`,children:[T(`span`,{children:`City`}),T(`input`,{autoComplete:`address-level2`,id:`${o}-city`,onChange:e=>y({city:e.currentTarget.value}),required:i,value:a.city})]}),E(`label`,{htmlFor:`${o}-state`,children:[T(`span`,{children:`State`}),T(`input`,{autoComplete:`address-level1`,id:`${o}-state`,onChange:e=>y({state:e.currentTarget.value}),required:i,value:a.state})]})]}),E(`div`,{className:`lockerverse-signup__address-row`,children:[E(`label`,{htmlFor:`${o}-postal`,children:[T(`span`,{children:`Postal code`}),T(`input`,{autoComplete:`postal-code`,id:`${o}-postal`,onChange:e=>y({postalCode:e.currentTarget.value}),required:i,value:a.postalCode})]}),E(`label`,{htmlFor:`${o}-country`,children:[T(`span`,{children:`Country`}),T(`input`,{autoComplete:`country`,id:`${o}-country`,maxLength:2,onChange:e=>y({country:e.currentTarget.value.toUpperCase()}),required:i,value:a.country})]})]})]})}const re=/^[1-9]\d*$/,ie=/^(?:$|[1-9]\d*)$/,ae=j(P(),I(),O(`Name is required.`)),U=j(P(),I(),M(ie,`Guest count must be a positive whole number.`),F(e=>e?Number(e):null),D(e=>e===null||Number.isSafeInteger(e),`Guest count must be a positive whole number.`)),W=j(P(),I(),O(`Guest count is required.`),M(re,`Guest count must be a positive whole number.`),F(Number),D(e=>Number.isSafeInteger(e),`Guest count must be a positive whole number.`)),G=A({city:P(),country:P(),line1:P(),line2:k(P()),postalCode:P(),state:P()}),K=j(G,D(Y,`Complete the address.`)),q={city:``,country:`US`,line1:``,line2:null,postalCode:``,state:``},oe=j(G,D(e=>J(e)||Y(e),`Complete the address or leave it blank.`));function J(e){return![e.city,e.line1,e.line2,e.postalCode,e.state].some(e=>e?.trim())}function Y(e){return[e.city,e.country,e.line1,e.postalCode,e.state].every(e=>e.trim())}function se(e,n){let r={...n,address:e.fields.address.enabled?n.address:q,customFields:g(e.customFields,n.customFields),email:e.fields.email.enabled?n.email:``,participantCount:e.fields.participantCount.enabled?n.participantCount:``,phone:e.fields.phone.enabled?n.phone:``},i=A({address:e.fields.address.enabled&&e.fields.address.required?K:oe,email:e.fields.email.enabled&&e.fields.email.required?t:s,name:ae,participantCount:e.fields.participantCount.enabled&&e.fields.participantCount.required?W:U,phone:e.fields.phone.enabled&&e.fields.phone.required?a:l}),o=N(i,r),c=v(e.customFields,r.customFields);if(!o.success)for(let e of o.issues){let t=e.path?.[0]?.key,n=[`address`,`email`,`name`,`participantCount`,`phone`].find(e=>e===t);n&&!c[n]&&(c[n]=e.message)}return o.success?{errors:c,value:{...r,...o.output}}:{errors:c,value:null}}const ce={city:``,country:`US`,line1:``,line2:``,postalCode:``,state:``};function le(e){return{address:ce,customFields:m(e.customFields),email:``,honeypot:``,name:``,participantCount:``,phone:``,phoneCountry:`US`}}function X(e,t){let n=e.elements.namedItem(t);if(n instanceof HTMLElement)return!n.matches(`:disabled`)&&(n.focus(),!0);if(n instanceof RadioNodeList){let e=Array.from(n).find(e=>e instanceof HTMLElement&&!e.matches(`:disabled`));return e?.focus(),!!e}return!1}function Z(e,t){let n=[[`name`,`name`],[`email`,`email`],[`phone`,`phone`],[`participantCount`,`participantCount`],[`address`,`address.line1`]];for(let[r,i]of n)if(t[r]&&X(e,i))return;let r=new Set(n.map(([e])=>e)),i=Object.keys(t).find(e=>!r.has(e));i&&X(e,`custom:${i}`)}function Q({children:e,loading:t=!1,status:n=!1,viewProps:r}){let{branding:i,className:a,googlePlacesApiKey:o,onSignupComplete:s,style:c,theme:l=`dark`,...u}=r,d=f(c?.[`--lockerverse-accent`]??c?.[`--lockerverse-signup-accent`]??i?.accentColor??`#5751f2`),m={...c};if((c?.[`--lockerverse-accent`]!==void 0||c?.[`--lockerverse-signup-accent`]!==void 0||i?.accentColor)&&(m[`--lockerverse-accent`]=d),c?.[`--lockerverse-accent-contrast`]===void 0&&c?.[`--lockerverse-signup-accent-contrast`]===void 0){let e=p(d);e&&(m[`--lockerverse-accent-contrast`]=e)}return T(`section`,{...u,...t?{"aria-busy":!0}:{},className:[`lockerverse-signup`,n?`lockerverse-signup__status`:null,a].filter(Boolean).join(` `),"data-lockerverse-theme":l,style:m,children:e})}function ue({client:e,loadError:t,onRetry:a,signup:s,...l}){let{branding:f,googlePlacesApiKey:p,onSignupComplete:m}=l,v=S(),y=C(!0),b=C(null),D=C(!1),[O,k]=w({phase:`idle`}),[A,j]=w(()=>le(s)),[M,N]=w({}),[P,F]=w(),I=g(s.customFields,A.customFields);if(x(()=>{I!==A.customFields&&j(e=>({...e,customFields:g(s.customFields,e.customFields)}))},[I,s.customFields,A.customFields]),x(()=>(y.current=!0,()=>{y.current=!1}),[]),x(()=>{O.phase!==`submitting`&&M.phone&&b.current?.focus()},[M.phone,O.phase]),!s.isActive)return E(Q,{status:!0,viewProps:l,children:[T(`h1`,{children:`Signup closed`}),T(`p`,{children:`This signup is not accepting submissions.`})]});if(O.phase===`submitted`)return E(Q,{status:!0,viewProps:l,children:[f?T($,{branding:f}):null,T(`span`,{"aria-hidden":`true`,className:`lockerverse-signup__success`,children:`✓`}),T(`h1`,{children:`Thank you`}),T(`p`,{children:`Your signup has been received.`})]});let L=e=>j(t=>({...t,...e})),R=O.phase===`submitting`,z=O.phase===`submit_error`?O.error.message:void 0;return E(Q,{viewProps:l,children:[s.coverImageUrl?T(`img`,{alt:``,className:`lockerverse-signup__cover`,height:192,src:s.coverImageUrl,width:440}):null,f?T($,{branding:f}):null,E(`header`,{children:[s.title?.trim()?T(`h1`,{children:s.title}):null,s.description?T(`p`,{children:s.description}):null]}),t?E(`div`,{role:`alert`,children:[T(`p`,{children:t.message}),T(`button`,{onClick:a,type:`button`,children:`Retry`})]}):null,E(`form`,{noValidate:!0,onSubmit:async t=>{if(t.preventDefault(),D.current)return;let n=se(s,{...A,customFields:I,phone:s.fields.phone.enabled?o(A.phone,A.phoneCountry):``});if(N(n.errors),Object.keys(n.errors).length>0||!n.value){let e=t.currentTarget;queueMicrotask(()=>Z(e,n.errors));return}let r=n.value,a={address:s.fields.address.enabled&&!J(r.address)?r.address:null,answers:_(s.customFields,r.customFields),email:s.fields.email.enabled&&r.email||null,honeypot:r.honeypot,name:r.name,participantCount:s.fields.participantCount.enabled?r.participantCount:null,phone:s.fields.phone.enabled&&r.phone||null},c=JSON.stringify(a),l=P?.payloadKey===c?P.reference:globalThis.crypto.randomUUID(),u;D.current=!0,k({phase:`submitting`});try{u=await e.submit(a,{submissionReference:l})}catch(e){if(!y.current)return;let t=e,n=i(t.serverCode);if(n){N(e=>({...e,phone:n})),k({phase:`idle`}),F(void 0);return}k({error:t,phase:`submit_error`}),t.recoveryRecommended?F({payloadKey:c,reference:l}):F(void 0);return}finally{D.current=!1}y.current&&(F(void 0),k({phase:`submitted`}),d(m,u))},children:[T(`input`,{"aria-hidden":`true`,autoComplete:`off`,className:`lockerverse-signup__honeypot`,onChange:e=>L({honeypot:e.currentTarget.value}),tabIndex:-1,value:A.honeypot}),E(`div`,{className:`lockerverse-signup__fields`,children:[E(`label`,{htmlFor:`${v}-name`,children:[T(`span`,{children:`Name`}),T(`input`,{"aria-describedby":M.name?`${v}-name-error`:void 0,"aria-invalid":M.name?`true`:void 0,autoComplete:`name`,id:`${v}-name`,name:`name`,onChange:e=>L({name:e.currentTarget.value}),required:!0,value:A.name}),T(r,{error:M.name,id:`${v}-name-error`})]}),s.fields.email.enabled?T(n,{error:M.email,id:`${v}-email`,label:`Email`,name:`email`,onChange:e=>L({email:e.currentTarget.value}),required:s.fields.email.required,value:A.email}):null,s.fields.phone.enabled?T(c,{error:M.phone,id:`${v}-phone`,label:`Phone`,children:T(u,{country:A.phoneCountry,error:M.phone,errorId:`${v}-phone-error`,id:`${v}-phone`,inputRef:b,name:`phone`,onChange:({value:e,country:t})=>L({phone:e,phoneCountry:t}),required:s.fields.phone.required,value:A.phone})}):null,s.fields.participantCount.enabled?E(`label`,{htmlFor:`${v}-participant-count`,children:[T(`span`,{children:`Guest count`}),T(`input`,{"aria-describedby":M.participantCount?`${v}-participant-count-error`:void 0,"aria-invalid":M.participantCount?`true`:void 0,id:`${v}-participant-count`,min:1,name:`participantCount`,onChange:e=>L({participantCount:e.currentTarget.value}),required:s.fields.participantCount.required,type:`number`,value:A.participantCount}),T(r,{error:M.participantCount,id:`${v}-participant-count-error`})]}):null,s.fields.address.enabled?E(`div`,{className:`lockerverse-signup__field-group`,children:[T(ne,{apiKey:p,errorId:M.address?`${v}-address-error`:void 0,invalid:!!M.address,onChange:e=>L({address:e}),required:s.fields.address.required,value:A.address}),T(r,{error:M.address,id:`${v}-address-error`})]}):null,T(h,{choiceClassName:`lockerverse-signup__choice`,errorClassName:`lockerverse-signup__field-error`,errors:M,fields:s.customFields,idPrefix:v,onChange:e=>L({customFields:e}),values:I})]}),z?E(`p`,{className:`lockerverse-signup__submit-error`,role:`alert`,children:[z,` Try again.`]}):null,T(`button`,{className:`lockerverse-signup__submit`,disabled:R,type:`submit`,children:R?`Submitting…`:`Submit`})]})]})}function de({widget:e,...t}){return e.error&&!e.signup?E(Q,{status:!0,viewProps:t,children:[T(`h1`,{children:`Signup unavailable`}),T(`p`,{role:`alert`,children:e.error.message}),T(`button`,{onClick:e.refresh,type:`button`,children:`Retry`})]}):e.signup?T(ue,{client:e.client,loadError:e.error,onRetry:e.refresh,signup:e.signup,...t}):T(Q,{loading:!0,viewProps:t,children:T(y,{fieldCount:4,label:`Loading signup…`})})}function $({branding:e}){return E(`div`,{className:`lockerverse-signup__branding`,children:[e.imageUrl?T(`img`,{alt:``,height:48,src:e.imageUrl,width:48}):null,T(`strong`,{children:e.name})]})}function fe(t,{initialSignup:n}={}){let{onError:r}=t;e(`signup`,{apiBaseUrl:t.apiBaseUrl,communitySlug:t.communitySlug,environment:t.environment,slug:t.signupSlug});let i=C(r);i.current=r;let[a]=w(()=>{let e={...t,onError:e=>i.current?.(e)};return L(e)}),[o,s]=w(0),[c,l]=w(()=>({error:null,loading:!0,signup:n??null}));x(()=>{let e=!0;return a.load().then(t=>{e&&l({error:null,loading:!1,signup:t})},t=>{e&&l(e=>({...e,error:t,loading:!1}))}),()=>{e=!1}},[a,o]);let u=b(()=>{l(e=>({...e,error:null,loading:!0})),s(e=>e+1)},[]);return{client:a,error:c.error,loading:c.loading,refresh:u,signup:c.signup}}export{de as LockerverseSignup,fe as useLockerverseSignup};
2
2
  //# sourceMappingURL=signup.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"signup.js","names":["googleWindow"],"sources":["../src/signup-address-field.tsx","../src/signup-validation.ts","../src/lockerverse-signup.tsx","../src/use-lockerverse-signup.ts"],"sourcesContent":["import {\n type FocusEvent,\n type KeyboardEvent,\n useEffect,\n useId,\n useRef,\n useState,\n} from \"react\";\nimport type { SignupAddressValues } from \"./signup-validation.ts\";\n\ntype GoogleAddressComponent = {\n longText?: string;\n shortText?: string;\n types: string[];\n};\n\ntype GoogleSessionToken = Record<never, never>;\n\ntype GooglePlace = {\n addressComponents?: GoogleAddressComponent[];\n formattedAddress?: string;\n fetchFields: (options: { fields: string[] }) => Promise<void>;\n};\n\ntype GooglePlacePrediction = {\n placeId: string;\n mainText?: { text: string };\n secondaryText?: { text: string };\n text: { text: string };\n toPlace: () => GooglePlace;\n};\n\ntype GooglePlacesLibrary = {\n AutocompleteSessionToken: new () => GoogleSessionToken;\n AutocompleteSuggestion: {\n fetchAutocompleteSuggestions: (options: {\n input: string;\n includedPrimaryTypes: string[];\n includedRegionCodes: string[];\n region: string;\n sessionToken: GoogleSessionToken;\n }) => Promise<{\n suggestions: { placePrediction?: GooglePlacePrediction }[];\n }>;\n };\n};\n\ntype GoogleMapsWindow = Window & {\n google?: {\n maps?: {\n __lockerverseSignupReady?: () => void;\n importLibrary?: (libraryName: string) => Promise<GooglePlacesLibrary>;\n };\n };\n};\n\ntype AddressSuggestion = {\n id: string;\n label: string;\n secondaryLabel: string;\n prediction: GooglePlacePrediction;\n};\n\nconst GOOGLE_MAPS_SCRIPT_ID = \"lockerverse-signup-google-places\";\nconst GOOGLE_ADDRESS_TYPES = [\n \"premise\",\n \"subpremise\",\n \"street_address\",\n \"route\",\n];\nlet googlePlacesLoader: Promise<GooglePlacesLibrary> | null = null;\n\nfunction installGoogleMaps(apiKey: string) {\n const googleWindow: GoogleMapsWindow = window;\n if (googleWindow.google?.maps?.importLibrary) {\n return;\n }\n googleWindow.google ||= {};\n const googleObject = googleWindow.google;\n googleObject.maps ||= {};\n const mapsObject = googleObject.maps;\n let scriptPromise: Promise<void> | null = null;\n mapsObject.importLibrary = (libraryName: string) => {\n scriptPromise ||= new Promise((resolve, reject) => {\n const existingScript = document.getElementById(GOOGLE_MAPS_SCRIPT_ID);\n mapsObject.__lockerverseSignupReady = resolve;\n if (existingScript) {\n existingScript.addEventListener(\n \"error\",\n () => reject(new Error(\"Unable to load Google Places.\")),\n { once: true }\n );\n return;\n }\n const script = document.createElement(\"script\");\n const parameters = new URLSearchParams({\n callback: \"google.maps.__lockerverseSignupReady\",\n key: apiKey,\n libraries: libraryName,\n v: \"weekly\",\n });\n script.async = true;\n script.id = GOOGLE_MAPS_SCRIPT_ID;\n script.src = `https://maps.googleapis.com/maps/api/js?${parameters}`;\n script.onerror = () => reject(new Error(\"Unable to load Google Places.\"));\n document.head.append(script);\n });\n return scriptPromise\n .then(() => {\n const importLibrary = googleWindow.google?.maps?.importLibrary;\n if (!importLibrary) {\n throw new Error(\"Unable to load Google Places.\");\n }\n return importLibrary(libraryName);\n })\n .catch((error) => {\n scriptPromise = null;\n document.getElementById(GOOGLE_MAPS_SCRIPT_ID)?.remove();\n throw error;\n });\n };\n}\n\nfunction loadGooglePlaces(apiKey: string) {\n googlePlacesLoader ||= (async () => {\n try {\n installGoogleMaps(apiKey);\n const googleWindow: GoogleMapsWindow = window;\n const importLibrary = googleWindow.google?.maps?.importLibrary;\n if (!importLibrary) {\n throw new Error(\"Unable to load Google Places.\");\n }\n return await importLibrary(\"places\");\n } catch (error) {\n googlePlacesLoader = null;\n throw error;\n }\n })();\n return googlePlacesLoader;\n}\n\nfunction getAddressPart(\n components: GoogleAddressComponent[],\n type: string,\n key: \"longText\" | \"shortText\" = \"longText\"\n) {\n return (\n components.find((component) => component.types.includes(type))?.[key] ?? \"\"\n );\n}\n\nfunction parseAddress(current: SignupAddressValues, place: GooglePlace) {\n const components = place.addressComponents ?? [];\n const street = [\n getAddressPart(components, \"street_number\"),\n getAddressPart(components, \"route\"),\n ]\n .filter(Boolean)\n .join(\" \");\n return {\n ...current,\n city:\n getAddressPart(components, \"locality\") ||\n getAddressPart(components, \"postal_town\") ||\n getAddressPart(components, \"sublocality_level_1\"),\n country: getAddressPart(components, \"country\", \"shortText\") || \"US\",\n line1: street || place.formattedAddress?.split(\",\")[0] || \"\",\n line2: getAddressPart(components, \"subpremise\"),\n postalCode: [\n getAddressPart(components, \"postal_code\"),\n getAddressPart(components, \"postal_code_suffix\"),\n ]\n .filter(Boolean)\n .join(\"-\"),\n state: getAddressPart(\n components,\n \"administrative_area_level_1\",\n \"shortText\"\n ),\n } satisfies SignupAddressValues;\n}\n\nexport function SignupAddressField({\n apiKey,\n errorId,\n invalid,\n onChange,\n required,\n value,\n}: {\n apiKey: string | undefined;\n errorId: string | undefined;\n invalid: boolean;\n onChange: (address: SignupAddressValues) => void;\n required: boolean;\n value: SignupAddressValues;\n}) {\n const id = useId();\n const listboxId = `${id}-suggestions`;\n const [activeSuggestionIndex, setActiveSuggestionIndex] = useState(-1);\n const [focused, setFocused] = useState(false);\n const [loading, setLoading] = useState(false);\n const [suggestions, setSuggestions] = useState<AddressSuggestion[]>([]);\n const detailRequestGeneration = useRef(0);\n const searchGeneration = useRef(0);\n const sessionToken = useRef<GoogleSessionToken | null>(null);\n\n useEffect(\n () => () => {\n detailRequestGeneration.current += 1;\n },\n []\n );\n\n useEffect(() => {\n const generation = searchGeneration.current + 1;\n searchGeneration.current = generation;\n const query = value.line1.trim();\n setActiveSuggestionIndex(-1);\n setLoading(false);\n if (!(apiKey && focused && query.length >= 3)) {\n setSuggestions([]);\n return;\n }\n const timeout = window.setTimeout(async () => {\n if (generation !== searchGeneration.current) {\n return;\n }\n setLoading(true);\n try {\n const { AutocompleteSessionToken, AutocompleteSuggestion } =\n await loadGooglePlaces(apiKey);\n sessionToken.current ??= new AutocompleteSessionToken();\n const response =\n await AutocompleteSuggestion.fetchAutocompleteSuggestions({\n includedPrimaryTypes: GOOGLE_ADDRESS_TYPES,\n includedRegionCodes: [\"US\"],\n input: query,\n region: \"US\",\n sessionToken: sessionToken.current,\n });\n if (generation === searchGeneration.current) {\n setSuggestions(\n response.suggestions.flatMap(({ placePrediction }) =>\n placePrediction\n ? [\n {\n id: placePrediction.placeId,\n label:\n placePrediction.mainText?.text ??\n placePrediction.text.text,\n prediction: placePrediction,\n secondaryLabel: placePrediction.secondaryText?.text ?? \"\",\n },\n ]\n : []\n )\n );\n }\n } catch {\n if (generation === searchGeneration.current) {\n setSuggestions([]);\n }\n } finally {\n if (generation === searchGeneration.current) {\n setLoading(false);\n }\n }\n }, 250);\n return () => {\n window.clearTimeout(timeout);\n };\n }, [apiKey, focused, value.line1]);\n\n const update = (patch: Partial<SignupAddressValues>) => {\n detailRequestGeneration.current += 1;\n onChange({ ...value, ...patch });\n };\n\n const selectSuggestion = async (suggestion: AddressSuggestion) => {\n const generation = detailRequestGeneration.current + 1;\n detailRequestGeneration.current = generation;\n const place = suggestion.prediction.toPlace();\n try {\n await place.fetchFields({\n fields: [\"addressComponents\", \"formattedAddress\"],\n });\n if (generation !== detailRequestGeneration.current) {\n return;\n }\n onChange(parseAddress(value, place));\n sessionToken.current = null;\n setSuggestions([]);\n setActiveSuggestionIndex(-1);\n setFocused(false);\n } catch {\n if (generation !== detailRequestGeneration.current) {\n return;\n }\n setSuggestions([]);\n setActiveSuggestionIndex(-1);\n }\n };\n\n const handleAddressKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n setSuggestions([]);\n setActiveSuggestionIndex(-1);\n return;\n }\n if (suggestions.length === 0) {\n return;\n }\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n setActiveSuggestionIndex((current) =>\n current < suggestions.length - 1 ? current + 1 : 0\n );\n return;\n }\n if (event.key === \"ArrowUp\") {\n event.preventDefault();\n setActiveSuggestionIndex((current) =>\n current > 0 ? current - 1 : suggestions.length - 1\n );\n return;\n }\n const suggestion = suggestions[activeSuggestionIndex];\n if (event.key === \"Enter\" && suggestion) {\n event.preventDefault();\n selectSuggestion(suggestion).catch(() => undefined);\n }\n };\n\n const handleAddressBlur = (event: FocusEvent<HTMLElement>) => {\n const search = event.currentTarget.closest(\n \".lockerverse-signup__address-search\"\n );\n if (search?.contains(event.relatedTarget)) {\n return;\n }\n window.setTimeout(() => setFocused(false), 120);\n };\n\n return (\n <fieldset\n aria-describedby={invalid ? errorId : undefined}\n aria-invalid={invalid ? \"true\" : undefined}\n className=\"lockerverse-signup__address\"\n >\n <legend>Address</legend>\n <label htmlFor={`${id}-line1`}>\n <span>Street address</span>\n <div className=\"lockerverse-signup__address-search\">\n <input\n aria-activedescendant={\n activeSuggestionIndex >= 0\n ? `${id}-suggestion-${activeSuggestionIndex}`\n : undefined\n }\n aria-autocomplete=\"list\"\n aria-controls={listboxId}\n aria-describedby={invalid ? errorId : undefined}\n aria-expanded={focused && suggestions.length > 0}\n aria-invalid={invalid ? \"true\" : undefined}\n autoComplete=\"street-address\"\n id={`${id}-line1`}\n name=\"address.line1\"\n onBlur={handleAddressBlur}\n onChange={(event) => update({ line1: event.currentTarget.value })}\n onFocus={() => setFocused(true)}\n onKeyDown={handleAddressKeyDown}\n required={required}\n role=\"combobox\"\n value={value.line1}\n />\n {loading ? (\n <span className=\"lockerverse-signup__address-loading\">\n Searching…\n </span>\n ) : null}\n {suggestions.length > 0 ? (\n <div\n className=\"lockerverse-signup__address-suggestions\"\n id={listboxId}\n role=\"listbox\"\n >\n {suggestions.map((suggestion, index) => (\n <button\n aria-selected={activeSuggestionIndex === index}\n id={`${id}-suggestion-${index}`}\n key={suggestion.id}\n onBlur={handleAddressBlur}\n onClick={(event) => {\n // Keyboard activation fires click without a prior mouse down.\n if (event.detail === 0) {\n selectSuggestion(suggestion).catch(() => undefined);\n }\n }}\n onMouseDown={(event) => {\n event.preventDefault();\n selectSuggestion(suggestion).catch(() => undefined);\n }}\n role=\"option\"\n type=\"button\"\n >\n <strong>{suggestion.label}</strong>\n {suggestion.secondaryLabel ? (\n <span>{suggestion.secondaryLabel}</span>\n ) : null}\n </button>\n ))}\n </div>\n ) : null}\n </div>\n </label>\n <label htmlFor={`${id}-line2`}>\n <span>Apartment, suite, or unit</span>\n <input\n autoComplete=\"address-line2\"\n id={`${id}-line2`}\n onChange={(event) => update({ line2: event.currentTarget.value })}\n placeholder=\"Optional\"\n value={value.line2 ?? \"\"}\n />\n </label>\n <div className=\"lockerverse-signup__address-row\">\n <label htmlFor={`${id}-city`}>\n <span>City</span>\n <input\n autoComplete=\"address-level2\"\n id={`${id}-city`}\n onChange={(event) => update({ city: event.currentTarget.value })}\n required={required}\n value={value.city}\n />\n </label>\n <label htmlFor={`${id}-state`}>\n <span>State</span>\n <input\n autoComplete=\"address-level1\"\n id={`${id}-state`}\n onChange={(event) => update({ state: event.currentTarget.value })}\n required={required}\n value={value.state}\n />\n </label>\n </div>\n <div className=\"lockerverse-signup__address-row\">\n <label htmlFor={`${id}-postal`}>\n <span>Postal code</span>\n <input\n autoComplete=\"postal-code\"\n id={`${id}-postal`}\n onChange={(event) =>\n update({ postalCode: event.currentTarget.value })\n }\n required={required}\n value={value.postalCode}\n />\n </label>\n <label htmlFor={`${id}-country`}>\n <span>Country</span>\n <input\n autoComplete=\"country\"\n id={`${id}-country`}\n maxLength={2}\n onChange={(event) =>\n update({ country: event.currentTarget.value.toUpperCase() })\n }\n required={required}\n value={value.country}\n />\n </label>\n </div>\n </fieldset>\n );\n}\n","import type {\n LockerverseSignup,\n LockerverseSignupAddress,\n} from \"@lockerverse/sdk/signup\";\nimport {\n check,\n nonEmpty,\n nullable,\n object,\n pipe,\n regex,\n safeParse,\n string,\n transform,\n trim,\n} from \"valibot\";\nimport {\n optionalEmailSchema,\n optionalPhoneSchema,\n requiredEmailSchema,\n requiredPhoneSchema,\n} from \"./contact-validation.ts\";\nimport {\n type CustomFieldValues,\n reconcileCustomFieldValues,\n validateCustomFields,\n} from \"./custom-fields.tsx\";\n\nconst POSITIVE_INTEGER_PATTERN = /^[1-9]\\d*$/;\nconst OPTIONAL_POSITIVE_INTEGER_PATTERN = /^(?:$|[1-9]\\d*)$/;\n\nexport type SignupAddressValues = Omit<LockerverseSignupAddress, \"line2\"> & {\n line2: string | null;\n};\n\nexport type SignupFormValues = {\n address: SignupAddressValues;\n customFields: CustomFieldValues;\n email: string;\n honeypot: string;\n name: string;\n participantCount: string;\n phone: string;\n phoneCountry: string;\n};\n\nconst nameSchema = pipe(string(), trim(), nonEmpty(\"Name is required.\"));\nconst optionalParticipantCountSchema = pipe(\n string(),\n trim(),\n regex(\n OPTIONAL_POSITIVE_INTEGER_PATTERN,\n \"Guest count must be a positive whole number.\"\n ),\n transform((value) => (value ? Number(value) : null)),\n check(\n (value) => value === null || Number.isSafeInteger(value),\n \"Guest count must be a positive whole number.\"\n )\n);\nconst requiredParticipantCountSchema = pipe(\n string(),\n trim(),\n nonEmpty(\"Guest count is required.\"),\n regex(\n POSITIVE_INTEGER_PATTERN,\n \"Guest count must be a positive whole number.\"\n ),\n transform(Number),\n check(\n (value) => Number.isSafeInteger(value),\n \"Guest count must be a positive whole number.\"\n )\n);\nconst addressFieldsSchema = object({\n city: string(),\n country: string(),\n line1: string(),\n line2: nullable(string()),\n postalCode: string(),\n state: string(),\n});\nconst requiredAddressSchema = pipe(\n addressFieldsSchema,\n check(isAddressComplete, \"Complete the address.\")\n);\n\nconst EMPTY_ADDRESS: SignupAddressValues = {\n city: \"\",\n country: \"US\",\n line1: \"\",\n line2: null,\n postalCode: \"\",\n state: \"\",\n};\nconst optionalAddressSchema = pipe(\n addressFieldsSchema,\n check(\n (address) => isAddressEmpty(address) || isAddressComplete(address),\n \"Complete the address or leave it blank.\"\n )\n);\n\nexport function isAddressEmpty(address: SignupAddressValues) {\n return ![\n address.city,\n address.line1,\n address.line2,\n address.postalCode,\n address.state,\n ].some((value) => value?.trim());\n}\n\nfunction isAddressComplete(address: SignupAddressValues) {\n return [\n address.city,\n address.country,\n address.line1,\n address.postalCode,\n address.state,\n ].every((value) => value.trim());\n}\n\n/** Phone must already be normalized by the shared phone helper when enabled. */\nexport function validateSignupForm(\n signup: LockerverseSignup,\n values: SignupFormValues\n) {\n const normalizedValues = {\n ...values,\n address: signup.fields.address.enabled ? values.address : EMPTY_ADDRESS,\n customFields: reconcileCustomFieldValues(\n signup.customFields,\n values.customFields\n ),\n email: signup.fields.email.enabled ? values.email : \"\",\n participantCount: signup.fields.participantCount.enabled\n ? values.participantCount\n : \"\",\n phone: signup.fields.phone.enabled ? values.phone : \"\",\n };\n const schema = object({\n address:\n signup.fields.address.enabled && signup.fields.address.required\n ? requiredAddressSchema\n : optionalAddressSchema,\n email:\n signup.fields.email.enabled && signup.fields.email.required\n ? requiredEmailSchema\n : optionalEmailSchema,\n name: nameSchema,\n participantCount:\n signup.fields.participantCount.enabled &&\n signup.fields.participantCount.required\n ? requiredParticipantCountSchema\n : optionalParticipantCountSchema,\n phone:\n signup.fields.phone.enabled && signup.fields.phone.required\n ? requiredPhoneSchema\n : optionalPhoneSchema,\n });\n const result = safeParse(schema, normalizedValues);\n const errors = validateCustomFields(\n signup.customFields,\n normalizedValues.customFields\n );\n if (!result.success) {\n for (const issue of result.issues) {\n const field = issue.path?.[0]?.key;\n const fieldName = [\n \"address\",\n \"email\",\n \"name\",\n \"participantCount\",\n \"phone\",\n ].find((name) => name === field);\n if (fieldName && !errors[fieldName]) {\n errors[fieldName] = issue.message;\n }\n }\n }\n return result.success\n ? { errors, value: { ...normalizedValues, ...result.output } }\n : { errors, value: null };\n}\n","import type {\n LockerverseSdkError,\n LockerverseSignupClient,\n LockerverseSignup as LockerverseSignupDefinition,\n LockerverseSignupSubmissionResult,\n} from \"@lockerverse/sdk/signup\";\nimport {\n type FormEvent,\n type ReactNode,\n useEffect,\n useId,\n useRef,\n useState,\n} from \"react\";\nimport { getAccentContrast, normalizeAccentColor } from \"./accent-contrast.ts\";\nimport { getPhoneServerError } from \"./contact-validation.ts\";\nimport {\n buildCustomFieldAnswers,\n CustomFields,\n createCustomFieldValues,\n reconcileCustomFieldValues,\n} from \"./custom-fields.tsx\";\nimport { EmailField, FieldError, FormField } from \"./form-field.tsx\";\nimport { FormSkeleton } from \"./form-skeleton.tsx\";\nimport { notifyHostCallback } from \"./host-callback.ts\";\nimport { getInternationalPhone } from \"./phone.ts\";\nimport { PhoneInput } from \"./phone-field.tsx\";\nimport { SignupAddressField } from \"./signup-address-field.tsx\";\nimport type { LockerverseSignupProps } from \"./signup-types.ts\";\nimport {\n type SignupFormValues as FormValues,\n isAddressEmpty,\n type SignupAddressValues,\n validateSignupForm,\n} from \"./signup-validation.ts\";\n\nconst DEFAULT_ADDRESS: SignupAddressValues = {\n city: \"\",\n country: \"US\",\n line1: \"\",\n line2: \"\",\n postalCode: \"\",\n state: \"\",\n};\n\nconst DEFAULT_ACCENT = \"#5751f2\";\n\nfunction createInitialValues(signup: LockerverseSignupDefinition): FormValues {\n return {\n address: DEFAULT_ADDRESS,\n customFields: createCustomFieldValues(signup.customFields),\n email: \"\",\n honeypot: \"\",\n name: \"\",\n participantCount: \"\",\n phone: \"\",\n phoneCountry: \"US\",\n };\n}\n\nfunction focusNamedControl(form: HTMLFormElement, name: string) {\n const control = form.elements.namedItem(name);\n if (control instanceof HTMLElement) {\n if (!control.matches(\":disabled\")) {\n control.focus();\n return true;\n }\n return false;\n }\n if (control instanceof RadioNodeList) {\n const focusable = Array.from(control).find(\n (item) => item instanceof HTMLElement && !item.matches(\":disabled\")\n );\n focusable?.focus();\n return Boolean(focusable);\n }\n return false;\n}\n\nfunction focusFirstSignupValidationError(\n form: HTMLFormElement,\n errors: Record<string, string>\n) {\n const builtInFields: [string, string][] = [\n [\"name\", \"name\"],\n [\"email\", \"email\"],\n [\"phone\", \"phone\"],\n [\"participantCount\", \"participantCount\"],\n [\"address\", \"address.line1\"],\n ];\n for (const [errorKey, controlName] of builtInFields) {\n if (errors[errorKey] && focusNamedControl(form, controlName)) {\n return;\n }\n }\n const builtInKeys = new Set(builtInFields.map(([errorKey]) => errorKey));\n const customFieldId = Object.keys(errors).find(\n (errorKey) => !builtInKeys.has(errorKey)\n );\n if (customFieldId) {\n focusNamedControl(form, `custom:${customFieldId}`);\n }\n}\n\ntype SignupViewProps = Omit<LockerverseSignupProps, \"widget\">;\n\nfunction SignupShell({\n children,\n loading = false,\n status = false,\n viewProps,\n}: {\n children: ReactNode;\n loading?: boolean;\n status?: boolean;\n viewProps: SignupViewProps;\n}) {\n const {\n branding,\n className,\n googlePlacesApiKey: _googlePlacesApiKey,\n onSignupComplete: _onSignupComplete,\n style,\n theme = \"dark\",\n ...sectionProps\n } = viewProps;\n const accent = normalizeAccentColor(\n style?.[\"--lockerverse-accent\"] ??\n style?.[\"--lockerverse-signup-accent\"] ??\n branding?.accentColor ??\n DEFAULT_ACCENT\n );\n const signupStyle: LockerverseSignupProps[\"style\"] = { ...style };\n if (\n style?.[\"--lockerverse-accent\"] !== undefined ||\n style?.[\"--lockerverse-signup-accent\"] !== undefined ||\n branding?.accentColor\n ) {\n signupStyle[\"--lockerverse-accent\"] = accent;\n }\n if (\n style?.[\"--lockerverse-accent-contrast\"] === undefined &&\n style?.[\"--lockerverse-signup-accent-contrast\"] === undefined\n ) {\n const accentContrast = getAccentContrast(accent);\n if (accentContrast) {\n signupStyle[\"--lockerverse-accent-contrast\"] = accentContrast;\n }\n }\n return (\n <section\n {...sectionProps}\n {...(loading ? { \"aria-busy\": true } : {})}\n className={[\n \"lockerverse-signup\",\n status ? \"lockerverse-signup__status\" : null,\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n data-lockerverse-theme={theme}\n style={signupStyle}\n >\n {children}\n </section>\n );\n}\n\ntype SignupSubmissionState =\n | { phase: \"idle\" }\n | { phase: \"submitting\" }\n | {\n error: LockerverseSdkError;\n phase: \"submit_error\";\n }\n | {\n phase: \"submitted\";\n };\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: The component renders server-defined field branches in one public form boundary.\nfunction SignupForm({\n client,\n loadError,\n onRetry,\n signup,\n ...viewProps\n}: SignupViewProps & {\n client: LockerverseSignupClient;\n loadError?: LockerverseSdkError | null;\n onRetry?: () => void;\n signup: LockerverseSignupDefinition;\n}) {\n const { branding, googlePlacesApiKey, onSignupComplete } = viewProps;\n const idPrefix = useId();\n const mountedRef = useRef(true);\n const phoneRef = useRef<HTMLInputElement>(null);\n const submittingRef = useRef(false);\n const [state, setState] = useState<SignupSubmissionState>({ phase: \"idle\" });\n const [values, setValues] = useState<FormValues>(() =>\n createInitialValues(signup)\n );\n const [errors, setErrors] = useState<Record<string, string>>({});\n const [submissionRetry, setSubmissionRetry] = useState<{\n payloadKey: string;\n reference: string;\n }>();\n const customFieldValues = reconcileCustomFieldValues(\n signup.customFields,\n values.customFields\n );\n\n useEffect(() => {\n if (customFieldValues !== values.customFields) {\n setValues((current) => ({\n ...current,\n customFields: reconcileCustomFieldValues(\n signup.customFields,\n current.customFields\n ),\n }));\n }\n }, [customFieldValues, signup.customFields, values.customFields]);\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n useEffect(() => {\n if (state.phase !== \"submitting\" && errors.phone) {\n phoneRef.current?.focus();\n }\n }, [errors.phone, state.phase]);\n\n if (!signup.isActive) {\n return (\n <SignupShell status viewProps={viewProps}>\n <h1>Signup closed</h1>\n <p>This signup is not accepting submissions.</p>\n </SignupShell>\n );\n }\n\n if (state.phase === \"submitted\") {\n return (\n <SignupShell status viewProps={viewProps}>\n {branding ? <Branding branding={branding} /> : null}\n <span aria-hidden=\"true\" className=\"lockerverse-signup__success\">\n ✓\n </span>\n <h1>Thank you</h1>\n <p>Your signup has been received.</p>\n </SignupShell>\n );\n }\n\n const update = (patch: Partial<FormValues>) =>\n setValues((current) => ({ ...current, ...patch }));\n const submitting = state.phase === \"submitting\";\n const submitError =\n state.phase === \"submit_error\" ? state.error.message : undefined;\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Submission maps the enabled server-defined fields to one SDK request.\n const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n // biome-ignore lint/suspicious/noUnnecessaryConditions: The ref blocks a second submit before React commits the submitting state.\n if (submittingRef.current) {\n return;\n }\n const validation = validateSignupForm(signup, {\n ...values,\n customFields: customFieldValues,\n phone: signup.fields.phone.enabled\n ? getInternationalPhone(values.phone, values.phoneCountry)\n : \"\",\n });\n setErrors(validation.errors);\n if (Object.keys(validation.errors).length > 0 || !validation.value) {\n const form = event.currentTarget;\n queueMicrotask(() =>\n focusFirstSignupValidationError(form, validation.errors)\n );\n return;\n }\n const validatedValues = validation.value;\n const submission = {\n address:\n signup.fields.address.enabled &&\n !isAddressEmpty(validatedValues.address)\n ? validatedValues.address\n : null,\n answers: buildCustomFieldAnswers(\n signup.customFields,\n validatedValues.customFields\n ),\n email: signup.fields.email.enabled ? validatedValues.email || null : null,\n honeypot: validatedValues.honeypot,\n name: validatedValues.name,\n participantCount: signup.fields.participantCount.enabled\n ? validatedValues.participantCount\n : null,\n phone: signup.fields.phone.enabled ? validatedValues.phone || null : null,\n };\n const payloadKey = JSON.stringify(submission);\n const submissionReference =\n submissionRetry?.payloadKey === payloadKey\n ? submissionRetry.reference\n : globalThis.crypto.randomUUID();\n let result: LockerverseSignupSubmissionResult;\n submittingRef.current = true;\n setState({ phase: \"submitting\" });\n try {\n result = await client.submit(submission, { submissionReference });\n } catch (error) {\n if (!mountedRef.current) {\n return;\n }\n // SAFETY: LockerverseSignupClient normalizes each submission rejection to LockerverseSdkError.\n const sdkError = error as LockerverseSdkError;\n const phoneError = getPhoneServerError(sdkError.serverCode);\n if (phoneError) {\n setErrors((current) => ({ ...current, phone: phoneError }));\n setState({ phase: \"idle\" });\n setSubmissionRetry(undefined);\n return;\n }\n setState({ error: sdkError, phase: \"submit_error\" });\n if (sdkError.recoveryRecommended) {\n setSubmissionRetry({\n payloadKey,\n reference: submissionReference,\n });\n } else {\n setSubmissionRetry(undefined);\n }\n return;\n } finally {\n submittingRef.current = false;\n }\n // biome-ignore lint/suspicious/noUnnecessaryConditions: The ref changes during unmount while this request is pending.\n if (!mountedRef.current) {\n return;\n }\n setSubmissionRetry(undefined);\n setState({ phase: \"submitted\" });\n notifyHostCallback(onSignupComplete, result);\n };\n\n return (\n <SignupShell viewProps={viewProps}>\n {signup.coverImageUrl ? (\n <img\n alt=\"\"\n className=\"lockerverse-signup__cover\"\n height={192}\n src={signup.coverImageUrl}\n width={440}\n />\n ) : null}\n {branding ? <Branding branding={branding} /> : null}\n <header>\n {signup.title?.trim() ? <h1>{signup.title}</h1> : null}\n {signup.description ? <p>{signup.description}</p> : null}\n </header>\n {loadError ? (\n <div role=\"alert\">\n <p>{loadError.message}</p>\n <button onClick={onRetry} type=\"button\">\n Retry\n </button>\n </div>\n ) : null}\n <form noValidate onSubmit={handleSubmit}>\n <input\n aria-hidden=\"true\"\n autoComplete=\"off\"\n className=\"lockerverse-signup__honeypot\"\n onChange={(event) => update({ honeypot: event.currentTarget.value })}\n tabIndex={-1}\n value={values.honeypot}\n />\n <div className=\"lockerverse-signup__fields\">\n <label htmlFor={`${idPrefix}-name`}>\n <span>Name</span>\n <input\n aria-describedby={\n errors.name ? `${idPrefix}-name-error` : undefined\n }\n aria-invalid={errors.name ? \"true\" : undefined}\n autoComplete=\"name\"\n id={`${idPrefix}-name`}\n name=\"name\"\n onChange={(event) => update({ name: event.currentTarget.value })}\n required\n value={values.name}\n />\n <FieldError error={errors.name} id={`${idPrefix}-name-error`} />\n </label>\n {signup.fields.email.enabled ? (\n <EmailField\n error={errors.email}\n id={`${idPrefix}-email`}\n label=\"Email\"\n name=\"email\"\n onChange={(event) => update({ email: event.currentTarget.value })}\n required={signup.fields.email.required}\n value={values.email}\n />\n ) : null}\n {signup.fields.phone.enabled ? (\n <FormField\n error={errors.phone}\n id={`${idPrefix}-phone`}\n label=\"Phone\"\n >\n <PhoneInput\n country={values.phoneCountry}\n error={errors.phone}\n errorId={`${idPrefix}-phone-error`}\n id={`${idPrefix}-phone`}\n inputRef={phoneRef}\n name=\"phone\"\n onChange={({ value, country }) =>\n update({ phone: value, phoneCountry: country })\n }\n required={signup.fields.phone.required}\n value={values.phone}\n />\n </FormField>\n ) : null}\n {signup.fields.participantCount.enabled ? (\n <label htmlFor={`${idPrefix}-participant-count`}>\n <span>Guest count</span>\n <input\n aria-describedby={\n errors.participantCount\n ? `${idPrefix}-participant-count-error`\n : undefined\n }\n aria-invalid={errors.participantCount ? \"true\" : undefined}\n id={`${idPrefix}-participant-count`}\n min={1}\n name=\"participantCount\"\n onChange={(event) =>\n update({ participantCount: event.currentTarget.value })\n }\n required={signup.fields.participantCount.required}\n type=\"number\"\n value={values.participantCount}\n />\n <FieldError\n error={errors.participantCount}\n id={`${idPrefix}-participant-count-error`}\n />\n </label>\n ) : null}\n {signup.fields.address.enabled ? (\n <div className=\"lockerverse-signup__field-group\">\n <SignupAddressField\n apiKey={googlePlacesApiKey}\n errorId={\n errors.address ? `${idPrefix}-address-error` : undefined\n }\n invalid={Boolean(errors.address)}\n onChange={(address) => update({ address })}\n required={signup.fields.address.required}\n value={values.address}\n />\n <FieldError\n error={errors.address}\n id={`${idPrefix}-address-error`}\n />\n </div>\n ) : null}\n <CustomFields\n choiceClassName=\"lockerverse-signup__choice\"\n errorClassName=\"lockerverse-signup__field-error\"\n errors={errors}\n fields={signup.customFields}\n idPrefix={idPrefix}\n onChange={(customFields) => update({ customFields })}\n values={customFieldValues}\n />\n </div>\n {submitError ? (\n <p className=\"lockerverse-signup__submit-error\" role=\"alert\">\n {submitError} Try again.\n </p>\n ) : null}\n <button\n className=\"lockerverse-signup__submit\"\n disabled={submitting}\n type=\"submit\"\n >\n {submitting ? \"Submitting…\" : \"Submit\"}\n </button>\n </form>\n </SignupShell>\n );\n}\n\nexport function LockerverseSignup({\n widget,\n ...viewProps\n}: LockerverseSignupProps) {\n if (widget.error && !widget.signup) {\n return (\n <SignupShell status viewProps={viewProps}>\n <h1>Signup unavailable</h1>\n <p role=\"alert\">{widget.error.message}</p>\n <button onClick={widget.refresh} type=\"button\">\n Retry\n </button>\n </SignupShell>\n );\n }\n if (!widget.signup) {\n return (\n <SignupShell loading viewProps={viewProps}>\n <FormSkeleton fieldCount={4} label=\"Loading signup…\" />\n </SignupShell>\n );\n }\n return (\n <SignupForm\n client={widget.client}\n loadError={widget.error}\n onRetry={widget.refresh}\n signup={widget.signup}\n {...viewProps}\n />\n );\n}\n\nfunction Branding({\n branding,\n}: {\n branding: NonNullable<LockerverseSignupProps[\"branding\"]>;\n}) {\n return (\n <div className=\"lockerverse-signup__branding\">\n {branding.imageUrl ? (\n <img alt=\"\" height={48} src={branding.imageUrl} width={48} />\n ) : null}\n <strong>{branding.name}</strong>\n </div>\n );\n}\n","import {\n type CreateLockerverseSignupOptions,\n createLockerverseSignupClient,\n type LockerverseSdkError,\n type LockerverseSignup,\n type LockerverseSignupClient,\n} from \"@lockerverse/sdk/signup\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useImmutableResourceIdentity } from \"./immutable-resource-identity.ts\";\n\ntype SignupLoadState = {\n error: LockerverseSdkError | null;\n loading: boolean;\n signup: LockerverseSignup | null;\n};\n\nexport type UseLockerverseSignupOptions = {\n /** Initial public SDK snapshot. The hook still refreshes on mount. */\n initialSignup?: LockerverseSignup;\n};\n\nexport type UseLockerverseSignupResult = {\n client: LockerverseSignupClient;\n error: LockerverseSdkError | null;\n loading: boolean;\n refresh: () => void;\n signup: LockerverseSignup | null;\n};\n\nexport function useLockerverseSignup(\n options: CreateLockerverseSignupOptions,\n { initialSignup }: UseLockerverseSignupOptions = {}\n): UseLockerverseSignupResult {\n const { onError } = options;\n useImmutableResourceIdentity(\"signup\", {\n apiBaseUrl: options.apiBaseUrl,\n communitySlug: options.communitySlug,\n environment: options.environment,\n slug: options.signupSlug,\n });\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const [client] = useState(() => {\n const clientOptions: CreateLockerverseSignupOptions = {\n ...options,\n onError: (error) => onErrorRef.current?.(error),\n };\n return createLockerverseSignupClient(clientOptions);\n });\n const [revision, setRevision] = useState(0);\n const [state, setState] = useState<SignupLoadState>(() => ({\n error: null,\n loading: true,\n signup: initialSignup ?? null,\n }));\n\n useEffect(() => {\n let active = true;\n client.load().then(\n (signup) => {\n if (active) {\n setState({\n error: null,\n loading: false,\n signup,\n });\n }\n },\n (error: LockerverseSdkError) => {\n if (active) {\n setState((current) => ({ ...current, error, loading: false }));\n }\n }\n );\n return () => {\n active = false;\n };\n }, [client, revision]);\n\n const refresh = useCallback(() => {\n setState((current) => ({ ...current, error: null, loading: true }));\n setRevision((value) => value + 1);\n }, []);\n\n return {\n client,\n error: state.error,\n loading: state.loading,\n refresh,\n signup: state.signup,\n };\n}\n"],"mappings":"+nBA+DA,MAAM,EAAwB,mCACxB,EAAuB,CAC3B,UACA,aACA,iBACA,OACF,EACA,IAAI,EAA0D,KAE9D,SAAS,GAAkB,EAAgB,CACzC,IAAM,EAAiC,OACvC,GAAI,EAAa,QAAQ,MAAM,cAC7B,OAEF,EAAa,SAAW,CAAC,EACzB,IAAM,EAAe,EAAa,OAClC,EAAa,OAAS,CAAC,EACvB,IAAM,EAAa,EAAa,KAC5B,EAAsC,KAC1C,EAAW,cAAiB,IAC1B,IAAkB,IAAI,SAAS,EAAS,IAAW,CACjD,IAAM,EAAiB,SAAS,eAAe,CAAqB,EAEpE,GADA,EAAW,yBAA2B,EAClC,EAAgB,CAClB,EAAe,iBACb,YACM,EAAW,MAAM,+BAA+B,CAAC,EACvD,CAAE,KAAM,EAAK,CACf,EACA,MACF,CACA,IAAM,EAAS,SAAS,cAAc,QAAQ,EACxC,EAAa,IAAI,gBAAgB,CACrC,SAAU,uCACV,IAAK,EACL,UAAW,EACX,EAAG,QACL,CAAC,EACD,EAAO,MAAQ,GACf,EAAO,GAAK,EACZ,EAAO,IAAM,2CAA2C,IACxD,EAAO,YAAgB,EAAW,MAAM,+BAA+B,CAAC,EACxE,SAAS,KAAK,OAAO,CAAM,CAC7B,CAAC,EACM,EACJ,SAAW,CACV,IAAM,EAAgB,EAAa,QAAQ,MAAM,cACjD,GAAI,CAAC,EACH,MAAU,MAAM,+BAA+B,EAEjD,OAAO,EAAc,CAAW,CAClC,CAAC,CAAC,CACD,MAAO,GAAU,CAGhB,KAFA,GAAgB,KAChB,SAAS,eAAe,CAAqB,CAAC,EAAE,OAAO,EACjD,CACR,CAAC,EAEP,CAEA,SAAS,EAAiB,EAAgB,CAexC,MAdA,MAAwB,SAAY,CAClC,GAAI,CACF,GAAkB,CAAM,EAExB,IAAM,EAAgBA,OAAa,QAAQ,MAAM,cACjD,GAAI,CAAC,EACH,MAAU,MAAM,+BAA+B,EAEjD,OAAO,MAAM,EAAc,QAAQ,CACrC,OAAS,EAAO,CAEd,KADA,GAAqB,KACf,CACR,CACF,EAAA,CAAG,EACI,CACT,CAEA,SAAS,EACP,EACA,EACA,EAAgC,WAChC,CACA,OACE,EAAW,KAAM,GAAc,EAAU,MAAM,SAAS,CAAI,CAAC,CAAC,GAAG,IAAQ,EAE7E,CAEA,SAAS,GAAa,EAA8B,EAAoB,CACtE,IAAM,EAAa,EAAM,mBAAqB,CAAC,EACzC,EAAS,CACb,EAAe,EAAY,eAAe,EAC1C,EAAe,EAAY,OAAO,CACpC,CAAC,CACE,OAAO,OAAO,CAAC,CACf,KAAK,GAAG,EACX,MAAO,CACL,GAAG,EACH,KACE,EAAe,EAAY,UAAU,GACrC,EAAe,EAAY,aAAa,GACxC,EAAe,EAAY,qBAAqB,EAClD,QAAS,EAAe,EAAY,UAAW,WAAW,GAAK,KAC/D,MAAO,GAAU,EAAM,kBAAkB,MAAM,GAAG,CAAC,CAAC,IAAM,GAC1D,MAAO,EAAe,EAAY,YAAY,EAC9C,WAAY,CACV,EAAe,EAAY,aAAa,EACxC,EAAe,EAAY,oBAAoB,CACjD,CAAC,CACE,OAAO,OAAO,CAAC,CACf,KAAK,GAAG,EACX,MAAO,EACL,EACA,8BACA,WACF,CACF,CACF,CAEA,SAAgB,GAAmB,CACjC,SACA,UACA,UACA,WACA,WACA,SAQC,CACD,IAAM,EAAK,EAAM,EACX,EAAY,GAAG,EAAG,cAClB,CAAC,EAAuB,GAA4B,EAAS,EAAE,EAC/D,CAAC,EAAS,GAAc,EAAS,EAAK,EACtC,CAAC,EAAS,GAAc,EAAS,EAAK,EACtC,CAAC,EAAa,GAAkB,EAA8B,CAAC,CAAC,EAChE,EAA0B,EAAO,CAAC,EAClC,EAAmB,EAAO,CAAC,EAC3B,EAAe,EAAkC,IAAI,EAE3D,UACc,CACV,EAAwB,SAAW,CACrC,EACA,CAAC,CACH,EAEA,MAAgB,CACd,IAAM,EAAa,EAAiB,QAAU,EAC9C,EAAiB,QAAU,EAC3B,IAAM,EAAQ,EAAM,MAAM,KAAK,EAG/B,GAFA,EAAyB,EAAE,EAC3B,EAAW,EAAK,EACZ,EAAE,GAAU,GAAW,EAAM,QAAU,GAAI,CAC7C,EAAe,CAAC,CAAC,EACjB,MACF,CACA,IAAM,EAAU,OAAO,WAAW,SAAY,CACxC,OAAe,EAAiB,QAGpC,GAAW,EAAI,EACf,GAAI,CACF,GAAM,CAAE,2BAA0B,0BAChC,MAAM,EAAiB,CAAM,EAC/B,EAAa,UAAY,IAAI,EAC7B,IAAM,EACJ,MAAM,EAAuB,6BAA6B,CACxD,qBAAsB,EACtB,oBAAqB,CAAC,IAAI,EAC1B,MAAO,EACP,OAAQ,KACR,aAAc,EAAa,OAC7B,CAAC,EACC,IAAe,EAAiB,SAClC,EACE,EAAS,YAAY,SAAS,CAAE,qBAC9B,EACI,CACE,CACE,GAAI,EAAgB,QACpB,MACE,EAAgB,UAAU,MAC1B,EAAgB,KAAK,KACvB,WAAY,EACZ,eAAgB,EAAgB,eAAe,MAAQ,EACzD,CACF,EACA,CAAC,CACP,CACF,CAEJ,MAAQ,CACF,IAAe,EAAiB,SAClC,EAAe,CAAC,CAAC,CAErB,QAAU,CACJ,IAAe,EAAiB,SAClC,EAAW,EAAK,CAEpB,CAvCe,CAwCjB,EAAG,GAAG,EACN,UAAa,CACX,OAAO,aAAa,CAAO,CAC7B,CACF,EAAG,CAAC,EAAQ,EAAS,EAAM,KAAK,CAAC,EAEjC,IAAM,EAAU,GAAwC,CACtD,EAAwB,SAAW,EACnC,EAAS,CAAE,GAAG,EAAO,GAAG,CAAM,CAAC,CACjC,EAEM,EAAmB,KAAO,IAAkC,CAChE,IAAM,EAAa,EAAwB,QAAU,EACrD,EAAwB,QAAU,EAClC,IAAM,EAAQ,EAAW,WAAW,QAAQ,EAC5C,GAAI,CAIF,GAHA,MAAM,EAAM,YAAY,CACtB,OAAQ,CAAC,oBAAqB,kBAAkB,CAClD,CAAC,EACG,IAAe,EAAwB,QACzC,OAEF,EAAS,GAAa,EAAO,CAAK,CAAC,EACnC,EAAa,QAAU,KACvB,EAAe,CAAC,CAAC,EACjB,EAAyB,EAAE,EAC3B,EAAW,EAAK,CAClB,MAAQ,CACN,GAAI,IAAe,EAAwB,QACzC,OAEF,EAAe,CAAC,CAAC,EACjB,EAAyB,EAAE,CAC7B,CACF,EAEM,EAAwB,GAA2C,CACvE,GAAI,EAAM,MAAQ,SAAU,CAC1B,EAAM,eAAe,EACrB,EAAe,CAAC,CAAC,EACjB,EAAyB,EAAE,EAC3B,MACF,CACA,GAAI,EAAY,SAAW,EACzB,OAEF,GAAI,EAAM,MAAQ,YAAa,CAC7B,EAAM,eAAe,EACrB,EAA0B,GACxB,EAAU,EAAY,OAAS,EAAI,EAAU,EAAI,CACnD,EACA,MACF,CACA,GAAI,EAAM,MAAQ,UAAW,CAC3B,EAAM,eAAe,EACrB,EAA0B,GACxB,EAAU,EAAI,EAAU,EAAI,EAAY,OAAS,CACnD,EACA,MACF,CACA,IAAM,EAAa,EAAY,GAC3B,EAAM,MAAQ,SAAW,IAC3B,EAAM,eAAe,EACrB,EAAiB,CAAU,CAAC,CAAC,UAAY,IAAA,EAAS,EAEtD,EAEM,EAAqB,GAAmC,CAC7C,EAAM,cAAc,QACjC,qCAEO,CAAC,EAAE,SAAS,EAAM,aAAa,GAGxC,OAAO,eAAiB,EAAW,EAAK,EAAG,GAAG,CAChD,EAEA,OACE,EAAC,WAAD,CACE,mBAAkB,EAAU,EAAU,IAAA,GACtC,eAAc,EAAU,OAAS,IAAA,GACjC,UAAU,8BAHZ,SAAA,CAKE,EAAC,SAAD,CAAA,SAAQ,SAAe,CAAA,EACvB,EAAC,QAAD,CAAO,QAAS,GAAG,EAAG,QAAtB,SAAA,CACE,EAAC,OAAD,CAAA,SAAM,gBAAoB,CAAA,EAC1B,EAAC,MAAD,CAAK,UAAU,qCAAf,SAAA,CACE,EAAC,QAAD,CACE,wBACE,GAAyB,EACrB,GAAG,EAAG,cAAc,IACpB,IAAA,GAEN,oBAAkB,OAClB,gBAAe,EACf,mBAAkB,EAAU,EAAU,IAAA,GACtC,gBAAe,GAAW,EAAY,OAAS,EAC/C,eAAc,EAAU,OAAS,IAAA,GACjC,aAAa,iBACb,GAAI,GAAG,EAAG,QACV,KAAK,gBACL,OAAQ,EACR,SAAW,GAAU,EAAO,CAAE,MAAO,EAAM,cAAc,KAAM,CAAC,EAChE,YAAe,EAAW,EAAI,EAC9B,UAAW,EACD,WACV,KAAK,WACL,MAAO,EAAM,KACd,CAAA,EACA,EACC,EAAC,OAAD,CAAM,UAAU,sCAAsC,SAAA,YAEhD,CAAA,EACJ,KACH,EAAY,OAAS,EACpB,EAAC,MAAD,CACE,UAAU,0CACV,GAAI,EACJ,KAAK,UAEJ,SAAA,EAAY,KAAK,EAAY,IAC5B,EAAC,SAAD,CACE,gBAAe,IAA0B,EACzC,GAAI,GAAG,EAAG,cAAc,IAExB,OAAQ,EACR,QAAU,GAAU,CAEd,EAAM,SAAW,GACnB,EAAiB,CAAU,CAAC,CAAC,UAAY,IAAA,EAAS,CAEtD,EACA,YAAc,GAAU,CACtB,EAAM,eAAe,EACrB,EAAiB,CAAU,CAAC,CAAC,UAAY,IAAA,EAAS,CACpD,EACA,KAAK,SACL,KAAK,SAhBP,SAAA,CAkBE,EAAC,SAAD,CAAA,SAAS,EAAW,KAAc,CAAA,EACjC,EAAW,eACV,EAAC,OAAD,CAAA,SAAO,EAAW,cAAqB,CAAA,EACrC,IACE,CAnBD,EAAA,EAAW,EAmBV,CACT,CACE,CAAA,EACH,IACD,CACA,CAAA,CAAA,IACP,EAAC,QAAD,CAAO,QAAS,GAAG,EAAG,QAAtB,SAAA,CACE,EAAC,OAAD,CAAA,SAAM,2BAA+B,CAAA,EACrC,EAAC,QAAD,CACE,aAAa,gBACb,GAAI,GAAG,EAAG,QACV,SAAW,GAAU,EAAO,CAAE,MAAO,EAAM,cAAc,KAAM,CAAC,EAChE,YAAY,WACZ,MAAO,EAAM,OAAS,EACvB,CAAA,CACI,IACP,EAAC,MAAD,CAAK,UAAU,kCAAf,SAAA,CACE,EAAC,QAAD,CAAO,QAAS,GAAG,EAAG,OAAtB,SAAA,CACE,EAAC,OAAD,CAAA,SAAM,MAAU,CAAA,EAChB,EAAC,QAAD,CACE,aAAa,iBACb,GAAI,GAAG,EAAG,OACV,SAAW,GAAU,EAAO,CAAE,KAAM,EAAM,cAAc,KAAM,CAAC,EACrD,WACV,MAAO,EAAM,IACd,CAAA,CACI,CACP,CAAA,EAAA,EAAC,QAAD,CAAO,QAAS,GAAG,EAAG,QAAtB,SAAA,CACE,EAAC,OAAD,CAAA,SAAM,OAAW,CAAA,EACjB,EAAC,QAAD,CACE,aAAa,iBACb,GAAI,GAAG,EAAG,QACV,SAAW,GAAU,EAAO,CAAE,MAAO,EAAM,cAAc,KAAM,CAAC,EACtD,WACV,MAAO,EAAM,KACd,CAAA,CACI,CACJ,CAAA,CAAA,IACL,EAAC,MAAD,CAAK,UAAU,kCAAf,SAAA,CACE,EAAC,QAAD,CAAO,QAAS,GAAG,EAAG,SAAtB,SAAA,CACE,EAAC,OAAD,CAAA,SAAM,aAAiB,CAAA,EACvB,EAAC,QAAD,CACE,aAAa,cACb,GAAI,GAAG,EAAG,SACV,SAAW,GACT,EAAO,CAAE,WAAY,EAAM,cAAc,KAAM,CAAC,EAExC,WACV,MAAO,EAAM,UACd,CAAA,CACI,CACP,CAAA,EAAA,EAAC,QAAD,CAAO,QAAS,GAAG,EAAG,UAAtB,SAAA,CACE,EAAC,OAAD,CAAA,SAAM,SAAa,CAAA,EACnB,EAAC,QAAD,CACE,aAAa,UACb,GAAI,GAAG,EAAG,UACV,UAAW,EACX,SAAW,GACT,EAAO,CAAE,QAAS,EAAM,cAAc,MAAM,YAAY,CAAE,CAAC,EAEnD,WACV,MAAO,EAAM,OACd,CAAA,CACI,CACJ,CAAA,CAAA,GACG,GAEd,CClcA,MAAM,GAA2B,aAC3B,GAAoC,mBAiBpC,GAAa,EAAK,EAAO,EAAG,EAAK,EAAG,EAAS,mBAAmB,CAAC,EACjE,EAAiC,EACrC,EAAO,EACP,EAAK,EACL,EACE,GACA,8CACF,EACA,EAAW,GAAW,EAAQ,OAAO,CAAK,EAAI,IAAK,EACnD,EACG,GAAU,IAAU,MAAQ,OAAO,cAAc,CAAK,EACvD,8CACF,CACF,EACM,EAAiC,EACrC,EAAO,EACP,EAAK,EACL,EAAS,0BAA0B,EACnC,EACE,GACA,8CACF,EACA,EAAU,MAAM,EAChB,EACG,GAAU,OAAO,cAAc,CAAK,EACrC,8CACF,CACF,EACM,EAAsB,EAAO,CACjC,KAAM,EAAO,EACb,QAAS,EAAO,EAChB,MAAO,EAAO,EACd,MAAO,EAAS,EAAO,CAAC,EACxB,WAAY,EAAO,EACnB,MAAO,EAAO,CAChB,CAAC,EACK,EAAwB,EAC5B,EACA,EAAM,EAAmB,uBAAuB,CAClD,EAEM,EAAqC,CACzC,KAAM,GACN,QAAS,KACT,MAAO,GACP,MAAO,KACP,WAAY,GACZ,MAAO,EACT,EACM,GAAwB,EAC5B,EACA,EACG,GAAY,EAAe,CAAO,GAAK,EAAkB,CAAO,EACjE,yCACF,CACF,EAEA,SAAgB,EAAe,EAA8B,CAC3D,MAAO,CAAC,CACN,EAAQ,KACR,EAAQ,MACR,EAAQ,MACR,EAAQ,WACR,EAAQ,KACV,CAAC,CAAC,KAAM,GAAU,GAAO,KAAK,CAAC,CACjC,CAEA,SAAS,EAAkB,EAA8B,CACvD,MAAO,CACL,EAAQ,KACR,EAAQ,QACR,EAAQ,MACR,EAAQ,WACR,EAAQ,KACV,CAAC,CAAC,MAAO,GAAU,EAAM,KAAK,CAAC,CACjC,CAGA,SAAgB,GACd,EACA,EACA,CACA,IAAM,EAAmB,CACvB,GAAG,EACH,QAAS,EAAO,OAAO,QAAQ,QAAU,EAAO,QAAU,EAC1D,aAAc,EACZ,EAAO,aACP,EAAO,YACT,EACA,MAAO,EAAO,OAAO,MAAM,QAAU,EAAO,MAAQ,GACpD,iBAAkB,EAAO,OAAO,iBAAiB,QAC7C,EAAO,iBACP,GACJ,MAAO,EAAO,OAAO,MAAM,QAAU,EAAO,MAAQ,EACtD,EACM,EAAS,EAAO,CACpB,QACE,EAAO,OAAO,QAAQ,SAAW,EAAO,OAAO,QAAQ,SACnD,EACA,GACN,MACE,EAAO,OAAO,MAAM,SAAW,EAAO,OAAO,MAAM,SAC/C,EACA,EACN,KAAM,GACN,iBACE,EAAO,OAAO,iBAAiB,SAC/B,EAAO,OAAO,iBAAiB,SAC3B,EACA,EACN,MACE,EAAO,OAAO,MAAM,SAAW,EAAO,OAAO,MAAM,SAC/C,EACA,CACR,CAAC,EACK,EAAS,EAAU,EAAQ,CAAgB,EAC3C,EAAS,EACb,EAAO,aACP,EAAiB,YACnB,EACA,GAAI,CAAC,EAAO,QACV,IAAK,IAAM,KAAS,EAAO,OAAQ,CACjC,IAAM,EAAQ,EAAM,OAAO,EAAE,EAAE,IACzB,EAAY,CAChB,UACA,QACA,OACA,mBACA,OACF,CAAC,CAAC,KAAM,GAAS,IAAS,CAAK,EAC3B,GAAa,CAAC,EAAO,KACvB,EAAO,GAAa,EAAM,QAE9B,CAEF,OAAO,EAAO,QACV,CAAE,SAAQ,MAAO,CAAE,GAAG,EAAkB,GAAG,EAAO,MAAO,CAAE,EAC3D,CAAE,SAAQ,MAAO,IAAK,CAC5B,CCpJA,MAAM,GAAuC,CAC3C,KAAM,GACN,QAAS,KACT,MAAO,GACP,MAAO,GACP,WAAY,GACZ,MAAO,EACT,EAIA,SAAS,GAAoB,EAAiD,CAC5E,MAAO,CACL,QAAS,GACT,aAAc,EAAwB,EAAO,YAAY,EACzD,MAAO,GACP,SAAU,GACV,KAAM,GACN,iBAAkB,GAClB,MAAO,GACP,aAAc,IAChB,CACF,CAEA,SAAS,EAAkB,EAAuB,EAAc,CAC9D,IAAM,EAAU,EAAK,SAAS,UAAU,CAAI,EAC5C,GAAI,aAAmB,YAKrB,MAJA,CAAK,EAAQ,QAAQ,WAAW,IAC9B,EAAQ,MAAM,EACP,IAIX,GAAI,aAAmB,cAAe,CACpC,IAAM,EAAY,MAAM,KAAK,CAAO,CAAC,CAAC,KACnC,GAAS,aAAgB,aAAe,CAAC,EAAK,QAAQ,WAAW,CACpE,EAEA,OADA,GAAW,MAAM,EACV,EAAQ,CACjB,CACA,MAAO,EACT,CAEA,SAAS,EACP,EACA,EACA,CACA,IAAM,EAAoC,CACxC,CAAC,OAAQ,MAAM,EACf,CAAC,QAAS,OAAO,EACjB,CAAC,QAAS,OAAO,EACjB,CAAC,mBAAoB,kBAAkB,EACvC,CAAC,UAAW,eAAe,CAC7B,EACA,IAAK,GAAM,CAAC,EAAU,KAAgB,EACpC,GAAI,EAAO,IAAa,EAAkB,EAAM,CAAW,EACzD,OAGJ,IAAM,EAAc,IAAI,IAAI,EAAc,KAAK,CAAC,KAAc,CAAQ,CAAC,EACjE,EAAgB,OAAO,KAAK,CAAM,CAAC,CAAC,KACvC,GAAa,CAAC,EAAY,IAAI,CAAQ,CACzC,EACI,GACF,EAAkB,EAAM,UAAU,GAAe,CAErD,CAIA,SAAS,EAAY,CACnB,WACA,UAAU,GACV,SAAS,GACT,aAMC,CACD,GAAM,CACJ,WACA,YACA,mBAAoB,EACpB,iBAAkB,EAClB,QACA,QAAQ,OACR,GAAG,GACD,EACE,EAAS,EACb,IAAQ,yBACN,IAAQ,gCACR,GAAU,aACV,SACJ,EACM,EAA+C,CAAE,GAAG,CAAM,EAQhE,IANE,IAAQ,0BAA4B,IAAA,IACpC,IAAQ,iCAAmC,IAAA,IAC3C,GAAU,eAEV,EAAY,wBAA0B,GAGtC,IAAQ,mCAAqC,IAAA,IAC7C,IAAQ,0CAA4C,IAAA,GACpD,CACA,IAAM,EAAiB,EAAkB,CAAM,EAC3C,IACF,EAAY,iCAAmC,EAEnD,CACA,OACE,EAAC,UAAD,CACE,GAAI,EACJ,GAAK,EAAU,CAAE,YAAa,EAAK,EAAI,CAAC,EACxC,UAAW,CACT,qBACA,EAAS,6BAA+B,KACxC,CACF,CAAC,CACE,OAAO,OAAO,CAAC,CACf,KAAK,GAAG,EACX,yBAAwB,EACxB,MAAO,EAEN,UACM,CAAA,CAEb,CAcA,SAAS,GAAW,CAClB,SACA,YACA,UACA,SACA,GAAG,GAMF,CACD,GAAM,CAAE,WAAU,qBAAoB,oBAAqB,EACrD,EAAW,EAAM,EACjB,EAAa,EAAO,EAAI,EACxB,EAAW,EAAyB,IAAI,EACxC,EAAgB,EAAO,EAAK,EAC5B,CAAC,EAAO,GAAY,EAAgC,CAAE,MAAO,MAAO,CAAC,EACrE,CAAC,EAAQ,GAAa,MAC1B,GAAoB,CAAM,CAC5B,EACM,CAAC,EAAQ,GAAa,EAAiC,CAAC,CAAC,EACzD,CAAC,EAAiB,GAAsB,EAG3C,EACG,EAAoB,EACxB,EAAO,aACP,EAAO,YACT,EA2BA,GAzBA,MAAgB,CACV,IAAsB,EAAO,cAC/B,EAAW,IAAa,CACtB,GAAG,EACH,aAAc,EACZ,EAAO,aACP,EAAQ,YACV,CACF,EAAE,CAEN,EAAG,CAAC,EAAmB,EAAO,aAAc,EAAO,YAAY,CAAC,EAEhE,OACE,EAAW,QAAU,OACR,CACX,EAAW,QAAU,EACvB,GACC,CAAC,CAAC,EAEL,MAAgB,CACV,EAAM,QAAU,cAAgB,EAAO,OACzC,EAAS,SAAS,MAAM,CAE5B,EAAG,CAAC,EAAO,MAAO,EAAM,KAAK,CAAC,EAE1B,CAAC,EAAO,SACV,OACE,EAAC,EAAD,CAAa,OAAA,GAAkB,YAA/B,SAAA,CACE,EAAC,KAAD,CAAA,SAAI,eAAiB,CAAA,EACrB,EAAC,IAAD,CAAA,SAAG,2CAA4C,CAAA,CACpC,IAIjB,GAAI,EAAM,QAAU,YAClB,OACE,EAAC,EAAD,CAAa,OAAA,GAAkB,YAA/B,SAAA,CACG,EAAW,EAAC,EAAD,CAAoB,UAAW,CAAA,EAAI,KAC/C,EAAC,OAAD,CAAM,cAAY,OAAO,UAAU,8BAA8B,SAAA,GAE3D,CAAA,EACN,EAAC,KAAD,CAAA,SAAI,WAAa,CAAA,EACjB,EAAC,IAAD,CAAA,SAAG,gCAAiC,CAAA,CACzB,IAIjB,IAAM,EAAU,GACd,EAAW,IAAa,CAAE,GAAG,EAAS,GAAG,CAAM,EAAE,EAC7C,EAAa,EAAM,QAAU,aAC7B,EACJ,EAAM,QAAU,eAAiB,EAAM,MAAM,QAAU,IAAA,GAuFzD,OACE,EAAC,EAAD,CAAwB,YAAxB,SAAA,CACG,EAAO,cACN,EAAC,MAAD,CACE,IAAI,GACJ,UAAU,4BACV,OAAQ,IACR,IAAK,EAAO,cACZ,MAAO,GACR,CAAA,EACC,KACH,EAAW,EAAC,EAAD,CAAoB,UAAW,CAAA,EAAI,KAC/C,EAAC,SAAD,CAAA,SAAA,CACG,EAAO,OAAO,KAAK,EAAI,EAAC,KAAD,CAAA,SAAK,EAAO,KAAU,CAAA,EAAI,KACjD,EAAO,YAAc,EAAC,IAAD,CAAA,SAAI,EAAO,WAAe,CAAA,EAAI,IAC9C,CAAA,CAAA,EACP,EACC,EAAC,MAAD,CAAK,KAAK,QAAV,SAAA,CACE,EAAC,IAAD,CAAA,SAAI,EAAU,OAAW,CAAA,EACzB,EAAC,SAAD,CAAQ,QAAS,EAAS,KAAK,SAAS,SAAA,OAEhC,CAAA,CACL,CACH,CAAA,EAAA,KACJ,EAAC,OAAD,CAAM,WAAA,GAAW,SAAU,KA7GH,IAAsC,CAGhE,GAFA,EAAM,eAAe,EAEjB,EAAc,QAChB,OAEF,IAAM,EAAa,GAAmB,EAAQ,CAC5C,GAAG,EACH,aAAc,EACd,MAAO,EAAO,OAAO,MAAM,QACvB,EAAsB,EAAO,MAAO,EAAO,YAAY,EACvD,EACN,CAAC,EAED,GADA,EAAU,EAAW,MAAM,EACvB,OAAO,KAAK,EAAW,MAAM,CAAC,CAAC,OAAS,GAAK,CAAC,EAAW,MAAO,CAClE,IAAM,EAAO,EAAM,cACnB,mBACE,EAAgC,EAAM,EAAW,MAAM,CACzD,EACA,MACF,CACA,IAAM,EAAkB,EAAW,MAC7B,EAAa,CACjB,QACE,EAAO,OAAO,QAAQ,SACtB,CAAC,EAAe,EAAgB,OAAO,EACnC,EAAgB,QAChB,KACN,QAAS,EACP,EAAO,aACP,EAAgB,YAClB,EACA,MAAO,EAAO,OAAO,MAAM,SAAU,EAAgB,OAAgB,KACrE,SAAU,EAAgB,SAC1B,KAAM,EAAgB,KACtB,iBAAkB,EAAO,OAAO,iBAAiB,QAC7C,EAAgB,iBAChB,KACJ,MAAO,EAAO,OAAO,MAAM,SAAU,EAAgB,OAAgB,IACvE,EACM,EAAa,KAAK,UAAU,CAAU,EACtC,EACJ,GAAiB,aAAe,EAC5B,EAAgB,UAChB,WAAW,OAAO,WAAW,EAC/B,EACJ,EAAc,QAAU,GACxB,EAAS,CAAE,MAAO,YAAa,CAAC,EAChC,GAAI,CACF,EAAS,MAAM,EAAO,OAAO,EAAY,CAAE,qBAAoB,CAAC,CAClE,OAAS,EAAO,CACd,GAAI,CAAC,EAAW,QACd,OAGF,IAAM,EAAW,EACX,EAAa,EAAoB,EAAS,UAAU,EAC1D,GAAI,EAAY,CACd,EAAW,IAAa,CAAE,GAAG,EAAS,MAAO,CAAW,EAAE,EAC1D,EAAS,CAAE,MAAO,MAAO,CAAC,EAC1B,EAAmB,IAAA,EAAS,EAC5B,MACF,CACA,EAAS,CAAE,MAAO,EAAU,MAAO,cAAe,CAAC,EAC/C,EAAS,oBACX,EAAmB,CACjB,aACA,UAAW,CACb,CAAC,EAED,EAAmB,IAAA,EAAS,EAE9B,MACF,QAAU,CACR,EAAc,QAAU,EAC1B,CAEK,EAAW,UAGhB,EAAmB,IAAA,EAAS,EAC5B,EAAS,CAAE,MAAO,WAAY,CAAC,EAC/B,EAAmB,EAAkB,CAAM,EAC7C,EA0BI,SAAA,CACE,EAAC,QAAD,CACE,cAAY,OACZ,aAAa,MACb,UAAU,+BACV,SAAW,GAAU,EAAO,CAAE,SAAU,EAAM,cAAc,KAAM,CAAC,EACnE,SAAU,GACV,MAAO,EAAO,QACf,CAAA,EACD,EAAC,MAAD,CAAK,UAAU,6BAAf,SAAA,CACE,EAAC,QAAD,CAAO,QAAS,GAAG,EAAS,OAA5B,SAAA,CACE,EAAC,OAAD,CAAA,SAAM,MAAU,CAAA,EAChB,EAAC,QAAD,CACE,mBACE,EAAO,KAAO,GAAG,EAAS,aAAe,IAAA,GAE3C,eAAc,EAAO,KAAO,OAAS,IAAA,GACrC,aAAa,OACb,GAAI,GAAG,EAAS,OAChB,KAAK,OACL,SAAW,GAAU,EAAO,CAAE,KAAM,EAAM,cAAc,KAAM,CAAC,EAC/D,SAAA,GACA,MAAO,EAAO,IACf,CAAA,EACD,EAAC,EAAD,CAAY,MAAO,EAAO,KAAM,GAAI,GAAG,EAAS,YAAe,CAAA,CAC1D,IACN,EAAO,OAAO,MAAM,QACnB,EAAC,EAAD,CACE,MAAO,EAAO,MACd,GAAI,GAAG,EAAS,QAChB,MAAM,QACN,KAAK,QACL,SAAW,GAAU,EAAO,CAAE,MAAO,EAAM,cAAc,KAAM,CAAC,EAChE,SAAU,EAAO,OAAO,MAAM,SAC9B,MAAO,EAAO,KACf,CAAA,EACC,KACH,EAAO,OAAO,MAAM,QACnB,EAAC,EAAD,CACE,MAAO,EAAO,MACd,GAAI,GAAG,EAAS,QAChB,MAAM,QAEN,SAAA,EAAC,EAAD,CACE,QAAS,EAAO,aAChB,MAAO,EAAO,MACd,QAAS,GAAG,EAAS,cACrB,GAAI,GAAG,EAAS,QAChB,SAAU,EACV,KAAK,QACL,UAAW,CAAE,QAAO,aAClB,EAAO,CAAE,MAAO,EAAO,aAAc,CAAQ,CAAC,EAEhD,SAAU,EAAO,OAAO,MAAM,SAC9B,MAAO,EAAO,KACf,CAAA,CACQ,CAAA,EACT,KACH,EAAO,OAAO,iBAAiB,QAC9B,EAAC,QAAD,CAAO,QAAS,GAAG,EAAS,oBAA5B,SAAA,CACE,EAAC,OAAD,CAAA,SAAM,aAAiB,CAAA,EACvB,EAAC,QAAD,CACE,mBACE,EAAO,iBACH,GAAG,EAAS,0BACZ,IAAA,GAEN,eAAc,EAAO,iBAAmB,OAAS,IAAA,GACjD,GAAI,GAAG,EAAS,oBAChB,IAAK,EACL,KAAK,mBACL,SAAW,GACT,EAAO,CAAE,iBAAkB,EAAM,cAAc,KAAM,CAAC,EAExD,SAAU,EAAO,OAAO,iBAAiB,SACzC,KAAK,SACL,MAAO,EAAO,gBACf,CAAA,EACD,EAAC,EAAD,CACE,MAAO,EAAO,iBACd,GAAI,GAAG,EAAS,yBACjB,CAAA,CACI,CACL,CAAA,EAAA,KACH,EAAO,OAAO,QAAQ,QACrB,EAAC,MAAD,CAAK,UAAU,kCAAf,SAAA,CACE,EAAC,GAAD,CACE,OAAQ,EACR,QACE,EAAO,QAAU,GAAG,EAAS,gBAAkB,IAAA,GAEjD,QAAS,EAAQ,EAAO,QACxB,SAAW,GAAY,EAAO,CAAE,SAAQ,CAAC,EACzC,SAAU,EAAO,OAAO,QAAQ,SAChC,MAAO,EAAO,OACf,CAAA,EACD,EAAC,EAAD,CACE,MAAO,EAAO,QACd,GAAI,GAAG,EAAS,eACjB,CAAA,CACE,CACH,CAAA,EAAA,KACJ,EAAC,EAAD,CACE,gBAAgB,6BAChB,eAAe,kCACP,SACR,OAAQ,EAAO,aACL,WACV,SAAW,GAAiB,EAAO,CAAE,cAAa,CAAC,EACnD,OAAQ,CACT,CAAA,CACE,IACJ,EACC,EAAC,IAAD,CAAG,UAAU,mCAAmC,KAAK,QAArD,SAAA,CACG,EAAY,aACZ,CACD,CAAA,EAAA,KACJ,EAAC,SAAD,CACE,UAAU,6BACV,SAAU,EACV,KAAK,SAEJ,SAAA,EAAa,cAAgB,QACxB,CAAA,CACJ,GACK,GAEjB,CAEA,SAAgB,GAAkB,CAChC,SACA,GAAG,GACsB,CAmBzB,OAlBI,EAAO,OAAS,CAAC,EAAO,OAExB,EAAC,EAAD,CAAa,OAAA,GAAkB,YAA/B,SAAA,CACE,EAAC,KAAD,CAAA,SAAI,oBAAsB,CAAA,EAC1B,EAAC,IAAD,CAAG,KAAK,QAAS,SAAA,EAAO,MAAM,OAAW,CAAA,EACzC,EAAC,SAAD,CAAQ,QAAS,EAAO,QAAS,KAAK,SAAS,SAAA,OAEvC,CAAA,CACG,IAGZ,EAAO,OAQV,EAAC,GAAD,CACE,OAAQ,EAAO,OACf,UAAW,EAAO,MAClB,QAAS,EAAO,QAChB,OAAQ,EAAO,OACf,GAAI,CACL,CAAA,EAZC,EAAC,EAAD,CAAa,QAAA,GAAmB,YAC9B,SAAA,EAAC,EAAD,CAAc,WAAY,EAAG,MAAM,iBAAmB,CAAA,CAC3C,CAAA,CAYnB,CAEA,SAAS,EAAS,CAChB,YAGC,CACD,OACE,EAAC,MAAD,CAAK,UAAU,+BAAf,SAAA,CACG,EAAS,SACR,EAAC,MAAD,CAAK,IAAI,GAAG,OAAQ,GAAI,IAAK,EAAS,SAAU,MAAO,EAAK,CAAA,EAC1D,KACJ,EAAC,SAAD,CAAA,SAAS,EAAS,IAAa,CAAA,CAC5B,GAET,CCvgBA,SAAgB,GACd,EACA,CAAE,iBAA+C,CAAC,EACtB,CAC5B,GAAM,CAAE,WAAY,EACpB,EAA6B,SAAU,CACrC,WAAY,EAAQ,WACpB,cAAe,EAAQ,cACvB,YAAa,EAAQ,YACrB,KAAM,EAAQ,UAChB,CAAC,EACD,IAAM,EAAa,EAAO,CAAO,EACjC,EAAW,QAAU,EACrB,GAAM,CAAC,GAAU,MAAe,CAC9B,IAAM,EAAgD,CACpD,GAAG,EACH,QAAU,GAAU,EAAW,UAAU,CAAK,CAChD,EACA,OAAO,EAA8B,CAAa,CACpD,CAAC,EACK,CAAC,EAAU,GAAe,EAAS,CAAC,EACpC,CAAC,EAAO,GAAY,OAAiC,CACzD,MAAO,KACP,QAAS,GACT,OAAQ,GAAiB,IAC3B,EAAE,EAEF,MAAgB,CACd,IAAI,EAAS,GAiBb,OAhBA,EAAO,KAAK,CAAC,CAAC,KACX,GAAW,CACN,GACF,EAAS,CACP,MAAO,KACP,QAAS,GACT,QACF,CAAC,CAEL,EACC,GAA+B,CAC1B,GACF,EAAU,IAAa,CAAE,GAAG,EAAS,QAAO,QAAS,EAAM,EAAE,CAEjE,CACF,MACa,CACX,EAAS,EACX,CACF,EAAG,CAAC,EAAQ,CAAQ,CAAC,EAErB,IAAM,EAAU,MAAkB,CAChC,EAAU,IAAa,CAAE,GAAG,EAAS,MAAO,KAAM,QAAS,EAAK,EAAE,EAClE,EAAa,GAAU,EAAQ,CAAC,CAClC,EAAG,CAAC,CAAC,EAEL,MAAO,CACL,SACA,MAAO,EAAM,MACb,QAAS,EAAM,QACf,UACA,OAAQ,EAAM,MAChB,CACF"}
1
+ {"version":3,"file":"signup.js","names":["googleWindow"],"sources":["../src/signup-address-field.tsx","../src/signup-validation.ts","../src/lockerverse-signup.tsx","../src/use-lockerverse-signup.ts"],"sourcesContent":["import {\n type FocusEvent,\n type KeyboardEvent,\n useEffect,\n useId,\n useRef,\n useState,\n} from \"react\";\nimport type { SignupAddressValues } from \"./signup-validation.ts\";\n\ntype GoogleAddressComponent = {\n longText?: string;\n shortText?: string;\n types: string[];\n};\n\ntype GoogleSessionToken = Record<never, never>;\n\ntype GooglePlace = {\n addressComponents?: GoogleAddressComponent[];\n formattedAddress?: string;\n fetchFields: (options: { fields: string[] }) => Promise<void>;\n};\n\ntype GooglePlacePrediction = {\n placeId: string;\n mainText?: { text: string };\n secondaryText?: { text: string };\n text: { text: string };\n toPlace: () => GooglePlace;\n};\n\ntype GooglePlacesLibrary = {\n AutocompleteSessionToken: new () => GoogleSessionToken;\n AutocompleteSuggestion: {\n fetchAutocompleteSuggestions: (options: {\n input: string;\n includedPrimaryTypes: string[];\n includedRegionCodes: string[];\n region: string;\n sessionToken: GoogleSessionToken;\n }) => Promise<{\n suggestions: { placePrediction?: GooglePlacePrediction }[];\n }>;\n };\n};\n\ntype GoogleMapsWindow = Window & {\n google?: {\n maps?: {\n __lockerverseSignupReady?: () => void;\n importLibrary?: (libraryName: string) => Promise<GooglePlacesLibrary>;\n };\n };\n};\n\ntype AddressSuggestion = {\n id: string;\n label: string;\n secondaryLabel: string;\n prediction: GooglePlacePrediction;\n};\n\nconst GOOGLE_MAPS_SCRIPT_ID = \"lockerverse-signup-google-places\";\nconst GOOGLE_ADDRESS_TYPES = [\n \"premise\",\n \"subpremise\",\n \"street_address\",\n \"route\",\n];\nlet googlePlacesLoader: Promise<GooglePlacesLibrary> | null = null;\n\nfunction installGoogleMaps(apiKey: string) {\n const googleWindow: GoogleMapsWindow = window;\n if (googleWindow.google?.maps?.importLibrary) {\n return;\n }\n googleWindow.google ||= {};\n const googleObject = googleWindow.google;\n googleObject.maps ||= {};\n const mapsObject = googleObject.maps;\n let scriptPromise: Promise<void> | null = null;\n mapsObject.importLibrary = (libraryName: string) => {\n scriptPromise ||= new Promise((resolve, reject) => {\n const existingScript = document.getElementById(GOOGLE_MAPS_SCRIPT_ID);\n mapsObject.__lockerverseSignupReady = resolve;\n if (existingScript) {\n existingScript.addEventListener(\n \"error\",\n () => reject(new Error(\"Unable to load Google Places.\")),\n { once: true }\n );\n return;\n }\n const script = document.createElement(\"script\");\n const parameters = new URLSearchParams({\n callback: \"google.maps.__lockerverseSignupReady\",\n key: apiKey,\n libraries: libraryName,\n v: \"weekly\",\n });\n script.async = true;\n script.id = GOOGLE_MAPS_SCRIPT_ID;\n script.src = `https://maps.googleapis.com/maps/api/js?${parameters}`;\n script.onerror = () => reject(new Error(\"Unable to load Google Places.\"));\n document.head.append(script);\n });\n return scriptPromise\n .then(() => {\n const importLibrary = googleWindow.google?.maps?.importLibrary;\n if (!importLibrary) {\n throw new Error(\"Unable to load Google Places.\");\n }\n return importLibrary(libraryName);\n })\n .catch((error) => {\n scriptPromise = null;\n document.getElementById(GOOGLE_MAPS_SCRIPT_ID)?.remove();\n throw error;\n });\n };\n}\n\nfunction loadGooglePlaces(apiKey: string) {\n googlePlacesLoader ||= (async () => {\n try {\n installGoogleMaps(apiKey);\n const googleWindow: GoogleMapsWindow = window;\n const importLibrary = googleWindow.google?.maps?.importLibrary;\n if (!importLibrary) {\n throw new Error(\"Unable to load Google Places.\");\n }\n return await importLibrary(\"places\");\n } catch (error) {\n googlePlacesLoader = null;\n throw error;\n }\n })();\n return googlePlacesLoader;\n}\n\nfunction getAddressPart(\n components: GoogleAddressComponent[],\n type: string,\n key: \"longText\" | \"shortText\" = \"longText\"\n) {\n return (\n components.find((component) => component.types.includes(type))?.[key] ?? \"\"\n );\n}\n\nfunction parseAddress(current: SignupAddressValues, place: GooglePlace) {\n const components = place.addressComponents ?? [];\n const street = [\n getAddressPart(components, \"street_number\"),\n getAddressPart(components, \"route\"),\n ]\n .filter(Boolean)\n .join(\" \");\n return {\n ...current,\n city:\n getAddressPart(components, \"locality\") ||\n getAddressPart(components, \"postal_town\") ||\n getAddressPart(components, \"sublocality_level_1\"),\n country: getAddressPart(components, \"country\", \"shortText\") || \"US\",\n line1: street || place.formattedAddress?.split(\",\")[0] || \"\",\n line2: getAddressPart(components, \"subpremise\"),\n postalCode: [\n getAddressPart(components, \"postal_code\"),\n getAddressPart(components, \"postal_code_suffix\"),\n ]\n .filter(Boolean)\n .join(\"-\"),\n state: getAddressPart(\n components,\n \"administrative_area_level_1\",\n \"shortText\"\n ),\n } satisfies SignupAddressValues;\n}\n\nexport function SignupAddressField({\n apiKey,\n errorId,\n invalid,\n onChange,\n required,\n value,\n}: {\n apiKey: string | undefined;\n errorId: string | undefined;\n invalid: boolean;\n onChange: (address: SignupAddressValues) => void;\n required: boolean;\n value: SignupAddressValues;\n}) {\n const id = useId();\n const listboxId = `${id}-suggestions`;\n const [activeSuggestionIndex, setActiveSuggestionIndex] = useState(-1);\n const [focused, setFocused] = useState(false);\n const [loading, setLoading] = useState(false);\n const [suggestions, setSuggestions] = useState<AddressSuggestion[]>([]);\n const detailRequestGeneration = useRef(0);\n const searchGeneration = useRef(0);\n const sessionToken = useRef<GoogleSessionToken | null>(null);\n\n useEffect(\n () => () => {\n detailRequestGeneration.current += 1;\n },\n []\n );\n\n useEffect(() => {\n const generation = searchGeneration.current + 1;\n searchGeneration.current = generation;\n const query = value.line1.trim();\n setActiveSuggestionIndex(-1);\n setLoading(false);\n if (!(apiKey && focused && query.length >= 3)) {\n setSuggestions([]);\n return;\n }\n const timeout = window.setTimeout(async () => {\n if (generation !== searchGeneration.current) {\n return;\n }\n setLoading(true);\n try {\n const { AutocompleteSessionToken, AutocompleteSuggestion } =\n await loadGooglePlaces(apiKey);\n sessionToken.current ??= new AutocompleteSessionToken();\n const response =\n await AutocompleteSuggestion.fetchAutocompleteSuggestions({\n includedPrimaryTypes: GOOGLE_ADDRESS_TYPES,\n includedRegionCodes: [\"US\"],\n input: query,\n region: \"US\",\n sessionToken: sessionToken.current,\n });\n if (generation === searchGeneration.current) {\n setSuggestions(\n response.suggestions.flatMap(({ placePrediction }) =>\n placePrediction\n ? [\n {\n id: placePrediction.placeId,\n label:\n placePrediction.mainText?.text ??\n placePrediction.text.text,\n prediction: placePrediction,\n secondaryLabel: placePrediction.secondaryText?.text ?? \"\",\n },\n ]\n : []\n )\n );\n }\n } catch {\n if (generation === searchGeneration.current) {\n setSuggestions([]);\n }\n } finally {\n if (generation === searchGeneration.current) {\n setLoading(false);\n }\n }\n }, 250);\n return () => {\n window.clearTimeout(timeout);\n };\n }, [apiKey, focused, value.line1]);\n\n const update = (patch: Partial<SignupAddressValues>) => {\n detailRequestGeneration.current += 1;\n onChange({ ...value, ...patch });\n };\n\n const selectSuggestion = async (suggestion: AddressSuggestion) => {\n const generation = detailRequestGeneration.current + 1;\n detailRequestGeneration.current = generation;\n const place = suggestion.prediction.toPlace();\n try {\n await place.fetchFields({\n fields: [\"addressComponents\", \"formattedAddress\"],\n });\n if (generation !== detailRequestGeneration.current) {\n return;\n }\n onChange(parseAddress(value, place));\n sessionToken.current = null;\n setSuggestions([]);\n setActiveSuggestionIndex(-1);\n setFocused(false);\n } catch {\n if (generation !== detailRequestGeneration.current) {\n return;\n }\n setSuggestions([]);\n setActiveSuggestionIndex(-1);\n }\n };\n\n const handleAddressKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n setSuggestions([]);\n setActiveSuggestionIndex(-1);\n return;\n }\n if (suggestions.length === 0) {\n return;\n }\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n setActiveSuggestionIndex((current) =>\n current < suggestions.length - 1 ? current + 1 : 0\n );\n return;\n }\n if (event.key === \"ArrowUp\") {\n event.preventDefault();\n setActiveSuggestionIndex((current) =>\n current > 0 ? current - 1 : suggestions.length - 1\n );\n return;\n }\n const suggestion = suggestions[activeSuggestionIndex];\n if (event.key === \"Enter\" && suggestion) {\n event.preventDefault();\n selectSuggestion(suggestion).catch(() => undefined);\n }\n };\n\n const handleAddressBlur = (event: FocusEvent<HTMLElement>) => {\n const search = event.currentTarget.closest(\n \".lockerverse-signup__address-search\"\n );\n if (search?.contains(event.relatedTarget)) {\n return;\n }\n window.setTimeout(() => setFocused(false), 120);\n };\n\n return (\n <fieldset\n aria-describedby={invalid ? errorId : undefined}\n aria-invalid={invalid ? \"true\" : undefined}\n className=\"lockerverse-signup__address\"\n >\n <legend>Address</legend>\n <label htmlFor={`${id}-line1`}>\n <span>Street address</span>\n <div className=\"lockerverse-signup__address-search\">\n <input\n aria-activedescendant={\n activeSuggestionIndex >= 0\n ? `${id}-suggestion-${activeSuggestionIndex}`\n : undefined\n }\n aria-autocomplete=\"list\"\n aria-controls={listboxId}\n aria-describedby={invalid ? errorId : undefined}\n aria-expanded={focused && suggestions.length > 0}\n aria-invalid={invalid ? \"true\" : undefined}\n autoComplete=\"street-address\"\n id={`${id}-line1`}\n name=\"address.line1\"\n onBlur={handleAddressBlur}\n onChange={(event) => update({ line1: event.currentTarget.value })}\n onFocus={() => setFocused(true)}\n onKeyDown={handleAddressKeyDown}\n required={required}\n role=\"combobox\"\n value={value.line1}\n />\n {loading ? (\n <span className=\"lockerverse-signup__address-loading\">\n Searching…\n </span>\n ) : null}\n {suggestions.length > 0 ? (\n <div\n className=\"lockerverse-signup__address-suggestions\"\n id={listboxId}\n role=\"listbox\"\n >\n {suggestions.map((suggestion, index) => (\n <button\n aria-selected={activeSuggestionIndex === index}\n id={`${id}-suggestion-${index}`}\n key={suggestion.id}\n onBlur={handleAddressBlur}\n onClick={(event) => {\n // Keyboard activation fires click without a prior mouse down.\n if (event.detail === 0) {\n selectSuggestion(suggestion).catch(() => undefined);\n }\n }}\n onMouseDown={(event) => {\n event.preventDefault();\n selectSuggestion(suggestion).catch(() => undefined);\n }}\n role=\"option\"\n type=\"button\"\n >\n <strong>{suggestion.label}</strong>\n {suggestion.secondaryLabel ? (\n <span>{suggestion.secondaryLabel}</span>\n ) : null}\n </button>\n ))}\n </div>\n ) : null}\n </div>\n </label>\n <label htmlFor={`${id}-line2`}>\n <span>Apartment, suite, or unit</span>\n <input\n autoComplete=\"address-line2\"\n id={`${id}-line2`}\n onChange={(event) => update({ line2: event.currentTarget.value })}\n placeholder=\"Optional\"\n value={value.line2 ?? \"\"}\n />\n </label>\n <div className=\"lockerverse-signup__address-row\">\n <label htmlFor={`${id}-city`}>\n <span>City</span>\n <input\n autoComplete=\"address-level2\"\n id={`${id}-city`}\n onChange={(event) => update({ city: event.currentTarget.value })}\n required={required}\n value={value.city}\n />\n </label>\n <label htmlFor={`${id}-state`}>\n <span>State</span>\n <input\n autoComplete=\"address-level1\"\n id={`${id}-state`}\n onChange={(event) => update({ state: event.currentTarget.value })}\n required={required}\n value={value.state}\n />\n </label>\n </div>\n <div className=\"lockerverse-signup__address-row\">\n <label htmlFor={`${id}-postal`}>\n <span>Postal code</span>\n <input\n autoComplete=\"postal-code\"\n id={`${id}-postal`}\n onChange={(event) =>\n update({ postalCode: event.currentTarget.value })\n }\n required={required}\n value={value.postalCode}\n />\n </label>\n <label htmlFor={`${id}-country`}>\n <span>Country</span>\n <input\n autoComplete=\"country\"\n id={`${id}-country`}\n maxLength={2}\n onChange={(event) =>\n update({ country: event.currentTarget.value.toUpperCase() })\n }\n required={required}\n value={value.country}\n />\n </label>\n </div>\n </fieldset>\n );\n}\n","import type {\n LockerverseSignup,\n LockerverseSignupAddress,\n} from \"@lockerverse/sdk/signup\";\nimport {\n check,\n nonEmpty,\n nullable,\n object,\n pipe,\n regex,\n safeParse,\n string,\n transform,\n trim,\n} from \"valibot\";\nimport {\n optionalEmailSchema,\n optionalPhoneSchema,\n requiredEmailSchema,\n requiredPhoneSchema,\n} from \"./contact-validation.ts\";\nimport {\n type CustomFieldValues,\n reconcileCustomFieldValues,\n validateCustomFields,\n} from \"./custom-fields.tsx\";\n\nconst POSITIVE_INTEGER_PATTERN = /^[1-9]\\d*$/;\nconst OPTIONAL_POSITIVE_INTEGER_PATTERN = /^(?:$|[1-9]\\d*)$/;\n\nexport type SignupAddressValues = Omit<LockerverseSignupAddress, \"line2\"> & {\n line2: string | null;\n};\n\nexport type SignupFormValues = {\n address: SignupAddressValues;\n customFields: CustomFieldValues;\n email: string;\n honeypot: string;\n name: string;\n participantCount: string;\n phone: string;\n phoneCountry: string;\n};\n\nconst nameSchema = pipe(string(), trim(), nonEmpty(\"Name is required.\"));\nconst optionalParticipantCountSchema = pipe(\n string(),\n trim(),\n regex(\n OPTIONAL_POSITIVE_INTEGER_PATTERN,\n \"Guest count must be a positive whole number.\"\n ),\n transform((value) => (value ? Number(value) : null)),\n check(\n (value) => value === null || Number.isSafeInteger(value),\n \"Guest count must be a positive whole number.\"\n )\n);\nconst requiredParticipantCountSchema = pipe(\n string(),\n trim(),\n nonEmpty(\"Guest count is required.\"),\n regex(\n POSITIVE_INTEGER_PATTERN,\n \"Guest count must be a positive whole number.\"\n ),\n transform(Number),\n check(\n (value) => Number.isSafeInteger(value),\n \"Guest count must be a positive whole number.\"\n )\n);\nconst addressFieldsSchema = object({\n city: string(),\n country: string(),\n line1: string(),\n line2: nullable(string()),\n postalCode: string(),\n state: string(),\n});\nconst requiredAddressSchema = pipe(\n addressFieldsSchema,\n check(isAddressComplete, \"Complete the address.\")\n);\n\nconst EMPTY_ADDRESS: SignupAddressValues = {\n city: \"\",\n country: \"US\",\n line1: \"\",\n line2: null,\n postalCode: \"\",\n state: \"\",\n};\nconst optionalAddressSchema = pipe(\n addressFieldsSchema,\n check(\n (address) => isAddressEmpty(address) || isAddressComplete(address),\n \"Complete the address or leave it blank.\"\n )\n);\n\nexport function isAddressEmpty(address: SignupAddressValues) {\n return ![\n address.city,\n address.line1,\n address.line2,\n address.postalCode,\n address.state,\n ].some((value) => value?.trim());\n}\n\nfunction isAddressComplete(address: SignupAddressValues) {\n return [\n address.city,\n address.country,\n address.line1,\n address.postalCode,\n address.state,\n ].every((value) => value.trim());\n}\n\n/** Phone must already be normalized by the shared phone helper when enabled. */\nexport function validateSignupForm(\n signup: LockerverseSignup,\n values: SignupFormValues\n) {\n const normalizedValues = {\n ...values,\n address: signup.fields.address.enabled ? values.address : EMPTY_ADDRESS,\n customFields: reconcileCustomFieldValues(\n signup.customFields,\n values.customFields\n ),\n email: signup.fields.email.enabled ? values.email : \"\",\n participantCount: signup.fields.participantCount.enabled\n ? values.participantCount\n : \"\",\n phone: signup.fields.phone.enabled ? values.phone : \"\",\n };\n const schema = object({\n address:\n signup.fields.address.enabled && signup.fields.address.required\n ? requiredAddressSchema\n : optionalAddressSchema,\n email:\n signup.fields.email.enabled && signup.fields.email.required\n ? requiredEmailSchema\n : optionalEmailSchema,\n name: nameSchema,\n participantCount:\n signup.fields.participantCount.enabled &&\n signup.fields.participantCount.required\n ? requiredParticipantCountSchema\n : optionalParticipantCountSchema,\n phone:\n signup.fields.phone.enabled && signup.fields.phone.required\n ? requiredPhoneSchema\n : optionalPhoneSchema,\n });\n const result = safeParse(schema, normalizedValues);\n const errors = validateCustomFields(\n signup.customFields,\n normalizedValues.customFields\n );\n if (!result.success) {\n for (const issue of result.issues) {\n const field = issue.path?.[0]?.key;\n const fieldName = [\n \"address\",\n \"email\",\n \"name\",\n \"participantCount\",\n \"phone\",\n ].find((name) => name === field);\n if (fieldName && !errors[fieldName]) {\n errors[fieldName] = issue.message;\n }\n }\n }\n return result.success\n ? { errors, value: { ...normalizedValues, ...result.output } }\n : { errors, value: null };\n}\n","import type {\n LockerverseSdkError,\n LockerverseSignupClient,\n LockerverseSignup as LockerverseSignupDefinition,\n LockerverseSignupSubmissionResult,\n} from \"@lockerverse/sdk/signup\";\nimport {\n type FormEvent,\n type ReactNode,\n useEffect,\n useId,\n useRef,\n useState,\n} from \"react\";\nimport { getAccentContrast, normalizeAccentColor } from \"./accent-contrast.ts\";\nimport { getPhoneServerError } from \"./contact-validation.ts\";\nimport {\n buildCustomFieldAnswers,\n CustomFields,\n createCustomFieldValues,\n reconcileCustomFieldValues,\n} from \"./custom-fields.tsx\";\nimport { EmailField, FieldError, FormField } from \"./form-field.tsx\";\nimport { FormSkeleton } from \"./form-skeleton.tsx\";\nimport { notifyHostCallback } from \"./host-callback.ts\";\nimport { getInternationalPhone } from \"./phone.ts\";\nimport { PhoneInput } from \"./phone-field.tsx\";\nimport { SignupAddressField } from \"./signup-address-field.tsx\";\nimport type { LockerverseSignupProps } from \"./signup-types.ts\";\nimport {\n type SignupFormValues as FormValues,\n isAddressEmpty,\n type SignupAddressValues,\n validateSignupForm,\n} from \"./signup-validation.ts\";\n\nconst DEFAULT_ADDRESS: SignupAddressValues = {\n city: \"\",\n country: \"US\",\n line1: \"\",\n line2: \"\",\n postalCode: \"\",\n state: \"\",\n};\n\nconst DEFAULT_ACCENT = \"#5751f2\";\n\nfunction createInitialValues(signup: LockerverseSignupDefinition): FormValues {\n return {\n address: DEFAULT_ADDRESS,\n customFields: createCustomFieldValues(signup.customFields),\n email: \"\",\n honeypot: \"\",\n name: \"\",\n participantCount: \"\",\n phone: \"\",\n phoneCountry: \"US\",\n };\n}\n\nfunction focusNamedControl(form: HTMLFormElement, name: string) {\n const control = form.elements.namedItem(name);\n if (control instanceof HTMLElement) {\n if (!control.matches(\":disabled\")) {\n control.focus();\n return true;\n }\n return false;\n }\n if (control instanceof RadioNodeList) {\n const focusable = Array.from(control).find(\n (item) => item instanceof HTMLElement && !item.matches(\":disabled\")\n );\n focusable?.focus();\n return Boolean(focusable);\n }\n return false;\n}\n\nfunction focusFirstSignupValidationError(\n form: HTMLFormElement,\n errors: Record<string, string>\n) {\n const builtInFields: [string, string][] = [\n [\"name\", \"name\"],\n [\"email\", \"email\"],\n [\"phone\", \"phone\"],\n [\"participantCount\", \"participantCount\"],\n [\"address\", \"address.line1\"],\n ];\n for (const [errorKey, controlName] of builtInFields) {\n if (errors[errorKey] && focusNamedControl(form, controlName)) {\n return;\n }\n }\n const builtInKeys = new Set(builtInFields.map(([errorKey]) => errorKey));\n const customFieldId = Object.keys(errors).find(\n (errorKey) => !builtInKeys.has(errorKey)\n );\n if (customFieldId) {\n focusNamedControl(form, `custom:${customFieldId}`);\n }\n}\n\ntype SignupViewProps = Omit<LockerverseSignupProps, \"widget\">;\n\nfunction SignupShell({\n children,\n loading = false,\n status = false,\n viewProps,\n}: {\n children: ReactNode;\n loading?: boolean;\n status?: boolean;\n viewProps: SignupViewProps;\n}) {\n const {\n branding,\n className,\n googlePlacesApiKey: _googlePlacesApiKey,\n onSignupComplete: _onSignupComplete,\n style,\n theme = \"dark\",\n ...sectionProps\n } = viewProps;\n const accent = normalizeAccentColor(\n style?.[\"--lockerverse-accent\"] ??\n style?.[\"--lockerverse-signup-accent\"] ??\n branding?.accentColor ??\n DEFAULT_ACCENT\n );\n const signupStyle: LockerverseSignupProps[\"style\"] = { ...style };\n if (\n style?.[\"--lockerverse-accent\"] !== undefined ||\n style?.[\"--lockerverse-signup-accent\"] !== undefined ||\n branding?.accentColor\n ) {\n signupStyle[\"--lockerverse-accent\"] = accent;\n }\n if (\n style?.[\"--lockerverse-accent-contrast\"] === undefined &&\n style?.[\"--lockerverse-signup-accent-contrast\"] === undefined\n ) {\n const accentContrast = getAccentContrast(accent);\n if (accentContrast) {\n signupStyle[\"--lockerverse-accent-contrast\"] = accentContrast;\n }\n }\n return (\n <section\n {...sectionProps}\n {...(loading ? { \"aria-busy\": true } : {})}\n className={[\n \"lockerverse-signup\",\n status ? \"lockerverse-signup__status\" : null,\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n data-lockerverse-theme={theme}\n style={signupStyle}\n >\n {children}\n </section>\n );\n}\n\ntype SignupSubmissionState =\n | { phase: \"idle\" }\n | { phase: \"submitting\" }\n | {\n error: LockerverseSdkError;\n phase: \"submit_error\";\n }\n | {\n phase: \"submitted\";\n };\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: The component renders server-defined field branches in one public form boundary.\nfunction SignupForm({\n client,\n loadError,\n onRetry,\n signup,\n ...viewProps\n}: SignupViewProps & {\n client: LockerverseSignupClient;\n loadError?: LockerverseSdkError | null;\n onRetry?: () => void;\n signup: LockerverseSignupDefinition;\n}) {\n const { branding, googlePlacesApiKey, onSignupComplete } = viewProps;\n const idPrefix = useId();\n const mountedRef = useRef(true);\n const phoneRef = useRef<HTMLInputElement>(null);\n const submittingRef = useRef(false);\n const [state, setState] = useState<SignupSubmissionState>({ phase: \"idle\" });\n const [values, setValues] = useState<FormValues>(() =>\n createInitialValues(signup)\n );\n const [errors, setErrors] = useState<Record<string, string>>({});\n const [submissionRetry, setSubmissionRetry] = useState<{\n payloadKey: string;\n reference: string;\n }>();\n const customFieldValues = reconcileCustomFieldValues(\n signup.customFields,\n values.customFields\n );\n\n useEffect(() => {\n if (customFieldValues !== values.customFields) {\n setValues((current) => ({\n ...current,\n customFields: reconcileCustomFieldValues(\n signup.customFields,\n current.customFields\n ),\n }));\n }\n }, [customFieldValues, signup.customFields, values.customFields]);\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n useEffect(() => {\n if (state.phase !== \"submitting\" && errors.phone) {\n phoneRef.current?.focus();\n }\n }, [errors.phone, state.phase]);\n\n if (!signup.isActive) {\n return (\n <SignupShell status viewProps={viewProps}>\n <h1>Signup closed</h1>\n <p>This signup is not accepting submissions.</p>\n </SignupShell>\n );\n }\n\n if (state.phase === \"submitted\") {\n return (\n <SignupShell status viewProps={viewProps}>\n {branding ? <Branding branding={branding} /> : null}\n <span aria-hidden=\"true\" className=\"lockerverse-signup__success\">\n ✓\n </span>\n <h1>Thank you</h1>\n <p>Your signup has been received.</p>\n </SignupShell>\n );\n }\n\n const update = (patch: Partial<FormValues>) =>\n setValues((current) => ({ ...current, ...patch }));\n const submitting = state.phase === \"submitting\";\n const submitError =\n state.phase === \"submit_error\" ? state.error.message : undefined;\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Submission maps the enabled server-defined fields to one SDK request.\n const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n // biome-ignore lint/suspicious/noUnnecessaryConditions: The ref blocks a second submit before React commits the submitting state.\n if (submittingRef.current) {\n return;\n }\n const validation = validateSignupForm(signup, {\n ...values,\n customFields: customFieldValues,\n phone: signup.fields.phone.enabled\n ? getInternationalPhone(values.phone, values.phoneCountry)\n : \"\",\n });\n setErrors(validation.errors);\n if (Object.keys(validation.errors).length > 0 || !validation.value) {\n const form = event.currentTarget;\n queueMicrotask(() =>\n focusFirstSignupValidationError(form, validation.errors)\n );\n return;\n }\n const validatedValues = validation.value;\n const submission = {\n address:\n signup.fields.address.enabled &&\n !isAddressEmpty(validatedValues.address)\n ? validatedValues.address\n : null,\n answers: buildCustomFieldAnswers(\n signup.customFields,\n validatedValues.customFields\n ),\n email: signup.fields.email.enabled ? validatedValues.email || null : null,\n honeypot: validatedValues.honeypot,\n name: validatedValues.name,\n participantCount: signup.fields.participantCount.enabled\n ? validatedValues.participantCount\n : null,\n phone: signup.fields.phone.enabled ? validatedValues.phone || null : null,\n };\n const payloadKey = JSON.stringify(submission);\n const submissionReference =\n submissionRetry?.payloadKey === payloadKey\n ? submissionRetry.reference\n : globalThis.crypto.randomUUID();\n let result: LockerverseSignupSubmissionResult;\n submittingRef.current = true;\n setState({ phase: \"submitting\" });\n try {\n result = await client.submit(submission, { submissionReference });\n } catch (error) {\n if (!mountedRef.current) {\n return;\n }\n // SAFETY: LockerverseSignupClient normalizes each submission rejection to LockerverseSdkError.\n const sdkError = error as LockerverseSdkError;\n const phoneError = getPhoneServerError(sdkError.serverCode);\n if (phoneError) {\n setErrors((current) => ({ ...current, phone: phoneError }));\n setState({ phase: \"idle\" });\n setSubmissionRetry(undefined);\n return;\n }\n setState({ error: sdkError, phase: \"submit_error\" });\n if (sdkError.recoveryRecommended) {\n setSubmissionRetry({\n payloadKey,\n reference: submissionReference,\n });\n } else {\n setSubmissionRetry(undefined);\n }\n return;\n } finally {\n submittingRef.current = false;\n }\n // biome-ignore lint/suspicious/noUnnecessaryConditions: The ref changes during unmount while this request is pending.\n if (!mountedRef.current) {\n return;\n }\n setSubmissionRetry(undefined);\n setState({ phase: \"submitted\" });\n notifyHostCallback(onSignupComplete, result);\n };\n\n return (\n <SignupShell viewProps={viewProps}>\n {signup.coverImageUrl ? (\n <img\n alt=\"\"\n className=\"lockerverse-signup__cover\"\n height={192}\n src={signup.coverImageUrl}\n width={440}\n />\n ) : null}\n {branding ? <Branding branding={branding} /> : null}\n <header>\n {signup.title?.trim() ? <h1>{signup.title}</h1> : null}\n {signup.description ? <p>{signup.description}</p> : null}\n </header>\n {loadError ? (\n <div role=\"alert\">\n <p>{loadError.message}</p>\n <button onClick={onRetry} type=\"button\">\n Retry\n </button>\n </div>\n ) : null}\n <form noValidate onSubmit={handleSubmit}>\n <input\n aria-hidden=\"true\"\n autoComplete=\"off\"\n className=\"lockerverse-signup__honeypot\"\n onChange={(event) => update({ honeypot: event.currentTarget.value })}\n tabIndex={-1}\n value={values.honeypot}\n />\n <div className=\"lockerverse-signup__fields\">\n <label htmlFor={`${idPrefix}-name`}>\n <span>Name</span>\n <input\n aria-describedby={\n errors.name ? `${idPrefix}-name-error` : undefined\n }\n aria-invalid={errors.name ? \"true\" : undefined}\n autoComplete=\"name\"\n id={`${idPrefix}-name`}\n name=\"name\"\n onChange={(event) => update({ name: event.currentTarget.value })}\n required\n value={values.name}\n />\n <FieldError error={errors.name} id={`${idPrefix}-name-error`} />\n </label>\n {signup.fields.email.enabled ? (\n <EmailField\n error={errors.email}\n id={`${idPrefix}-email`}\n label=\"Email\"\n name=\"email\"\n onChange={(event) => update({ email: event.currentTarget.value })}\n required={signup.fields.email.required}\n value={values.email}\n />\n ) : null}\n {signup.fields.phone.enabled ? (\n <FormField\n error={errors.phone}\n id={`${idPrefix}-phone`}\n label=\"Phone\"\n >\n <PhoneInput\n country={values.phoneCountry}\n error={errors.phone}\n errorId={`${idPrefix}-phone-error`}\n id={`${idPrefix}-phone`}\n inputRef={phoneRef}\n name=\"phone\"\n onChange={({ value, country }) =>\n update({ phone: value, phoneCountry: country })\n }\n required={signup.fields.phone.required}\n value={values.phone}\n />\n </FormField>\n ) : null}\n {signup.fields.participantCount.enabled ? (\n <label htmlFor={`${idPrefix}-participant-count`}>\n <span>Guest count</span>\n <input\n aria-describedby={\n errors.participantCount\n ? `${idPrefix}-participant-count-error`\n : undefined\n }\n aria-invalid={errors.participantCount ? \"true\" : undefined}\n id={`${idPrefix}-participant-count`}\n min={1}\n name=\"participantCount\"\n onChange={(event) =>\n update({ participantCount: event.currentTarget.value })\n }\n required={signup.fields.participantCount.required}\n type=\"number\"\n value={values.participantCount}\n />\n <FieldError\n error={errors.participantCount}\n id={`${idPrefix}-participant-count-error`}\n />\n </label>\n ) : null}\n {signup.fields.address.enabled ? (\n <div className=\"lockerverse-signup__field-group\">\n <SignupAddressField\n apiKey={googlePlacesApiKey}\n errorId={\n errors.address ? `${idPrefix}-address-error` : undefined\n }\n invalid={Boolean(errors.address)}\n onChange={(address) => update({ address })}\n required={signup.fields.address.required}\n value={values.address}\n />\n <FieldError\n error={errors.address}\n id={`${idPrefix}-address-error`}\n />\n </div>\n ) : null}\n <CustomFields\n choiceClassName=\"lockerverse-signup__choice\"\n errorClassName=\"lockerverse-signup__field-error\"\n errors={errors}\n fields={signup.customFields}\n idPrefix={idPrefix}\n onChange={(customFields) => update({ customFields })}\n values={customFieldValues}\n />\n </div>\n {submitError ? (\n <p className=\"lockerverse-signup__submit-error\" role=\"alert\">\n {submitError} Try again.\n </p>\n ) : null}\n <button\n className=\"lockerverse-signup__submit\"\n disabled={submitting}\n type=\"submit\"\n >\n {submitting ? \"Submitting…\" : \"Submit\"}\n </button>\n </form>\n </SignupShell>\n );\n}\n\nexport function LockerverseSignup({\n widget,\n ...viewProps\n}: LockerverseSignupProps) {\n if (widget.error && !widget.signup) {\n return (\n <SignupShell status viewProps={viewProps}>\n <h1>Signup unavailable</h1>\n <p role=\"alert\">{widget.error.message}</p>\n <button onClick={widget.refresh} type=\"button\">\n Retry\n </button>\n </SignupShell>\n );\n }\n if (!widget.signup) {\n return (\n <SignupShell loading viewProps={viewProps}>\n <FormSkeleton fieldCount={4} label=\"Loading signup…\" />\n </SignupShell>\n );\n }\n return (\n <SignupForm\n client={widget.client}\n loadError={widget.error}\n onRetry={widget.refresh}\n signup={widget.signup}\n {...viewProps}\n />\n );\n}\n\nfunction Branding({\n branding,\n}: {\n branding: NonNullable<LockerverseSignupProps[\"branding\"]>;\n}) {\n return (\n <div className=\"lockerverse-signup__branding\">\n {branding.imageUrl ? (\n <img alt=\"\" height={48} src={branding.imageUrl} width={48} />\n ) : null}\n <strong>{branding.name}</strong>\n </div>\n );\n}\n","import {\n type CreateLockerverseSignupOptions,\n createLockerverseSignupClient,\n type LockerverseSdkError,\n type LockerverseSignup,\n type LockerverseSignupClient,\n} from \"@lockerverse/sdk/signup\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useImmutableResourceIdentity } from \"./immutable-resource-identity.ts\";\n\ntype SignupLoadState = {\n error: LockerverseSdkError | null;\n loading: boolean;\n signup: LockerverseSignup | null;\n};\n\nexport type UseLockerverseSignupOptions = {\n /** Initial public SDK snapshot. The hook still refreshes on mount. */\n initialSignup?: LockerverseSignup;\n};\n\nexport type UseLockerverseSignupResult = {\n client: LockerverseSignupClient;\n error: LockerverseSdkError | null;\n loading: boolean;\n refresh: () => void;\n signup: LockerverseSignup | null;\n};\n\nexport function useLockerverseSignup(\n options: CreateLockerverseSignupOptions,\n { initialSignup }: UseLockerverseSignupOptions = {}\n): UseLockerverseSignupResult {\n const { onError } = options;\n useImmutableResourceIdentity(\"signup\", {\n apiBaseUrl: options.apiBaseUrl,\n communitySlug: options.communitySlug,\n environment: options.environment,\n slug: options.signupSlug,\n });\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const [client] = useState(() => {\n const clientOptions: CreateLockerverseSignupOptions = {\n ...options,\n onError: (error) => onErrorRef.current?.(error),\n };\n return createLockerverseSignupClient(clientOptions);\n });\n const [revision, setRevision] = useState(0);\n const [state, setState] = useState<SignupLoadState>(() => ({\n error: null,\n loading: true,\n signup: initialSignup ?? null,\n }));\n\n useEffect(() => {\n let active = true;\n client.load().then(\n (signup) => {\n if (active) {\n setState({\n error: null,\n loading: false,\n signup,\n });\n }\n },\n (error: LockerverseSdkError) => {\n if (active) {\n setState((current) => ({ ...current, error, loading: false }));\n }\n }\n );\n return () => {\n active = false;\n };\n }, [client, revision]);\n\n const refresh = useCallback(() => {\n setState((current) => ({ ...current, error: null, loading: true }));\n setRevision((value) => value + 1);\n }, []);\n\n return {\n client,\n error: state.error,\n loading: state.loading,\n refresh,\n signup: state.signup,\n };\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{l as e,o as t,u as n}from"./host-callback.js";import{useEffect as r,useRef as i,useState as a}from"react";import{object as o,safeParse as s}from"valibot";import{loadStripe as c}from"@stripe/stripe-js/pure/index.js";function l(e){return t(e)}function u(t,r){let i=r?{...t,phone:l(t.phone)}:t,a=o(r?{email:e,phone:n}:{email:e}),c=s(a,i);if(c.success)return{errors:{},value:c.output};let u={};for(let e of c.issues){let t=e.path?.[0]?.key;(t===`email`||t===`phone`)&&!u[t]&&(u[t]=e.message)}return{errors:u,value:null}}const d=`ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`,f=/var\(|currentcolor|inherit|initial|unset|revert/i;function p(e,t,n,r,i){let a=e.ownerDocument.defaultView;if(!a)return i;let o=a.getComputedStyle(e).getPropertyValue(`--lockerverse-${r}`).trim();return!o||!a.CSS?.supports(n,o)?i:f.test(o)?(t.style.removeProperty(n),t.style.setProperty(n,o,`important`),a.getComputedStyle(t).getPropertyValue(n).trim()||i):o}function m(e,t,n){let r=t===`light`,i={borderRadius:`10px`,colorBackground:r?`#f5f6f7`:`#121212`,colorDanger:r?`#c52b3e`:`#f08a98`,colorPrimary:n??`#38d77a`,colorText:r?`#121416`:`#ffffff`,colorTextPlaceholder:r?`#72767d`:`#6b6b6b`,colorTextSecondary:r?`#62666d`:`#a1a1aa`,focusBoxShadow:`none`,focusOutline:`none`,fontFamily:d,fontSizeBase:`16px`},a=e?.ownerDocument.defaultView;if(e?.isConnected&&a){i.fontFamily=a.getComputedStyle(e).fontFamily||d;let t=e.ownerDocument.createElement(`span`);t.setAttribute(`aria-hidden`,`true`),t.style.cssText=`position:absolute;visibility:hidden;pointer-events:none;width:0;height:0;overflow:hidden`,e.append(t);try{for(let[n,r,a]of[[`borderRadius`,`radius`,`border-radius`],[`colorBackground`,`control`,`color`],[`colorDanger`,`danger`,`color`],[`colorPrimary`,`accent`,`color`],[`colorText`,`text`,`color`],[`colorTextPlaceholder`,`placeholder`,`color`],[`colorTextSecondary`,`muted`,`color`]])i[n]=p(e,t,a,r,i[n]??``)}finally{t.remove()}}return{rules:{".Input:focus":{borderColor:i.colorPrimary??`#38d77a`,boxShadow:`0 0 0 1px ${i.colorPrimary}`,outline:`none`}},theme:r?`stripe`:`night`,variables:i}}function h(e,t,n,o,s){let[c,l]=a(null),u=i(null);return r(()=>{if(o&&u.current)return;let n=m(e.current,t??`dark`,s);JSON.stringify(u.current)!==JSON.stringify(n)&&(u.current=n,l(n))},[e,t,n,o,s]),c}const g=new Map,_=(e,t)=>{let n=t?.stripeAccount??null,r=g.get(e);r||(r=new Map,g.set(e,r));let i=r.get(n);if(i)return i;let a=c(e,t).catch(()=>null).then(t=>t||(r?.get(n)===a&&(r.delete(n),r.size===0&&g.delete(e)),null));return r.set(n,a),a};export{u as i,h as n,l as r,_ as t};
1
+ import{a as e,c as t,l as n}from"./phone-field.js";import{useEffect as r,useRef as i,useState as a}from"react";import{object as o,safeParse as s}from"valibot";import{loadStripe as c}from"@stripe/stripe-js/pure/index.js";function l(t){return e(t)}function u(e,r){let i=r?{...e,phone:l(e.phone)}:e,a=o(r?{email:t,phone:n}:{email:t}),c=s(a,i);if(c.success)return{errors:{},value:c.output};let u={};for(let e of c.issues){let t=e.path?.[0]?.key;(t===`email`||t===`phone`)&&!u[t]&&(u[t]=e.message)}return{errors:u,value:null}}const d=`ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`,f=/var\(|currentcolor|inherit|initial|unset|revert/i;function p(e,t,n,r,i){let a=e.ownerDocument.defaultView;if(!a)return i;let o=a.getComputedStyle(e).getPropertyValue(`--lockerverse-${r}`).trim();return!o||!a.CSS?.supports(n,o)?i:f.test(o)?(t.style.removeProperty(n),t.style.setProperty(n,o,`important`),a.getComputedStyle(t).getPropertyValue(n).trim()||i):o}function m(e,t,n){let r=t===`light`,i={borderRadius:`10px`,colorBackground:r?`#f5f6f7`:`#121212`,colorDanger:r?`#c52b3e`:`#f08a98`,colorPrimary:n??`#38d77a`,colorText:r?`#121416`:`#ffffff`,colorTextPlaceholder:r?`#72767d`:`#6b6b6b`,colorTextSecondary:r?`#62666d`:`#a1a1aa`,focusBoxShadow:`none`,focusOutline:`none`,fontFamily:d,fontSizeBase:`16px`},a=e?.ownerDocument.defaultView;if(e?.isConnected&&a){i.fontFamily=a.getComputedStyle(e).fontFamily||d;let t=e.ownerDocument.createElement(`span`);t.setAttribute(`aria-hidden`,`true`),t.style.cssText=`position:absolute;visibility:hidden;pointer-events:none;width:0;height:0;overflow:hidden`,e.append(t);try{for(let[n,r,a]of[[`borderRadius`,`radius`,`border-radius`],[`colorBackground`,`control`,`color`],[`colorDanger`,`danger`,`color`],[`colorPrimary`,`accent`,`color`],[`colorText`,`text`,`color`],[`colorTextPlaceholder`,`placeholder`,`color`],[`colorTextSecondary`,`muted`,`color`]])i[n]=p(e,t,a,r,i[n]??``)}finally{t.remove()}}return{rules:{".Input:focus":{borderColor:i.colorPrimary??`#38d77a`,boxShadow:`0 0 0 1px ${i.colorPrimary}`,outline:`none`}},theme:r?`stripe`:`night`,variables:i}}function h(e,t,n,o,s){let[c,l]=a(null),u=i(null);return r(()=>{if(o&&u.current)return;let n=m(e.current,t??`dark`,s);JSON.stringify(u.current)!==JSON.stringify(n)&&(u.current=n,l(n))},[e,t,n,o,s]),c}const g=new Map,_=(e,t)=>{let n=t?.stripeAccount??null,r=g.get(e);r||(r=new Map,g.set(e,r));let i=r.get(n);if(i)return i;let a=c(e,t).catch(()=>null).then(t=>t||(r?.get(n)===a&&(r.delete(n),r.size===0&&g.delete(e)),null));return r.set(n,a),a};export{u as i,h as n,l as r,_ as t};
2
2
  //# sourceMappingURL=stripe-loader.js.map