{"version":3,"file":"static/js/4362.4ae54be8.js","sources":["webpack://@jotforminc/portal/./src/assets/cardItemPlaceholder.svg","webpack://@jotforminc/portal/./src/components/EditableTextRenderer/index.js","webpack://@jotforminc/portal/./src/components/EmbeddedForm/index.js","webpack://@jotforminc/portal/./src/components/ItemOverQuotaWrapper/ScItemOverQuotaWrapper.js","webpack://@jotforminc/portal/./src/components/ItemOverQuotaWrapper/index.js","webpack://@jotforminc/portal/./src/components/Items/AppHeader/ScAppHeader.js","webpack://@jotforminc/portal/./src/components/Items/AppHeader/ScAppHeaderWrapper.js","webpack://@jotforminc/portal/./src/components/Items/AppHeader/index.js","webpack://@jotforminc/portal/./src/components/Items/ButtonItem/ScButtonItem.js","webpack://@jotforminc/portal/./src/components/Items/ButtonItem/index.js","webpack://@jotforminc/portal/./src/components/Items/CardItem/ScCardItem.js","webpack://@jotforminc/portal/./src/components/Items/CardItem/index.js","webpack://@jotforminc/portal/./src/components/Items/DataElement/index.js","webpack://@jotforminc/portal/./src/components/Items/DividerItem/ScDividerItem.js","webpack://@jotforminc/portal/./src/components/Items/DividerItem/index.js","webpack://@jotforminc/portal/./src/components/Items/DocumentItem/index.js","webpack://@jotforminc/portal/../../libs/payment-settings-editor/src/components/DonationBox/ProgressBar.tsx","webpack://@jotforminc/portal/../../libs/payment-settings-editor/src/components/DonationBox/DonationGoalBar.tsx","webpack://@jotforminc/portal/../../libs/payment-settings-editor/src/components/DonationBox/DonationCustomAmount.tsx","webpack://@jotforminc/portal/../../libs/payment-settings-editor/src/components/DonationBox/index.tsx","webpack://@jotforminc/portal/./src/components/Items/DonationItem/index.js","webpack://@jotforminc/portal/./src/components/Items/HeadingItem/index.js","webpack://@jotforminc/portal/./src/components/Items/ImageItem/index.js","webpack://@jotforminc/portal/./src/components/Items/LinkItem/index.js","webpack://@jotforminc/portal/./src/components/Items/List/helper.js","webpack://@jotforminc/portal/./src/components/Items/List/constants.js","webpack://@jotforminc/portal/./src/components/Items/List/index.js","webpack://@jotforminc/portal/./src/components/Items/List/styled.js","webpack://@jotforminc/portal/./src/components/Items/ParagraphItem/ScParagraphItem.js","webpack://@jotforminc/portal/./src/components/Items/ParagraphItem/index.js","webpack://@jotforminc/portal/./src/components/Link/scLinkThumbnail.js","webpack://@jotforminc/portal/./src/components/Items/SimpleItem/LinkThumbnail.js","webpack://@jotforminc/portal/./src/components/Items/WidgetItem/index.js","webpack://@jotforminc/portal/./src/components/ListItemBase/index.js","webpack://@jotforminc/portal/../../libs/branding-footer/src/assets/svg/jotform_21_logo.svg","webpack://@jotforminc/portal/../../libs/branding-footer/src/utils/HOCs/withClickOutside.js","webpack://@jotforminc/portal/../../libs/branding-footer/src/components/RemoveBrandingFooter.js","webpack://@jotforminc/portal/../../libs/branding-footer/src/components/constants.js","webpack://@jotforminc/portal/../../libs/branding-footer/src/utils/index.js","webpack://@jotforminc/portal/../../libs/branding-footer/src/components/BrandingFooter.js","webpack://@jotforminc/portal/./src/components/PortalBrandingFooter/index.js","webpack://@jotforminc/portal/./src/modules/Builder/components/HomePage/BuilderItem/EditableTextRendererFor.js","webpack://@jotforminc/portal/./src/modules/Builder/components/HomePage/Editors/InlineFileUpload.js","webpack://@jotforminc/portal/./src/modules/Builder/components/HomePage/BuilderItem/NewFileUploader.js","webpack://@jotforminc/portal/./src/modules/Builder/components/HomePage/BuilderItem/withInlineEditor.js","webpack://@jotforminc/portal/./src/modules/Builder/components/HomePage/Editors/InlineEditor/scInlineEditor.js","webpack://@jotforminc/portal/./src/modules/Builder/components/HomePage/Editors/InlineEditor/index.js","webpack://@jotforminc/portal/./src/modules/Builder/components/HomePage/ScAppContentWrapper.js","webpack://@jotforminc/portal/./src/modules/Builder/components/HomePage/ScItemListWrapper.js","webpack://@jotforminc/portal/./src/modules/Builder/components/LinkFieldItem/ScLinkFieldItem.js","webpack://@jotforminc/portal/./src/modules/Builder/components/LinkFieldItem/LinkFieldItem.js","webpack://@jotforminc/portal/./src/modules/PublicApp/AiAgent/ScAiAgent.js","webpack://@jotforminc/portal/./src/modules/PublicApp/AiAgent/index.js","webpack://@jotforminc/portal/./src/constants/nakedItems.js","webpack://@jotforminc/portal/./src/modules/PublicApp/AppItem/ScAppItemWrapper.js","webpack://@jotforminc/portal/./src/modules/PublicApp/ButtonItem/index.js","webpack://@jotforminc/portal/./src/modules/PublicApp/CtxMenuItems.js","webpack://@jotforminc/portal/./src/modules/PublicApp/FormItem/InlineCtxMenu/ScArrow.js","webpack://@jotforminc/portal/./src/modules/PublicApp/FormItem/ScFormItemWrapper.js","webpack://@jotforminc/portal/./src/modules/PublicApp/FormItem/InlineCtxMenu/ScInlineCtxMenu.js","webpack://@jotforminc/portal/./src/modules/PublicApp/FormItem/InlineCtxMenu/index.js","webpack://@jotforminc/portal/./src/modules/PublicApp/FormItem/index.js","webpack://@jotforminc/portal/./src/modules/PublicApp/ScItemContainer.js","webpack://@jotforminc/portal/./src/modules/PublicApp/SignItem/index.js","webpack://@jotforminc/portal/./src/styles/scWidgets.js","webpack://@jotforminc/portal/./src/utils/mutateItems.js","webpack://@jotforminc/portal/../../libs/common/src/components/InlineEditor/index.js","webpack://@jotforminc/portal/../../libs/constants/src/countries/index.js","webpack://@jotforminc/portal/../../libs/constants/src/days/index.js","webpack://@jotforminc/portal/../../libs/constants/src/genders/index.js","webpack://@jotforminc/portal/../../libs/constants/src/months/index.js","webpack://@jotforminc/portal/../../libs/constants/src/widgets/index.js","webpack://@jotforminc/portal/../../libs/form-common/src/constants.js","webpack://@jotforminc/portal/../../libs/form-common/src/utils.js","webpack://@jotforminc/portal/../../libs/form-common/src/appointment.js","webpack://@jotforminc/portal/../../libs/form-common/src/components/FormLogo.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Range.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Rating.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Ratingv2.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Separator.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Slider.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Spinner.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Textarea.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Textbox.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Widget.js","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/BaseInput.js","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/QuestionProps.js","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/SubLabel.js","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/Utils.js","webpack://@jotforminc/portal/../../../../src/icons/editor/list-check.svg","webpack://@jotforminc/portal/../../../../src/icons/general/circle-lg.svg","webpack://@jotforminc/portal/../../../../src/logos/payment/square-ach-logomark-dark.svg","webpack://@jotforminc/portal/../../../../src/logos/payment/applepay-logomark-color.svg","webpack://@jotforminc/portal/../../../../src/logos/payment/googlepay-logomark-color.svg","webpack://@jotforminc/portal/../../../../src/icons/editor/pen-sign-filled.svg","webpack://@jotforminc/portal/../../../../src/icons/general/dropdown-filled.svg","webpack://@jotforminc/portal/../../../../src/icons/general/number-square-filled.svg","webpack://@jotforminc/portal/../../../../src/icons/editor/text-color.svg","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Address.js","webpack://@jotforminc/portal/../../libs/payment-constants/src/unsupportedDecimalCurrencies.ts","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/FormatPrice.js","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/MakeProductText.js","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/PaymentUtils.js","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/ImageOverlay.js","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/MultiSelectDropdown.js","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/PaymentDropdown.js","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/Payment/WarningMessage.js","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/ProductContainer.js","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/PaymentAPMList.js","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/PaymentCreditCardAndAddress.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Authnet.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Autocomp.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Autoincrement.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Appointment.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Birthdate.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Bluepay.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Bluesnap.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Braintree.js","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/BaseButton.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Pagebreak.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Button.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Calculation.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/JotCaptcha.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/ReCaptcha.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/HCaptcha.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Captcha.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Cardconnect.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Chargify.js","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/OptionsBase.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Checkbox.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Clear.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Clickbank.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Collapse.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Timev2.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Datetime.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Dropdown.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Dwolla.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Email.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Echeck.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Eway.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Firstdata.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/PaypalInvoicing.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Payu.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/PayuMoney.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Pagseguro.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Moneris.js","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/MollieApmLists.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Mollie.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/FilepickerIO.js","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/IconSVG.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Fileuploadv2.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Fileupload.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Footer.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Fullname.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Geolocation.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Gocardless.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Googleco.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Grading.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Head.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Helper.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Hidden.js","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/Link.js","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/DivWrapper.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Image.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Inline.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Location.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Matrix.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Number.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Onebip.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Passwordbox.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Payjunction.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Payment.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Paymentwall.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Sensepass.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Paypal.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Paypalexpress.js","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/PaymentTypeContainer.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Paypalpro.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Paypalcomplete.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Cybersource.js","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/PaypalMessages.js","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/PaypalSPBButtons.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/PaypalSPB.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Paysafe.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Iyzico.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Phone.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Radio.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Scalev2.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Scale.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Screenshot.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Signature.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Sofort.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Skrill.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Square.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Stripe.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/StripeCheckout.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/StripeACH.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/StripeACHManual.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Payfast.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Text.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Time.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/2co.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Wepay.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Worldpay.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Worldpayus.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Divider.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Mixed.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Imagechoice.js","webpack://@jotforminc/portal/../../libs/form-fields/src/helpers/PaypalCommercePlatform.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/Paymentmethods.js","webpack://@jotforminc/portal/../../libs/form-fields/src/fields/PortalPayment.js","webpack://@jotforminc/portal/../../libs/form-fields/src/index.js","webpack://@jotforminc/portal/../../../../src/icons/general/bars.svg","webpack://@jotforminc/portal/../../../../src/icons/layout/grid-3-filled.svg","webpack://@jotforminc/portal/../../libs/product-list/src/components/ProductImage.js","webpack://@jotforminc/portal/../../libs/product-list/src/store/index.js","webpack://@jotforminc/portal/../../libs/product-list/src/utils/index.js","webpack://@jotforminc/portal/../../libs/product-list/src/components/ProductNameAndPrice.js","webpack://@jotforminc/portal/../../libs/product-list/src/constants/propTypes.js","webpack://@jotforminc/portal/../../libs/product-list/src/components/ProductFavoriteButton.js","webpack://@jotforminc/portal/../../libs/product-list/src/components/ProductControllerButtons.js","webpack://@jotforminc/portal/../../libs/product-list/src/components/ProductController.js","webpack://@jotforminc/portal/../../libs/product-list/src/components/ProductItemSettingsBar.js","webpack://@jotforminc/portal/../../libs/product-list/src/components/ProductListItem.js","webpack://@jotforminc/portal/../../libs/product-list/src/constants/index.js","webpack://@jotforminc/portal/../../libs/product-list/src/components/ProductAddButton.js","webpack://@jotforminc/portal/../../libs/product-list/src/components/ProductList.js","webpack://@jotforminc/portal/../../libs/product-list/src/components/ProductToolbar.js","webpack://@jotforminc/portal/../../libs/product-list/src/components/ProductContainer.js","webpack://@jotforminc/portal/../../../../src/icons/general/plus-circle-filled.svg","webpack://@jotforminc/portal/../../../../src/icons/general/plus-circle.svg","webpack://@jotforminc/portal/../../../../src/icons/general/square-filled.svg","webpack://@jotforminc/portal/../../../../src/icons/layout/grid-2-filled.svg","webpack://@jotforminc/portal/../../../../src/icons/time-date/calendar-filled.svg"],"sourcesContent":["var _defs;\nfunction _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }\nimport * as React from \"react\";\nconst SvgCardItemPlaceholder = props => /*#__PURE__*/React.createElement(\"svg\", _extends({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n style: {\n maxWidth: \"100%\",\n height: \"auto\"\n },\n viewBox: \"0 0 498 105\"\n}, props), /*#__PURE__*/React.createElement(\"rect\", {\n width: 105,\n height: 105,\n rx: 8,\n style: {\n fill: \"url(#cardItemPlaceholder_svg__a)\"\n }\n}), /*#__PURE__*/React.createElement(\"g\", {\n clipPath: \"url(#cardItemPlaceholder_svg__b)\"\n}, /*#__PURE__*/React.createElement(\"rect\", {\n width: 373,\n height: 16,\n x: 125,\n y: 57,\n rx: 8,\n style: {\n fill: \"url(#cardItemPlaceholder_svg__a)\"\n }\n})), /*#__PURE__*/React.createElement(\"g\", {\n clipPath: \"url(#cardItemPlaceholder_svg__c)\"\n}, /*#__PURE__*/React.createElement(\"rect\", {\n width: 227,\n height: 16,\n x: 125,\n y: 33,\n rx: 8,\n style: {\n fill: \"url(#cardItemPlaceholder_svg__a)\"\n }\n})), _defs || (_defs = /*#__PURE__*/React.createElement(\"defs\", null, /*#__PURE__*/React.createElement(\"clipPath\", {\n id: \"cardItemPlaceholder_svg__b\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n fill: \"#fff\",\n d: \"M125 57h373v16H125z\"\n})), /*#__PURE__*/React.createElement(\"clipPath\", {\n id: \"cardItemPlaceholder_svg__c\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n fill: \"#fff\",\n d: \"M125 33h227v16H125z\"\n})), /*#__PURE__*/React.createElement(\"linearGradient\", {\n id: \"cardItemPlaceholder_svg__a\"\n}, /*#__PURE__*/React.createElement(\"stop\", {\n offset: 0.6,\n stopColor: \"#f3f3f3\"\n}, /*#__PURE__*/React.createElement(\"animate\", {\n attributeName: \"offset\",\n dur: \"2s\",\n keyTimes: \"0; 0.25; 1\",\n repeatCount: \"indefinite\",\n values: \"-2; -2; 1\"\n})), /*#__PURE__*/React.createElement(\"stop\", {\n offset: 1.6,\n stopColor: \"#ecebeb\"\n}, /*#__PURE__*/React.createElement(\"animate\", {\n attributeName: \"offset\",\n dur: \"2s\",\n keyTimes: \"0; 0.25; 1\",\n repeatCount: \"indefinite\",\n values: \"-1; -1; 2\"\n})), /*#__PURE__*/React.createElement(\"stop\", {\n offset: 2.6,\n stopColor: \"#f3f3f3\"\n}, /*#__PURE__*/React.createElement(\"animate\", {\n attributeName: \"offset\",\n dur: \"2s\",\n keyTimes: \"0; 0.25; 1\",\n repeatCount: \"indefinite\",\n values: \"0; 0; 3\"\n}))))));\nexport default SvgCardItemPlaceholder;","import React, { useCallback, useRef, useEffect } from 'react';\nimport PropTypes from 'prop-types';\nimport InlineEditor from '../../modules/Builder/components/HomePage/Editors/InlineEditor';\nimport { checkMobileOrTablet, isMultiSelection } from '../../utils';\nimport { DESCRIPTION_LIMIT } from '../../constants';\n\nconst EditableTextRenderer = ({\n children, characterLimit, onChange, contentEditable, onFocus, ...props\n}) => {\n const textRendererRef = useRef(null);\n const { placeholder = '' } = props;\n\n const clipText = element => {\n // eslint-disable-next-line no-param-reassign\n if (element.innerText) element.innerText = element.innerText.slice(0, characterLimit);\n };\n\n useEffect(() => {\n const contentEditableRef = textRendererRef.current?.contentEditableRef?.current;\n if (contentEditableRef) {\n clipText(contentEditableRef);\n }\n }, [children]);\n\n const onBlur = useCallback(({ target }) => {\n clipText(target);\n }, [characterLimit]);\n\n const onKeyPress = useCallback(e => {\n if (e.target.innerText.length >= characterLimit) e.preventDefault();\n }, [characterLimit]);\n\n const handleFocus = e => {\n // To handle focus with iOS arrow keys - Bugfix #3496941\n window.getSelection().selectAllChildren(e.target);\n window.getSelection().collapseToEnd();\n onFocus(e);\n };\n\n const handleDoubleClick = useCallback(e => contentEditable && e && e.stopPropagation && e.stopPropagation(), [contentEditable]);\n const handleMouseDown = useCallback(e => isMultiSelection(e) && e.preventDefault(), []);\n const handleClick = useCallback(e => checkMobileOrTablet() && e.stopPropagation(), []);\n\n // TODO: refactor this code. @faruk this is hot fix\n // useEffect(() => {\n // if (autoFocus) {\n // textRendererRef?.current?.contentEditableRef?.current.focus();\n // }\n // }, [autoFocus]);\n\n return (\n \n {children}\n \n );\n};\n\nEditableTextRenderer.propTypes = {\n characterLimit: PropTypes.number,\n onChange: PropTypes.func.isRequired,\n contentEditable: PropTypes.bool,\n onFocus: PropTypes.func,\n placeholder: PropTypes.string,\n autoFocus: PropTypes.bool,\n children: PropTypes.element\n};\n\nEditableTextRenderer.defaultProps = {\n characterLimit: DESCRIPTION_LIMIT,\n contentEditable: true,\n onFocus: f => f,\n placeholder: '',\n autoFocus: false,\n children: undefined\n};\n\nexport default EditableTextRenderer;\n","/* eslint-disable camelcase */\nimport React, {\n useCallback, useEffect, useMemo, useState\n} from 'react';\nimport {\n bool, shape, string\n} from 'prop-types';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { useEventListener } from '@jotforminc/hooks';\n\nimport { isYes } from '../../utils';\nimport { generateContinueWithDraftURL, generateIframeURL } from '../../modules/PublicApp/utils';\nimport SELECTORS from '../../store/selectors';\nimport IframeRenderer from '../../modules/PublicApp/ProductRenderer/Renderers/IframeRenderer';\nimport {\n useFormHeightHandler, useFormMessageSender, useFormSubmissionCompleteHandler, useFormMessageHandler\n} from '../../utils/hooks';\nimport { onTodoCompleteAction, trackEventAction } from '../../store/actionCreators';\nimport { APP_PREVIEW_URL_HASH } from '../../constants';\nimport * as NAVIGATION from '../../utils/navigation';\n\nconst EmbeddedForm = ({\n formProps, interactive, itemID\n}) => {\n const appID = useSelector(SELECTORS.getAppID);\n const loginable = useSelector(SELECTORS.selectIsAppLoginable);\n const user = useSelector(SELECTORS.getUser);\n\n const dispatch = useDispatch();\n\n const isUserLoggedIn = useMemo(() => (user.USER_TYPE && !!user.email), [user]);\n const isAppLoginable = isYes(loginable);\n const isBuilder = useSelector(SELECTORS.getIsBuilder);\n const isPreview = NAVIGATION.getLocationHash() === APP_PREVIEW_URL_HASH;\n\n const {\n title,\n submissionCount,\n completed_showBadge,\n embeddedFormHeight,\n id: _id,\n resourceID,\n showEmbeddedFormFullHeight,\n embeddedFormThankYouPageDisplaySecond\n } = formProps;\n\n const embeddedFormThankYouPageDisplayMs = parseInt(embeddedFormThankYouPageDisplaySecond, 10) * 1000;\n\n const id = resourceID || _id;\n\n const _frameURL = generateIframeURL({ appID, id });\n\n const [frameURL, setFrameURL] = useState(_frameURL);\n\n const formMessageSender = useFormMessageSender(id);\n\n const [isFormSubmitted, setFormSubmitted] = useState(false);\n\n const handleFormSubmitted = useCallback(() => {\n setFormSubmitted(true);\n if (!isAppLoginable || !isUserLoggedIn) return;\n\n dispatch(onTodoCompleteAction(itemID, submissionCount));\n }, [itemID, isAppLoginable, isUserLoggedIn, submissionCount]);\n\n useFormSubmissionCompleteHandler(itemID, handleFormSubmitted);\n\n const frameHeight = useFormHeightHandler(id);\n\n useFormMessageHandler(id, ({ name: actionName, payload }) => {\n switch (actionName) {\n case 'appFlowReady':\n console.log('JF Apps is ready.');\n if (!isBuilder && !isPreview) {\n dispatch(trackEventAction({ action: 'formViewed', target: { formID: id } }));\n }\n break;\n case 'initAppFlow':\n const formIsCompletable = isAppLoginable && isYes(completed_showBadge);\n formMessageSender('initManager', { user, formIsCompletable, formIsEmbedded: true });\n break;\n case 'continueWithDraft':\n const { sessionID, token, continueKey } = payload;\n const continueURL = generateContinueWithDraftURL(frameURL, sessionID, token, continueKey);\n setFrameURL(continueURL);\n break;\n case 'scrollApp':\n const { href, formTop } = payload;\n const iframe = document.querySelector(`iframe[src=\"${href}\"]`);\n const embeddedFormTop = iframe.getBoundingClientRect().top + formTop;\n setTimeout(() => {\n document.querySelector('.scrollableItemListWrapper').scrollBy(0, embeddedFormTop);\n }, 300);\n break;\n case 'thankYouFillAgain':\n const { prefillURL } = payload;\n if (prefillURL) setFrameURL(prefillURL);\n break;\n default:\n console.log('Dont know what to do with the message:', { actionName, payload });\n }\n });\n\n const [reloadFormToggle, setReloadFormToggle] = useState(false);\n\n useEffect(() => {\n const timer = isFormSubmitted && setTimeout(() => {\n setReloadFormToggle(!reloadFormToggle);\n setFormSubmitted(false);\n }, embeddedFormThankYouPageDisplayMs);\n\n return () => clearTimeout(timer);\n }, [isFormSubmitted, reloadFormToggle]);\n\n // browser back button caching handler for blank iframe issue\n useEventListener('pageshow', event => event.persisted && setReloadFormToggle(t => !t));\n\n const finalFormHeight = useMemo(() => (isYes(showEmbeddedFormFullHeight) ? frameHeight : embeddedFormHeight), [frameHeight, showEmbeddedFormFullHeight, embeddedFormHeight]);\n\n const FormIframe = useCallback(({ height }) => {\n return (\n \n );\n }, [reloadFormToggle, frameURL, title, interactive, showEmbeddedFormFullHeight]); // !!! CAUTION :: THINK TWICE => will cause the rerender of iframe!\n\n return (\n <>\n \n \n );\n};\n\nexport default EmbeddedForm;\n\nEmbeddedForm.propTypes = {\n formProps: shape({\n title: string\n }),\n interactive: bool,\n itemID: string\n};\n\nEmbeddedForm.defaultProps = {\n formProps: {\n title: ''\n },\n interactive: false,\n itemID: ''\n};\n","import Styled from 'styled-components';\n\nexport const ScItemOverQuotaWrapper = Styled.div`\n width: 100%;\n position: relative;\n cursor: not-allowed;\n pointer-events: none;\n\n & * {\n opacity: .8;\n }\n\n .product-list-item-controller {\n margin-top: 0;\n\n .item-addToCartBtn {\n display: none;\n }\n }\n`;\n\nexport const ScItemOverQuotaWarning = Styled.div`\n display: flex;\n align-items: center;\n padding: 15px;\n color: #FF2E00;\n margin-bottom: 20px;\n font-size: 14px;\n background-color: #ff2e0033;\n border-radius: 4px;\n width: 100%;\n\n svg {\n width: 19px;\n height: 15px;\n margin-right: 10px;\n color: #FF2E00;\n }\n\n b {\n margin-right: .3em;\n }\n`;\n","import React from 'react';\nimport { useSelector } from 'react-redux';\nimport { IconExclamationTriangleFilled } from '@jotforminc/svg-icons';\nimport SELECTORS from '../../store/selectors';\nimport { renderable } from '../../constants/propTypes';\nimport { ScItemOverQuotaWrapper, ScItemOverQuotaWarning } from './ScItemOverQuotaWrapper';\nimport { FEATURE_NAMES } from '../../constants/features';\nimport { isFeatureEnabled } from '../../utils/features/helper';\n\nconst OverQuota = ({ children }) => {\n const isDonationApp = useSelector(SELECTORS.getIsDonationApp);\n const isPaymentOverQuota = useSelector(SELECTORS.getIsPaymentOverQuota);\n const isBuilder = useSelector(SELECTORS.getIsBuilder);\n\n return isPaymentOverQuota && isFeatureEnabled(FEATURE_NAMES.OverQuota) && !isBuilder ? (\n <>\n \n \n
\n {`This ${isDonationApp ? 'donation campaign' : 'store'} is currently unavailable.`}\n {' '}\n Please try again later.\n
\n
\n \n {children}\n \n \n ) : children;\n};\n\nOverQuota.propTypes = {\n children: renderable.isRequired\n};\n\nexport default OverQuota;\n","/* eslint-disable complexity */\nimport Styled, { css } from 'styled-components';\nimport { AppIconBox } from '@jotforminc/portal-components';\nimport { FEATURE_NAMES } from '../../../constants/features';\nimport { isFeatureEnabled } from '../../../utils/features/helper';\nimport { contentOverlapSize } from '../../../modules/Builder/components/HomePage/ScAppContentWrapper';\nimport {\n alignWrapper, applyAlpha, calculatedAppLogoSize, generateStyleByTextAlignment, getWidth\n} from '../../../utils/styleUtils';\n\nconst getAppHeaderSpacing = ({\n hasLogo, hasTitle, hasDescription, isBuilder\n}) => {\n const isEmptyHeader = !hasLogo && !hasTitle && !hasDescription;\n const paddingValue = isEmptyHeader ? '28px' : '40px';\n const paddingValueMobileAndEmptyHeader = isBuilder ? '28px' : '14px';\n const minHeightValue = isEmptyHeader ? '0' : '100px';\n\n return `\n padding-top: ${paddingValue};\n padding-bottom: calc(${contentOverlapSize} + ${paddingValue});\n\n @media screen and (max-width: 480px) {\n padding-top: calc(${contentOverlapSize} + ${isEmptyHeader ? paddingValueMobileAndEmptyHeader : paddingValue});\n padding-bottom: calc(${contentOverlapSize} + ${isEmptyHeader ? paddingValueMobileAndEmptyHeader : paddingValue});\n min-height: ${minHeightValue};\n }\n `;\n};\n\nconst ScAppHeader = Styled.div`\n display: flex;\n flex-direction: column;\n align-items: center;\n position: relative; // about appHeaderBg Image\n overflow: hidden;\n box-shadow: none;\n border-radius: none;\n ${isFeatureEnabled(FEATURE_NAMES.AppLogoSize) ? 'min-height: 133px;' : 'min-height: 16.25em;'}\n transition: all ease .3s;\n\n ${({\n hasLogo, hasTitle, hasDescription, isBuilder\n }) => css`${getAppHeaderSpacing({\n hasLogo, hasTitle, hasDescription, isBuilder\n })}`}\n\n\n ${({ textAlignment }) => alignWrapper(textAlignment)};\n ${({ bgColor }) => {\n return css`background-color: ${bgColor};`;\n }}\n\n ${({ appHeaderBgURL, appHeaderBgCropInfo }) => {\n const hasCropInfo = !!Object.keys(appHeaderBgCropInfo).length;\n return (!hasCropInfo && appHeaderBgURL ? css`background: #ffffff url(\"${appHeaderBgURL}\") no-repeat center/cover;` : '');\n }}\n\n z-index: unset;\n\n ${({ textAlignment }) => generateStyleByTextAlignment(textAlignment, {\n left: 'justify-content: center;',\n center: 'justify-content: center;',\n right: 'justify-content: center;'\n })}\n\n .appHeaderContent {\n ${isFeatureEnabled(FEATURE_NAMES.AppLogoSize) ? `\n padding: 0 16px;\n max-width: ${getWidth()};\n min-width: ${getWidth()};\n\n @media screen and (max-width: 768px) {\n max-width: ${getWidth('tablet')};\n min-width: ${getWidth('tablet')};\n }\n\n @media screen and (max-width: 480px) {\n max-width: ${getWidth('mobile')};\n min-width: ${getWidth('mobile')};\n padding: 0;\n }\n ` : 'width: unset;'}\n }\n\n .appHeaderBg {\n max-width: 100%;\n max-height: 100%;\n margin: auto;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n z-index: 1;\n will-change: transform;\n }\n\n .logoCont {\n ${AppIconBox}\n cursor: pointer;\n flex-shrink: 0;\n z-index: 2;\n position: relative;\n\n ${({\n appLogoSize, textAlignment, isLogoIcon, hasTitle, hasDescription\n }) => ((appLogoSize && isFeatureEnabled(FEATURE_NAMES.AppLogoSize) && !isLogoIcon) ? `\n width: ${calculatedAppLogoSize(parseInt(appLogoSize, 10))}px;\n min-width: 80px;\n max-width: 624px;\n margin-bottom: ${!hasTitle && !hasDescription ? '0' : '12px'};\n\n ${generateStyleByTextAlignment(textAlignment, {\n left: 'margin-left: 0;',\n center: 'margin-left: auto; margin-right: auto;',\n right: 'margin-right: 0;'\n })}\n\n @media screen and (max-width: 480px) {\n width: ${appLogoSize}%;\n min-width: 25%;\n max-width: 50%;\n }\n ` : `\n width: 80px;\n height: 80px;\n\n @media screen and (max-width: 480px) {\n width: 80px;\n height: 80px;\n margin: 14px;\n }\n `)}\n }\n\n ${({ showAppHeader }) => ((!showAppHeader) ? `\n box-shadow: none;\n background: transparent;\n\n .appHeaderBg {\n display: none;\n }\n ` : '')}\n\n .appHeaderContent {\n display: flex;\n\n ${({ textAlignment, appFontFamily, hasLogo }) => (isFeatureEnabled(FEATURE_NAMES.AppLogoSize) ? `\n align-items: center;\n flex-wrap: wrap;\n z-index: 2;\n\n ${generateStyleByTextAlignment(textAlignment, {\n left: 'flex-direction: row; justify-content: flex-start;',\n center: 'flex-direction: column; justify-content: center;',\n right: 'flex-direction: row-reverse; justify-content: flex-start;'\n })}\n\n @media screen and (max-width: 480px) {\n flex-direction: row;\n flex-wrap: nowrap;\n\n ${generateStyleByTextAlignment(textAlignment, {\n left: 'flex-direction: row; justify-content: flex-start;',\n center: 'flex-direction: column; justify-content: center;',\n right: 'flex-direction: row-reverse; justify-content: flex-start;'\n })}\n }\n\n &-text {\n width: 100%;\n display: flex;\n flex-direction: column;\n justify-content: center;\n text-align: ${textAlignment};\n ${appFontFamily ? `\n font-family: ${appFontFamily};\n ` : ''}\n\n /* couldn't indent properly sorry */\n ${generateStyleByTextAlignment(textAlignment, {\n left: 'margin-left: 0; margin-right: 126px;',\n center: 'margin-top: 0;',\n right: 'margin-right: 0; margin-left: 126px;'\n })\n }\n\n /* couldn't indent properly sorry */\n ${hasLogo && generateStyleByTextAlignment(textAlignment, {\n left: 'margin-left: 0; margin-right: 0;',\n center: 'margin-top: 0px;',\n right: 'margin-right: 0px; margin-left: 0;'\n })}\n }\n\n ` : `\n flex-direction: column;\n justify-content: center;\n text-align: ${textAlignment};\n z-index: 2;\n\n ${appFontFamily ? `\n font-family: ${appFontFamily};\n ` : ''}\n\n/* couldn't indent properly sorry */\n ${\n generateStyleByTextAlignment(textAlignment, {\n left: 'margin-left: 0; margin-right: 126px;',\n center: 'margin-top: 0;',\n right: 'margin-right: 0; margin-left: 126px;'\n })\n }}\n\n/* couldn't indent properly sorry */\n ${hasLogo\n && generateStyleByTextAlignment(textAlignment, {\n left: 'margin-left: 0; margin-right: 0;',\n center: 'margin-top: 0px;',\n right: 'margin-right: 0px; margin-left: 0;'\n })\n }\n `)}\n }\n\n ${({ appFontColor, hasTitle }) => css`\n .appTitle {\n color: ${appFontColor};\n ${isFeatureEnabled(FEATURE_NAMES.AppLogoSize) ? 'font-size: 28px;' : 'font-size: 1.75em;'}\n font-weight: 700;\n line-height: normal;\n overflow-wrap: break-word;\n &:empty { \n display: none;\n }\n &:empty ~ .appDesc { margin-top: 0; }\n white-space: normal;\n }\n\n .appDesc, .formCount{\n color: ${applyAlpha(appFontColor, 0.7)}\n }\n\n .appDesc {\n ${isFeatureEnabled(FEATURE_NAMES.AppLogoSize) ? `\n font-size: 16px;\n margin-top: 10px;\n ` : `\n font-size: 1em;\n line-height: 1.625em;\n `}\n overflow-wrap: break-word;\n &:empty { \n display: none;\n }\n white-space: normal;\n margin-top: ${hasTitle ? '8px' : '0'}\n }\n\n .formCount {\n font-size: .875em;\n margin: 1em 0;\n }\n\n @media screen and (max-width: 480px) {\n .appTitle {\n font-size: 18px;\n }\n\n .appDesc {\n font-size: 14px;\n }\n }\n `}\n\n${({ hasLogo, hasContent }) => !hasLogo && !hasContent && css`\n .overlay {\n display: none;\n }\n`}`;\n\nexport default ScAppHeader;\n","import Styled from 'styled-components';\n\nconst ScAppHeaderWrapper = Styled.div`\n position: relative;\n margin: 0 auto; \n width: 100%;\n font-size: 1em;\n text-align: center;\n`;\n\nexport default ScAppHeaderWrapper;\n","import React, { memo, useCallback, useMemo } from 'react';\nimport { t } from '@jotforminc/translation';\nimport { elementType } from 'prop-types';\nimport { safeJSONParse } from '@jotforminc/utils';\nimport { shallowEqual, useDispatch, useSelector } from 'react-redux';\nimport { Utils } from '@jotforminc/uikit';\nimport ScAppHeader from './ScAppHeader';\nimport { isYes } from '../../../utils';\nimport { IMAGE_TYPE } from '../../../constants';\nimport SELECTORS from '../../../store/selectors';\nimport AppLogo from '../../AppLogo';\nimport * as ACTION_CREATORS from '../../../store/actionCreators';\nimport { RightPanelModes } from '../../../modules/Builder/components/HomePage/constants';\n\nconst AppHeader = ({\n TitleRenderer, DescriptionRenderer, LogoRenderer\n}) => {\n const dispatch = useDispatch();\n const logoProperties = useSelector(SELECTORS.getLogoProperties, shallowEqual);\n const showAppHeader = useSelector(SELECTORS.getShowAppHeader);\n const {\n appHeaderBgColor, appHeaderBgURL, appHeaderBgCropInfo, appHeaderTextAlignment\n } = useSelector(SELECTORS.getAppHeaderProperties, shallowEqual);\n const appFontColor = useSelector(SELECTORS.getAppFontColor);\n const appFontFamily = useSelector(SELECTORS.getAppFontFamily);\n const name = useSelector(SELECTORS.getAppName);\n const description = useSelector(SELECTORS.getAppDescription);\n const { logoType, logoURL, appLogoSize } = logoProperties;\n\n const handlePropChange = useCallback(prop => value => dispatch(ACTION_CREATORS.updatePortalAction({ [prop]: value })), []);\n\n const parsedCropInfo = useMemo(() => safeJSONParse(appHeaderBgCropInfo), [appHeaderBgCropInfo]);\n const hasCropInfo = useMemo(() => !!Object.keys(parsedCropInfo).length, [parsedCropInfo]);\n const { x, y, zoom } = parsedCropInfo;\n\n const hasLogo = useMemo(() => !!logoURL, [logoURL]);\n const hasTitle = !!name;\n const hasDescription = !!description;\n const hasContent = !!name || !!description;\n\n const isAppHeaderStylesActive = useMemo(() => isYes(showAppHeader), [showAppHeader]);\n const isLogoIcon = useMemo(() => logoType === IMAGE_TYPE.icon, [logoType]);\n\n const handleTitleClick = e => {\n e.stopPropagation();\n dispatch(ACTION_CREATORS.openRightPanelWithModeAction(RightPanelModes.APP_HEADER));\n };\n\n return (\n \n {hasCropInfo && appHeaderBgURL && (\n \n )}\n {isAppHeaderStylesActive && appHeaderBgURL &&
}\n
\n {hasLogo && (\n
\n \n
\n )}\n (Utils.isPressedKeyEnter(e) && handleTitleClick(e))}\n >\n \n \n
\n
\n \n );\n};\n\nAppHeader.propTypes = {\n TitleRenderer: elementType,\n DescriptionRenderer: elementType,\n LogoRenderer: elementType\n};\n\n/* eslint-disable react/prop-types */\nAppHeader.defaultProps = {\n TitleRenderer: ({ defaultValue, ...props }) =>

{defaultValue}

,\n DescriptionRenderer: ({ defaultValue, ...props }) =>

{defaultValue}

,\n LogoRenderer: AppLogo\n};\n\nexport default memo(AppHeader);\n","import Styled, { css } from 'styled-components';\nimport { darken, lighten } from 'polished';\nimport { convertTextAlignment2Flex } from '../../../utils/styleUtils';\n\nconst handleButtonRadius = buttonRadius => {\n switch (buttonRadius) {\n case 'rounded':\n return '100px';\n default: // also case 'default'\n return '4px';\n }\n};\n\nconst handleButtonWidth = buttonWidth => {\n switch (buttonWidth) {\n case 'full':\n return css`min-width: 100%;`;\n default: // also case 'auto'\n return css`\n min-width: 157px;\n\n @media screen and (max-width: 480px) {\n min-width: 120px;\n }\n `;\n }\n};\n\nconst ScButtonItem = Styled.div`\n align-items: ${({ itemTextAlignment }) => convertTextAlignment2Flex(itemTextAlignment)};\n\n .buttonItem {\n ${({ buttonWidth }) => handleButtonWidth(buttonWidth)};\n color: ${({ itemFontColor }) => itemFontColor};\n border-radius: ${({ buttonRadius }) => handleButtonRadius(buttonRadius)};\n border: 1px solid ${({ itemBorderColor }) => itemBorderColor};\n ${({ itemBgColor }) => (itemBgColor) && `background: ${itemBgColor}`};\n\n &:hover {\n transition: .3s background ease;\n ${({ itemBgColor }) => (itemBgColor) && `background: ${lighten(0.10, itemBgColor)}`}; \n }\n \n &:active {\n transition: .3s background ease;\n ${({ itemBgColor }) => (itemBgColor) && `background: ${darken(0.10, itemBgColor)}`}; \n }\n }\n // empty item display rule override\n li:not([aria-selected=\"true\"]) \n && {\n [contenteditable=true]:empty {\n display: block;\n }\n }\n`;\n\nexport default ScButtonItem;\n","import React from 'react';\nimport { elementType, string } from 'prop-types';\nimport ScButtonItem from './ScButtonItem';\nimport './item-button.scss';\nimport { sanitizeHTML } from '../../../utils';\nimport { DefaultDivRenderer } from '../defaultRenderers';\n\nconst ButtonItem = ({\n TitleRenderer,\n title,\n ...props\n}) => {\n const {\n itemTextAlignment,\n itemFontColor,\n buttonRadius,\n buttonWidth,\n itemBorderColor,\n itemBgColor\n } = props;\n\n const buttonItemStyleProps = {\n itemTextAlignment,\n itemFontColor,\n buttonRadius,\n buttonWidth,\n itemBorderColor,\n itemBgColor\n };\n\n return (\n \n
\n {sanitizeHTML(title)}\n
\n \n );\n};\n\nButtonItem.propTypes = {\n title: string,\n TitleRenderer: elementType,\n itemTextAlignment: string,\n itemFontColor: string,\n buttonRadius: string,\n buttonWidth: string,\n itemBorderColor: string,\n itemBgColor: string\n};\n\nButtonItem.defaultProps = {\n title: '',\n TitleRenderer: DefaultDivRenderer,\n itemTextAlignment: '',\n itemFontColor: '',\n buttonRadius: '',\n buttonWidth: '',\n itemBorderColor: '',\n itemBgColor: ''\n};\n\nexport default ButtonItem;\n","import Styled from 'styled-components';\n\nconst ScCardItem = Styled.div`\n width: 100%;\n .card-text-wrapper {\n min-width: 30px;\n display: flex;\n flex-direction: column;\n justify-content: center;\n }\n .card-left-side-wrapper {\n width: 100%;\n }\n .end-element-container {\n white-space: unset;\n overflow: unset;\n text-overflow: unset;\n word-break: break-word;\n &.button div {\n height: 32px;\n min-width: 80px;\n padding: 8px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n cursor: pointer;\n font-size: 1em;\n font-weight: 500;\n font-family: inherit;\n color: ${({ itemFontColor }) => itemFontColor};\n background-color: ${({ itemBgColor }) => itemBgColor};\n border: 1px solid ${({ itemBorderColor }) => itemBorderColor};\n }\n }\n &:has(.start-element-container.avatar) {\n .card-text-wrapper {\n padding: 0;\n }\n }\n &.horizontal {\n > div {\n @media screen and (max-width: 480px){\n align-items: flex-start;\n flex-wrap: wrap;\n }\n }\n &:has(.end-element-container) {\n .card-text-wrapper {\n padding-right: 8px;\n\n @media screen and (max-width: 768px){\n justify-content: flex-start;\n }\n }\n }\n .card-left-side-wrapper {\n display: flex;\n align-items: center;\n\n &:has(.end-element-container) {\n &:has(.button) {\n @media screen and (max-width: 768px){\n align-items: stretch;\n }\n }\n }\n\n @media screen and (max-width: 430px){\n align-items: stretch;\n }\n }\n .card-content-side-wrapper {\n display: flex;\n justify-content: space-between;\n width: 100%;\n\n &:has(.button) {\n @media screen and (max-width: 768px){\n flex-direction: column;\n gap: 16px;\n }\n }\n\n &:has(.icon) {\n @media screen and (max-width: 430px){\n flex-direction: column;\n gap: 16px;\n }\n }\n }\n }\n .start-element-container {\n width: 105px;\n height: 105px;\n border-radius: 4px;\n &:has(.isAvatarImage) {\n width: 60px;\n height: 60px;\n padding: 2px;\n }\n img {\n display: flex;\n aspect-ratio: 1;\n object-fit: cover;\n border-radius: inherit;\n }\n .isAvatarImage {\n .default-preview {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n }\n img {\n display: flex;\n aspect-ratio: 1;\n object-fit: cover;\n border-radius: 50%;\n width: 60px;\n height: 60px;\n }\n }\n &.image {\n width: 105px;\n height: 105px;\n }\n &.icon {\n width: 60px;\n height: 60px;\n margin-right: 0;\n\n > div {\n @media screen and (max-width: 430px){\n align-items: flex-start;\n }\n }\n }\n &.alignCenter > div {\n align-items: center;\n }\n }\n\n\n\n &.vertical {\n &:has(.start-element-container.icon), \n &:has(.start-element-container.avatar) {\n .card-text-wrapper {\n padding: 8px 0;\n }\n }\n &:has(.start-element-container.image) {\n .end-element-container {\n margin: 0 8px 8px auto;\n }\n }\n > div {\n width: 100%;\n display: flex;\n flex-direction: column;\n }\n .start-element-container:not(.icon) {\n width: 100%;\n height: auto;\n &.image img {\n object-fit: cover;\n width: 100%;\n height: 163px;\n }\n }\n .start-element-container {\n &.icon {\n width: 60px;\n height: 60px;\n }\n }\n .start-element-container {\n margin-right: 0;\n }\n .card-text-wrapper {\n width: 100%;\n text-align: left;\n padding: 8px;\n }\n &:not(:has(.start-element-container)) .card-text-wrapper {\n padding: 0px;\n }\n .card-content-side-wrapper {\n display: flex;\n flex-direction: column;\n gap: 16px;\n }\n }\n`;\n\nexport default ScCardItem;\n","import React from 'react';\nimport propTypes from 'prop-types';\nimport { useSelector } from 'react-redux';\nimport ListItemBase from '../../ListItemBase';\nimport { DefaultDivRenderer } from '../defaultRenderers';\nimport { withContentWrapper } from '../withContentWrapper';\nimport ScCardItem from './ScCardItem';\nimport SELECTORS from '../../../store/selectors';\nimport { BUTTON_STYLING_LIST } from '../../../properties/styling';\n\nconst CardItem = ({\n title,\n description,\n TitleRenderer,\n DescriptionRenderer,\n start,\n end,\n itemBgColor,\n itemBorderColor,\n itemFontColor,\n cardLayout,\n buttonValue,\n ...rest\n}) => {\n const colorScheme = { itemBgColor, itemBorderColor, itemFontColor };\n const { buttonColors = { ...BUTTON_STYLING_LIST.default } } = useSelector(SELECTORS.getOverridingProps);\n\n return (\n \n \n \n );\n};\n\nCardItem.propTypes = {\n title: propTypes.string,\n description: propTypes.string,\n TitleRenderer: propTypes.func,\n DescriptionRenderer: propTypes.func,\n start: propTypes.object,\n end: propTypes.object,\n itemBgColor: propTypes.string,\n itemBorderColor: propTypes.string,\n itemFontColor: propTypes.string,\n cardLayout: propTypes.string,\n buttonValue: propTypes.string\n};\n\nCardItem.defaultProps = {\n TitleRenderer: DefaultDivRenderer,\n DescriptionRenderer: DefaultDivRenderer,\n title: '',\n description: '',\n start: {},\n end: {},\n itemBgColor: '',\n itemBorderColor: '',\n itemFontColor: '',\n cardLayout: '',\n buttonValue: ''\n};\n\nexport default withContentWrapper(CardItem);\n","import { func, string, bool } from 'prop-types';\nimport React from 'react';\nimport ScFormItemWrapper from '../../../modules/PublicApp/FormItem/ScFormItemWrapper';\nimport Button from '../../Button';\nimport LinkItem from '../LinkItem';\nimport SimpleItem from '../SimpleItem/SimpleItem';\n\nconst DataElement = ({\n onClick, resourceID, resourceSubType, behaveAsLink, ...props\n}) => {\n const { title = '' } = props;\n return (behaveAsLink ? (\n \n ) : (\n \n \n \n )\n );\n};\n\nDataElement.propTypes = {\n onClick: func,\n resourceID: string,\n resourceSubType: string,\n behaveAsLink: bool,\n title: string\n};\n\nDataElement.defaultProps = {\n onClick: f => f,\n resourceID: '',\n resourceSubType: '',\n behaveAsLink: false,\n title: ''\n};\n\nexport default DataElement;\n","import Styled, { css } from 'styled-components';\n\nconst ScDividerItem = Styled.div`\n div {\n ${({ itemFontColor }) => {\n return css`border-color:${itemFontColor};`;\n }}\n }\n`;\n\nexport default ScDividerItem;\n","import React from 'react';\nimport { string } from 'prop-types';\nimport ScDividerItem from './ScDividerItem';\nimport './item-divider.scss';\n\nconst DividerItem = ({ itemFontColor }) => {\n return (\n \n \n \n );\n};\n\nDividerItem.propTypes = {\n itemFontColor: string\n};\n\nDividerItem.defaultProps = {\n itemFontColor: ''\n};\n\nexport default DividerItem;\n","import React from 'react';\nimport SimpleItem from '../SimpleItem/SimpleItem';\n\nconst DocumentItem = props => ;\n\nexport default DocumentItem;\n","import React, { FunctionComponent } from 'react';\nimport { ProgressBarType } from './types';\n\nconst ProgressBar: FunctionComponent = ({\n percentage = 0,\n percentageBarBg,\n totalBarBg,\n borderColor\n}) => {\n const reducedPercentage = percentage > 100 ? 100 : percentage;\n return (\n \n \n \n );\n};\n\nexport default ProgressBar;\n","import React, { FunctionComponent } from 'react';\nimport { t, translationRenderer } from '@jotforminc/translation';\nimport { DonationGoalBarType } from './types';\nimport ProgressBar from './ProgressBar';\nimport { useFormattedPrice } from '../../hooks';\n\nconst DonationGoalBar: FunctionComponent = ({\n isBuilder,\n donationGoal,\n currentDonationGoal,\n fontColor,\n bgColor,\n borderColor,\n currency,\n useDecimal,\n decimalMark\n}) => {\n const getFormattedPrice = useFormattedPrice({ currency, useDecimal, decimalMark });\n return (\n
\n \n {translationRenderer('[1[{currentDonation}]] raised of [2[{donationGoal}]]')({\n renderer1: () => (\n
\n {getFormattedPrice(isBuilder ? 0 : currentDonationGoal)}\n
\n ),\n renderer2: () => (\n
\n {`${getFormattedPrice(donationGoal)} ${t('goal')}`}\n
\n )\n })}\n
\n\n \n \n );\n};\n\nexport default DonationGoalBar;\n","/* eslint-disable jsx-a11y/click-events-have-key-events */\nimport React, {\n FocusEvent, KeyboardEvent, useState, useRef, FunctionComponent, useEffect\n} from 'react';\nimport { t, translationRenderer } from '@jotforminc/translation';\nimport { getCurrencyPrefixSuffix, getExactPrice } from '@jotforminc/money-utils';\nimport { Utils } from '@jotforminc/uikit';\nimport WarningBox from '@jotforminc/warning-box';\nimport { transparentize } from 'polished';\nimport { DonationCustomAmountType } from './types';\n\nconst DonationCustomAmount: FunctionComponent = ({\n isBuilder,\n fontColor,\n borderColor,\n buttonBgColor,\n currency,\n useDecimal,\n decimalMark,\n customAmount = '',\n onCustomAmountChange,\n enableCustomAmountLimits,\n minCustomAmountLimit,\n maxCustomAmountLimit,\n inputError = '',\n onInputError,\n selectedPrice,\n donationItems\n}) => {\n const customInputRef = useRef(null);\n const [currencyPrefix, currencySuffix] = getCurrencyPrefixSuffix(currency);\n const [active, setActive] = useState(false);\n\n const getNumberFromString = (str: string): number => parseFloat(str);\n\n useEffect(() => {\n const currentValueStr = getNumberFromString(customAmount);\n const isValueInItems = donationItems.filter(item => getNumberFromString(item.amount) === currentValueStr).length;\n\n setActive(isValueInItems ? false : getNumberFromString(selectedPrice) === currentValueStr);\n }, [customAmount, selectedPrice, donationItems]);\n\n const errorText = 'Please enter an amount within a range of [1[minAmount]] to [2[maxAmount]].';\n\n const checkInputLimitError = (numberVal: number) => {\n if (enableCustomAmountLimits) {\n if (numberVal < getNumberFromString(minCustomAmountLimit) || numberVal > getNumberFromString(maxCustomAmountLimit)) {\n onInputError(\n translationRenderer(errorText)({\n renderer1: () => (minCustomAmountLimit),\n renderer2: () => (maxCustomAmountLimit)\n })\n );\n }\n }\n };\n\n useEffect(() => {\n if (customInputRef.current) {\n customInputRef.current.innerText = customAmount ? getExactPrice({\n price: customAmount, currency, useDecimal, decimalMark\n }) : '';\n }\n }, [customAmount]);\n\n const handleCustomPriceBlur = ({ target: { innerText } }: FocusEvent): void => {\n const numberVal = getNumberFromString(innerText);\n const value = !Number.isNaN(numberVal) && numberVal > 0 ? innerText : '';\n if (value === customAmount) {\n return;\n }\n if (customInputRef.current) {\n customInputRef.current.innerText = value ? getExactPrice({\n price: value, currency, useDecimal, decimalMark\n }) : '';\n }\n\n onCustomAmountChange(value);\n checkInputLimitError(numberVal);\n };\n\n const handleCustomPriceFocus = (): void => {\n onInputError('');\n if (customInputRef.current) {\n customInputRef.current.innerText = customAmount;\n }\n };\n\n const handleKeydown = (e: KeyboardEvent) => Utils.isPressedKeyEnter(e) && (e.target as HTMLElement).blur();\n\n return (\n <>\n customInputRef?.current?.focus()}\n style={{\n '--ScCustomInputContainerBorderColor': inputError ? '#EF2727' : borderColor,\n '--ScCustomInputContainerActiveBorderColor': buttonBgColor,\n '--ScCustomInputContainerActiveBackgroundColor': transparentize('0.9', buttonBgColor),\n '--ScCustomInputContainerActiveColor': buttonBgColor,\n '--ScCustomInputContainerFontColor': fontColor\n } as React.CSSProperties}\n >\n {currencyPrefix && {currencyPrefix}}\n \n {currencySuffix && (\n \n {` ${currencySuffix}`}\n \n )}\n \n {inputError && (\n \n {inputError}\n \n )}\n \n );\n};\n\nexport default DonationCustomAmount;\n","/* eslint-disable jsx-a11y/click-events-have-key-events */\nimport React, {\n FunctionComponent, useState, MouseEvent\n} from 'react';\nimport { IconPlusCircle } from '@jotforminc/svg-icons';\nimport { t } from '@jotforminc/translation';\nimport { darken, lighten, transparentize } from 'polished';\nimport { DonationBoxType } from './types';\nimport { chunk, convertTextAlignment2Flex } from '../../utils';\nimport DonationGoalBar from './DonationGoalBar';\nimport { useFormattedPrice } from '../../hooks';\nimport DonationCustomAmount from './DonationCustomAmount';\n\nconst DonationBox: FunctionComponent = ({\n isBuilder,\n title,\n description,\n donateButtonTitle,\n showDonationGoalBar = false,\n donationGoal,\n currentDonationGoal,\n buttonBgColor,\n buttonFontColor,\n buttonRadius,\n itemTextAlignment,\n fontColor,\n borderColor,\n currency,\n useDecimal,\n decimalMark,\n donationItems = [],\n selectedPrice,\n onSelectPrice,\n isBuilderItemSelected,\n onAddDonateItemClick,\n showCustomAmount = true,\n enableCustomAmountLimits = false,\n minCustomAmountLimit = '',\n maxCustomAmountLimit = '',\n showDonateButton = false,\n onDonateClick,\n onCustomAmountChange,\n TitleRenderer,\n DonateButtonTextRenderer,\n DescriptionRenderer\n}) => {\n const [inputError, setInputError] = useState('');\n const getFormattedPrice = useFormattedPrice({ currency, useDecimal, decimalMark });\n const [customAmount, setCustomAmount] = useState('');\n\n const handleDonateClick = (e: MouseEvent) => {\n if (!inputError) {\n onDonateClick(e);\n }\n };\n\n const handleCustomAmountChange = (realPrice: string) => {\n setCustomAmount(realPrice);\n onCustomAmountChange(realPrice);\n };\n\n return (\n
\n
\n {(title || description) && (\n \n {title && (\n {title}\n )}\n {description && ({description})}\n
\n )}\n {showDonationGoalBar && (\n \n )}\n
\n {chunk(donationItems.filter(({ amount }) => !!amount), 3).map((items, index) => {\n return (\n
\n {items.map(({ id, amount }) => {\n return (\n {\n setCustomAmount('');\n onSelectPrice(amount);\n setInputError('');\n }}\n type='button'\n >\n \n {getFormattedPrice(amount)}\n \n \n );\n })}\n
\n );\n })}\n\n {(isBuilder && isBuilderItemSelected) && (\n \n \n {t('Add New Amount')}\n \n )}\n
\n {showCustomAmount && (\n \n )}\n {showDonateButton && donateButtonTitle && (\n \n {donateButtonTitle}\n
\n )}\n \n \n );\n};\n\nexport default DonationBox;\n","import React from 'react';\nimport {\n string, elementType, oneOfType, number\n} from 'prop-types';\nimport { safeJSONParse } from '@jotforminc/utils';\nimport { DonationBox } from '@jotforminc/payment-settings-editor';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { DESTINATION_TYPES } from '../../../constants/navigation';\nimport * as ACTION_CREATORS from '../../../store/actionCreators';\nimport { RightPanelModes } from '../../../modules/Builder/components/HomePage/constants';\nimport SELECTORS from '../../../store/selectors';\nimport { isYes, sanitizeHTML } from '../../../utils';\nimport { DefaultDivRenderer } from '../defaultRenderers';\nimport { useItemDefaults } from '../../../properties';\nimport { ITEM_TYPES } from '../../../constants/itemTypes';\nimport { ItemVisualDefaultProps, ItemVisualPropTypes } from '../../../constants/propTypes';\nimport { withContentWrapper } from '../withContentWrapper';\nimport ItemOverQuotaWrapper from '../../ItemOverQuotaWrapper';\n\nconst DonationItem = ({\n id: itemID,\n title,\n description,\n showCustomAmount,\n enableCustomAmountLimits,\n minCustomAmountLimit,\n maxCustomAmountLimit,\n showDonationGoal,\n donationGoal,\n donation,\n donateButtonTitle,\n TitleRenderer,\n DescriptionRenderer,\n DonateButtonTextRenderer,\n itemBgColor,\n itemBorderColor,\n itemFontColor,\n itemButtonBgColor,\n itemButtonFontColor,\n buttonRadius,\n itemTextAlignment\n}) => {\n const dispatch = useDispatch();\n const isBuilder = useSelector(SELECTORS.getIsBuilder);\n const { currency, useDecimal, decimalMark } = useSelector(SELECTORS.getPortalPaymentCurrencyInfo);\n const selectedPrice = useSelector(SELECTORS.getDonationPriceInCart);\n const isItemSelected = useSelector(SELECTORS.getIsItemSelected(itemID));\n const currentDonationGoal = useSelector(SELECTORS.getCurrentDonationGoal);\n\n const { donation: defaultDonation } = useItemDefaults(ITEM_TYPES.DONATION);\n const parsedDonation = safeJSONParse(donation, safeJSONParse(defaultDonation, []));\n const handleDonateClick = () => {\n dispatch(ACTION_CREATORS.navigateToAction({ to: DESTINATION_TYPES.SPECIAL_PAGE, pageID: 'checkout' }));\n dispatch(ACTION_CREATORS.trackEventAction({ action: 'donateNowButtonClicked' }));\n };\n\n const handleAddDonateItemClick = () => {\n dispatch(ACTION_CREATORS.updateItemPropAction({\n itemID,\n prop: {\n donation: JSON.stringify([...parsedDonation, {\n id: Date.now().toString(), forceActive: true, amount: ''\n }])\n }\n }));\n\n dispatch(ACTION_CREATORS.openRightPanelWithModeAction(RightPanelModes.APP_ITEM));\n dispatch(ACTION_CREATORS.trackEventAction({ action: 'donationBoxAddNewAmountClicked' }));\n };\n\n const handleCustomAmountChange = realPrice => dispatch(ACTION_CREATORS.donateAction({ title, description, selectedPrice: realPrice }));\n const handleDonationOptionSelect = amount => dispatch(ACTION_CREATORS.donateAction({ title, description, selectedPrice: amount }));\n\n return (\n \n f}\n onCustomAmountChange={handleCustomAmountChange}\n showDonateButton={true}\n showCustomAmount={isYes(showCustomAmount)}\n enableCustomAmountLimits={isYes(enableCustomAmountLimits)}\n minCustomAmountLimit={minCustomAmountLimit}\n maxCustomAmountLimit={maxCustomAmountLimit}\n TitleRenderer={TitleRenderer}\n DescriptionRenderer={DescriptionRenderer}\n DonateButtonTextRenderer={DonateButtonTextRenderer}\n />\n \n );\n};\n\nDonationItem.propTypes = {\n id: oneOfType([string, number]).isRequired,\n title: string,\n description: string,\n donation: string,\n showCustomAmount: string,\n enableCustomAmountLimits: string,\n minCustomAmountLimit: string,\n maxCustomAmountLimit: string,\n showDonationGoal: string,\n donationGoal: number,\n donateButtonTitle: string,\n TitleRenderer: elementType,\n DescriptionRenderer: elementType,\n DonateButtonTextRenderer: elementType,\n ...ItemVisualPropTypes\n};\n\nDonationItem.defaultProps = {\n title: '',\n description: '',\n donation: '[]',\n showCustomAmount: 'Yes',\n enableCustomAmountLimits: 'No',\n minCustomAmountLimit: '',\n maxCustomAmountLimit: '',\n showDonationGoal: 'No',\n donationGoal: 1000,\n donateButtonTitle: '',\n TitleRenderer: DefaultDivRenderer,\n DescriptionRenderer: DefaultDivRenderer,\n DonateButtonTextRenderer: DefaultDivRenderer,\n ...ItemVisualDefaultProps\n};\n\nexport default withContentWrapper(DonationItem);\n","import React from 'react';\nimport SimpleItem from '../SimpleItem/SimpleItem';\n\nconst HeadingItem = props => ;\n\nexport default HeadingItem;\n","import React from 'react';\nimport { string } from 'prop-types';\nimport { IconImageFilled } from '@jotforminc/svg-icons';\nimport { withContentWrapper } from '../withContentWrapper';\nimport Image from '../../Image';\n\nconst ImageItem = ({\n imageURL, altText\n}) => {\n return (\n \n );\n};\nImageItem.propTypes = {\n imageURL: string,\n altText: string\n};\nImageItem.defaultProps = {\n imageURL: '',\n altText: ''\n};\n\nexport default withContentWrapper(ImageItem);\n","import React from 'react';\nimport SimpleItem from '../SimpleItem/SimpleItem';\n\nconst LinkItem = props => ;\n\nexport default LinkItem;\n","import { getEditorProps } from '../../../modules/Builder/components/HomePage/BuilderItem/withInlineEditor';\n\nexport const clipPropsWrtCharLimits = itemProps => {\n const itemRendererProps = getEditorProps(itemProps);\n const itemRendererConfig = Object.values(itemRendererProps).filter(config => !!config?.args);\n\n const charLimits = itemRendererConfig.reduce((prev, { args }) => {\n const [propName,, charLimit] = args;\n if (!propName || !charLimit) {\n return prev;\n }\n\n return { ...prev, [propName]: charLimit };\n }, {});\n\n const newItemProps = { ...itemProps };\n\n Object.entries(charLimits).forEach(([propName, limit]) => {\n if (typeof newItemProps[propName] !== 'string') {\n return;\n }\n\n newItemProps[propName] = newItemProps[propName].slice(0, limit);\n });\n\n return newItemProps;\n};\n","/* eslint-disable no-unused-vars */\nimport React from 'react';\nimport { ITEM_TYPES } from '../../../constants/itemTypes';\nimport InAppButtonItem from '../../../modules/PublicApp/ButtonItem';\nimport InAppFormItem from '../../../modules/PublicApp/FormItem';\nimport SignItem from '../../../modules/PublicApp/SignItem';\nimport ListItemBase from '../../ListItemBase';\nimport CardItem from '../CardItem';\nimport DataElement from '../DataElement';\nimport DocumentItem from '../DocumentItem';\nimport DonationItem from '../DonationItem';\nimport HeadingItem from '../HeadingItem';\nimport ImageItem from '../ImageItem';\nimport LinkItem from '../LinkItem';\nimport ParagraphItem from '../ParagraphItem';\nimport WidgetItem from '../WidgetItem';\n\nexport const getBuilderPresentationItem = type => {\n const comp = {\n [ITEM_TYPES.CARD_ITEM]: CardItem,\n [ITEM_TYPES.FORM]: InAppFormItem,\n [ITEM_TYPES.HEADING]: HeadingItem,\n [ITEM_TYPES.DONATION]: DonationItem,\n [ITEM_TYPES.PARAGRAPH]: ParagraphItem,\n [ITEM_TYPES.LINK]: LinkItem,\n [ITEM_TYPES.TABLE_LINK]: DataElement,\n [ITEM_TYPES.REPORT_LINK]: DataElement,\n [ITEM_TYPES.SENTBOX_LINK]: DataElement,\n [ITEM_TYPES.SIGN_LINK]: SignItem,\n [ITEM_TYPES.DOCUMENT]: DocumentItem,\n [ITEM_TYPES.IMAGE]: ImageItem,\n [ITEM_TYPES.BUTTON]: InAppButtonItem,\n [ITEM_TYPES.WIDGET]: WidgetItem\n };\n\n return comp[type] || ListItemBase;\n};\n","import React, { forwardRef } from 'react';\nimport {\n string, func, array, object, elementType\n} from 'prop-types';\nimport { ListWrapper, Divider } from './styled';\nimport { getBuilderPresentationItem } from './constants';\nimport ScAppItemWrapper from '../../../modules/PublicApp/AppItem/ScAppItemWrapper';\nimport { isYes } from '../../../utils';\nimport { ITEM_TYPES } from '../../../constants/itemTypes';\nimport { clipPropsWrtCharLimits } from './helper';\nimport { DefaultDivRenderer } from '../defaultRenderers';\n\nconst List = forwardRef(({\n id,\n presentationItemType,\n getPresentationItem,\n data,\n onItemClick,\n presentationItemProps: itemProps,\n TitleRenderer = DefaultDivRenderer,\n DescriptionRenderer = DefaultDivRenderer\n}, lastElementRef) => {\n const { shrink, itemBorderColor } = itemProps;\n\n const Wrapper = ScAppItemWrapper;\n\n const Li = getPresentationItem(presentationItemType);\n\n return (\n \n {\n data?.map((row, index) => {\n const isLastElement = index === data.length - 1;\n const { cardLayout } = itemProps;\n const liProps = { ...itemProps, ...row, cardLayout };\n const normalizedItemProps = clipPropsWrtCharLimits(liProps);\n\n return (\n // eslint-disable-next-line jsx-a11y/click-events-have-key-events\n onItemClick(row.sid)}\n >\n \n \n \n {data.length - 1 !== index && }\n \n );\n })\n }\n \n );\n});\n\nList.propTypes = {\n id: string.isRequired,\n data: array,\n onItemClick: func,\n presentationItemType: string,\n getPresentationItem: func,\n presentationItemProps: object,\n TitleRenderer: elementType,\n DescriptionRenderer: elementType\n};\n\nList.defaultProps = {\n data: [],\n onItemClick: f => f,\n presentationItemType: ITEM_TYPES.CARD_ITEM,\n getPresentationItem: getBuilderPresentationItem,\n presentationItemProps: {}\n};\n\nexport default List;\n","import styled from 'styled-components';\n\nexport const ListWrapper = styled.div`\n width: 100%;\n display: ${({ isShrink }) => (isShrink ? 'flex' : '')};\n flex-wrap: ${({ isShrink }) => (isShrink ? 'wrap' : '')};\n\n .shrink-wrapper {\n width: ${({ isShrink }) => (isShrink ? '50%' : '')};\n .vertical {\n border: 1px solid ${({ itemBorderColor }) => itemBorderColor};\n\n &:not(:has(.start-element-container.image)) {\n padding: 8px;\n }\n }\n &:has(.vertical) {\n .divider {\n display: none;\n }\n }\n .horizontal {\n .card-text-wrapper {\n min-height: 44px;\n }\n }\n .vertical {\n .card-text-wrapper {\n min-height: 76px;\n }\n }\n }\n`;\n\nexport const Divider = styled.div`\n height: 1px;\n background: ${({ itemBorderColor }) => itemBorderColor};\n margin: 12px 4px;\n`;\n","import Styled from 'styled-components';\nimport { mainFontColor } from '../../../styles/colors';\n\nconst ScParagraphItem = Styled.div`\n color: ${mainFontColor};\n`;\n\nexport default ScParagraphItem;\n","import React, { useMemo, useCallback } from 'react';\nimport { string, func } from 'prop-types';\nimport { t } from '@jotforminc/translation';\nimport { Utils } from '@jotforminc/uikit';\n\nimport { withContentWrapper } from '../withContentWrapper';\nimport { sanitizeHTML } from '../../../utils';\nimport ScParagraphItem from './ScParagraphItem';\nimport './paragraph-item.scss';\n\nconst ParagraphItem = ({ content, onClick }) => {\n const htmlContent = useMemo(() => {\n const placeholder = t('Paragraph');\n return content ? sanitizeHTML(content, { ADD_ATTR: ['target'] }) : placeholder;\n }, [content]);\n const handleEnterPressed = useCallback(e => Utils.isPressedKeyEnter(e) && onClick(), []);\n\n return (\n \n );\n};\n\nParagraphItem.propTypes = {\n content: string,\n onClick: func\n};\n\nParagraphItem.defaultProps = {\n content: '',\n onClick: f => f\n};\n\nexport default withContentWrapper(ParagraphItem);\n","import Styled from 'styled-components';\n\nexport const ScLinkThumbnail = Styled.div`\n ${({ itemTextAlignment }) => {\n switch (itemTextAlignment) {\n case 'left':\n return 'margin: 0 16px 0 0;';\n case 'center':\n return 'align-self: center; margin: 0 0 8px 0;';\n case 'right':\n return 'margin: 0 0 0 16px;';\n default:\n return '';\n }\n }}\n`;\n","import { bool, string } from 'prop-types';\nimport React from 'react';\nimport { ScLinkThumbnail } from '../../Link/scLinkThumbnail';\nimport '../../Link/item-link-thumbnail.scss';\nimport { Loading } from '../../Loading';\n\nconst LinkThumbnail = ({ linkPreviewImageURL, itemTextAlignment, isLoading }) => (\n \n {\n isLoading\n ? \n : \"link-preview\"\n }\n \n);\n\nLinkThumbnail.propTypes = {\n linkPreviewImageURL: string,\n itemTextAlignment: string,\n isLoading: bool\n};\n\nLinkThumbnail.defaultProps = {\n linkPreviewImageURL: '',\n itemTextAlignment: '',\n isLoading: false\n};\n\nexport default LinkThumbnail;\n","import React, { useEffect } from 'react';\nimport { elementType, string, bool } from 'prop-types';\nimport Fields from '@jotforminc/form-fields';\nimport { useSelector } from 'react-redux';\nimport { isEnterprise } from '@jotforminc/enterprise-utils';\nimport { DefaultDivRenderer } from '../defaultRenderers';\nimport PortalErrorBoundary from '../../PortalErrorBoundary';\nimport { WidgetWrapper } from '../../../styles/scWidgets';\nimport SELECTORS from '../../../store/selectors';\n\nconst widgetDefinitions = {\n cfname: {\n text: 'Widget Name',\n value: '',\n toolbar: false\n },\n maxWidth: {\n text: 'Max Width',\n value: 587,\n toolbar: false,\n hidden: true\n },\n widgetType: {\n text: 'Widget Type',\n value: 'Unset',\n toolbar: false,\n hidden: true\n },\n builderDescription: {\n text: 'Builder Description',\n value: '',\n toolbar: false,\n hidden: true\n },\n static: {\n text: 'Static Widget',\n value: 'No',\n toolbar: false,\n hidden: true\n },\n boxAlign: {\n text: 'Align',\n value: 'Left',\n dropdown: [\n ['Left', 'Left'],\n ['Center', 'Center'],\n ['Right', 'Right']\n ],\n icon: 'images/blank.gif',\n iconClassName: 'toolbar-button_align'\n },\n text: {\n text: 'Text',\n value: 'Type a question',\n forceDisplay: true,\n icon: 'images/blank.gif',\n iconClassName: 'toolbar-font_new',\n toolbar: false\n },\n label: {\n text: 'Label',\n value: 'Yes',\n dropdown: [\n ['No', 'Disable'],\n ['Yes', 'Enable']\n ],\n icon: 'images/blank.gif',\n iconClassName: 'toolbar-dropdown_selected'\n },\n labelAlign: {\n text: 'Label Align',\n value: 'Auto',\n dropdown: [\n ['Left', 'Left'],\n ['Right', 'Right'],\n ['Top', 'Top']\n ],\n checkbox: {\n name: 'labelAlign',\n text: 'Set as form default',\n value: 'Auto'\n }\n },\n settingNames: {\n text: 'General Settings',\n value: '',\n toolbar: false,\n hidden: true\n },\n settingNamesCSS: {\n text: 'Custom CSS',\n value: '',\n toolbar: false,\n hidden: true\n },\n widgetTabs: {\n value: [\n ['general', 'settingNames'],\n ['customcss', 'settingNamesCSS']\n ],\n toolbar: false,\n hidden: true\n },\n paramChunks: {\n text: 'Parameter value chunks',\n value: '',\n toolbar: false,\n hidden: true\n },\n customCSS: {\n text: 'Custom CSS',\n value: '',\n toolbar: false,\n hidden: true,\n widgettab: 'customcss',\n tip: 'Customize your widget layout. (Optional)',\n type: 'textarea'\n },\n frameWidth: {\n text: 'Width',\n value: 600,\n toolbar: true,\n icon: 'images/blank.gif',\n iconClassName: 'toolbar-dropdown_width',\n type: 'spinner',\n size: 10\n },\n frameHeight: {\n text: 'Height',\n value: 350,\n toolbar: true,\n icon: 'images/blank.gif',\n iconClassName: 'toolbar-dropdown_size',\n type: 'spinner',\n size: 10\n },\n frameSrc: {\n text: 'Frame URL',\n value: '',\n toolbar: false,\n hidden: true\n },\n finalSrc: {\n text: 'Frame Final URL',\n value: '',\n toolbar: false,\n hidden: true\n },\n required: {\n text: 'Required',\n value: 'No',\n dropdown: [\n ['No', 'No'],\n ['Yes', 'Yes']\n ]\n }\n};\n\nconst WidgetItem = ({\n id, TitleRenderer, clientID, passive, ...props\n}) => {\n const appID = useSelector(SELECTORS.getAppID);\n const cdnConfig = useSelector(SELECTORS.getCDNConfigSelector);\n\n const convertedWidgetProps = Object.keys(props).reduce((pre, key) => {\n return { ...pre, [key]: { value: props[key] } };\n }, {\n ...widgetDefinitions,\n ...{\n selectedField: { value: clientID },\n qname: { value: clientID },\n passive: passive,\n themeVersion: 'v2',\n formID: appID,\n portalWidget: true,\n id: { value: id },\n cdnconfig: { ...cdnConfig },\n enterprise: { value: isEnterprise() },\n environment: 'JOTFORM_ENV' in window && window.JOTFORM_ENV\n }\n });\n\n useEffect(() => {\n if (!passive) {\n // eslint-disable-next-line no-eval\n eval(Fields.Widget.getEmbeddedScript(convertedWidgetProps));\n }\n }, [convertedWidgetProps]);\n\n if (!id) {\n return '';\n }\n\n return (\n \n \n \n \n \n );\n};\n\nWidgetItem.propTypes = {\n id: string,\n title: string,\n TitleRenderer: elementType,\n clientID: string.isRequired,\n passive: bool\n};\n\nWidgetItem.defaultProps = {\n id: '',\n title: '',\n TitleRenderer: DefaultDivRenderer,\n passive: true\n};\n\nexport default WidgetItem;\n","import React, { useMemo } from 'react';\nimport { useDispatch } from 'react-redux';\nimport propTypes from 'prop-types';\nimport { t } from '@jotforminc/translation';\nimport { VALUE_BOUNDED_OPTIONS, sideOptionRenderer } from './helper';\nimport * as ACTION_CREATORS from '../../store/actionCreators';\nimport { sanitizeHTML } from '../../utils';\nimport { ScListItemContainer, ScSideElementContainer } from './styled';\nimport { PROP_TYPES } from '../../modules/Builder/components/HomePage/RightPanel/ListItemSideItemSelection/constants';\n\nconst ListItemBase = ({\n id,\n title,\n description,\n TitleRenderer,\n DescriptionRenderer,\n startOpts,\n endOpts,\n colorScheme\n}) => {\n const dispatch = useDispatch();\n const SIDE_OPTS = {\n [PROP_TYPES.START]: startOpts,\n [PROP_TYPES.END]: endOpts\n };\n\n const handleSideOptionPropChange = id\n ? type => value => dispatch(\n ACTION_CREATORS.updateItemPropAction({\n itemID: id,\n prop: { [type]: { type: SIDE_OPTS[type].type, data: { ...SIDE_OPTS[type].data, ...value } } }\n })\n )\n : () => { };\n\n // Those are for dynamic memoization, it is needed for data source\n const startElementMemoizationProps = VALUE_BOUNDED_OPTIONS[SIDE_OPTS[PROP_TYPES.START].type]?.props.map(prop => SIDE_OPTS[PROP_TYPES.START].data?.[prop]);\n const endElementMemoizationProps = VALUE_BOUNDED_OPTIONS[SIDE_OPTS[PROP_TYPES.END].type]?.props.map(prop => SIDE_OPTS[PROP_TYPES.END].data?.[prop]);\n\n const StartElement = useMemo(() => sideOptionRenderer(SIDE_OPTS[PROP_TYPES.START]),\n [SIDE_OPTS[PROP_TYPES.START].type, ...(startElementMemoizationProps) ?? [SIDE_OPTS[PROP_TYPES.START].data]]);\n\n const EndElement = useMemo(() => sideOptionRenderer(SIDE_OPTS[PROP_TYPES.END], true),\n [SIDE_OPTS[PROP_TYPES.END].type, ...(endElementMemoizationProps) ?? [SIDE_OPTS[PROP_TYPES.END].data]]);\n\n return (\n \n
\n {\n StartElement && (\n \n handleSideOptionPropChange(PROP_TYPES.START)(val)}\n />\n \n )\n }\n
\n
\n \n {sanitizeHTML(title)}\n \n \n {sanitizeHTML(description)}\n \n
\n {\n EndElement && (\n \n handleSideOptionPropChange(PROP_TYPES.END)(val)}\n {...endOpts.props}\n />\n \n )\n }\n
\n
\n
\n );\n};\n\nListItemBase.propTypes = {\n id: propTypes.string,\n title: propTypes.string,\n description: propTypes.string,\n startOpts: propTypes.object,\n endOpts: propTypes.object,\n TitleRenderer: propTypes.elementType.isRequired,\n DescriptionRenderer: propTypes.elementType.isRequired,\n colorScheme: propTypes.shape({\n itemBgColor: propTypes.string,\n itemBorderColor: propTypes.string,\n itemFontColor: propTypes.string\n })\n};\n\nListItemBase.defaultProps = {\n id: '',\n title: '',\n description: '',\n startOpts: {},\n endOpts: {},\n colorScheme: {\n itemBgColor: '',\n itemBorderColor: '',\n itemFontColor: ''\n }\n};\n\nexport default ListItemBase;\n","var _path, _path2, _path3, _path4, _path5, _path6, _path7, _path8, _path9, _path10, _path11;\nfunction _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }\nimport * as React from \"react\";\nconst SvgJotform21Logo = props => /*#__PURE__*/React.createElement(\"svg\", _extends({\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 123 22\"\n}, props), _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M85.6679 16.885C84.9073 16.885 84.1829 16.6078 83.6489 16.0712C83.1165 15.5363 82.757 14.7269 82.757 13.6326C82.757 12.5251 83.1169 11.7163 83.6484 11.1851C84.1817 10.6521 84.9059 10.3802 85.6679 10.3802C86.43 10.3802 87.1541 10.6521 87.6874 11.1851C88.2189 11.7163 88.5788 12.5251 88.5788 13.6326C88.5788 14.7401 88.2189 15.5489 87.6874 16.0802C87.1541 16.6131 86.43 16.885 85.6679 16.885ZM85.6679 6.84459C81.8053 6.84459 78.8799 9.68648 78.8799 13.6326C78.8799 17.5531 81.8047 20.4206 85.6679 20.4206C89.5311 20.4206 92.4559 17.5531 92.4559 13.6326C92.4559 9.68648 89.5305 6.84459 85.6679 6.84459Z\",\n fill: \"white\"\n})), _path2 || (_path2 = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M53.5485 16.9803C52.7879 16.9803 52.0635 16.7031 51.5295 16.1665C50.9971 15.6316 50.6376 14.8222 50.6376 13.7279C50.6376 12.6204 50.9975 11.8116 51.529 11.2804C52.0622 10.7474 52.7864 10.4755 53.5485 10.4755C54.3105 10.4755 55.0347 10.7474 55.5679 11.2804C56.0994 11.8116 56.4593 12.6204 56.4593 13.7279C56.4593 14.8354 56.0994 15.6442 55.5679 16.1755C55.0347 16.7084 54.3105 16.9803 53.5485 16.9803ZM53.5485 6.93989C49.6859 6.93989 46.7604 9.78178 46.7604 13.7279C46.7604 17.6484 49.6852 20.5159 53.5485 20.5159C57.4117 20.5159 60.3365 17.6484 60.3365 13.7279C60.3365 9.78178 57.411 6.93989 53.5485 6.93989Z\",\n fill: \"white\"\n})), _path3 || (_path3 = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M103.013 20.3794H106.867V12.7258C106.867 12.0936 107.065 11.5425 107.414 11.1527C107.76 10.7662 108.27 10.521 108.934 10.521C109.63 10.521 110.103 10.7515 110.406 11.107C110.715 11.4688 110.875 11.9926 110.875 12.6245V20.3794H114.704V12.7258C114.704 12.1071 114.902 11.5548 115.249 11.1608C115.594 10.7702 116.098 10.521 116.746 10.521C117.456 10.521 117.928 10.7521 118.227 11.1061C118.532 11.4671 118.687 11.9905 118.687 12.6245V20.3794H122.44V11.9409C122.44 10.2116 121.871 8.95622 120.976 8.13508C120.086 7.31786 118.899 6.9549 117.704 6.9549C116.856 6.9549 116.078 7.09903 115.38 7.45005C114.785 7.74881 114.259 8.19198 113.8 8.80406C113.056 7.5945 111.698 6.9549 110.094 6.9549C108.923 6.9549 107.569 7.41893 106.716 8.32123V7.26695H103.013V20.3794Z\",\n fill: \"white\"\n})), _path4 || (_path4 = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M101.563 7.27813V11.2056L101.262 11.1449C100.903 11.0726 100.593 11.0486 100.307 11.0486C99.4899 11.0486 98.7637 11.2486 98.2425 11.7345C97.7247 12.2172 97.3678 13.0208 97.3678 14.3174V20.3794H93.5243V7.26692H97.2674V8.53249C98.1931 7.41962 99.6306 7.20343 100.533 7.20343C100.822 7.20343 101.084 7.22982 101.332 7.25488L101.563 7.27813Z\",\n fill: \"white\"\n})), _path5 || (_path5 = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M32.2668 14.0609L36.0242 14.0609L36.0669 14.1026C36.0955 14.1306 36.1153 14.1705 36.1193 14.2149C36.1921 15.0378 36.5154 15.6584 36.9992 16.0718C37.4806 16.4832 38.1036 16.6747 38.7527 16.6747C39.5448 16.6747 40.1926 16.3829 40.6401 15.8757C41.0851 15.3714 41.3168 14.672 41.3168 13.8792V2.89618H45.3792V13.9928C45.3792 17.5452 42.6615 20.5161 38.7811 20.5161C36.8426 20.5161 35.2171 19.8719 34.0772 18.7542C32.9636 17.6622 32.2986 16.1037 32.2691 14.21L32.2668 14.0609Z\",\n fill: \"white\"\n})), _path6 || (_path6 = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M78.3341 4.67614L78.5476 4.73713V1.76251L78.4495 1.71789C78.2991 1.64955 78.0573 1.5877 77.7781 1.54267C77.4953 1.49705 77.1616 1.46674 76.8216 1.46674C75.4968 1.46674 74.0073 1.90515 73.236 2.69495C72.4652 3.48433 72.0402 4.60944 72.0402 5.95556V6.58402H70.1038V9.99872H72.0402V20.3794H73.9833H75.9265V9.99872H78.5476V6.58402H75.9265V6.00279C75.9265 5.3979 76.1381 5.04969 76.4085 4.84686C76.6875 4.63764 77.054 4.56452 77.3884 4.56452C77.8911 4.56452 78.1826 4.63285 78.3341 4.67614Z\",\n fill: \"white\"\n})), _path7 || (_path7 = /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n d: \"M68.7132 17.3115L68.9138 17.2503V20.2366L68.8215 20.2814C68.6803 20.35 68.453 20.4121 68.1906 20.4573C67.9248 20.5031 67.6113 20.5336 67.2918 20.5336C66.0468 20.5336 64.6545 20.0934 63.9298 19.3005C63.2054 18.508 62.8059 17.3785 62.8059 16.0271V10.0004H60.9862L60.9862 6.60158L62.8059 6.60158L62.8059 2.9137H66.4505V6.60158L68.9138 6.60158V10.0004L66.4505 10.0004V15.9797C66.4505 16.5869 66.6494 16.9365 66.9035 17.1402C67.1657 17.3502 67.5101 17.4236 67.8244 17.4236C68.2969 17.4236 68.5708 17.355 68.7132 17.3115Z\",\n fill: \"white\"\n})), _path8 || (_path8 = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M5.48 20.9075C5.89536 21.3101 5.60184 22 5.01202 22H1.32085C0.592582 22 0 21.4256 0 20.7196V17.1413C0 16.5695 0.711652 16.285 1.12701 16.6876L5.48 20.9075Z\",\n fill: \"white\"\n})), _path9 || (_path9 = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M11.2498 21.1857C10.1572 20.1002 10.1572 18.3403 11.2498 17.2549L15.193 13.3374C16.2856 12.2519 18.0571 12.2519 19.1497 13.3374C20.2423 14.4228 20.2423 16.1828 19.1497 17.2682L15.2065 21.1857C14.1139 22.2712 12.3424 22.2712 11.2498 21.1857Z\",\n fill: \"#FFB629\"\n})), _path10 || (_path10 = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M0.831535 11.3423C-0.261065 10.2569 -0.261065 8.49695 0.831536 7.41147L7.46751 0.814111C8.56011 -0.27137 10.3316 -0.271371 11.4242 0.81411C12.5168 1.89959 12.5168 3.6595 11.4242 4.74498L4.78819 11.3423C3.69559 12.4278 1.92414 12.4278 0.831535 11.3423Z\",\n fill: \"#0099FF\"\n})), _path11 || (_path11 = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M6.25756 16.0445C5.16496 14.959 5.16496 13.1991 6.25756 12.1136L15.224 3.20565C16.3166 2.12017 18.088 2.12017 19.1806 3.20565C20.2732 4.29113 20.2732 6.05104 19.1806 7.13652L10.2142 16.0445C9.12162 17.13 7.35016 17.13 6.25756 16.0445Z\",\n fill: \"#FF6100\"\n})));\nexport default SvgJotform21Logo;","import React, { useEffect, useRef } from 'react';\nimport PropTypes from 'prop-types';\n\nfunction getDisplayName(WrappedComponent) {\n return WrappedComponent.displayName || WrappedComponent.name || 'Component';\n}\n\nfunction withClickOutside(WrappedComponent) {\n function WithClickOutside(props) {\n const {\n exceptionalClasses,\n onClickOutside,\n withClickOutsideWrapperClass,\n ...otherProps\n } = props;\n\n const wrapper = useRef(null);\n\n const handleClickOutside = event => {\n const { classList } = event.target;\n if (\n exceptionalClasses\n && (\n classList.contains(exceptionalClasses)\n || [...classList].some(xClass => exceptionalClasses.includes(xClass))\n || exceptionalClasses.some(item => event.target.closest(`.${item}`))\n )\n ) {\n return;\n }\n\n if (wrapper.current && !wrapper.current.contains(event.target)) {\n onClickOutside(event);\n }\n };\n\n useEffect(() => {\n window.addEventListener('mousedown', handleClickOutside, true);\n return () => {\n window.removeEventListener('mousedown', handleClickOutside, true);\n };\n }, []);\n\n return (\n \n \n \n );\n }\n\n WithClickOutside.propTypes = {\n exceptionalClasses: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.arrayOf(PropTypes.string)\n ]),\n onClickOutside: PropTypes.func.isRequired,\n withClickOutsideWrapperClass: PropTypes.string\n };\n\n WithClickOutside.defaultProps = {\n exceptionalClasses: null,\n withClickOutsideWrapperClass: null\n };\n\n WithClickOutside.displayName = `inlineEdit(${getDisplayName(WrappedComponent)})`;\n\n return WithClickOutside;\n}\n\nexport default withClickOutside;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { t, translationRenderer } from '@jotforminc/translation';\nimport withClickOutside from '../utils/HOCs/withClickOutside';\n\nconst RemoveBrandingFooter = ({\n isPaidUser,\n isOwner,\n referrerUrl,\n removeBranding\n}) => {\n let content = (\n \n {translationRenderer('[1[Upgrade your account]] to remove it.')({\n renderer1: text => (\n \n {text}\n \n )\n })}\n \n );\n\n if (isPaidUser) {\n content = (\n \n {translationRenderer('[1[Click here]] to remove it.')({\n renderer1: text => (\n \n {text}\n \n )\n })}\n \n );\n }\n\n if (!isOwner) {\n content = (\n \n {t('Contact resource owner to remove it.')}\n \n );\n }\n\n return (\n
\n {t('Remove Jotform Branding?')}\n {content}\n
\n );\n};\n\nRemoveBrandingFooter.propTypes = {\n isPaidUser: PropTypes.bool,\n isOwner: PropTypes.bool,\n referrerUrl: PropTypes.string,\n removeBranding: PropTypes.func\n};\n\nRemoveBrandingFooter.defaultProps = {\n isPaidUser: false,\n isOwner: false,\n referrerUrl: '',\n removeBranding: () => { }\n};\n\nexport default withClickOutside(RemoveBrandingFooter);\n","import { string } from 'prop-types';\n\nexport const BASE_JOTFORM_URL = 'https://www.jotform.com/';\nexport const PRICING_JOTFORM_URL = `${BASE_JOTFORM_URL}pricing/`;\n\nexport const UTM_PROP_SCHEME = {\n default: {\n source: 'source',\n medium: 'banner',\n campaing: 'campaign',\n content: 'content',\n term: 'term'\n },\n props: {\n source: string,\n medium: string,\n campaing: string,\n content: string,\n term: string\n }\n};\n\nexport const PRODUCT_CONFIGS = {\n reports: {\n appName: 'Reports',\n showAppName: true,\n bannerTagLine: 'Create your own Jotform Report - It’s free',\n buttonText: 'Create your own Report'\n },\n tables: {\n appName: 'Tables',\n showAppName: true,\n bannerTagLine: 'Create your own Jotform Table - It’s free',\n buttonText: 'Create your own Table'\n },\n forms: {\n appName: 'Forms',\n showAppName: false,\n bannerTagLine: 'Now create your own Jotform - It’s free!',\n buttonText: 'Create your own Jotform'\n },\n apps: {\n appName: 'Apps',\n showAppName: true,\n bannerTagLine: 'Create your own Jotform App - It’s free',\n buttonText: 'Create your own App'\n },\n store: {\n appName: 'Store Builder',\n showAppName: true,\n bannerTagLine: 'Create your own Jotform Store - It’s free',\n buttonText: 'Create your own Store'\n }\n};\n","export const utmParser = scheme => {\n return Object.keys(scheme)\n .map(key => `utm_${key}=${encodeURIComponent(scheme[key])}`)\n .join('&');\n};\n","import React, { useState } from 'react';\nimport {\n bool,\n func,\n node,\n oneOf,\n shape\n} from 'prop-types';\nimport { t } from '@jotforminc/translation';\nimport RemoveBrandingFooter from './RemoveBrandingFooter';\nimport JotformLogo from '../assets/svg/jotform_21_logo.svg';\n\nimport {\n BASE_JOTFORM_URL,\n PRICING_JOTFORM_URL,\n PRODUCT_CONFIGS,\n UTM_PROP_SCHEME\n} from './constants';\nimport { utmParser } from '../utils';\n\nimport '../styles/_jfBrandingFooter.scss';\n\nconst BrandingFooter = ({\n activeUtmScheme, // in builder\n passiveUtmScheme, // shared\n showBranding, // generally user prop\n isPaidUser,\n isOwner,\n removeBranding,\n isPassive, // mode => builder/product\n brandingIcon,\n style,\n product,\n onClick\n}) => {\n const [showRemove, setShowRemove] = useState(false);\n\n if (!showBranding) {\n return null;\n }\n\n const handleClick = () => {\n if (onClick) {\n onClick();\n return;\n }\n if (isPassive) {\n window.open(`${BASE_JOTFORM_URL}?${utmParser(passiveUtmScheme)}`, '_blank');\n } else if (!showRemove) {\n setShowRemove(true);\n }\n };\n\n const {\n appName,\n showAppName,\n bannerTagLine,\n buttonText\n } = PRODUCT_CONFIGS[product] || PRODUCT_CONFIGS.reports;\n\n return (\n <>\n f}\n style={style}\n >\n
\n
\n {brandingIcon}\n
\n {showAppName && (\n
\n {t(appName)}\n
\n )}\n
\n
\n
\n {t(bannerTagLine)}\n
\n
\n {t(buttonText)}\n
\n
\n \n {!isPassive && showRemove && (\n setShowRemove(false)}\n withClickOutsideWrapperClass=\"jfBrandingFooter-removal forPage\"\n isPaidUser={isPaidUser}\n isOwner={isOwner}\n removeBranding={() => {\n setShowRemove(false);\n removeBranding();\n }}\n />\n )}\n \n );\n};\n\nBrandingFooter.propTypes = {\n activeUtmScheme: shape(UTM_PROP_SCHEME.props),\n passiveUtmScheme: shape(UTM_PROP_SCHEME.props),\n isPaidUser: bool,\n isOwner: bool,\n removeBranding: func,\n showBranding: bool,\n isPassive: bool,\n brandingIcon: node,\n style: shape({}),\n product: oneOf(['reports', 'forms', 'tables', 'apps', 'store']),\n onClick: func\n};\n\nBrandingFooter.defaultProps = {\n activeUtmScheme: UTM_PROP_SCHEME.default,\n passiveUtmScheme: UTM_PROP_SCHEME.default,\n isPaidUser: false,\n isOwner: false,\n removeBranding: () => {},\n showBranding: true,\n isPassive: true,\n brandingIcon: ,\n style: {},\n product: 'reports',\n onClick: null\n};\n\nexport default BrandingFooter;\n","import React, { useCallback } from 'react';\nimport { string } from 'prop-types';\nimport Styled from 'styled-components';\nimport { BrandingFooter } from '@jotforminc/branding-footer';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { isYes } from '../../utils';\nimport { brandingButtonClickAction } from '../../store/actionCreators';\nimport SELECTORS from '../../store/selectors';\n\nconst ScPortalBrandingFooter = Styled.div`\n flex: 1 1 auto;\n\n .jfBrandingFooter {\n z-index: 1;\n position: fixed;\n }\n\n @media screen and (max-width: 480px) {\n .jfBrandingFooter-appName, .jfBrandingFooter-bannerTagLine {\n display: none;\n }\n }\n`;\n\nconst PortalBrandingFooter = ({ showBrandingInBuilder }) => {\n const dispatch = useDispatch();\n const isShoppingApp = useSelector(SELECTORS.getIsShoppingApp);\n const showBranding = useSelector(SELECTORS.getHasBrandingFooter);\n const isBuilder = useSelector(SELECTORS.getIsBuilder);\n const productType = isShoppingApp ? 'store' : 'apps';\n\n const handleClick = useCallback(() => {\n if (!isBuilder) {\n dispatch(brandingButtonClickAction());\n }\n }, []);\n\n return (\n \n \n \n );\n};\n\nPortalBrandingFooter.propTypes = {\n showBrandingInBuilder: string\n};\n\nPortalBrandingFooter.defaultProps = {\n showBrandingInBuilder: ''\n};\n\nexport default PortalBrandingFooter;\n","import React, { useCallback } from 'react';\nimport isEqual from 'lodash/isEqual';\nimport { useDispatch, useSelector } from 'react-redux';\nimport PropTypes from 'prop-types';\nimport EditableTextRenderer from '../../../../../components/EditableTextRenderer';\nimport { handleSelectAllText } from '../../../../../utils';\nimport SELECTORS from '../../../../../store/selectors';\nimport * as ACTION_CREATORS from '../../../../../store/actionCreators';\nimport { useItemDefaults } from '../../../../../properties';\n\nconst EditableTextRendererFor = item => (propName, extraProps = {}, characterLimit) => {\n const Component = ({ children, overrideProps, ...props }) => {\n const dispatch = useDispatch();\n const isItemInlineEditMode = useSelector(SELECTORS.getIsItemInlineEditMode);\n\n const { title: defaultItemValue } = useItemDefaults(item.type);\n\n const { defaultValue } = props;\n\n const handleInlineEditorFocus = useCallback(e => {\n if (defaultValue === defaultItemValue) handleSelectAllText(e);\n }, [defaultItemValue, handleSelectAllText, defaultValue]);\n\n const onChange = useCallback(val => {\n if (!isEqual(val, defaultValue)) {\n dispatch(ACTION_CREATORS.updateItemPropAction({ itemID: item.id, prop: { [propName]: val } }));\n }\n }, []);\n\n return (\n \n {children}\n \n );\n };\n\n Component.propTypes = {\n defaultValue: PropTypes.string,\n overrideProps: PropTypes.object,\n children: PropTypes.element\n };\n\n Component.defaultProps = {\n defaultValue: '',\n overrideProps: {},\n children: undefined\n };\n\n return Component;\n};\n\nexport default EditableTextRendererFor;\n","import React, { useCallback } from 'react';\nimport { elementType } from 'prop-types';\nimport { IconDocumentSimpleFilled } from '@jotforminc/svg-icons';\n\nimport DocumentFileUpload from './DocumentFileUpload';\n\nconst InlineFileUpload = ({ FileUploadIcon, ...props }) => {\n const TextWrapperRenderer = useCallback(({ children }) => (\n
\n \n \n \n {children}\n
\n ), [FileUploadIcon]);\n\n return (\n \n );\n};\n\nInlineFileUpload.propTypes = {\n FileUploadIcon: elementType\n};\n\nInlineFileUpload.defaultProps = {\n FileUploadIcon: props => \n};\n\nexport default InlineFileUpload;\n","import React from 'react';\nimport { useDispatch } from 'react-redux';\nimport InlineFileUpload from '../Editors/InlineFileUpload';\nimport * as ACTION_CREATORS from '../../../../../store/actionCreators';\nimport { handleImageWithDimensions } from '../../../../../utils/image';\n\nconst NewFileUploader = item => ({\n propName, valueProp, inputButtonText, FileUploadIcon, allowedFileTypes, allowImageUpload, autoRetrieveDimensions\n} = {}) => props => {\n const dispatch = useDispatch();\n\n const handleChange = async newData => {\n const prop = propName ? { [propName]: newData[valueProp] } : newData;\n dispatch(ACTION_CREATORS.updateItemPropAction({ itemID: item.id, prop }));\n\n if (autoRetrieveDimensions) {\n const { width, height, proportion } = await handleImageWithDimensions(newData[valueProp]);\n dispatch(ACTION_CREATORS.updateItemPropAction({\n itemID: item.id,\n prop: {\n [propName]: newData[valueProp],\n width,\n height,\n proportion\n }\n }));\n }\n };\n\n return (\n \n );\n};\n\nexport default NewFileUploader;\n","import React, { useMemo } from 'react';\nimport { t } from '@jotforminc/translation';\nimport { IconDocumentImageFilled, IconDocumentSimpleFilled } from '@jotforminc/svg-icons';\nimport isEmpty from 'lodash/isEmpty';\nimport isArray from 'lodash/isArray';\nimport { ITEM_TYPES } from '../../../../../constants/itemTypes';\nimport { isYes } from '../../../../../utils';\nimport EditableTextRendererFor from './EditableTextRendererFor';\nimport NewFileUploader from './NewFileUploader';\nimport { DESCRIPTION_LIMIT } from '../../../../../constants';\n\nconst RENDERERS = {\n FILE_UPLOADER: 'FILE_UPLOADER',\n EDITABLE_TEXT_RENDERER: 'EDITABLE_TEXT_RENDERER'\n};\n\nexport const getEditorProps = item => {\n const {\n type, showURL, embeddedForm, previewImageURL, isLastAddedItem, title\n } = item;\n\n const getNewFileUploader = NewFileUploader(item);\n\n const ImageUploadIcon = () => ;\n const FileUploadIcon = () => ;\n\n switch (type) {\n case ITEM_TYPES.DOCUMENT:\n return {\n UploaderRenderer: getNewFileUploader({ FileUploadIcon: FileUploadIcon }),\n TitleRenderer: {\n type: RENDERERS.EDITABLE_TEXT_RENDERER, args: ['title', { placeholder: t('Add Document Name') }]\n },\n DescriptionRenderer: {\n type: RENDERERS.EDITABLE_TEXT_RENDERER, args: ['description', { placeholder: t('Add Description') }]\n }\n };\n case ITEM_TYPES.IMAGE:\n return {\n UploaderRenderer: getNewFileUploader({\n propName: 'imageURL',\n valueProp: 'fileURL',\n inputButtonText: 'Upload Image',\n FileUploadIcon: ImageUploadIcon,\n allowedFileTypes: 'image',\n allowImageUpload: true,\n autoRetrieveDimensions: true\n })\n };\n case ITEM_TYPES.TABLE_LINK:\n case ITEM_TYPES.REPORT_LINK:\n case ITEM_TYPES.SENTBOX_LINK:\n case ITEM_TYPES.SIGN_LINK:\n return {\n TitleRenderer: {\n type: RENDERERS.EDITABLE_TEXT_RENDERER, args: ['title', { placeholder: t('Enter a title') }]\n },\n DescriptionRenderer: {\n type: RENDERERS.EDITABLE_TEXT_RENDERER, args: ['description', { placeholder: t('Type a description') }]\n }\n };\n case ITEM_TYPES.LINK:\n // Swap attributes\n const TitleRenderer = { type: RENDERERS.EDITABLE_TEXT_RENDERER, args: ['description', { placeholder: t('Enter a title') }] };\n const DescriptionRenderer = { type: RENDERERS.EDITABLE_TEXT_RENDERER, args: ['title', { placeholder: t('Type or paste URL'), autoFocus: isLastAddedItem }] };\n return {\n ...(isEmpty(previewImageURL) && isEmpty(title)) ? { TitleRenderer: () => null } : { TitleRenderer },\n ...!isYes(showURL) ? { DescriptionRenderer: () => null } : { DescriptionRenderer }\n };\n case ITEM_TYPES.BUTTON:\n return {\n TitleRenderer: { type: RENDERERS.EDITABLE_TEXT_RENDERER, args: ['title', { placeholder: t('Type a button text') }] }\n };\n case ITEM_TYPES.FORM:\n const isEmbeddedForm = isYes(embeddedForm);\n return {\n TitleRenderer: isEmbeddedForm\n ? () => null\n : { type: RENDERERS.EDITABLE_TEXT_RENDERER, args: ['title', { placeholder: t('Type a form label') }, 150] },\n DescriptionRenderer: {\n type: RENDERERS.EDITABLE_TEXT_RENDERER, args: ['description', { placeholder: t('Type a description') }, 150]\n }\n };\n case ITEM_TYPES.HEADING:\n return {\n TitleRenderer: { type: RENDERERS.EDITABLE_TEXT_RENDERER, args: ['title', { placeholder: t('Type a heading') }, 150] },\n DescriptionRenderer: { type: RENDERERS.EDITABLE_TEXT_RENDERER, args: ['description', { placeholder: t('Type a subheading') }] }\n };\n case ITEM_TYPES.PRODUCT_LIST:\n return {\n TitleRenderer: {\n type: RENDERERS.EDITABLE_TEXT_RENDERER, args: ['title', { placeholder: t('Product List Title') }, 150]\n }\n };\n case ITEM_TYPES.DONATION:\n return {\n TitleRenderer: { type: RENDERERS.EDITABLE_TEXT_RENDERER, args: ['title', { placeholder: t('Type a heading') }, 150] },\n DescriptionRenderer: { type: RENDERERS.EDITABLE_TEXT_RENDERER, args: ['description', { placeholder: t('Type a subheading') }] },\n DonateButtonTextRenderer: { type: RENDERERS.EDITABLE_TEXT_RENDERER, args: ['donateButtonTitle', { placeholder: t('Type a donate button text') }] }\n };\n case ITEM_TYPES.CARD_ITEM: {\n return {\n TitleRenderer: { type: RENDERERS.EDITABLE_TEXT_RENDERER, args: ['title', { placeholder: t('Enter a title') }, 80] },\n DescriptionRenderer: { type: RENDERERS.EDITABLE_TEXT_RENDERER, args: ['description', { placeholder: t('Type a description') }, DESCRIPTION_LIMIT] },\n ButtonTextRenderer: { type: RENDERERS.EDITABLE_TEXT_RENDERER, args: ['', { placeholder: t('Button') }, 20] }\n };\n }\n default: // Divider, Widget, etc..\n return {};\n }\n};\n\nexport const withInlineEditor = WrappedComponent => item => {\n const {\n type, showURL, previewImageURL, isLastAddedItem, title, previewTitle, isLinkedWithDataSource\n } = item;\n\n const getEditableTextRendererFor = EditableTextRendererFor(item);\n\n const itemRenderers = {\n [RENDERERS.EDITABLE_TEXT_RENDERER]: getEditableTextRendererFor\n\n };\n\n const editorProps = useMemo(() => getEditorProps(item), [type, showURL, previewImageURL, isLastAddedItem, title, previewTitle]);\n\n const mapRenderers = rendererProps => Object.entries(rendererProps).reduce((prev, [propKey, propValue]) => {\n if (!propValue.type) {\n return { ...prev, [propKey]: propValue };\n }\n\n const { type: propType, args } = propValue;\n\n const renderer = itemRenderers[propType];\n\n return { ...prev, [propKey]: isArray(args) ? renderer(...args) : renderer({ ...args }) };\n }, {});\n\n const mutatedEditorProps = isLinkedWithDataSource ? Object.entries(editorProps).reduce((prev, [propKey, propValue]) => {\n const { type: propType, args } = propValue;\n\n switch (propType) {\n case RENDERERS.EDITABLE_TEXT_RENDERER: {\n const [propName, extraProps, charLimit] = args;\n return { ...prev, [propKey]: { ...propValue, args: [propName, { ...extraProps, contentEditable: false }, charLimit] } };\n }\n\n default:\n return { ...prev, [propKey]: propValue };\n }\n }, {}) : editorProps;\n\n return (\n <>\n {type === ITEM_TYPES.WIDGET && (
)}\n \n \n );\n};\n","import React, { forwardRef } from 'react';\nimport Styled from 'styled-components';\nimport { InlineEditor as CommonInlineEditor } from '@jotforminc/jotform-common';\n\nconst InlineEditor = forwardRef((props, ref) => );\nexport const ScInlineEditor = Styled(InlineEditor)`\n display: block;\n height: auto;\n cursor: ${({ contentEditable }) => (contentEditable ? 'text' : 'inherit')};\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\n","import React, { forwardRef, useCallback } from 'react';\nimport { func, string } from 'prop-types';\nimport { ScInlineEditor } from './scInlineEditor';\n\nconst InlineEditor = forwardRef(({\n onChange, defaultValue, wrapperClassName, ...rest\n}, ref) => {\n const handleChange = useCallback(newValue => {\n if (newValue !== defaultValue) onChange(newValue);\n }, [defaultValue, onChange]);\n\n return (\n
\n \n
\n );\n});\n\nInlineEditor.propTypes = {\n onChange: func,\n defaultValue: string.isRequired,\n wrapperClassName: string\n};\n\nInlineEditor.defaultProps = {\n onChange: f => f,\n wrapperClassName: ''\n};\n\nexport default InlineEditor;\n","import Styled, { css } from 'styled-components';\nimport { getWidth } from '../../../../utils/styleUtils';\nimport { isYes } from '../../../../utils';\nimport { FEATURE_NAMES } from '../../../../constants/features';\nimport { isFeatureEnabled } from '../../../../utils/features/helper';\n\nexport const responsivenessRules = `\n max-width: ${getWidth()};\n min-width: ${getWidth()};\n\n @media screen and (max-width: 768px) {\n max-width: ${getWidth('tablet')};\n min-width: ${getWidth('tablet')};\n }\n\n @media screen and (max-width: 480px) {\n max-width: ${getWidth('mobile')};\n min-width: ${getWidth('mobile')};\n }\n`;\n\nexport const contentOverlapSize = '39px';\n\nconst ScAppContentWrapper = Styled.div`\n position: relative;\n padding: 14px;\n\n ${({ isHomepage, openAppHeader }) => (isHomepage ? css`\n margin: 0 auto; \n margin-top: -${contentOverlapSize};\n\n @media screen and (max-width: 480px) {\n margin: 0 auto;\n padding: 0;\n }\n\n .appHeaderCropperActive & {\n margin-top: calc(0px - ${contentOverlapSize} - 51px);\n }\n\n ${isFeatureEnabled(FEATURE_NAMES.AppHeaderVisibility) ? css`\n ${isYes(openAppHeader) ? css`\n margin: 0 auto; \n margin-top: -${contentOverlapSize};\n \n @media screen and (max-width: 480px) {\n margin: 0 auto;\n padding: 0;\n }\n ` : `\n margin-top: 32px;\n\n `}\n ` : ''}\n\n ` : css`\n margin: 36px auto 0 auto;\n\n @media screen and (max-width: 480px) {\n margin: 64px auto 0 auto;\n padding: 0;\n }\n `)}\n\n ${({ isBuilder, openAppHeader }) => (isBuilder ? css`\n ${isYes(openAppHeader) ? css`\n margin-top: -${contentOverlapSize};\n\n @media screen and (max-width: 480px) {\n margin: 0 auto; \n margin-top: -${contentOverlapSize};\n }\n ` : `\n margin: 15px auto 0 auto;\n\n @media screen and (max-width: 480px) {\n margin: 0 auto;\n }\n `}\n ` : '')}\n \n transition: all ease .3s;\n z-index: 1;\n ${responsivenessRules}\n`;\nexport default ScAppContentWrapper;\n","import Styled, { css } from 'styled-components';\n\nconst ScItemListWrapper = Styled.div`\n${({ bgColor }) => {\n return css`\n position: relative;\n display: flex;\n margin: 0;\n transition: all ease .3s;\n ${bgColor ? `background-color: ${bgColor};` : ''}\n width: 100%;\n border-radius: 8px;\n padding: 25px 15px 9px 15px;\n\n @media screen and (max-width: 480px) {\n padding: 16px 16px 0 16px;\n border-radius: 0;\n }\n\n .appHeaderCropperActive & {\n z-index: 4;\n opacity: .8;\n pointer-events: none;\n transition: opacity ease .3s;\n background: #ffffff;\n & > * {\n opacity: 0;\n }\n }\n `;\n }\n}\n`;\nexport default ScItemListWrapper;\n","import Styled, { css } from 'styled-components';\nimport { applyAlpha } from '../../../../utils/styleUtils';\n\nconst loaderPassiveColor = applyAlpha('#d9d7e2', 0.8);\n\nexport const ScLinkFieldItem = Styled.div`\n width: 100%;\n .withIconItemContent {\n opacity: 1 !important;\n .link-thumnail-wrapper {\n flex-shrink: 0;\n min-width: 44px;\n\n img {\n object-fit: contain;\n width: 44px;\n height: 44px;\n max-height: 44px;\n }\n \n ${({ elementSize }) => (elementSize === 'large' && css`\n width: 100px;\n height: 100px;\n img {\n height: 60px;\n width: 60px;\n max-height: 60px;\n }\n `)};\n }\n }\n .app-loading-spinner {\n padding: 0;\n\n & > div {\n border-color: ${loaderPassiveColor} ${loaderPassiveColor} ${loaderPassiveColor} #0A1551;\n }\n }\n\n .itemContent {\n gap: 4px;\n .description {\n font-size: 16px; \n display: block !important;\n &:focus {\n &:before {\n color: #C8CEED;\n }\n }\n }\n .description[contenteditable=true][placeholder]:empty:before {\n content: attr(placeholder);\n display: block;\n }\n .description[contenteditable=true][placeholder]:not(:empty):before {\n display: none;\n }\n }\n`;\n","import React, { memo } from 'react';\nimport SimpleItem from '../../../../components/Items/SimpleItem/SimpleItem';\nimport { ScLinkFieldItem } from './ScLinkFieldItem';\n\nconst LinkFieldItem = props => {\n const itemProps = (({\n TitleRenderer,\n DescriptionRenderer,\n showIcon,\n IconRenderer,\n title,\n description,\n badge,\n elementSize,\n shrink\n }) => ({\n TitleRenderer,\n DescriptionRenderer,\n showIcon,\n IconRenderer,\n title,\n description,\n badge,\n elementSize,\n shrink\n }))(props);\n\n return (\n \n \n \n );\n};\n\nexport default memo(LinkFieldItem);\n","import Styled from 'styled-components';\n\nexport const ScAiAgentWrapper = Styled.div`\n width: 100%;\n height:100%;\n\n iframe {\n width: 100%;\n height: 100%;\n }\n`;\n","import React from 'react';\nimport { getBaseURL } from '@jotforminc/router-bridge';\nimport { string } from 'prop-types';\nimport { ScAiAgentWrapper } from './ScAiAgent';\nimport { populateURLwithPWAParams } from '../utils';\n\nconst AiAgent = ({ appID, resourceID }) => {\n const iframeURL = populateURLwithPWAParams(`${getBaseURL()}/agent/${resourceID}?shrinkToolbar=1`, appID);\n\n return (\n \n \n \n );\n};\n\nexport default AiAgent;\n\nAiAgent.propTypes = {\n appID: string.isRequired,\n resourceID: string.isRequired\n};\n","import { ITEM_TYPES } from './itemTypes';\n\nexport const nakedItems = [\n ITEM_TYPES.HEADING,\n ITEM_TYPES.PARAGRAPH,\n ITEM_TYPES.DONATION,\n ITEM_TYPES.IMAGE,\n ITEM_TYPES.BUTTON,\n ITEM_TYPES.DIVIDER,\n ITEM_TYPES.WIDGET,\n ITEM_TYPES.PRODUCT_LIST,\n ITEM_TYPES.CONTACT_INFORMATION,\n ITEM_TYPES.LIST\n];\n","import Styled, { css } from 'styled-components';\nimport { nakedItems } from '../../../constants/nakedItems';\nimport { ITEM_TYPES } from '../../../constants/itemTypes';\nimport { alignWrapper, applyAlpha, convertTextAlignment2Flex } from '../../../utils/styleUtils';\n\n/**\n * @Buri TODO Let's discuss specific style injection when we really need it\n * const exampleToSpecificItemStyling = `.title { ... }`;\n */\n\nconst handleHeadingSize = headingSize => {\n switch (headingSize) {\n case 'small':\n return 'font-size: 20px; line-height: 24px; font-weight: 700;';\n case 'large':\n return 'font-size: 28px; line-height: 32px; font-weight: 700;';\n default: // also case 'default'\n return 'font-size: 24px; line-height: 28px; font-weight: 700;';\n }\n};\n\nconst handleHeadingSpacing = headingSize => {\n switch (headingSize) {\n case 'small':\n return 'margin-top: 8px;';\n case 'large':\n return 'margin-top: 4px;';\n default: // also case 'default'\n return 'margin-top: 6px;';\n }\n};\n\nconst limitedItemTypes = [ITEM_TYPES.HEADING, ITEM_TYPES.FORM];\n\nconst ScAppItemWrapper = Styled.div`\n transition: box-shadow .15s;\n text-decoration: none;\n color: ${({ itemFontColor }) => itemFontColor};\n margin: 4px;\n ${({ itemTextAlignment, type }) => type === ITEM_TYPES.IMAGE && css`\n text-align: ${itemTextAlignment}\n `};\n\n ${({ appFontFamily }) => appFontFamily && `\n font-family: ${appFontFamily};\n `};\n\n .withIconItemContent, .withBadgeItemContent {\n display: flex;\n align-items: center;\n flex-grow: 1;\n overflow: hidden;\n ${({ itemTextAlignment }) => alignWrapper(itemTextAlignment)};\n margin: 16px;\n\n ${({ elementSize }) => (elementSize === 'large' && css`\n margin: 20px;\n `)};\n\n .itemContent {\n margin: 0;\n }\n }\n\n .widgetCurtain {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n }\n\n .badge {\n align-self: center;\n flex-shrink: 0;\n\n ${({ itemTextAlignment }) => {\n switch (itemTextAlignment) {\n case 'center':\n return 'align-self: center; margin-top: 8px;';\n default:\n return '';\n }\n }}\n\n @media screen and (max-width: 768px) {\n align-self: center;\n }\n\n @media screen and (max-width: 480px) {\n align-self: unset;\n height: unset;\n margin-top: 8px;\n }\n }\n\n .itemContent {\n display: flex;\n text-align: left;\n flex-grow: 1;\n overflow: hidden;\n flex-direction: column;\n margin: 16px;\n justify-content: center;\n align-items: ${({ itemTextAlignment }) => convertTextAlignment2Flex(itemTextAlignment)};\n text-align: ${({ itemTextAlignment }) => itemTextAlignment};\n\n .title {\n margin: 0;\n padding: 0;\n max-width: 100%;\n font-size: 16px;\n line-height: 20px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n min-width: 30px;\n display: block;\n font-weight: 500;\n\n ${({ type }) => ([ITEM_TYPES.CARD_ITEM, ITEM_TYPES.DOCUMENT, ITEM_TYPES.LINK, ITEM_TYPES.REPORT_LINK, ITEM_TYPES.TABLE_LINK, ITEM_TYPES.SENTBOX_LINK].includes(type)) && css`\n white-space: unset;\n overflow: unset;\n text-overflow: unset;\n word-break: break-word;\n `}\n\n ${({ type }) => (limitedItemTypes.includes(type) ? css`\n white-space: unset;\n overflow: unset;\n text-overflow: unset;\n word-break: break-word;\n ` : '')}\n }\n .title[contenteditable=true] {\n &[placeholder]:empty:before {\n content: attr(placeholder);\n color: ${({ itemFontColor }) => applyAlpha(itemFontColor, 0.7)};\n }\n &:focus-visible {\n outline: none;\n }\n }\n .description {\n color: ${({ itemFontColor }) => applyAlpha(itemFontColor, 0.7)};\n outline: none;\n margin-top: 6px;\n font-size: 14px;\n line-height: 18px;\n font-weight: 400;\n word-break: break-word;\n min-width: 30px;\n white-space: unset;\n }\n\n ${({ elementSize }) => (elementSize === 'large' && css`\n .title {\n font-size: 18px;\n }\n\n .description {\n font-size: 16px;\n }\n `)};\n\n ul {\n list-style: disc outside;\n padding-left: 40px;\n\n & > li {\n list-style: unset;\n margin-top: unset;\n }\n }\n\n ol {\n padding-inline-start: 40px;\n\n & > li {\n list-style: unset;\n margin-top: unset;\n }\n }\n\n .imageElementImg {\n max-width: 100%;\n max-height: fit-content;\n width: ${({ width }) => width}px;\n ${({ width, height }) => css` aspect-ratio: ${width}/${height}; `}\n }\n }\n\n ${({\n type,\n itemBgColor,\n itemBorderColor,\n itemBgURL,\n headingSize,\n isPresentationItem\n }) => {\n switch (true) {\n case nakedItems.includes(type) || isPresentationItem:\n return css`\n .itemContent {\n${\n [ITEM_TYPES.HEADING, ITEM_TYPES.DONATION].includes(type)\n ? css`.title { ${handleHeadingSize(headingSize)} }\n .description { ${handleHeadingSpacing(headingSize)}}\n justify-content: flex-end;`\n : ''\n}\n\n//Paragraph Item spesific styles on ScParagraphItem\n margin: 0;\n }\n `;\n\n default:\n return css`\n border: 1px solid ${itemBorderColor};\n border-radius: 4px;\n\n ${itemBgURL ? `\n background: url(\"${itemBgURL}\") #0000004d;\n background-position: center;\n background-repeat: no-repeat;\n background-size: cover;\n background-blend-mode: multiply;\n ` : `background-color: ${itemBgColor};`}\n\n &:hover {\n box-shadow: 0 0 0 1px ${itemBorderColor};\n }\n `;\n }\n }}\n`;\n\nexport default ScAppItemWrapper;\n","import React, { useCallback } from 'react';\nimport { func, string } from 'prop-types';\nimport { useDispatch } from 'react-redux';\nimport { Utils } from '@jotforminc/uikit';\nimport ButtonItem from '../../../components/Items/ButtonItem';\nimport { BUTTON_ROLE_TYPES } from '../../Builder/components/HomePage/RightPanel/ButtonActions/buttonRoleTypes';\nimport * as ACTION_CREATORS from '../../../store/actionCreators';\nimport ActionHelper from '../../../utils/ActionsHelper';\nimport { ITEM_TYPES } from '../../../constants/itemTypes';\n\nconst InAppButtonItem = ({\n id, buttonRole, buttonValue, onFormViewClick, onShareAppClick, ...rest\n}) => {\n const dispatch = useDispatch();\n const ButtonActionHelper = ActionHelper.createComponent(ITEM_TYPES.BUTTON);\n const handleClick = useCallback(() => {\n dispatch(ACTION_CREATORS.trackEventAction({ action: 'ButtonItemClicked', target: { itemID: id } }));\n\n ButtonActionHelper.dispatchAction(\n buttonRole,\n {\n id,\n buttonRole,\n value: buttonValue,\n onFormViewClick,\n onShareAppClick,\n dispatch\n }\n );\n }, [buttonRole, buttonValue]);\n\n const handleEnterPressed = useCallback(e => Utils.isPressedKeyEnter(e) && handleClick(), [handleClick]);\n\n const TitleRenderer = ({ children, ...others }) => { // eslint-disable-line react/prop-types\n const { defaultValue } = others;\n return (\n \n {children}\n
\n );\n };\n\n return (\n \n );\n};\n\nInAppButtonItem.propTypes = {\n id: string.isRequired,\n buttonRole: string,\n buttonValue: string,\n onFormViewClick: func,\n onShareAppClick: func\n};\n\nInAppButtonItem.defaultProps = {\n buttonRole: BUTTON_ROLE_TYPES.LINK,\n buttonValue: '',\n onFormViewClick: f => f,\n onShareAppClick: f => f\n};\n\nexport default InAppButtonItem;\n","import React from 'react';\nimport {\n arrayOf, number, oneOfType, shape, string\n} from 'prop-types';\nimport { Button } from '@jotforminc/magnet';\n\nconst CtxMenuItems = ({ formID, items }) => {\n return items.map(({\n key, handlerFn, Icon, text, isDisabled\n }) => { // texts are already translated\n const ariaLabel = isDisabled ? `${text}-notClickable` : text;\n return (\n
  • \n {\n e.stopPropagation();\n return !isDisabled && handlerFn(formID, true);\n }}\n data-testid={`ctx_${key}`}\n aria-label={ariaLabel}\n startIcon={Icon}\n disabled={isDisabled}\n colorStyle='secondary'\n variant='ghost'\n className='justify-start'\n fullWidth\n >\n {text}\n \n
  • \n );\n });\n};\n\nCtxMenuItems.propTypes = {\n formID: oneOfType([string, number]).isRequired,\n items: arrayOf(shape({}))\n};\n\nCtxMenuItems.defaultProps = {\n items: []\n};\n\nexport default CtxMenuItems;\n","import Styled from 'styled-components';\n\nconst ScArrow = Styled.div`\n &, &:before{\n position: absolute;\n width: 10px;\n height: 10px;\n z-index: -1;\n }\n\n &:before{\n content: '';\n transform: rotate(45deg);\n background-color: #fff;\n box-shadow: 0 0 9px 0 rgba(0, 0, 0, 0.16);\n border: 1px solid #d8dae9;\n }\n`;\n\nexport default ScArrow;\n","import Styled, { css } from 'styled-components';\n\nconst ScFormItemWrapper = Styled.div`\n position: relative;\n\n ${({ isEmbeddedForm }) => (isEmbeddedForm ? css`\n & ~ iframe {\n border: none !important;\n border-top: 1px solid #D3DCEF !important;\n }\n\n display: flex;\n\n button.threeDots {\n position: static !important;\n transform: none !important;\n align-self: center !important; \n }\n `\n : css`\n `)}\n\n button.formItemWrapperButton {\n display: flex;\n justify-content: space-between;\n align-items: center;\n cursor: pointer;\n transition: .2s all ease;\n margin: 0;\n padding: 0;\n border: none;\n outline: none;\n font-family: inherit;\n background-color: transparent;\n width: 100%;\n color: inherit;\n\n ${({ isEmbeddedForm }) => (isEmbeddedForm ? css`\n .itemContent {\n margin: 0;\n min-height: unset;\n\n .description {\n margin: 14px;\n }\n }\n\n .withBadgeItemContent {\n margin: 0;\n\n .badge {\n margin: 8px;\n }\n }\n `\n : '')}\n }\n\n button.threeDots {\n position: absolute;\n top: 50%;\n right: 0;\n transform: translateY(-50%);\n display: inline-flex;\n justify-content: center;\n align-items: center;\n height: 44px;\n width: 44px;\n cursor: pointer;\n margin: 0;\n padding: 0;\n border: none;\n outline: none;\n font-family: inherit;\n color: inherit;\n background-color: transparent;\n color: ${({ itemFontColor }) => itemFontColor};\n }\n\n // Overriding AppItemWrapper styles which is not cool.\n .hasThreeDots {\n .withIconItemContent, .itemContent, .withBadgeItemContent {\n margin-right: 44px;\n }\n\n .withIconItemContent, .withBadgeItemContent {\n .itemContent {\n margin: 0;\n }\n }\n }\n\n @media screen and (max-width: 480px) {\n button.threeDots {\n ${({ isEmbeddedForm }) => (isEmbeddedForm ? css`\n display: block;\n `\n : css`\n display: none;\n `)}\n }\n\n .hasThreeDots {\n .withIconItemContent, .itemContent, .withBadgeItemContent {\n margin: 16px;\n }\n\n .withIconItemContent, .withBadgeItemContent {\n .itemContent {\n margin: 0;\n }\n }\n }\n }\n`;\n\nexport default ScFormItemWrapper;\n","import Styled from 'styled-components';\nimport { mainFont } from '../../../../styles/global';\n\nconst ScInlineCtxMenu = Styled.div`\n display: flex;\n align-items: center;\n font-family: ${mainFont};\n\n div[data-popper-placement^='top'] > div[data-popper-arrow=\"true\"] {\n bottom: -5px;\n }\n div[data-popper-placement^='bottom'] > div[data-popper-arrow=\"true\"] {\n top: -5px;\n }\n div[data-popper-placement^='left'] > div[data-popper-arrow=\"true\"] {\n right: -5px;\n }\n div[data-popper-placement^='right'] > div[data-popper-arrow=\"true\"] {\n left: -5px;\n }\n\n && li {\n margin-bottom: 0;\n &:not(:first-child) {\n margin-top: 0;\n }\n }\n`;\nexport default ScInlineCtxMenu;\n","import React, { forwardRef } from 'react';\nimport {\n arrayOf, number, oneOfType, shape, string\n} from 'prop-types';\nimport { Popover } from '@jotforminc/uikit';\n\nimport ScArrow from './ScArrow';\nimport CtxMenuItems from '../../CtxMenuItems';\n\nconst InlineCtxMenu = forwardRef(({\n popoverTargetRef, formID, items\n}, ref) => (\n \n \n
      \n \n
    \n \n));\n\nInlineCtxMenu.propTypes = {\n popoverTargetRef: shape({}).isRequired,\n formID: oneOfType([string, number]).isRequired,\n items: arrayOf(shape({}))\n};\n\nInlineCtxMenu.defaultProps = {\n items: []\n};\n\nexport default InlineCtxMenu;\n","import React, { useRef, useMemo } from 'react';\nimport {\n arrayOf,\n bool,\n func, number, oneOfType, shape, string\n} from 'prop-types';\nimport { Hooks } from '@jotforminc/uikit';\nimport { IconEllipsisVertical } from '@jotforminc/svg-icons';\nimport { ItemVisualDefaultProps, ItemVisualPropTypes } from '../../../constants/propTypes';\nimport ScInlineCtxMenu from './InlineCtxMenu/ScInlineCtxMenu';\nimport ScFormItemWrapper from './ScFormItemWrapper';\nimport InlineCtxMenu from './InlineCtxMenu';\nimport FormItem from '../../../components/Items/FormItem';\nimport Button from '../../../components/Button';\nimport { checkMobilePhone, isYes } from '../../../utils';\nimport { FEATURE_NAMES } from '../../../constants/features';\nimport { isFeatureEnabled } from '../../../utils/features/helper';\nimport EmbeddedForm from '../../../components/EmbeddedForm';\nimport { useRequiredBadge } from '../../../utils/hooks';\n\nconst InAppFormItem = ({\n id,\n onClick,\n hasThreeDots,\n ctxMenuItems,\n timeZone,\n appLoginable, userLoggedIn,\n ...itemProps\n}) => {\n const isMobilePhone = checkMobilePhone();\n const formItemWrapperRef = useRef();\n const menuContainerRef = useRef();\n const threeDotsRef = useRef();\n\n const [isCtxMenuOpened, setCtxMenuOpened] = Hooks.useClickOutsideState(false, [formItemWrapperRef, menuContainerRef]);\n\n const handle3DotsClick = () => {\n if (hasThreeDots && !isMobilePhone) {\n setCtxMenuOpened(true);\n return;\n }\n onClick(id); // let the parent component handle it's own gig.\n };\n\n const handleFormItemClick = () => onClick(id);\n\n const threeDots = useMemo(() => {\n return hasThreeDots && (\n \n \n \n );\n }, [hasThreeDots]);\n\n const inlineCtxMenu = useMemo(() => {\n return hasThreeDots && isCtxMenuOpened && (\n \n \n \n );\n }, [hasThreeDots, isCtxMenuOpened]);\n\n const {\n itemFontColor, embeddedForm\n } = itemProps;\n\n const badge = useRequiredBadge(id);\n\n const isEmbeddedForm = isYes(embeddedForm);\n\n const formElement = useMemo(() => {\n return (\n \n \n {threeDots}\n {inlineCtxMenu}\n \n );\n }, [itemFontColor, handleFormItemClick, hasThreeDots, itemProps, isEmbeddedForm]);\n\n return isFeatureEnabled(FEATURE_NAMES.EmbeddedForm) && isEmbeddedForm ? (\n <>\n {formElement}\n \n \n ) : formElement;\n};\n\nInAppFormItem.propTypes = {\n id: oneOfType([string, number]).isRequired,\n title: string,\n onClick: func,\n onViewForm: func,\n description: string,\n hasThreeDots: bool,\n ctxMenuItems: arrayOf(shape({})),\n ...ItemVisualPropTypes\n};\n\nInAppFormItem.defaultProps = {\n title: '',\n description: '',\n onClick: f => f,\n onViewForm: f => f,\n isUserLoggedIn: false,\n ctxMenuItems: [],\n hasThreeDots: false,\n ...ItemVisualDefaultProps\n};\n\nexport default InAppFormItem;\n","import Styled from 'styled-components';\n\nconst ScItemContainer = Styled.ul`\n align-self: stretch;\n text-align: left;\n width: 100%;\n display: flex;\n flex-wrap: wrap;\n justify-content: space-between;\n .shrink {\n width: calc(50% - 3px);\n @media screen and (max-width: 768px) {\n .withIconItemContent {\n flex-direction: column;\n > div:first-child,\n .link-thumnail-wrapper {\n margin: 0 0 8px 0;\n align-self: center;\n }\n .itemContent {\n align-items: center;\n text-align: center;\n }\n }\n }\n }\n li {\n width: 100%;\n margin-bottom: 8px;\n }\n .appItem {\n ${({ forApp }) => forApp && `\n .description:empty {\n display: none;\n }\n `}\n }\n .appItem[type=\"CARD_ITEM\"] {\n box-shadow: 0px 0px 0px 2px transparent;\n\n &:has(.horizontal .start-element-container) .itemContent {\n margin: 8px;\n }\n &:has(.vertical .start-element-container) .itemContent {\n margin: 0px;\n }\n &:has(.vertical .start-element-container.icon) .itemContent, \n &:has(.vertical .start-element-container.avatar) .itemContent {\n margin: 8px;\n }\n &:not(:has(.start-element-container)) .itemContent {\n margin: 8px;\n }\n }\n`;\n\nexport default ScItemContainer;\n","/* eslint-disable react/prop-types */\n/* eslint-disable camelcase */\nimport React from 'react';\nimport cn from 'classnames';\nimport { useRequiredBadge } from '../../../utils/hooks';\nimport Button from '../../../components/Button';\nimport SimpleItem from '../../../components/Items/SimpleItem/SimpleItem';\nimport ScFormItemWrapper from '../FormItem/ScFormItemWrapper';\n\nconst SignItem = props => {\n const {\n id, title, onClick, resourceID, hasThreeDots\n } = props;\n\n const badge = useRequiredBadge(id);\n\n return (\n \n \n \n );\n};\n\nexport default SignItem;\n","import Styled from 'styled-components';\n\nexport const WidgetWrapper = Styled.div`\n width: 100%;\n\n [data-component=\"widget-field\"] { display: flex; }\n\n iframe {\n max-width: 100% !important;\n width: 100% !important;\n } \n`;\n","import { ITEM_TYPES } from '../constants/itemTypes';\n\nconst isListItem = item => {\n if (!item) return false;\n return item.type === ITEM_TYPES.CARD_ITEM;\n};\n\nexport const mutateItems = items => {\n const mutatedItems = items.map((item, indx) => {\n if (!isListItem(item)) {\n return item;\n }\n\n const hasTrailingItem = isListItem(items[indx - 1]);\n const hasLeadingItem = isListItem(items[indx + 1]);\n\n return {\n ...item,\n hasAdjacentListItem: (hasTrailingItem || hasLeadingItem),\n firstAdjacentListItem: (!hasTrailingItem && hasLeadingItem),\n lastAdjacentListItem: (hasTrailingItem && !hasLeadingItem)\n };\n });\n return mutatedItems;\n};\n","import React, { createRef, useImperativeHandle } from 'react';\nimport {\n elementType, string, func, bool\n} from 'prop-types';\nimport Styled from 'styled-components';\nimport { Utils } from '@jotforminc/uikit';\n\nconst ScInlineEditor = Styled.div`\n user-select: auto;\n`;\n\nconst InlineEditor = React.forwardRef(({\n defaultValue, onChange, onBlur, Renderer, contentEditable, isAllowedEmpty, ...rest\n}, ref) => {\n const contentEditableRef = createRef();\n\n const handleKeyDown = event => {\n event.nativeEvent.stopPropagation();\n event.nativeEvent.stopImmediatePropagation();\n event.stopPropagation();\n\n switch (true) {\n case Utils.isPressedKeyEnter(event): {\n contentEditableRef.current.blur();\n break;\n }\n case Utils.isPressedKeyEscape(event): {\n contentEditableRef.current.textContent = defaultValue;\n contentEditableRef.current.blur();\n break;\n }\n default:\n break;\n }\n };\n\n const handleBlur = e => {\n if (!isAllowedEmpty && !contentEditableRef.current.textContent?.trim()) {\n contentEditableRef.current.textContent = defaultValue;\n contentEditableRef.current.blur();\n return;\n }\n onBlur(e);\n onChange(contentEditableRef.current.textContent);\n };\n\n useImperativeHandle(ref, () => ({\n contentEditableRef\n }));\n\n return (\n \n {defaultValue}\n \n\n );\n});\n\nInlineEditor.propTypes = {\n Renderer: elementType,\n defaultValue: string.isRequired,\n onChange: func.isRequired,\n onBlur: func,\n contentEditable: bool,\n isAllowedEmpty: bool\n};\n\nInlineEditor.defaultProps = {\n Renderer: ScInlineEditor,\n onBlur: x => x,\n contentEditable: true,\n isAllowedEmpty: true\n};\n\nexport default InlineEditor;\n","export const COUNTRIES = [\n 'Afghanistan',\n 'Albania',\n 'Algeria',\n 'American Samoa',\n 'Andorra',\n 'Angola',\n 'Anguilla',\n 'Antigua and Barbuda',\n 'Argentina',\n 'Armenia',\n 'Aruba',\n 'Australia',\n 'Austria',\n 'Azerbaijan',\n 'The Bahamas',\n 'Bahrain',\n 'Bangladesh',\n 'Barbados',\n 'Belarus',\n 'Belgium',\n 'Belize',\n 'Benin',\n 'Bermuda',\n 'Bhutan',\n 'Bolivia',\n 'Bosnia and Herzegovina',\n 'Botswana',\n 'Brazil',\n 'Brunei',\n 'Bulgaria',\n 'Burkina Faso',\n 'Burundi',\n 'Cambodia',\n 'Cameroon',\n 'Canada',\n 'Cape Verde',\n 'Cayman Islands',\n 'Central African Republic',\n 'Chad',\n 'Chile',\n 'China',\n 'Christmas Island',\n 'Cocos (Keeling) Islands',\n 'Colombia',\n 'Comoros',\n 'Congo',\n 'Cook Islands',\n 'Costa Rica',\n 'Cote d\\'Ivoire',\n 'Croatia',\n 'Cuba',\n 'Curaçao',\n 'Cyprus',\n 'Czech Republic',\n 'Democratic Republic of the Congo',\n 'Denmark',\n 'Djibouti',\n 'Dominica',\n 'Dominican Republic',\n 'Ecuador',\n 'Egypt',\n 'El Salvador',\n 'Equatorial Guinea',\n 'Eritrea',\n 'Estonia',\n 'Ethiopia',\n 'Falkland Islands',\n 'Faroe Islands',\n 'Fiji',\n 'Finland',\n 'France',\n 'French Polynesia',\n 'Gabon',\n 'The Gambia',\n 'Georgia',\n 'Germany',\n 'Ghana',\n 'Gibraltar',\n 'Greece',\n 'Greenland',\n 'Grenada',\n 'Guadeloupe',\n 'Guam',\n 'Guatemala',\n 'Guernsey',\n 'Guinea',\n 'Guinea-Bissau',\n 'Guyana',\n 'Haiti',\n 'Honduras',\n 'Hong Kong',\n 'Hungary',\n 'Iceland',\n 'India',\n 'Indonesia',\n 'Iran',\n 'Iraq',\n 'Ireland',\n 'Israel',\n 'Italy',\n 'Jamaica',\n 'Japan',\n 'Jersey',\n 'Jordan',\n 'Kazakhstan',\n 'Kenya',\n 'Kiribati',\n 'North Korea',\n 'South Korea',\n 'Kosovo',\n 'Kuwait',\n 'Kyrgyzstan',\n 'Laos',\n 'Latvia',\n 'Lebanon',\n 'Lesotho',\n 'Liberia',\n 'Libya',\n 'Liechtenstein',\n 'Lithuania',\n 'Luxembourg',\n 'Macau',\n 'Macedonia',\n 'Madagascar',\n 'Malawi',\n 'Malaysia',\n 'Maldives',\n 'Mali',\n 'Malta',\n 'Marshall Islands',\n 'Martinique',\n 'Mauritania',\n 'Mauritius',\n 'Mayotte',\n 'Mexico',\n 'Micronesia',\n 'Moldova',\n 'Monaco',\n 'Mongolia',\n 'Montenegro',\n 'Montserrat',\n 'Morocco',\n 'Mozambique',\n 'Myanmar',\n 'Nagorno-Karabakh',\n 'Namibia',\n 'Nauru',\n 'Nepal',\n 'Netherlands',\n 'Netherlands Antilles',\n 'New Caledonia',\n 'New Zealand',\n 'Nicaragua',\n 'Niger',\n 'Nigeria',\n 'Niue',\n 'Norfolk Island',\n 'Turkish Republic of Northern Cyprus',\n 'Northern Mariana',\n 'Norway',\n 'Oman',\n 'Pakistan',\n 'Palau',\n 'Palestine',\n 'Panama',\n 'Papua New Guinea',\n 'Paraguay',\n 'Peru',\n 'Philippines',\n 'Pitcairn Islands',\n 'Poland',\n 'Portugal',\n 'Puerto Rico',\n 'Qatar',\n 'Republic of the Congo',\n 'Romania',\n 'Russia',\n 'Rwanda',\n 'Saint Barthelemy',\n 'Saint Helena',\n 'Saint Kitts and Nevis',\n 'Saint Lucia',\n 'Saint Martin',\n 'Saint Pierre and Miquelon',\n 'Saint Vincent and the Grenadines',\n 'Samoa',\n 'San Marino',\n 'Sao Tome and Principe',\n 'Saudi Arabia',\n 'Senegal',\n 'Serbia',\n 'Seychelles',\n 'Sierra Leone',\n 'Singapore',\n 'Slovakia',\n 'Slovenia',\n 'Solomon Islands',\n 'Somalia',\n 'Somaliland',\n 'South Africa',\n 'South Ossetia',\n 'South Sudan',\n 'Spain',\n 'Sri Lanka',\n 'Sudan',\n 'Suriname',\n 'Svalbard',\n 'eSwatini',\n 'Sweden',\n 'Switzerland',\n 'Syria',\n 'Taiwan',\n 'Tajikistan',\n 'Tanzania',\n 'Thailand',\n 'Timor-Leste',\n 'Togo',\n 'Tokelau',\n 'Tonga',\n 'Transnistria Pridnestrovie',\n 'Trinidad and Tobago',\n 'Tristan da Cunha',\n 'Tunisia',\n 'Turkey',\n 'Turkmenistan',\n 'Turks and Caicos Islands',\n 'Tuvalu',\n 'Uganda',\n 'Ukraine',\n 'United Arab Emirates',\n 'United Kingdom',\n 'United States',\n 'Uruguay',\n 'Uzbekistan',\n 'Vanuatu',\n 'Vatican City',\n 'Venezuela',\n 'Vietnam',\n 'British Virgin Islands',\n 'Isle of Man',\n 'US Virgin Islands',\n 'Wallis and Futuna',\n 'Western Sahara',\n 'Yemen',\n 'Zambia',\n 'Zimbabwe'];\n","export const DAYS = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];\n","export const GENDERS = ['Male', 'Female', 'N/A'];\n","export const MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];\n","export const WIDGET_NAMES = {\n '533946093c1ad0c45d000070': 'ConfigurableList',\n '5294d72eb1dd20af46000006': 'Passage Test',\n '52987bda949b78ac2b000009': 'Infinite list',\n '5321bc1dec233a2e15000006': 'Spreadsheet',\n '5299b58aba554b7e24000007': 'Matrix Dynamique',\n '53b2b2b1447f4bec1b000004': 'Narative Field',\n '5bd77a175db736710a00000b': 'Radio button scale',\n '52a4bc26cd5522e81500001e': 'Bmi Calculator',\n '529e18322c0cc6240a000004': 'Body Weight',\n '52961c97e3e5266570000004': 'Checklist Widget',\n '528ee7cf8d5a5fc76a000004': 'Dynamic Textbox',\n '538dddaa976bf61129000004': 'Multiple Text Fields',\n '53201a2d6866be393e000028': 'Dynamic Dropdowns',\n '5295f3aef2426e7969000009': 'Add Options',\n '529058b0ca06414051000011': 'Field Multiplier',\n '5293157eb5ac485477000004': 'Multiple Selection',\n '52970c81b8daa66b03000004': 'Dropdown With Paging',\n '5290397c57a764425100000b': 'Button Checkboxes',\n '529c82a772a985697f000007': 'Checkbox in Dropdown',\n '5329a28886bd958e4c000007': 'MultiSelect Grid',\n '5298b265886815755900001e': 'Visual Multi Select',\n '533426cf4c4b0bf81a000023': 'Sliders with Calculated Result',\n '52943d56dacb3d5320000010': 'Orderable List',\n '528edc96a4de152e2a00001a': 'Dual ListBox',\n '529c8286a75dae5e7f000005': 'Take Photo',\n '533a8c19a3f5fec35d00009a': 'Initials',\n '52900b6557a7644251000004': 'QR Code',\n '535a49d40a05fdff5200002b': 'Draw on Image',\n '5593eb4edc0ffe5e7a000018': 'Dynamic QR Code',\n '5295b800485bd19f5d000005': 'Image Upload Preview',\n '52a02b574b41f8114a000004': 'Image Picker',\n '573ae96be567f40178000011': 'File Uploader by Uploadcare',\n '529cb089728b3bc46f000004': 'Drawing Board',\n '5d493b3b3ecd623d69000045': 'Annotate Image',\n '52948fb29322cd302b00000c': 'Terms & Condition',\n '5295f8da6396ecd66d00000e': 'TinyMCE'\n};\n\nexport const WIDGETS = {\n ConfigurableList: '533946093c1ad0c45d000070',\n PassageTest: '5294d72eb1dd20af46000006',\n InfiniteList: '52987bda949b78ac2b000009',\n Spreadsheet: '5321bc1dec233a2e15000006',\n MatrixDynamique: '5299b58aba554b7e24000007',\n NarativeField: '53b2b2b1447f4bec1b000004',\n RadioButtonScale: '5bd77a175db736710a00000b',\n BmiCalculator: '52a4bc26cd5522e81500001e',\n BodyWeight: '529e18322c0cc6240a000004',\n ChecklistWidget: '52961c97e3e5266570000004',\n DynamicTextbox: '528ee7cf8d5a5fc76a000004',\n MultipleTextFields: '538dddaa976bf61129000004',\n DynamicDropdowns: '53201a2d6866be393e000028',\n AddOptions: '5295f3aef2426e7969000009',\n FieldMultiplier: '529058b0ca06414051000011',\n MultipleSelection: '5293157eb5ac485477000004',\n DropdownWithPaging: '52970c81b8daa66b03000004',\n ButtonCheckboxes: '5290397c57a764425100000b',\n CheckboxInDropdown: '529c82a772a985697f000007',\n MultiSelectGrid: '5329a28886bd958e4c000007',\n VisualMultiSelect: '5298b265886815755900001e',\n SlidersWithCalculatedResult: '533426cf4c4b0bf81a000023',\n OrderableList: '52943d56dacb3d5320000010',\n DualListBox: '528edc96a4de152e2a00001a',\n TakePhoto: '529c8286a75dae5e7f000005',\n Initials: '533a8c19a3f5fec35d00009a',\n QRCode: '52900b6557a7644251000004',\n DrawOnImage: '535a49d40a05fdff5200002b',\n DynamicQRCode: '5593eb4edc0ffe5e7a000018',\n ImageUploadPreview: '5295b800485bd19f5d000005',\n ImagePicker: '52a02b574b41f8114a000004',\n FileUploaderByUploadcare: '573ae96be567f40178000011',\n DrawingBoard: '529cb089728b3bc46f000004',\n AnnotateImage: '5d493b3b3ecd623d69000045',\n SigplusTopaz: '5371caff4775c55f46000020',\n TermsAndCondition: '52948fb29322cd302b00000c',\n TinyMCE: '5295f8da6396ecd66d00000e',\n AdobeSign: '53bfd5c2ec70ec9f25000005',\n NarrativeFields: '5294d72eb1dd20af46000006',\n SmoothSignature: '529467003477f3512000001f',\n DatePicker: '52934dbf3be147110a000030',\n DateTimeSingle: '528eea9eec60d3b530000005',\n ShortScrollableTerms: '52f8550f0019ace53000000b',\n DataGrid: '5297606bfe8fa6bf0d000016',\n TextareaAutosize: '528f290e597910923e000004',\n DatesDifference: '532714968a621dd23e000033',\n FieldConfirmation: '533f59d51a9ff70146000022',\n CheckInCheckOut: '52a1957635fd1d2172000009',\n CodeEditor: '5292ac3a05a7114f7000000f',\n FixedFormat: '529ece4a5e9f2a8d0d000014',\n PhonePicker: '529dde1d1c79f7a47000000d',\n UserContibutedCheckbox: '53ea27a3a122f41c12000043',\n SquireEditor: '549d6dadbd3b15911b000057',\n SliderTimeRange: '52984a3fbcd0197714000011',\n AllStatesAndCities: '5332f3a44c4b0bf81a000005',\n CKEditor: '5295fdda9ab6253f6e000004',\n UserContributedRadioButtons: '53eba61513722c9c2a000019',\n ScrollToTop: '529c802f72a985697f000004',\n Smarty: '55ac891c52ef1852630000bb',\n ProgressBar: '52a8531850e4cbc101000004',\n ReviewBeforeSubmit: '538da19e8f1162765c000011',\n FormSeperators: '54ec34ea0405960f50000004',\n GetFormPageURL: '56095842e855b0bf1b000033',\n UniqueID: '528c8b464b1a424916000004',\n DocuSign: '576e95b157faed3f6e000006',\n FacebookComments: '53ba80d0435e9ce71500000a',\n GoogleAnalytics: '529860b42db548b827000004',\n GetReferrer: '529cceb8cb6ab58725000004',\n Spacer: '528ea7c6a4de152e2a00000b',\n FormTabs: '529ca5f5caf2cd9e58000004',\n HiddenBox: '528b67afddabdf070a000004',\n TimeTracker: '5345402093a2afcc5f000004',\n GetUserAgent: '543ea3eb3066feaa30000036',\n UnfilledFields: '52a846c576fc316f4700001a',\n FilledFields: '52a1fdaf2213aced2b000006',\n Breadcrumbs: '59928996ad70efd97d000318',\n AccessibilityEnhancer: '591bfab2b81b39d90500089b',\n Shuffle: '5407daa93d1ca3c06c000015',\n NoScript: '530b08530c30f5313e000026',\n ChartBeat: '5298a98f886815755900000b',\n MouseStats: '5501387426b5ca0441000061',\n Zuko: '3a8d7c0b3bb275c66088cf14',\n FacebookPixel: '6f593662fe9211a88d996506',\n AddToHomeScreen: '53bd24bf6fd2f85c53000004',\n TextResizer: '54bb4df81957a5866500001d',\n StatCounter: '529899cb81e567424f000004',\n AnimatedHeading: '529d9a5c4b5cd3fd5a000005',\n PDFEmbedder: '529641beb15ce2ac76000007'\n};\n","export const HiddenQuestionTypes = ['control_helper', 'control_hidden', 'control_autoincrement'];\n\nexport const BLOT_REGEX = /\\{([a-z0-9]*?-[a-z0-9]*?)\\}/gi;\nexport const TIMESTAMP_OF_2019 = 1546300000000;\n\nexport const paymentTypeWithShipping = [\n 'control_paypal',\n 'control_payment',\n 'control_stripe',\n 'control_stripeCheckout',\n 'control_stripeACH',\n 'control_stripeACHManual',\n 'control_authnet',\n 'control_bluepay',\n 'control_bluesnap',\n 'control_braintree',\n 'control_chargify',\n 'control_cardconnect',\n 'control_echeck',\n 'control_eway',\n 'control_2co',\n 'control_paypalpro',\n 'control_paypalcomplete',\n 'control_cybersource',\n 'control_paymentwall',\n 'control_paypalexpress',\n 'control_worldpay',\n 'control_dwolla',\n 'control_square',\n 'control_firstdata',\n 'control_paypalInvoicing',\n 'control_payjunction',\n 'control_wepay',\n 'control_worldpayus',\n 'control_payu',\n 'control_pagseguro',\n 'control_moneris',\n 'control_mollie',\n 'control_sofort',\n 'control_sensepass',\n 'control_paysafe',\n 'control_iyzico',\n 'control_skrill',\n 'control_gocardless',\n 'control_paypalSPB',\n 'control_payfast'\n];\n\nexport const paymentTypeWithTax = [\n 'control_payment',\n 'control_paypal',\n 'control_authnet',\n 'control_echeck',\n 'control_eway',\n 'control_stripe',\n 'control_stripeCheckout',\n 'control_stripeACH',\n 'control_stripeACHManual',\n 'control_paypalpro',\n 'control_paypalcomplete',\n 'control_cybersource',\n 'control_2co',\n 'control_paypalexpress',\n 'control_braintree',\n 'control_dwolla',\n 'control_square',\n 'control_bluepay',\n 'control_bluesnap',\n 'control_firstdata',\n 'control_paypalInvoicing',\n 'control_payjunction',\n 'control_paymentwall',\n 'control_wepay',\n 'control_worldpayus',\n 'control_chargify',\n 'control_cardconnect',\n 'control_payu',\n 'control_payuMoney',\n 'control_pagseguro',\n 'control_moneris',\n 'control_mollie',\n 'control_sofort',\n 'control_sensepass',\n 'control_skrill',\n 'control_paysafe',\n 'control_iyzico',\n 'control_gocardless',\n 'control_paypalSPB',\n 'control_payfast'\n];\n","import { capitalize, fixUTF } from '@jotforminc/utils';\nimport { unsupportedDecimalCurrencies } from '@jotforminc/payment-constants';\nimport { TIMESTAMP_OF_2019 } from './constants';\n\nif (global.Element && !global.Element.prototype.matches) {\n global.Element.prototype.matches = global.Element.prototype.matchesSelector\n || global.Element.prototype.mozMatchesSelector\n || global.Element.prototype.msMatchesSelector\n || global.Element.prototype.oMatchesSelector\n || global.Element.prototype.webkitMatchesSelector\n || function matchesFN(s) {\n var matches = (this.document || this.ownerDocument).querySelectorAll(s);\n var i = matches.length;\n while (--i >= 0 && matches.item(i) !== this) {\n // eslist-disable-next-line\n }\n return i > -1;\n };\n}\n\nexport function htmlDecode(text, quoteS) {\n let quoteStyle = quoteS;\n let string = text ?? '';\n let optTemp = 0;\n let i = 0;\n let noquotes = false;\n if (typeof quoteStyle === 'undefined') {\n quoteStyle = 2;\n }\n string = string.toString().replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n const OPTS = {\n ENT_NOQUOTES: 0,\n ENT_HTML_QUOTE_SINGLE: 1,\n ENT_HTML_QUOTE_DOUBLE: 2,\n ENT_COMPAT: 2,\n ENT_QUOTES: 3,\n ENT_IGNORE: 4\n };\n if (quoteStyle === 0) {\n noquotes = true;\n }\n if (typeof quoteStyle !== 'number') {\n quoteStyle = [].concat(quoteStyle);\n for (i = 0; i < quoteStyle.length; i++) {\n if (OPTS[quoteStyle[i]] === 0) {\n noquotes = true;\n } else if (OPTS[quoteStyle[i]]) {\n optTemp = optTemp || OPTS[quoteStyle[i]];\n }\n }\n quoteStyle = optTemp;\n }\n if (quoteStyle && OPTS.ENT_HTML_QUOTE_SINGLE) {\n string = string.replace(/�*39;/g, \"'\").replace(/'/g, \"'\");\n }\n if (!noquotes) {\n string = string.replace(/"/g, '\"');\n string = string.replace(/&quot;/g, '\"');\n }\n\n string = string.replace(/&/g, '&');\n\n return string;\n}\n\nexport const isOldBlotId = id => Number(id) > TIMESTAMP_OF_2019;\nexport const setParsedId = ([x, y]) => (isOldBlotId(x) ? ({ id: x, label: y }) : ({ id: y, label: x }));\nexport const parseBlotId = (blotId = '') => setParsedId(blotId.split('-'));\nexport const setBlotId = id => label => (isOldBlotId(id) ? `${id}-${label}` : `${label}-${id}`);\n\nexport const getBlotOptions = (field) => {\n if (field.type === 'control_dropdown') {\n return [field.options.reduce((acc, o) => ({\n type: o.type,\n id: setBlotId(field.id)(o.type),\n default: field.label,\n options: [...(acc?.options || [acc.label]), o.label]\n }))];\n }\n\n return field.options || [];\n};\n\nexport function debounce(func, wait, immediate) {\n let timeout;\n return function() {\n const context = this, args = arguments;\n const later = function() {\n timeout = null;\n if (!immediate) func.apply(context, args);\n };\n const callNow = immediate && !timeout;\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n if (callNow) func.apply(context, args);\n };\n}\n\nexport const classNames = (obj) => {\n return Object.keys(obj).reduce((acc, key) => {\n if (!obj[key]) return acc;\n return [...acc, key];\n }, []).join(' ');\n};\n\nexport const assignObject = (...objects) => {\n return objects.reduce((acc, obj) => {\n Object.keys(obj).forEach((key) => {\n acc[key] = obj[key];\n });\n\n return acc;\n }, {});\n};\n\nexport const fillArray = (arr, value) => {\n const newArr = [];\n for (let i = 0; i < arr.length; i++) {\n newArr.push(value);\n }\n return newArr;\n};\n\nexport const getJSON = (url) => {\n if (typeof Ajax !== 'undefined') {\n return new Promise((resolve) => {\n new Ajax.Request(url, {\n evalJSON: 'force',\n method: 'GET',\n onComplete: response => resolve(response.responseJSON)\n });\n })\n }\n return fetch(url).then(res => res.json());\n};\n\nexport function getCDN() {\n return '/';\n}\n\nexport function getCurrentTime(prop, currentHour, currentMin, currentHourRange, currentMinRange) {\n const date = new Date();\n\n let hour = !currentHour ? date.getHours() : currentHour;\n let min = !currentMin ? date.getMinutes() : currentMin;\n let hourRange = !currentHourRange ? hour : currentHourRange;\n let minRange = !currentMin ? min : currentMinRange;\n\n const step = (prop.step.value) ? prop.step.value : 10;\n\n const getTime = function (timeHour, timeMinute) {\n let currentAmpm = '';\n\n let h = Number(timeHour);\n let m = Number(timeMinute);\n\n let twentyFour = true;\n if (prop.timeFormat.value === 'AM/PM') {\n twentyFour = false;\n currentAmpm = (h > 11) ? 'PM' : 'AM';\n h = (h > 12) ? h - 12 : h;\n h = (h === 0) ? 12 : h;\n }\n\n m = Math.round(m / step) * step;\n m = addZeros(m, 2);\n if (m >= 60) { // ntw roll over to next h/day\n m = '00';\n h++;\n if (twentyFour) {\n if (h === 24) h = 0;\n } else if (currentAmpm === 'AM' && h === 12) currentAmpm = 'PM';\n else if (currentAmpm === 'PM' && h === 12) currentAmpm = 'AM';\n else if (h === 13) h = 1;\n }\n return { hour: h.toString(), min: m, currentAmpm };\n };\n\n const fromD = getTime(hour, min);\n hour = prop.timeFormat.value === 'AM/PM' ? fromD.hour : addZeros(fromD.hour, 2);\n min = fromD.min;\n const currentAmpm = fromD.currentAmpm;\n\n const to = getTime(hourRange, minRange);\n hourRange = to.hour;\n minRange = to.min;\n const currentAmpmRange = to.currentAmpm;\n\n const time = {\n limit: prop.timeFormat.value === 'AM/PM' ? 12 : 23,\n start: prop.timeFormat.value === 'AM/PM' ? 1 : 0,\n step,\n\n hour,\n min,\n currentAmpm,\n\n hourRange,\n minRange,\n currentAmpmRange\n };\n\n return time;\n}\n\nexport function getDefaultTime(prop) {\n if (!prop.defaultTime.value || prop.defaultTime.value === 'none') {\n return '';\n }\n if (prop.defaultTime.value.indexOf('custom_') > -1) {\n let toCustomHour = false;\n let toCustomMinute = false;\n let fromD = prop.defaultTime.value.split('custom_')[1];\n // time range\n if (fromD.indexOf('-') > -1) {\n const range = fromD.split('-');\n const to = range[1];\n fromD = range[0];\n const toSplit = to.split(':');\n toCustomHour = toSplit[0];\n toCustomMinute = toSplit[1];\n }\n\n return getCurrentTime(prop, fromD.split(':')[0], fromD.split(':')[1], toCustomHour, toCustomMinute);\n }\n\n return getCurrentTime(prop);\n}\n\nexport function newlineToEntities(string) {\n return string.toString().replace(/\\n\\r?/g, ' ');\n}\n\n\n/**\n* Build parameters and settings for the widget\n*/\nexport function buildParams(_params, fieldNames, prop) {\n for (let i = 0; i < fieldNames.length; i++) {\n const key = fieldNames[i];\n if (key === '') { continue; }\n const el = prop[key];\n if (el && el.value) {\n let propvalue = (typeof el.value === 'string') ? htmlDecode(el.value) : el.value;\n\n // from here lets check chunks - lets include them\n if ('paramChunks' in prop && prop.paramChunks.value) {\n const chunkProps = prop.paramChunks.value;\n /* eslint guard-for-in:0 */\n for (const chunkKey in chunkProps) {\n const chunkProp = chunkProps[chunkKey];\n // if current key matches the mainpart\n // it means we have a chunks to merge\n if (chunkKey === key && chunkProp.parts) {\n for (let y = 0; y < chunkProp.parts.length; y++) {\n const partnameProp = chunkProp.parts[y];\n // if part name is registered as prop then concatenate to final value\n if (prop[partnameProp] && prop[partnameProp].value) {\n propvalue += prop[partnameProp].value;\n }\n }\n }\n }\n /* eslint guard-for-in:1 */\n }\n\n // push the data to settings array\n _params.push({\n name: key,\n value: propvalue\n });\n\n // avoid memory leak\n propvalue = null;\n }\n }\n return _params;\n}\nexport function fixNumbers(number) {\n if (typeof number === 'string') {\n return number.replace(/\\D/gim, '');\n }\n return number;\n}\n\nexport function numberFormat(number, decimals, decPoint, thousandsSep) {\n let n = number;\n let prec = decimals;\n\n const toFixedFix = function (num, dec) {\n const k = Math.pow(10, dec);\n return (Math.round(num * k) / k).toString();\n };\n\n n = !isFinite(+n) ? 0 : +n;\n prec = !isFinite(+prec) ? 0 : Math.abs(prec);\n const sep = (typeof thousandsSep === 'undefined') ? ',' : thousandsSep;\n const dec = (typeof decPoint === 'undefined') ? '.' : decPoint;\n let s = (prec > 0) ? toFixedFix(n, prec) : toFixedFix(Math.round(n), prec);\n const abs = toFixedFix(Math.abs(n), prec);\n let _;\n let i;\n\n if (abs >= 1000) {\n _ = abs.split(/\\D/);\n i = _[0].length % 3 || 3;\n _[0] = s.slice(0, i + (n < 0)) + _[0].slice(i).replace(/(\\d{3})/g, `${sep}$1`);\n s = _.join(dec);\n } else {\n s = s.replace('.', dec);\n }\n\n if (s.indexOf(dec) === -1 && prec > 1) {\n const preca = [];\n preca[prec - 1] = undefined;\n s += `${dec + preca.join(0)}0`;\n } else if (s.indexOf(dec) === s.length - 2 && s.length > 1) { // incorrect: 2.7, correct: 2.70\n s += '0';\n }\n\n return s;\n}\n\n\nexport function formatPrice(priceAmount, currency, priceID, nofree, decimalMark) {\n const curr = !currency ? 'USD' : currency;\n\n const id = priceID || '';\n let amount = priceAmount;\n // decimal places\n const dec = unsupportedDecimalCurrencies.indexOf(curr) > -1 ? 0 : 2;\n\n if (parseFloat(amount) === 0 && nofree !== true) {\n amount = 'Free'.locale();\n } else {\n const useComma = decimalMark && decimalMark === 'comma';\n amount = numberFormat(amount, dec, (useComma ? ',' : '.'), (useComma ? '.' : ',')); // Format the number for money currency\n }\n let symbol;\n switch (curr) {\n case 'EUR': symbol = ['€', curr]; break;\n case 'GBP': symbol = ['£', curr]; break;\n case 'BRL': symbol = ['R$', '']; break;\n case 'JPY': symbol = ['¥', curr]; break;\n case 'USD': symbol = ['$', '']; break;\n case 'AUD':\n case 'CAD':\n case 'NZD':\n case 'SGD':\n case 'HKD':\n case 'CLP':\n symbol = ['$', curr]; break;\n case 'TRY':\n symbol = ['', 'TL']; break;\n default:\n symbol = ['', curr]; break;\n }\n\n let out;\n // the word 'free' can be in other languages\n // parse and check if it's a number to determine if it's free or not\n if (isNaN(parseInt(amount, 10))) {\n out = ` ${amount} `;\n } else {\n out = `${symbol[0]}${amount} ${symbol[1]}`;\n }\n return out;\n}\n/**\n * Makes formatted text for products. Just like paypal\n * @param {Object} name\n * @param {Object} price\n * @param {Object} curr\n * @param {Object} duration\n * @param {Object} setupfee\n * @param {Object} trial\n * @param {Object} id\n * @param {Object} times (number of subscription payments)\n * @param {Boolean} noPrice\n * @param {Boolean} passive Whether env is form builder or not\n * @param {Boolean} customPrice Whether the item's price is variable/user-defined (for subscriptions only)\n */\nexport function makeProductText(name, price, curr, duration, setupfee, productTrial, id, times, noPrice, passive, customPrice, customPriceSource) {\n let text = '';\n let currDisplay = curr ? curr : undefined;\n\n switch (curr) {\n\n case 'TRY':\n currDisplay = 'TL';\n break;\n\n // case 'USD':\n // currDisplay = '$';\n // break;\n\n default:\n currDisplay = curr;\n break;\n\n }\n\n let fprice = noPrice ? '' : `${formatPrice(price || 0, currDisplay, id || '')}`; // Get formatted price\n let fsetupfee = `${formatPrice(Number(setupfee) || 0, curr, id ? id.replace('price', 'setupfee') : '')}`; // Get calculated and formatted setupfee\n let setuptext = ''; // setupfee text will be here\n const trialText = setupfee > 0 ? fsetupfee : 'Free'.locale();\n const installmentText = '.'; // installmentText placeholder\n\n\n if (customPrice === '1') {\n const readOnly = customPriceSource > 0 || passive;\n\n fprice = ` 0) {\n fprice += ` data-price-source=\"${customPriceSource}\"`;\n }\n\n fprice += `/>${currDisplay}`;\n }\n\n /** re-implement if requested\n *\n if(times && !isNaN(times)) {\n installmentText = times !== '1' ? \", for \" + times + \" installments.\" : \".\";\n }\n **/\n\n let trial;\n if (duration && productTrial && productTrial.toLowerCase() !== 'none' && productTrial !== 'Enabled') { // If trial period is set\n trial = productTrial.locale();\n if (trial === 'One Day') { // Special text for 1 day trial\n text += `${trialText} ${'for the first day then,'.locale()} `;\n } else {\n text += `${trialText} ${'for the first '.locale()}${trial.toLowerCase()}${' then,'.locale()} `;\n }\n }\n\n if (trial === 'Enabled') {\n fsetupfee = 'Free'.locale();\n }\n\n setuptext = `${fsetupfee} ${'for the first payment then,'.locale()} `;\n\n if (duration) { // If recurring duration is set\n // If recurring times is equal to 1\n if (times === '1') {\n text += `${fprice} ${'one-time payment'.locale()}`;\n } else {\n switch (duration) {\n case 'Daily':\n setuptext = `${fsetupfee} ${'for the first day then,'.locale()} `;\n text += `${fprice} ${'for each day'.locale()}`;\n break;\n case 'Weekly':\n setuptext = `${fsetupfee} ${'for the first week then,'.locale()} `;\n text += `${fprice} ${'for each week'.locale()}`;\n break;\n case 'Bi-Weekly':\n text += `${fprice} ${'for each two weeks'.locale()}`;\n break;\n case 'Monthly':\n setuptext = `${fsetupfee} ${'for the first month then,'.locale()} `;\n text += `${fprice} ${'for each month'.locale()}`;\n break;\n case 'Bi-Monthly':\n text += `${fprice} ${'for each two months'.locale()}`;\n break;\n case 'Quarterly':\n text += `${fprice} ${'for each three months'.locale()}`;\n break;\n case 'Semi-Yearly':\n text += `${fprice} ${'for each six months'.locale()}`;\n break;\n case 'Yearly':\n setuptext = `${fsetupfee} for the first year then, `;\n text += `${fprice} ${'for each year'.locale()}`;\n break;\n case 'Bi-Yearly':\n text += `${fprice} ${'for each two years'.locale()}`;\n break;\n default:\n if (duration.match(/custom-/g)) {\n setuptext = `${fsetupfee} for the first ${duration.replace(/custom-/g, '')} days then,`;\n text += `${fprice} every ${duration.replace(/custom-/g, '')} days`;\n } else {\n // Default for monthly\n setuptext = `${fsetupfee} ${'for the first month then,'.locale()} `;\n text += `${fprice} ${'for each month'.locale()}`;\n }\n }\n }\n\n text += installmentText;\n\n if ((!trial || trial === 'None') && (setupfee > 0 || trial === 'Enabled')) { // Trial overwrites the setupfee\n text = setuptext + text; // Add setupfee text if no trial was set\n }\n\n text = `(${text})`; // Put long text in parenthesis\n } else {\n text += fprice; // Default price.\n }\n\n // Finish the sentence here\n // Place product name to first then, wrap details in span for easier styling\n return `${name || ''} ${text}`;\n}\n\n// build aria-labelledBy attribute for input field\n// Returns a string with two ids:\n// First one is top label id, the second one is sub label id\nexport function ariaLabelledBy(props, subLabelObject) {\n const topLabel = props?.id?.value && `label_${props.id.value}`;\n const subLabel = subLabelObject?.id && subLabelObject?.text && !props?.hiddenLabel && `sublabel_${subLabelObject.id}`;\n return [topLabel, subLabel].filter(Boolean).join(' ');\n}\n\nexport function parseJSON(data) {\n try {\n if (!data) { return false; }\n if (typeof data === typeof 'string') {\n return JSON.parse(data);\n }\n return data;\n } catch (e) {\n return false;\n }\n}\n\nexport function loadScript(file, callback = function () {}, arg) {\n try {\n const templateCache = {};\n templateCache[file] = callback;\n const script = global.document.createElement('script');\n script.type = 'text/javascript';\n script.src = `${file}?${(new Date()).getTime()}`;\n global.$(global.document.body).appendChild(script);\n if (arg === true) {\n callback();\n }\n } catch (e) {\n console.error(e);\n }\n}\n\nexport function getDefaultDate(defaultDate, format, dateSeparator) {\n let liteModeInitialValue = '';\n let year = '';\n let month = '';\n let day = '';\n if (defaultDate) {\n if (defaultDate === 'none') {\n return '';\n } else if (defaultDate === 'current') {\n const date = new Date();\n month = addZeros(date.getMonth() + 1, 2);\n day = addZeros(date.getDate(), 2);\n year = date.getYear() < 1000 ? date.getYear() + 1900 : date.getYear();\n } else if (typeof defaultDate === 'string' && defaultDate.indexOf('custom_') > -1) {\n const dateString = defaultDate.split('_')[1];\n if (dateString) {\n const dateComponents = dateString.split('-');\n if (dateComponents.length > 2) {\n year = dateComponents[0] || '';\n month = dateComponents[1] || '';\n day = dateComponents[2] || '';\n }\n }\n }\n liteModeInitialValue = month + dateSeparator + day + dateSeparator + year;\n if (format === 'ddmmyyyy') {\n liteModeInitialValue = day + dateSeparator + month + dateSeparator + year;\n } else if (format === 'yyyymmdd') {\n liteModeInitialValue = year + dateSeparator + month + dateSeparator + day;\n }\n }\n return {\n litemode: liteModeInitialValue,\n year,\n month,\n day\n };\n}\n\nexport function addZeros(num, totalDigits) {\n const n = num.toString();\n let pd = '';\n if (totalDigits > n.length) {\n for (let i = 0; i < (totalDigits - n.length); i++) {\n pd += '0';\n }\n }\n return pd + n.toString();\n}\n\n\nexport function makeQuestionName(text) {\n let name = text.replace(' ', '');\n const tokens = name.split(/\\s+/);\n name = fixUTF((tokens[1]) ? tokens[0].toLowerCase() + capitalize(tokens[1].toLowerCase()) : tokens[0].toLowerCase());\n name = name.replace(/\\W/gim, '');\n return name.length === 0 ? 'input' : name;\n}\n\nconst subLabelObj = (subLabelValue, key, id) => ({\n text: subLabelValue,\n id: id ? `${id}_${key}` : key\n});\n\n// Neil: id is for address sublabels - must have different element ID (89823)\nexport const subLabel = (prop, key, id) => (\n (prop.sublabels && prop.sublabels.value && (key in prop.sublabels.value))\n ? subLabelObj(prop.sublabels.value[key], key, id)\n : ''\n);\n\nexport const generateChecker = (obj1, obj2) => {\n return (prop) => {\n const { value: v1 } = obj1[prop] || {};\n const { value: v2 } = obj2[prop] || {};\n\n if (typeof v1 === 'object') {\n return JSON.stringify(v1) !== JSON.stringify(v2);\n }\n\n return v1 !== v2;\n };\n};\n","import {\n COUNTRIES, GENDERS, DAYS, MONTHS, FORM_TEXTS\n} from '@jotforminc/constants';\nimport { objectEntries } from '@jotforminc/utils';\nimport { fillArray, debounce, getJSON, assignObject, classNames } from './utils'\n\nlet lastHundredYears = [];\n(function () {\n const date = new Date();\n // get current year\n const cyear = (date.getYear() < 1000) ? date.getYear() + 1900 : date.getYear();\n const years = [];\n for (let year = cyear; year >= (cyear - 100); year--) {\n years.push(`${year}`);\n }\n\n lastHundredYears = years;\n}());\n\nif (typeof String.prototype.locale === 'undefined') {\n String.prototype.locale = function () {\n return this.toString();\n };\n}\n\nconst specialOptions = {\n None: {\n controls: 'dropdown,radio,checkbox,matrix'\n },\n 'US States': {\n controls: 'dropdown',\n value: ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'District of Columbia', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Puerto Rico', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virgin Islands', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming']\n },\n 'US States Abbr': {\n controls: 'dropdown',\n value: ['AL', 'AK', 'AR', 'AZ', 'CA', 'CO', 'CT', 'DC', 'DE', 'FL', 'GA', 'HI', 'ID', 'IL', 'IN', 'IA', 'KS', 'KY', 'LA', 'ME', 'MD', 'MA', 'MI', 'MN', 'MS', 'MO', 'MT', 'NE', 'NV', 'NH', 'NJ', 'NM', 'NY', 'NC', 'ND', 'OH', 'OK', 'OR', 'PA', 'PR', 'RI', 'SC', 'SD', 'TN', 'TX', 'UT', 'VT', 'VI', 'VA', 'WA', 'WV', 'WI', 'WY']\n },\n 'Canadian Provinces': {\n controls: 'dropdown',\n value: ['Alberta', 'British Columbia', 'Manitoba', 'New Brunswick', 'Newfoundland', 'Northwest Territories', 'Nova Scotia', 'Nunavut', 'Ontario', 'Prince Edward Island', 'Quebec', 'Saskatchewan', 'Yukon']\n },\n Countries: {\n controls: 'dropdown',\n value: COUNTRIES.map(country => country.locale())\n },\n 'Last 100 Years': {\n controls: 'dropdown',\n value: lastHundredYears\n },\n Gender: {\n controls: 'dropdown,radio,checkbox',\n value: GENDERS.map(gender => gender.locale())\n },\n Days: {\n controls: 'dropdown,radio,checkbox',\n value: DAYS.map(day => day.locale())\n },\n Months: {\n controls: 'dropdown,radio,checkbox',\n value: MONTHS.map(month => month.locale()),\n nonLocale: MONTHS\n },\n 'Time Zones': {\n controls: 'dropdown',\n value: ['[[Africa]]', 'Abidjan (GMT)', 'Accra (GMT)', 'Addis Ababa (GMT+03:00)', 'Algiers (GMT+01:00)', 'Asmara (GMT+03:00)', 'Bamako (GMT)', 'Bangui (GMT+01:00)', 'Banjul (GMT)', 'Bissau (GMT)', 'Blantyre (GMT+02:00)', 'Brazzaville (GMT+01:00)', 'Bujumbura (GMT+02:00)', 'Cairo (GMT+03:00)', 'Casablanca (GMT)', 'Ceuta (GMT+02:00)', 'Conakry (GMT)', 'Dakar (GMT)', 'Dar es Salaam (GMT+03:00)', 'Djibouti (GMT+03:00)', 'Douala (GMT+01:00)', 'El Aaiun (GMT)', 'Freetown (GMT)', 'Gaborone (GMT+02:00)', 'Harare (GMT+02:00)', 'Johannesburg (GMT+02:00)', 'Kampala (GMT+03:00)', 'Khartoum (GMT+03:00)', 'Kigali (GMT+02:00)', 'Kinshasa (GMT+01:00)', 'Lagos (GMT+01:00)', 'Libreville (GMT+01:00)', 'Lome (GMT)', 'Luanda (GMT+01:00)', 'Lubumbashi (GMT+02:00)', 'Lusaka (GMT+02:00)', 'Malabo (GMT+01:00)', 'Maputo (GMT+02:00)', 'Maseru (GMT+02:00)', 'Mbabane (GMT+02:00)', 'Mogadishu (GMT+03:00)', 'Monrovia (GMT)', 'Nairobi (GMT+03:00)', 'Ndjamena (GMT+01:00)', 'Niamey (GMT+01:00)', 'Nouakchott (GMT)', 'Ouagadougou (GMT)', 'Porto-Novo (GMT+01:00)', 'Sao Tome (GMT)', 'Tripoli (GMT+02:00)', 'Tunis (GMT+02:00)', 'Windhoek (GMT+01:00)', '[[America]]', 'Adak (GMT-09:00)', 'Anchorage (GMT-08:00)', 'Anguilla (GMT-04:00)', 'Antigua (GMT-04:00)', 'Araguaina (GMT-03:00)', 'Buenos Aires, Argentina (GMT-03:00)', 'Catamarca, Argentina (GMT-03:00)', 'Cordoba, Argentina (GMT-03:00)', 'Jujuy, Argentina (GMT-03:00)', 'La Rioja, Argentina (GMT-03:00)', 'Mendoza, Argentina (GMT-03:00)', 'Rio Gallegos, Argentina (GMT-03:00)', 'Salta, Argentina (GMT-03:00)', 'San Juan, Argentina (GMT-03:00)', 'San Luis, Argentina (GMT-04:00)', 'Tucuman, Argentina (GMT-03:00)', 'Ushuaia, Argentina (GMT-03:00)', 'Aruba (GMT-04:00)', 'Asuncion (GMT-04:00)', 'Atikokan (GMT-05:00)', 'Bahia (GMT-03:00)', 'Barbados (GMT-04:00)', 'Belem (GMT-03:00)', 'Belize (GMT-06:00)', 'Blanc-Sablon (GMT-04:00)', 'Boa Vista (GMT-04:00)', 'Bogota (GMT-05:00)', 'Boise (GMT-06:00)', 'Cambridge Bay (GMT-06:00)', 'Campo Grande (GMT-04:00)', 'Cancun (GMT-05:00)', 'Caracas (GMT-04:30)', 'Cayenne (GMT-03:00)', 'Cayman (GMT-05:00)', 'Chicago (GMT-05:00)', 'Chihuahua (GMT-06:00)', 'Costa Rica (GMT-06:00)', 'Cuiaba (GMT-04:00)', 'Curacao (GMT-04:00)', 'Danmarkshavn (GMT)', 'Dawson (GMT-07:00)', 'Dawson Creek (GMT-07:00)', 'Denver (GMT-06:00)', 'Detroit (GMT-04:00)', 'Dominica (GMT-04:00)', 'Edmonton (GMT-06:00)', 'Eirunepe (GMT-04:00)', 'El Salvador (GMT-06:00)', 'Fortaleza (GMT-03:00)', 'Glace Bay (GMT-03:00)', 'Godthab (GMT-02:00)', 'Goose Bay (GMT-03:00)', 'Grand Turk (GMT-04:00)', 'Grenada (GMT-04:00)', 'Guadeloupe (GMT-04:00)', 'Guatemala (GMT-06:00)', 'Guayaquil (GMT-05:00)', 'Guyana (GMT-04:00)', 'Halifax (GMT-03:00)', 'Havana (GMT-04:00)', 'Hermosillo (GMT-07:00)', 'Indianapolis, Indiana (GMT-04:00)', 'Knox, Indiana (GMT-05:00)', 'Marengo, Indiana (GMT-04:00)', 'Petersburg, Indiana (GMT-04:00)', 'Tell City, Indiana (GMT-05:00)', 'Vevay, Indiana (GMT-04:00)', 'Vincennes, Indiana (GMT-04:00)', 'Winamac, Indiana (GMT-04:00)', 'Inuvik (GMT-06:00)', 'Iqaluit (GMT-04:00)', 'Jamaica (GMT-05:00)', 'Juneau (GMT-08:00)', 'Louisville, Kentucky (GMT-04:00)', 'Monticello, Kentucky (GMT-04:00)', 'La Paz (GMT-04:00)', 'Lima (GMT-05:00)', 'Los Angeles (GMT-07:00)', 'Maceio (GMT-03:00)', 'Managua (GMT-06:00)', 'Manaus (GMT-04:00)', 'Marigot (GMT-04:00)', 'Martinique (GMT-04:00)', 'Mazatlan (GMT-06:00)', 'Menominee (GMT-05:00)', 'Merida (GMT-05:00)', 'Mexico City (GMT-05:00)', 'Miquelon (GMT-02:00)', 'Moncton (GMT-03:00)', 'Monterrey (GMT-05:00)', 'Montevideo (GMT-03:00)', 'Montreal (GMT-04:00)', 'Montserrat (GMT-04:00)', 'Nassau (GMT-04:00)', 'New York (GMT-04:00)', 'Nipigon (GMT-04:00)', 'Nome (GMT-08:00)', 'Noronha (GMT-02:00)', 'Center, North Dakota (GMT-05:00)', 'New Salem, North Dakota (GMT-05:00)', 'Panama (GMT-05:00)', 'Pangnirtung (GMT-04:00)', 'Paramaribo (GMT-03:00)', 'Phoenix (GMT-07:00)', 'Port-au-Prince (GMT-05:00)', 'Port of Spain (GMT-04:00)', 'Porto Velho (GMT-04:00)', 'Puerto Rico (GMT-04:00)', 'Rainy River (GMT-05:00)', 'Rankin Inlet (GMT-05:00)', 'Recife (GMT-03:00)', 'Regina (GMT-06:00)', 'Resolute (GMT-05:00)', 'Rio Branco (GMT-04:00)', 'Santarem (GMT-03:00)', 'Santiago (GMT-04:00)', 'Santo Domingo (GMT-04:00)', 'Sao Paulo (GMT-03:00)', 'Scoresbysund (GMT)', 'Shiprock (GMT-06:00)', 'St Barthelemy (GMT-04:00)', 'St Johns (GMT-02:30)', 'St Kitts (GMT-04:00)', 'St Lucia (GMT-04:00)', 'St Thomas (GMT-04:00)', 'St Vincent (GMT-04:00)', 'Swift Current (GMT-06:00)', 'Tegucigalpa (GMT-06:00)', 'Thule (GMT-03:00)', 'Thunder Bay (GMT-04:00)', 'Tijuana (GMT-07:00)', 'Toronto (GMT-04:00)', 'Tortola (GMT-04:00)', 'Vancouver (GMT-07:00)', 'Whitehorse (GMT-07:00)', 'Winnipeg (GMT-05:00)', 'Yakutat (GMT-08:00)', 'Yellowknife (GMT-06:00)', '[[Antarctica]]', 'Casey (GMT+11:00)', 'Davis (GMT+05:00)', 'DumontDUrville (GMT+10:00)', 'Mawson (GMT+05:00)', 'McMurdo (GMT+12:00)', 'Palmer (GMT-04:00)', 'Rothera (GMT-03:00)', 'South Pole (GMT+12:00)', 'Syowa (GMT+03:00)', 'Vostok (GMT+06:00)', '[[Arctic]]', 'Longyearbyen (GMT+02:00)', '[[Asia]]', 'Aden (GMT+03:00)', 'Almaty (GMT+06:00)', 'Amman (GMT+03:00)', 'Anadyr (GMT+13:00)', 'Aqtau (GMT+05:00)', 'Aqtobe (GMT+05:00)', 'Ashgabat (GMT+05:00)', 'Baghdad (GMT+03:00)', 'Bahrain (GMT+03:00)', 'Baku (GMT+05:00)', 'Bangkok (GMT+07:00)', 'Beirut (GMT+03:00)', 'Bishkek (GMT+06:00)', 'Brunei (GMT+08:00)', 'Choibalsan (GMT+08:00)', 'Chongqing (GMT+08:00)', 'Colombo (GMT+05:30)', 'Damascus (GMT+03:00)', 'Dhaka (GMT+07:00)', 'Dili (GMT+09:00)', 'Dubai (GMT+04:00)', 'Dushanbe (GMT+05:00)', 'Gaza (GMT+03:00)', 'Harbin (GMT+08:00)', 'Ho Chi Minh (GMT+07:00)', 'Hong Kong (GMT+08:00)', 'Hovd (GMT+07:00)', 'Irkutsk (GMT+09:00)', 'Jakarta (GMT+07:00)', 'Jayapura (GMT+09:00)', 'Jerusalem (GMT+03:00)', 'Kabul (GMT+04:30)', 'Kamchatka (GMT+13:00)', 'Karachi (GMT+06:00)', 'Kashgar (GMT+08:00)', 'Kathmandu (GMT+05:45)', 'Kolkata (GMT+05:30)', 'Krasnoyarsk (GMT+08:00)', 'Kuala Lumpur (GMT+08:00)', 'Kuching (GMT+08:00)', 'Kuwait (GMT+03:00)', 'Macau (GMT+08:00)', 'Magadan (GMT+12:00)', 'Makassar (GMT+08:00)', 'Manila (GMT+08:00)', 'Muscat (GMT+04:00)', 'Nicosia (GMT+03:00)', 'Novokuznetsk (GMT+07:00)', 'Novosibirsk (GMT+07:00)', 'Omsk (GMT+07:00)', 'Oral (GMT+05:00)', 'Phnom Penh (GMT+07:00)', 'Pontianak (GMT+07:00)', 'Pyongyang (GMT+09:00)', 'Qatar (GMT+03:00)', 'Qyzylorda (GMT+06:00)', 'Rangoon (GMT+06:30)', 'Riyadh (GMT+03:00)', 'Sakhalin (GMT+11:00)', 'Samarkand (GMT+05:00)', 'Seoul (GMT+09:00)', 'Shanghai (GMT+08:00)', 'Singapore (GMT+08:00)', 'Taipei (GMT+08:00)', 'Tashkent (GMT+05:00)', 'Tbilisi (GMT+04:00)', 'Tehran (GMT+04:30)', 'Thimphu (GMT+06:00)', 'Tokyo (GMT+09:00)', 'Ulaanbaatar (GMT+08:00)', 'Urumqi (GMT+08:00)', 'Vientiane (GMT+07:00)', 'Vladivostok (GMT+11:00)', 'Yakutsk (GMT+10:00)', 'Yekaterinburg (GMT+06:00)', 'Yerevan (GMT+05:00)', '[[Atlantic]]', 'Azores (GMT)', 'Bermuda (GMT-03:00)', 'Canary (GMT+01:00)', 'Cape Verde (GMT-01:00)', 'Faroe (GMT+01:00)', 'Madeira (GMT+01:00)', 'Reykjavik (GMT)', 'South Georgia (GMT-02:00)', 'St Helena (GMT)', 'Stanley (GMT-04:00)', '[[Australia]]', 'Adelaide (GMT+09:30)', 'Brisbane (GMT+10:00)', 'Broken Hill (GMT+09:30)', 'Currie (GMT+10:00)', 'Darwin (GMT+09:30)', 'Eucla (GMT+08:45)', 'Hobart (GMT+10:00)', 'Lindeman (GMT+10:00)', 'Lord Howe (GMT+10:30)', 'Melbourne (GMT+10:00)', 'Perth (GMT+08:00)', 'Sydney (GMT+10:00)', '[[Europe]]', 'Amsterdam (GMT+02:00)', 'Andorra (GMT+02:00)', 'Athens (GMT+03:00)', 'Belgrade (GMT+02:00)', 'Berlin (GMT+02:00)', 'Bratislava (GMT+02:00)', 'Brussels (GMT+02:00)', 'Bucharest (GMT+03:00)', 'Budapest (GMT+02:00)', 'Chisinau (GMT+03:00)', 'Copenhagen (GMT+02:00)', 'Dublin (GMT+01:00)', 'Gibraltar (GMT+02:00)', 'Guernsey (GMT+01:00)', 'Helsinki (GMT+03:00)', 'Isle of Man (GMT+01:00)', 'Istanbul (GMT+03:00)', 'Jersey (GMT+01:00)', 'Kaliningrad (GMT+03:00)', 'Kiev (GMT+03:00)', 'Lisbon (GMT+01:00)', 'Ljubljana (GMT+02:00)', 'London (GMT+01:00)', 'Luxembourg (GMT+02:00)', 'Madrid (GMT+02:00)', 'Malta (GMT+02:00)', 'Mariehamn (GMT+03:00)', 'Minsk (GMT+03:00)', 'Monaco (GMT+02:00)', 'Moscow (GMT+04:00)', 'Oslo (GMT+02:00)', 'Paris (GMT+02:00)', 'Podgorica (GMT+02:00)', 'Prague (GMT+02:00)', 'Riga (GMT+03:00)', 'Rome (GMT+02:00)', 'Samara (GMT+05:00)', 'San Marino (GMT+02:00)', 'Sarajevo (GMT+02:00)', 'Simferopol (GMT+03:00)', 'Skopje (GMT+02:00)', 'Sofia (GMT+03:00)', 'Stockholm (GMT+02:00)', 'Tallinn (GMT+03:00)', 'Tirane (GMT+02:00)', 'Uzhgorod (GMT+03:00)', 'Vaduz (GMT+02:00)', 'Vatican (GMT+02:00)', 'Vienna (GMT+02:00)', 'Vilnius (GMT+03:00)', 'Volgograd (GMT+04:00)', 'Warsaw (GMT+02:00)', 'Zagreb (GMT+02:00)', 'Zaporozhye (GMT+03:00)', 'Zurich (GMT+02:00)', '[[Indian]]', 'Antananarivo (GMT+03:00)', 'Chagos (GMT+06:00)', 'Christmas (GMT+07:00)', 'Cocos (GMT+06:30)', 'Comoro (GMT+03:00)', 'Kerguelen (GMT+05:00)', 'Mahe (GMT+04:00)', 'Maldives (GMT+05:00)', 'Mauritius (GMT+04:00)', 'Mayotte (GMT+03:00)', 'Reunion (GMT+04:00)', '[[Pacific]]', 'Apia (GMT-11:00)', 'Auckland (GMT+12:00)', 'Chatham (GMT+12:45)', 'Easter (GMT-06:00)', 'Efate (GMT+11:00)', 'Enderbury (GMT+13:00)', 'Fakaofo (GMT-10:00)', 'Fiji (GMT+12:00)', 'Funafuti (GMT+12:00)', 'Galapagos (GMT-06:00)', 'Gambier (GMT-09:00)', 'Guadalcanal (GMT+11:00)', 'Guam (GMT+10:00)', 'Honolulu (GMT-10:00)', 'Johnston (GMT-10:00)', 'Kiritimati (GMT+14:00)', 'Kosrae (GMT+11:00)', 'Kwajalein (GMT+12:00)', 'Majuro (GMT+12:00)', 'Marquesas (GMT-09:30)', 'Midway (GMT-11:00)', 'Nauru (GMT+12:00)', 'Niue (GMT-11:00)', 'Norfolk (GMT+11:30)', 'Noumea (GMT+11:00)', 'Pago Pago (GMT-11:00)', 'Palau (GMT+09:00)', 'Pitcairn (GMT-08:00)', 'Ponape (GMT+11:00)', 'Port Moresby (GMT+10:00)', 'Rarotonga (GMT-10:00)', 'Saipan (GMT+10:00)', 'Tahiti (GMT-10:00)', 'Tarawa (GMT+12:00)', 'Tongatapu (GMT+13:00)', 'Truk (GMT+10:00)', 'Wake (GMT+12:00)', 'Wallis (GMT+12:00)']\n },\n LocationCountries: {\n controls: 'location',\n value: ['Canada', 'United States', 'Afghanistan', 'Albania', 'Algeria', 'American Samoa', 'Andorra', 'Angola', 'Anguilla', 'Antarctica', 'Antigua and Barbuda', 'Argentina', 'Armenia', 'Aruba', 'Australia', 'Austria', 'Azerbaijan', 'Bahamas', 'Bahrain', 'Bangladesh', 'Barbados', 'Belarus', 'Belgium', 'Belize', 'Benin', 'Bermuda', 'Bhutan', 'Bolivia', 'Bosnia Herzegowina', 'Botswana', 'Bouvet Island', 'Brazil', 'British Ind. Ocean', 'Brunei Darussalam', 'Bulgaria', 'Burkina Faso', 'Burundi', 'Cambodia', 'Cameroon', 'Cape Verde', 'Cayman Islands', 'Central African Rep.', 'Chad', 'Chile', 'China', 'Christmas Island', 'Cocoa (Keeling) Is.', 'Colombia', 'Comoros', 'Congo', 'Cook Islands', 'Costa Rica', 'Cote Divoire', 'Croatia', 'Cuba', 'Curacao', 'Cyprus', 'Czech Republic', 'Denmark', 'Djibouti', 'Dominica', 'Dominican Republic', 'East Timor', 'Ecuador', 'Egypt', 'El Salvador', 'Equatorial Guinea', 'Eritrea', 'Estonia', 'Ethiopia', 'Falkland Islands', 'Faroe Islands', 'Fiji', 'Finland', 'France', 'Gabon', 'Gambia', 'Georgia', 'Germany', 'Ghana', 'Gibraltar', 'Greece', 'Greenland', 'Grenada', 'Guadeloupe', 'Guam', 'Guatemala', 'Guinea', 'Guinea-Bissau', 'Guyana', 'Haiti', 'Honduras', 'Hong Kong', 'Hungary', 'Iceland', 'India', 'Indonesia', 'Iran', 'Iraq', 'Ireland', 'Israel', 'Italy', 'Jamaica', 'Japan', 'Jordan', 'Kazakhstan', 'Kenya', 'Kiribati', 'Korea', 'Kuwait', 'Kyrgyzstan', 'Lao', 'Latvia', 'Lebanon', 'Lesotho', 'Liberia', 'Liechtenstein', 'Lithuania', 'Luxembourg', 'Macau', 'Macedonia', 'Madagascar', 'Malawi', 'Malaysia', 'Maldives', 'Mali', 'Malta', 'Marshall Islands', 'Martinique', 'Mauritania', 'Mauritius', 'Mayotte', 'Mexico', 'Micronesia', 'Moldova', 'Monaco', 'Mongolia', 'Montserrat', 'Morocco', 'Mozambique', 'Myanmar', 'Namibia', 'Nauru', 'Nepal', 'Netherlands', 'New Caledonia', 'New Zealand', 'Nicaragua', 'Niger', 'Nigeria', 'Niue', 'Norfolk Island', 'Norway', 'Oman', 'Pakistan', 'Palau', 'Panama', 'Papua New Guinea', 'Paraguay', 'Peru', 'Philippines', 'Pitcairn', 'Poland', 'Portugal', 'Puerto Rico', 'Qatar', 'Reunion', 'Romania', 'Russia', 'Rwanda', 'Saint Lucia', 'Samoa', 'San Marino', 'Saudi Arabia', 'Senegal', 'Seychelles', 'Sierra Leone', 'Singapore', 'Slovakia', 'Solomon Islands', 'Somalia', 'South Africa', 'South Sudan', 'Spain', 'Sri Lanka', 'St. Helena', 'Sudan', 'Suriname', 'eSwatini', 'Sweden', 'Switzerland', 'Syria', 'Taiwan', 'Tajikistan', 'Tanzania', 'Thailand', 'Togo', 'Tokelau', 'Tonga', 'Trinidad and Tobago', 'Tunisia', 'Turkey', 'Turkmenistan', 'Tuvalu', 'Uganda', 'Ukraine', 'United Arab Emirates', 'United Kingdom', 'Uruguay', 'Uzbekistan', 'Vanuatu', 'Vatican', 'Venezuela', 'Viet Nam', 'Virgin Islands', 'Western Sahara', 'Yeman', 'Yugoslavia', 'Zaire', 'Zambia']\n },\n\n\n /* eslint max-len:1 */\n\n /**\n * Gets the special options for specific element\n * @example special_options.getByType('dropdown') => ['Months', 'Days', 'US States' .... ]\n * @param {Object} type\n */\n getByType(type) {\n const options = [];\n for (const key in specialOptions) {\n if (specialOptions[key].controls && specialOptions[key].controls.indexOf(type) >= 0) {\n options.push(key);\n }\n }\n return options;\n }\n};\n\n\nexport const checkAppointmentAvailability = (day, slot, data) => {\n if (!(day && slot && data && data[day])) return false;\n return data[day][slot];\n};\n\nexport const initializeAppointment = (props) => {\n const PREFIX = (\n window.location.href.indexOf('jotform.pro') > -1\n || window.location.pathname.indexOf('build') > -1\n || window.location.pathname.indexOf('form-templates') > -1\n || window.location.pathname.indexOf('pdf-templates') > -1\n || window.location.pathname.indexOf('table-templates') > -1\n || window.location.pathname.indexOf('approval-templates') > -1\n || window.location.pathname.indexOf('workflow-templates') > -1\n || window.location.pathname.indexOf('themes') > -1\n ) ? '/server.php' : JotForm.server;\n\n // boilerplate\n let effectsOut = null;\n let changed = {};\n let constructed = false;\n const { document } = window;\n const wrapper = document.querySelector(`#${props.qid.value}`);\n const uniqueId = props.qid.value;\n const element = wrapper.querySelector('.appointmentField');\n const input = wrapper.querySelector(`#input_${props.id.value}_date`);\n const tzInput = wrapper.querySelector(`#input_${props.id.value}_timezone`);\n\n const currentYear = new Date().getFullYear();\n let timezonePickerCommon;\n let isTimezonePickerFromCommonLoaded = false;\n\n const beforeRender = () => {\n if (effectsOut) {\n effectsOut();\n effectsOut = null;\n }\n };\n\n const afterRender = () => {\n effectsOut = effects();\n };\n\n const setState = (newState) => {\n const changedKeys = Object.keys(newState).filter(key => state[key] !== newState[key]);\n\n if (!changedKeys.length) {\n return;\n }\n\n changed = changedKeys.reduce((acc, key) => assignObject({}, acc, { [key]: state[key] }), changed);\n\n state = assignObject({}, state, newState);\n if (constructed) {\n render();\n }\n };\n\n const isStartWeekOnMonday = () => {\n const { startWeekOn: { value: startDay } } = props;\n return !startDay || (startDay === 'Monday');\n };\n\n const monthNames = () => (JotForm.appointmentCalendarMonthsTranslated || JotForm.appointmentCalendarMonths || JotForm.calendarMonthsTranslated || JotForm.calendarMonths || specialOptions.Months.value).map(monthName => (String.prototype.locale ? monthName.locale() : monthName));\n const daysOfWeek = () => (JotForm.appointmentCalendarDaysTranslated || JotForm.appointmentCalendarDays || specialOptions.Days.value).map(dayName =>\n (String.prototype.locale ? dayName.locale() : dayName)\n );\n // we need remove unnecessary \"Sunday\", if there is time field on the form\n const dayNames = () => {\n const days = daysOfWeek().length === 8 ? daysOfWeek().slice(1) : daysOfWeek();\n return isStartWeekOnMonday() ? days : [days[days.length - 1]].concat(days.slice(0, 6));\n };\n\n const oneHour = 1000 * 60 * 60;\n // const oneDay = oneHour * 24;\n\n const intPrefix = (d) => {\n if (d < 10) {\n return `0${d}`;\n }\n\n return `${d}`;\n };\n\n const toFormattedDateStr = (date) => {\n const { dateFormat: { value: format = 'yyyy-mm-dd' } } = props;\n if (!date) return;\n if (typeof date === 'string') {\n const [year, month, day] = date.split('-');\n return format.replace(/yyyy/, year).replace(/mm/, month).replace(/dd/, day);\n }\n\n const year = date.getFullYear();\n const month = intPrefix(date.getMonth() + 1);\n const day = intPrefix(date.getUTCDate());\n return format.replace(/yyyy/, year).replace(/mm/, month).replace(/dd/, day);\n };\n\n const toDateStr = (date) => {\n if (!date) return;\n const year = date.getFullYear();\n const month = intPrefix(date.getMonth() + 1);\n const day = intPrefix(date.getDate());\n\n return `${year}-${month}-${day}`;\n };\n\n const toDateTimeStr = (date) => {\n if (!date) return;\n const ymd = toDateStr(date);\n const hour = intPrefix(date.getHours());\n const minute = intPrefix(date.getMinutes());\n return `${ymd} ${hour}:${minute}`;\n };\n\n const getTimezoneOffset = (timezone) => {\n if (!timezone) {\n return 0;\n }\n const cityArgs = timezone.split(' ');\n const splitted = cityArgs[cityArgs.length - 1].replace(/\\(GMT|\\)/g, '').split(':');\n\n if (!splitted) {\n return 0;\n }\n\n return parseInt(splitted[0] || 0, 10) + ((parseInt(splitted[1] || 0, 10) / 60) || 0);\n };\n\n const getGMTSuffix = (offset) => {\n if (offset === 0) {\n return '';\n }\n\n const offsetMinutes = Math.abs(offset) % 60;\n const offsetHours = Math.abs(offset - offsetMinutes) / 60;\n\n const str = `${intPrefix(offsetHours)}:${intPrefix(offsetMinutes)}`;\n\n if (offset < 0) {\n return `+${str}`;\n }\n\n return `-${str}`;\n };\n\n const getYearMonth = (date) => {\n if (!date) return;\n const [y, m] = date.split('-');\n return `${y}-${m}`;\n };\n\n const getMondayBasedDay = (date) => {\n const day = date.getUTCDay();\n if (day === 0) {\n return 6; // sunday index\n }\n return day - 1;\n };\n\n const getDay = (date) => {\n return isStartWeekOnMonday() ? getMondayBasedDay(date) : date.getUTCDay();\n };\n\n\n const getUserTimezone = () => {\n const { autoDetectTimezone: { value: autoDetectValue } = {}, timezone: { value: timezoneAtProps } = {} } = props;\n if (autoDetectValue === 'No') {\n return timezoneAtProps;\n }\n\n try {\n const tzStr = Intl.DateTimeFormat().resolvedOptions().timeZone;\n if (tzStr) {\n const tz = `${tzStr} (GMT${getGMTSuffix(new Date().getTimezoneOffset())})`;\n return tz;\n }\n } catch (e) {\n console.error(e.message);\n }\n\n return props.timezone.value;\n };\n\n const convertStrToTime = ({ dateStr = '', value = '' }) => {\n const calculateVal = toFormattedDateStr(dateStr);\n const {\n timeFormat: { value: timeFormat = '24 Hour' } = {}\n } = props;\n const date = new Date(dateStr);\n const time = new Date((value).replace(/-/g, '/')).toLocaleTimeString('en-US', { hour: 'numeric', minute: 'numeric', hourCycle: timeFormat === 'AM/PM' ? 'h12' : 'h23' });\n const day = getDay(date);\n const specialDays = specialOptions.Days.value;\n const datetime = `${dayNames()[day]}, ${monthNames()[date.getUTCMonth()]} ${intPrefix(date.getUTCDate())}, ${date.getFullYear()}`;\n const unTranslatedDatetime = `${isStartWeekOnMonday() ? specialDays[day] : [specialDays[specialDays.length - 1]].concat(specialDays.slice(0, 6))[day]}, ${specialOptions.Months.value[date.getUTCMonth()]} ${intPrefix(date.getUTCDate())}, ${date.getFullYear()}`;\n\n return {\n calculateVal, time, datetime, unTranslatedDatetime\n }\n }\n\n const hasDatePassed = (givenDateString, comparedDateString = new Date()) => {\n // Parse the given date string and create a date object\n const givenDate = new Date(givenDateString);\n const comparedDate = new Date(comparedDateString);\n\n // Get today's date with time set to 00:00:00 for accurate comparison\n comparedDate.setHours(0, 0, 0, 0);\n\n return givenDate < comparedDate;\n}\n\n const passedProps = props;\n\n let state = {};\n\n const getStateFromProps = (newProps = {}) => {\n const { timezone: { value: timezoneValue } } = newProps;\n const startDate = new Date(newProps.startDate ? newProps.startDate.value : '');\n const today = new Date();\n const date = toDateStr(new Date(Math.max(startDate, today) || today));\n\n return {\n date,\n timezones: state ? state.timezones : { loading: true },\n ...(window.location.pathname.indexOf('build') > -1\n ? { timezone: timezoneValue, defaultTimezone: timezoneValue } : {})\n };\n };\n\n state = getStateFromProps(props);\n\n const loadTimezones = (cb) => {\n setState({\n timezones: { loading: true }\n });\n\n const cdnUrl = props.cdnconfig?.CDN.endsWith('/') ? props.cdnconfig.CDN : `${props.cdnconfig.CDN}/`;\n getJSON(`${cdnUrl}assets/form/timezones.json?ncTz=${(new Date().getTime())}`).then((data) => {\n const timezones = objectEntries(data).reduce((acc, [group, cities]) => {\n acc.push({\n group,\n cities\n });\n return acc;\n }, []);\n\n cb(timezones);\n });\n };\n\n const loadMonthData = (startDate, endDate, cb) => {\n const { formID = (typeof global === 'object' ? global.__formInfo.id : null), id: { value: id } } = props;\n const { timezone } = state;\n\n if (!formID || !timezone) return;\n\n // eslint-disable-next-line max-len\n const url = `${PREFIX}?action=getAppointments&formID=${formID}&qid=${id}&timezone=${encodeURIComponent(timezone)}&startDate=${toDateStr(startDate)}&endDate=${toDateStr(endDate)}&ncTz=${(new Date().getTime())}`;\n\n return getJSON(url).then(({ content: data }) => cb(data));\n };\n\n const getMonthData = (startDate, endDate) => {\n let returnData = null;\n const res = loadMonthData(startDate, endDate, (data) => { returnData = data; });\n\n function _wait(resolve, reject) {\n if (res._complete) {\n resolve(returnData);\n } else {\n setTimeout(_wait.bind(this, resolve, reject), 100);\n }\n }\n\n return new Promise(_wait);\n }\n\n const generateMonthData = (startDate, endDate, data) => {\n const d1 = startDate.getDate();\n const d2 = endDate.getDate();\n const dPrefix = `${startDate.getFullYear()}-${intPrefix(startDate.getMonth() + 1)}-`;\n\n const daysLength = (d2 - d1) + 1 || 0;\n const days = fillArray(new Array(daysLength), '');\n\n const slots = days.reduce((acc, x, day) => {\n const dayStr = `${dPrefix}${intPrefix(day + 1)}`;\n return assignObject(acc, { [dayStr]: data[dayStr] || false });\n }, {});\n\n\n const availableDays = Object.keys(data).filter(d => !Array.isArray(slots[d]) && !!slots[d]);\n\n return {\n availableDays,\n slots\n };\n };\n\n let lastReq;\n\n const updateMonthData = (startDate, endDate, data) => {\n const { availableDays, slots } = generateMonthData(startDate, endDate, data);\n\n if (JSON.stringify(slots) === JSON.stringify(state.slots)) {\n return;\n }\n\n setState({\n availableDays,\n slots\n });\n };\n\n const getDateRange = (dateStr) => {\n const [y, m] = dateStr.split('-');\n\n const startDate = new Date(y, m - 1, 1);\n const endDate = new Date(y, m, 0);\n return [startDate, endDate];\n };\n\n const load = () => {\n const { date: dateStr } = state;\n\n const [startDate, endDate] = getDateRange(dateStr);\n\n setState(assignObject({ loading: true }, generateMonthData(startDate, endDate, {})));\n\n const req = loadMonthData(startDate, endDate, (data) => {\n if (lastReq !== req) {\n return;\n }\n\n updateMonthData(startDate, endDate, data);\n const { availableDays, forcedStartDate, forcedEndDate, slots } = state;\n\n const firstAvailable = availableDays.find((d) => {\n const foundSlot = Object.keys(slots[d]).find((slot) => {\n\n const slotDate = new Date(`${d} ${slot}`.replace(/-/g, '/'));\n\n if (forcedStartDate && slotDate > forcedStartDate) return false;\n if (forcedEndDate && slotDate < forcedEndDate) return false;\n\n return true;\n });\n\n return foundSlot;\n });\n\n const newDate = availableDays.indexOf(dateStr) === -1 && firstAvailable;\n\n setState({\n loading: false,\n date: newDate || dateStr\n });\n });\n\n lastReq = req;\n };\n\n\n const dz = (date, tz1, tz2) => {\n if (!date) return;\n const diffTime = (tz1 - tz2) * oneHour;\n return new Date(date.getTime() - diffTime);\n };\n\n const revertDate = (d, t1, t2) => {\n if (!d) return '';\n\n const pDate = new Date(d.replace(/-/, '/'));\n const utz = getTimezoneOffset(getUserTimezone());\n const tz1 = getTimezoneOffset(t1) - utz;\n const tz2 = getTimezoneOffset(t2) - utz;\n\n const val = dz(\n pDate,\n tz1,\n tz2\n );\n\n return toDateTimeStr(val);\n };\n\n const amPmConverter = (_time) => {\n const {\n timeFormat: { value: timeFormat = '24 Hour' } = {}\n } = props;\n if (!_time\n || !(typeof _time === 'string')\n || (_time.indexOf('M') > -1)\n || !timeFormat\n || (timeFormat === '24 Hour')) {\n return _time;\n }\n const time = _time.substring(0, 2);\n const hour = (time % 12) || 12;\n const ampm = time < 12 ? 'AM' : 'PM';\n return `${hour}${_time.substring(2, 5)} ${ampm}`;\n };\n\n const validate = (dateStr, cb) => {\n const { defaultValue } = state;\n\n if (\n JotForm.isEditMode()\n && defaultValue === dateStr\n ) {\n return cb(true);\n }\n\n const parts = dateStr.split(' ');\n const slot = parts.slice(1).join(' ');\n const [y, m, d] = parts[0].split('-');\n\n const startDate = new Date(y, m - 1, 1);\n const endDate = new Date(y, m, 0);\n\n loadMonthData(startDate, endDate, (data) => {\n const day = `${y}-${m}-${d}`;\n const isValid = checkAppointmentAvailability(day, amPmConverter(slot), data);\n cb(isValid);\n if (!isValid) {\n // add unavailable slot if it is not in response for deselection\n data[day] = assignObject({}, data[day], { [slot]: false });\n }\n\n // still in same month\n if (state.date.indexOf(`${y}-${m}`) === 0) {\n updateMonthData(startDate, endDate, data);\n }\n });\n };\n\n // let validationInterval;\n\n const validation = (_value) => {\n const shouldValidate = _value || input.classList.contains('validate');\n\n if (!shouldValidate) {\n input.classList.add('valid')\n JotForm.corrected(input);\n JotForm.runConditionForId(props.id.value);\n return;\n }\n\n if (!_value) {\n input.classList.remove('valid');\n JotForm.errored(input, window.JotForm.texts?.required || FORM_TEXTS.required);\n JotForm.runConditionForId(props.id.value);\n return;\n }\n\n validate(_value, (isValid) => {\n if (isValid) {\n input.classList.add('valid');\n JotForm.corrected(input);\n JotForm.runConditionForId(props.id.value);\n return;\n }\n\n const parts = _value.split(' ');\n const dateStr = parts[0];\n\n const date = new Date(dateStr);\n const day = getDay(date);\n const datetime = `${dayNames()[day]}, ${monthNames()[date.getMonth()]} ${intPrefix(date.getUTCDate())}, ${date.getFullYear()}`;\n\n const time = parts.slice(1).join(' ');\n const slotUnavailableText = window.JotForm.texts?.slotUnavailable || FORM_TEXTS.slotUnavailable;\n const errorText = slotUnavailableText.slotUnavailable.replace('{time}', time).replace('{date}', datetime);\n\n input.classList.remove('valid')\n JotForm.errored(input, errorText);\n JotForm.runConditionForId(props.id.value);\n });\n };\n\n const debouncedValidation = debounce(validation, 300);\n\n const setValue = (value) => {\n input.value = value ? toDateTimeStr(new Date(value.replace(/-/g, '/'))) : '';\n\n setState({\n value\n });\n\n // trigger input event for supporting progress bar widget\n input.triggerEvent('input');\n\n debouncedValidation(value);\n };\n\n const handleClick = (e) => {\n const { target } = e;\n\n if (!target || !target.classList) {\n return;\n }\n\n if (target.classList.contains('disabled') && !target.classList.contains('active')) {\n return;\n }\n\n e.preventDefault();\n const { value } = target.dataset;\n // formerValue can be undefined\n setValue(target.classList.contains('active') ? state.formerValue : value);\n };\n\n const setTimezone = (timezone) => {\n tzInput.value = timezone;\n let oldTimezone = state.timezone;\n setState({ timezone });\n if (input.value) {\n const date = oldTimezone ? toDateTimeStr(dz(new Date(input.value.replace(/-/g, '/')), getTimezoneOffset(oldTimezone), getTimezoneOffset(state.timezone))) : toDateTimeStr(new Date(input.value.replace(/-/g, '/')));\n setDate(date.split(' ')[0]);\n setState({ value: date });\n \n loadFormerValue(oldTimezone);\n\n input.value = state.value;\n }\n };\n\n const handleTimezoneChange = (e) => {\n const { target } = e;\n const { value: timezone } = target;\n setTimezone(timezone);\n };\n\n const setDate = date => setState({ date });\n\n const handleDateChange = (e) => {\n const { target } = e;\n const { value: date } = target.dataset;\n\n if (!date) return;\n setDate(date);\n };\n\n const handleMonthYearChange = (e) => {\n const { dataset, value: inputVal } = e.target;\n const { name } = dataset;\n if (!name) {\n return;\n }\n\n const { date } = state;\n const oldDate = new Date(date);\n const oldMonth = oldDate.getMonth();\n const oldYear = oldDate.getFullYear();\n const oldDay = oldDate.getUTCDate();\n\n const value = inputVal || e.target.getAttribute('value');\n\n if (name === 'month') {\n let newDate = new Date(oldYear, value, oldDay);\n let i = 1;\n while (`${newDate.getMonth()}` !== `${value}` && i < 10) {\n newDate = new Date(oldYear, value, oldDay - i);\n i++;\n }\n\n return setDate(toDateStr(newDate));\n }\n\n return setDate(toDateStr(new Date(value, oldMonth, oldDay)));\n };\n\n const toggleMobileState = () => {\n if (wrapper.classList.contains('isOpenMobile')) {\n wrapper.classList.remove('isOpenMobile');\n } else {\n wrapper.classList.add('isOpenMobile');\n }\n };\n\n const keepSlotsScrollPosition = () => {\n const visibleSlot = element.querySelector('.appointmentSlots.slots .slot.active, .appointmentSlots.slots .slot:not(.disabled).active');\n\n element.querySelector('.appointmentSlots.slots').scrollTop = visibleSlot ? visibleSlot.offsetTop : 0;\n };\n\n const setTimezonePickerState = () => {\n const { timezone } = state;\n const {\n autoDetectTimezone: { value: autoDetecTimezoneValue } = {}\n } = props;\n timezonePickerCommon.setSelectedTimezone(timezone);\n timezonePickerCommon.setIsAutoSelectTimezoneOpen(autoDetecTimezoneValue);\n };\n\n const loadFormerValue = (oldTimezone) => {\n const { formerValue = '' } = state;\n const date = oldTimezone ? toDateTimeStr(dz(new Date(input.value.replace(/-/g, '/')), getTimezoneOffset(oldTimezone), getTimezoneOffset(state.timezone))) : toDateTimeStr(new Date(input.value.replace(/-/g, '/')));\n const formerDate = formerValue ? (oldTimezone ? toDateTimeStr(dz(new Date(formerValue.replace(/-/g, '/')), getTimezoneOffset(oldTimezone), getTimezoneOffset(state.timezone))) : toDateTimeStr(new Date(formerValue.replace(/-/g, '/')))) : undefined;\n const formerDateTimezoned = oldTimezone ? formerDate : date \n\n if (JotForm.isEditMode() && date && date !== formerValue) {\n setState({ formerValue: formerDateTimezoned });\n }\n }\n\n const handleUIUpdate = () => {\n try {\n const breakpoints = {\n 450: 'isLarge',\n 225: 'isNormal',\n 175: 'shouldBreakIntoNewLine'\n };\n\n const offsetWidth = (() => {\n try {\n const appointmentCalendarRow = element.querySelector('.appointmentFieldRow.forCalendar');\n const appointmendCalendar = element.querySelector('.appointmentCalendar');\n return appointmentCalendarRow.getBoundingClientRect().width - appointmendCalendar.getBoundingClientRect().width;\n } catch (e) {\n return null;\n }\n })();\n\n if (offsetWidth === null || parseInt(wrapper.getAttribute('data-breakpoint-offset'), 10) === offsetWidth) {\n return;\n }\n\n const breakpoint = Object.keys(breakpoints).reduce((prev, curr) => { return Math.abs(curr - offsetWidth) < Math.abs(prev - offsetWidth) ? curr : prev; });\n const breakpointName = breakpoints[breakpoint];\n\n wrapper.setAttribute('data-breakpoint', breakpointName);\n wrapper.setAttribute('data-breakpoint-offset', offsetWidth);\n } catch (e) {\n // noop.\n }\n };\n\n let uiUpdateInterval;\n\n const effects = () => {\n clearInterval(uiUpdateInterval);\n\n const shouldLoad = (changed.timezone && changed.timezone !== state.timezone) // time zone changed\n || (changed.date && getYearMonth(changed.date) !== getYearMonth(state.date)); // y-m changed\n\n changed = {};\n\n if (shouldLoad) {\n load();\n }\n\n const cancelAppointmentBtn = element.querySelector('.cancelAppointmentBtn');\n const cancelSelectionBtn = element.querySelector('.cancelSelectionBtn');\n\n if (cancelAppointmentBtn) {\n cancelAppointmentBtn.addEventListener('click', () => {\n setValue(undefined);\n setState({ formerValue: undefined });\n });\n }\n\n if (cancelSelectionBtn) {\n cancelSelectionBtn.addEventListener('click', () => {\n const { date = '', initialStartDate = '', formerValue = '' } = state;\n const isFormerDatePassed = hasDatePassed(formerValue, initialStartDate);\n const currentOrFormerDate = formerValue ? state.formerValue.split(' ')[0] : date;\n\n setDate(isFormerDatePassed ? initialStartDate : currentOrFormerDate);\n setValue(state.formerValue);\n });\n }\n\n const forSelectedDate = element.querySelector('.forSelectedDate span');\n\n if (forSelectedDate) {\n forSelectedDate.addEventListener('click', () => {\n setDate(state.value.split(' ')[0]);\n });\n }\n\n if (isTimezonePickerFromCommonLoaded) {\n setTimezonePickerState();\n const timezonePickerWrapper = element.querySelector('.forTimezonePicker');\n timezonePickerCommon.init(timezonePickerWrapper);\n } else {\n const timezonepicker = element.querySelector('.timezonePicker');\n if (timezonepicker) {\n timezonepicker.addEventListener('change', handleTimezoneChange);\n }\n }\n\n element.querySelector('.calendar .days').addEventListener('click', handleDateChange);\n element.querySelector('.monthYearPicker').addEventListener('change', handleMonthYearChange);\n element.querySelector('.dayPicker').addEventListener('click', handleDateChange);\n element.querySelector('.selectedDate').addEventListener('click', toggleMobileState);\n\n Array.prototype.slice.call(element.querySelectorAll('.monthYearPicker .pickerArrow')).forEach(el => el.addEventListener('click', handleMonthYearChange));\n Array.prototype.slice.call(element.querySelectorAll('.slot')).forEach(el => el.addEventListener('click', handleClick));\n\n keepSlotsScrollPosition();\n uiUpdateInterval = setInterval(handleUIUpdate, 250);\n\n JotForm.runAllCalculations();\n };\n\n const onTimezoneOptionClick = (timezoneValue) => {\n setTimezone(timezoneValue);\n };\n\n const renderMonthYearPicker = () => {\n const { date } = state;\n\n const [year, month] = (date || '-').split('-');\n const yearOpts = fillArray(new Array(20), '').map((v, i) => `${currentYear + i}`);\n\n const prevMonthButtonText = (props.prevMonthButtonText && props.prevMonthButtonText.text) || 'Previous month';\n const nextMonthButtonText = (props.nextMonthButtonText && props.nextMonthButtonText.text) || 'Next month';\n const prevYearButtonText = (props.prevYearButtonText && props.prevYearButtonText.text) || 'Previous year';\n const nextYearButtonText = (props.nextYearButtonText && props.nextYearButtonText.text) || 'Next year';\n\n return `\n
    \n
    \n \n \n \n \n
    \n
    \n \n \n \n
    \n
    \n `;\n };\n\n const getNav = () => {\n const { availableDays, date: dateStr } = state;\n\n let next;\n let prev;\n const [year, month] = dateStr.split('-');\n if (availableDays) {\n const dayIndex = availableDays.indexOf(dateStr);\n if (dayIndex > 0) {\n prev = availableDays[dayIndex - 1];\n } else {\n const prevDate = new Date(year, month - 1, 0);\n if (prevDate.getFullYear() >= currentYear) {\n prev = toDateStr(prevDate);\n }\n }\n\n if (dayIndex + 1 < availableDays.length) {\n next = availableDays[dayIndex + 1];\n } else {\n const nextDate = new Date(year, month, 1);\n if (nextDate.getFullYear() <= currentYear + 19) {\n next = toDateStr(nextDate);\n }\n }\n }\n return { prev, next };\n };\n\n const renderDayPicker = () => {\n const { loading } = state;\n\n const { prev, next } = getNav();\n\n const prevDayButtonText = (props.prevDayButtonText && props.prevDayButtonText.text) || 'Previous day';\n const nextDayButtonText = (props.nextDayButtonText && props.nextDayButtonText.text) || 'Next day';\n\n return `\n
    \n \n \n
    \n `;\n };\n\n const renderTimezonePicker = () => {\n const { timezone, timezones } = state;\n if (!timezones) return;\n\n return `\n
    \n \n
    ${timezone}
    \n
    \n `;\n };\n\n const renderCalendarDays = () => {\n const { slots, date: dateStr, value, availableDays } = state;\n const days = slots ? Object.keys(slots) : [];\n const todayStr = toDateStr(new Date());\n\n if (!days.length) {\n return '';\n }\n\n const firstDay = getDay(new Date(days[0]));\n days.unshift(...fillArray(new Array(firstDay), 'precedingDay'));\n\n const trailingDays = (Math.ceil(days.length / 7) * 7) - days.length;\n days.push(...fillArray(new Array(trailingDays), 'trailingDay'));\n\n const weeks = days.map((item, i) => { return (i % 7 === 0) ? days.slice(i, i + 7) : null; }).filter(a => a);\n\n const dateValue = value && value.split(' ')[0];\n \n return `\n ${weeks.map((week) => {\n return `
    ${\n week.map((day) => {\n const dayObj = new Date(day);\n if (day === 'precedingDay' || day === 'trailingDay') {\n return `
    `;\n }\n const active = day === dateStr;\n const isToday = todayStr === day;\n const beforeStartDate = state.forcedStartDate ? state.forcedStartDate > dayObj : false;\n const afterEndDate = state.forcedEndDate ? state.forcedEndDate < dayObj : false;\n const isUnavailable = availableDays.indexOf(day) === -1 || beforeStartDate || afterEndDate;\n const isPassed = hasDatePassed(day);\n const isStartDayGreaterThanDay = hasDatePassed(day, state.initialStartDate);\n const isSelected = !isPassed && !isStartDayGreaterThanDay && day === dateValue;\n const isActive = !isPassed && !isStartDayGreaterThanDay && active;\n\n const classes = `calendarDay ${classNames({\n isSelected,\n isToday,\n isUnavailable,\n isActive,\n })}`;\n\n return `\n ${day.split('-')[2].replace(/^0/, '')}\n
    `;\n }).join('')\n }`;\n }).join('')}\n `;\n };\n\n const renderEmptyState = () => {\n /* eslint-disable */\n return `\n
    \n
    \n
    \n \n \n \n
    \n
    ${window.JotForm.texts?.noSlotsAvailable || FORM_TEXTS.noSlotsAvailable}
    \n
    \n
    \n `;\n /* eslint-enable */\n };\n\n const dateWithAMPM = (date = '') => {\n const {\n timeFormat: { value: timeFormat = '24 Hour' } = {}\n } = props;\n const time = new Date(date.replace(/-/g, '/'))\n .toLocaleTimeString('en-US', { hour: 'numeric', minute: 'numeric', hourCycle: timeFormat === 'AM/PM' ? 'h12' : 'h23' });\n const day = date && date.split(' ')[0];\n return `${day} ${time}`;\n };\n\n\n const renderSlots = () => {\n const { date: dateStr, value: dateValue = '', defaultValue = '', timezone, forcedStartDate, forcedEndDate } = state;\n const dateSlots = (state.slots && state.slots[dateStr]) || {};\n\n const stateValue = dateWithAMPM(dateValue);\n const stateDefaultValue = dateWithAMPM(defaultValue);\n const defaultValueTZ = revertDate(defaultValue, ' ', timezone);\n\n const parsedDefaultVal = dateWithAMPM(defaultValueTZ);\n\n const entries = objectEntries(dateSlots);\n\n if (!entries || !entries.length) {\n return renderEmptyState();\n }\n\n return entries.map(([name, value]) => {\n if (name.indexOf('M') > -1) {\n name = name.split(' ');\n name = `${name[0]} ${name[1].locale()}`;\n }\n const rn = amPmConverter(name);\n const slotValue = `${dateStr} ${rn}`;\n const realD = new Date(slotValue.replace(/-/g, '/'));\n const active = stateValue.replace(/\\s/g, ' ') === slotValue.replace(/\\s/g, ' ');\n\n const disabled = (\n (((forcedStartDate && forcedStartDate > realD)\n || (forcedEndDate && forcedEndDate < realD)\n || !(value || parsedDefaultVal === slotValue))) && stateDefaultValue !== slotValue\n );\n\n return `
    ${name}
    `;\n }).join('');\n };\n\n const renderDay = () => {\n const { date: dateStr } = state;\n const date = new Date(dateStr);\n const day = getDay(date);\n\n return `\n
    \n ${dateStr && `${dayNames()[day]}, ${monthNames()[date.getUTCMonth()]} ${intPrefix(date.getUTCDate())}`}\n
    \n `;\n };\n\n const renderCalendar = () => {\n const { date: dateStr } = state;\n\n return `\n
    \n \n
    \n ${renderMonthYearPicker()}\n
    \n
    \n ${dayNames().map(day => (\n `
    ${day.toUpperCase().slice(0, 3)}
    `\n )).join('')}\n
    \n ${renderCalendarDays()}\n
    \n `;\n };\n\n const renderSelectedDate = () => {\n const { value = '', formerValue = '' } = state;\n const dateStr = value && value.split(' ')[0];\n const formerDateStr = formerValue && formerValue.split(' ')[0];\n const { calculateVal, time, datetime, unTranslatedDatetime } = convertStrToTime({ dateStr, value });\n const {\n time: formerTime,\n datetime: formerDateTime,\n } = convertStrToTime({ dateStr: formerDateStr, value: formerValue });\n const selectedTimeText = window.JotForm.texts?.selectedTime || FORM_TEXTS.selectedTime;\n const cancelSelectionText = window.JotForm.texts?.cancelSelection || FORM_TEXTS.cancelSelection;\n const cancelAppointmentText = window.JotForm.texts?.cancelAppointment || FORM_TEXTS.cancelAppointment;\n const formerSelectedText = window.JotForm.texts?.formerSelectedTime || FORM_TEXTS.formerSelectedTime;\n const text = `${time} ${datetime}`;\n const formerText = `${formerTime} ${formerDateTime}`;\n const hasFormerly = value !== formerValue;\n const appointmentDateTime = new Date(value.replace(/(\\.|-)/g, '/')).getTime();\n const valEl = ``;\n const cancelAppointmentButton = ``;\n const cancelSelectionButton = ``;\n const selectedField = `
    ${selectedTimeText}${text}
    `;\n const formerTimeField = `
    ${formerSelectedText}${formerText}
    `;\n const selectedFieldContainer = `
    \n ${selectedField}\n ${hasFormerly ? cancelSelectionButton : cancelAppointmentButton}\n ${JotForm.isEditMode() && formerValue && hasFormerly ? formerTimeField : ''}\n
    `;\n\n return value ? `${valEl}${selectedFieldContainer}` : ``; \n };\n\n const render = debounce(() => {\n const { loading } = state;\n const { text } = props\n beforeRender();\n element.innerHTML = `\n
    \n
    \n
    \n
    \n ${renderCalendar()}\n
    \n
    \n
    \n
    \n ${renderDay()}\n ${renderDayPicker()}\n
    \n
    \n
    \n ${renderSlots()}\n
    \n
    \n
    \n ${isTimezonePickerFromCommonLoaded ? '' : renderTimezonePicker()}\n
    \n
    \n
    \n ${renderSelectedDate()}\n
    \n `;\n afterRender();\n // Frame height needs to be recalculated and\n // updated after any UI change on appointment\n // field. We force it from here.\n try {\n global.JotForm.handleIFrameHeight();\n } catch (e) {\n // noop.\n }\n });\n\n const update = (newProps) => {\n state = assignObject({}, state, getStateFromProps(newProps));\n props = newProps;\n constructTimezonePickerCommon(props);\n load();\n };\n\n input.addEventListener('change', (e) => {\n const date = e.target.value ? toDateTimeStr(new Date(e.target.value.replace(/-/g, '/'))) : '';\n const isAMPM = props.timeFormat === '24 hour';\n if (date) {\n setDate(date.split(' ')[0]);\n setState({ value: date, defaultValue: isAMPM ? date : dateWithAMPM(date) });\n validation(isAMPM ? date : dateWithAMPM(date));\n }\n });\n tzInput.addEventListener('change', (e) => {\n const defaultTimezone = e.target.value;\n setTimezone(defaultTimezone);\n setState({ defaultTimezone });\n });\n document.addEventListener('translationLoad', () => render());\n\n const triggerConstruct = (timezones) => {\n JotForm.appointments.listeners.forEach(fn => fn({ timezones }));\n }\n\n if (!JotForm.appointments) {\n JotForm.appointments = { listeners: [] };\n\n loadTimezones((timezones) => {\n JotForm.timezones = timezones;\n\n if (JotForm.isEditMode()) {\n ensureEditResultSet(10000).then(()=> {\n triggerConstruct(timezones);\n });\n } else {\n triggerConstruct(timezones);\n }\n });\n }\n\n // Appointment flickers if we don't wait for submission result on edit\n function ensureEditResultSet(timeout) {\n var dateStart = Date.now();\n return new Promise(waitForEditResult);\n\n function waitForEditResult(resolve, reject) {\n if (JotForm.editValueSet)\n resolve();\n else if (timeout && (Date.now() - dateStart) >= timeout)\n resolve();\n else\n setTimeout(waitForEditResult.bind(this, resolve, reject), 30);\n }\n }\n\n const requestTimeout = 1000;\n\n const getFirstAvailableDates = async ({ formID, timezone, qid }) => {\n const url = `${PREFIX}?action=getAppointments&formID=${formID}&timezone=${encodeURIComponent(timezone)}&ncTz=${(new Date().getTime())}&firstAvailableDates&qid=${qid}`;\n const { content } = await getJSON(url);\n JotForm.appointments.initialData = {...JotForm.appointments.initialData, ...content}\n return content[qid];\n }\n\n const constructTimezonePickerCommon = (props) => {\n const isAm = props?.timeFormat?.value === 'AM/PM';\n const userTimezone = getUserTimezone();\n const timezone = state.defaultTimezone || userTimezone\n\n if (window.timezonePickerCommon) {\n isTimezonePickerFromCommonLoaded = true;\n timezonePickerCommon = window.timezonePickerCommon({\n id: uniqueId,\n timezones: JotForm.timezones,\n selectedTimezone: timezone,\n onOptionClick: onTimezoneOptionClick,\n usePortal: true,\n isAm\n });\n }\n }\n\n const construct = async ({ timezones }) => {\n const { formID = global.__formInfo.id, id: { value: qid }, autoDetectTimezone: { value: autoDetectValue } = {} } = props;\n\n const userTimezone = getUserTimezone();\n const timezone = state.defaultTimezone || userTimezone\n\n if (!formID || !timezone) return;\n\n if (autoDetectValue === 'No') {\n load();\n }\n\n const qdata = await getFirstAvailableDates({ formID, timezone, qid });\n\n if (!qdata || qdata.error) {\n constructed = true;\n return;\n }\n\n constructed = false;\n\n constructTimezonePickerCommon(props);\n\n setTimezone(timezone);\n const dateStr = Object.keys(qdata)[0];\n\n const [startDate, endDate] = getDateRange(dateStr);\n\n updateMonthData(startDate, endDate, qdata);\n const { availableDays } = state;\n const newDate = availableDays.indexOf(dateStr) === -1 ? availableDays[0] : dateStr;\n\n constructed = true;\n\n setState({\n timezones,\n loading: false,\n date: newDate || dateStr,\n initialStartDate: dateStr,\n });\n \n const isDatePassed = hasDatePassed(state.value);\n const isForcedStartDay = hasDatePassed(state.value, dateStr);\n\n // should wait for submission results for edit mode to correct input value for user timezone\n if (JotForm.isEditMode()) {\n ensureEditResultSet(10000).then(() => {\n // if appointment is passed, get first available day\n if (!isDatePassed && !isForcedStartDay) {\n input.triggerEvent('change');\n input.value = state.value || '';\n }\n })\n } else {\n setTimeout(() => {\n if (input.value) {\n input.triggerEvent('change');\n }\n }, 100);\n }\n };\n\n JotForm.appointments.listeners.push(construct);\n\n if (JotForm.appointments.initialData) {\n setTimeout(() => {\n construct({\n timezones: JotForm.timezones\n });\n }, requestTimeout);\n }\n\n JotForm.appointments[props.id.value] = {\n update: newProps => update(assignObject(passedProps, newProps)),\n forceStartDate: async (newDate, equation = '') => {\n if (!newDate) {\n setState({ forcedStartDate: undefined });\n return;\n }\n try {\n const forcedStartDate = new Date(newDate);\n if (`${forcedStartDate}` === `${state.forcedStartDate}`) return;\n let date = new Date(state.availableDays.find(d => new Date(`${d} 23:59:59`) >= forcedStartDate));\n\n if (!date.getTime()) {\n date = forcedStartDate;\n }\n\n date = toDateStr(date);\n\n if (equation && !state.loading) {\n const realDate = new Date(forcedStartDate.getTime());\n if (`${state.forcedStartDate}` === `${realDate}`) return;\n const getFirstAvailableDay = (_availableDays) => { return new Date(_availableDays.find(d => new Date(`${d} 23:59:59`) >= realDate)) };\n let firstAvailableDay = getFirstAvailableDay(state.availableDays);\n\n if (firstAvailableDay.toString() === 'Invalid Date') {\n const [startDate, endDate] = getDateRange(toDateStr(realDate));\n const monthData = await getMonthData(startDate, endDate);\n const { availableDays } = generateMonthData(startDate, endDate, monthData);\n firstAvailableDay = getFirstAvailableDay(availableDays);\n }\n\n setValue('');\n setState({ forcedStartDate, date: toDateStr(firstAvailableDay) });\n return;\n }\n\n setState({ forcedStartDate, date });\n } catch (e) {\n console.log(e);\n }\n },\n forceEndDate: (newDate) => {\n if (!newDate) {\n setState({ forcedEndDate: undefined });\n return;\n }\n\n try {\n const forcedEndDate = new Date(newDate);\n if (`${forcedEndDate}` === `${state.forcedEndDate}`) return;\n const availableDays = state.availableDays.filter(d => new Date(`${d} 00:00:00`) <= forcedEndDate);\n\n let date = new Date(\n availableDays.indexOf(state.date) > -1\n ? state.date\n : availableDays[availableDays.length - 1]\n );\n\n if (!date.getTime()) {\n date = forcedEndDate;\n }\n\n date = toDateStr(date);\n\n setState({ forcedEndDate, date });\n } catch (e) {\n console.log(e);\n }\n },\n getComparableValue: () => (\n input.value && toDateTimeStr(new Date(input.value.replace(/-/g, '/')))\n ) || ''\n };\n\n return update;\n};\n","import React, { useEffect, useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { debounce } from '../utils';\n\nconst MIN_LOGO_WIDTH = 100;\n\nconst LogoComponent = ({\n isBuilder, logoTitle, handleAddFormLogo, formWidth, formLogoProperties, usePreLoad\n}) => {\n const { url = '', width = MIN_LOGO_WIDTH, height = 100 } = formLogoProperties.image;\n const [imageLoaded, setImageLoaded] = useState(false);\n\n useEffect(() => {\n const img = new Image();\n img.src = url;\n\n img.onload = () => {\n setImageLoaded(true);\n };\n\n img.onerror = (error) => {\n console.error('Error loading image:', error);\n setImageLoaded(true);\n };\n\n return () => {\n img.onload = null;\n img.onerror = null;\n };\n }, []);\n\n return React.useMemo(() => {\n const logoWidth = width > formWidth ? formWidth : width;\n\n const logoImage = (\n \n );\n\n return (\n \n {isBuilder ? (\n \n {logoImage}\n \n ) : (\n logoImage\n )}\n \n );\n }, [formWidth, url, width, height, imageLoaded]);\n};\n\nconst FormLogo = ({\n isBuilder,\n handleAddFormLogo,\n formWidth,\n formLogoProperties,\n logoTitle,\n updateFormProperty,\n styleJSON, \n usePreLoad = false\n}) => {\n\n const wrapperClass = `form-cover-wrapper form-has-cover form-page-cover-image-align-${formLogoProperties.topPosition?.toLowerCase()}`;\n\n const handleFormWidthChange = onUpdating => {\n if (!onUpdating) {\n const { width, height } = formLogoProperties?.image || {};\n if (width > formWidth) {\n const ratio = height / width;\n const logoWidth = formWidth > MIN_LOGO_WIDTH ? formWidth : MIN_LOGO_WIDTH;\n\n styleJSON['@formCoverImgWidth'] = logoWidth;\n styleJSON['@formCoverImgHeight'] = logoWidth * ratio;\n\n updateFormProperty({\n styleJSON\n }, true, true);\n }\n }\n };\n\n useEffect(() => {\n let onUpdating = false;\n\n const debouncedHandleFormWidthChange = debounce(() => handleFormWidthChange(onUpdating), 500);\n\n if (!onUpdating) {\n debouncedHandleFormWidthChange();\n }\n\n return () => {\n onUpdating = true;\n };\n }, [formWidth, formLogoProperties?.image?.width]);\n\n return (\n \n );\n};\n\nFormLogo.defaultProps = {\n handleAddFormLogo: () => { },\n logoTitle: '',\n isBuilder: false,\n updateFormProperty: () => { },\n styleJSON: {}\n};\n\nFormLogo.propTypes = {\n isBuilder: PropTypes.bool,\n logoTitle: PropTypes.string,\n handleAddFormLogo: PropTypes.func,\n formWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,\n formLogoProperties: PropTypes.shape({\n bottomMargin: PropTypes.number,\n topPosition: PropTypes.string,\n image: PropTypes.shape({\n url: PropTypes.string.isRequired,\n width: PropTypes.number.isRequired,\n height: PropTypes.number.isRequired\n }).isRequired\n }).isRequired,\n updateFormProperty: PropTypes.func,\n styleJSON: PropTypes.object,\n usePreLoad: PropTypes.bool\n};\n\nexport default FormLogo;\n","/* eslint no-eval:0 */\nimport PropTypes from 'prop-types';\n\nimport React, { Component } from 'react';\nimport { fixNumbers, subLabel } from '@jotforminc/form-common';\nimport SubLabel from '../helpers/SubLabel';\nimport { classNames, addValidation } from '../helpers/Utils';\nimport QuestionProps from '../helpers/QuestionProps';\n\nexport default class Range extends Component {\n\n componentDidMount() {\n eval(Range.getScript(this.props));\n }\n\n componentDidUpdate() {\n eval(Range.getScript(this.props));\n }\n\n render() {\n const qid = this.props.qid.value;\n const qname = this.props.qname.value;\n const markup = [];\n\n markup.push(\n \n \n \n );\n\n markup.push(\n \n \n \n );\n\n return (\n
    \n {markup}\n
    \n );\n }\n}\n\nRange.getState = (prop) => {\n return {\n addAmount: prop.addAmount.value,\n allowMinus: prop.allowMinus.value === 'Yes' ? 'true' : 'false',\n defaultTo: prop.defaultTo.value,\n defaultFrom: prop.defaultFrom.value\n };\n};\n\nRange.getScript = (prop) => {\n const state = Range.getState(prop);\n const qid = prop.qid.value;\n /* eslint max-len:0 */\n let script = ` $('${qid}_to').spinner({ imgPath:'${prop.cdnconfig.CDN}images/', width: '60', allowNegative: ${state.allowMinus}, addAmount: ${fixNumbers(state.addAmount)}, value:'${fixNumbers(state.defaultTo)}' });\\n`;\n script += ` $('${qid}_from').spinner({ imgPath:'${prop.cdnconfig.CDN}images/', width: '60', allowNegative: ${state.allowMinus}, addAmount: ${fixNumbers(state.addAmount)}, value:'${fixNumbers(state.defaultFrom)}' });\\n`;\n /* eslint max-len:1 */\n return script;\n};\n\nRange.propTypes = {\n qid: PropTypes.shape({\n value: PropTypes.string\n }),\n qname: PropTypes.shape({\n value: PropTypes.string\n }),\n inlineEditClass: PropTypes.elementType\n};\n","/* eslint no-eval:0 */\n\nimport PropTypes from 'prop-types';\n\nimport React, { Component } from 'react';\nimport { addValidation, classNames } from '../helpers/Utils';\nimport QuestionProps from '../helpers/QuestionProps';\nimport SubLabel from '../helpers/SubLabel';\nimport Ratingv2 from './Ratingv2';\n\nexport default class Rating extends Component {\n componentDidMount() {\n this.comp = eval(Rating.getScript(this.props));\n }\n\n componentDidUpdate() {\n this.comp = eval(Rating.getScript(this.props));\n }\n\n render() {\n if (this.props.themeVersion && this.props.themeVersion === 'v2') {\n return ;\n }\n const ratingOptions = [];\n\n for (let i = 1; i <= this.props.stars.value; i++) {\n ratingOptions.push();\n }\n\n return (\n \n { this.comp = ref; }}\n id={this.props.qid.value}\n name={this.props.qname.value}\n key={this.props.passive ? `${Math.round(Math.random() * 100000)}` : null}\n data-component=\"rating\"\n >\n \n \n \n );\n }\n}\n\nRating.propTypes = {\n qid: PropTypes.shape({\n value: PropTypes.string\n }),\n qname: PropTypes.shape({\n value: PropTypes.string\n }),\n stars: PropTypes.shape({\n value: PropTypes.integer\n }),\n starStyle: PropTypes.shape({\n value: PropTypes.string\n }),\n defaultValue: PropTypes.shape({\n value: PropTypes.string\n }),\n subLabel: PropTypes.shape(),\n passive: PropTypes.bool,\n inlineEditClass: PropTypes.elementType,\n themeVersion: PropTypes.string,\n type: PropTypes.shape()\n};\n\nRating.getState = (prop) => {\n let stars = 'stars';\n\n const typeMap = {\n Hearts: 'hearts',\n 'Stars 2': 'stars2',\n Lightnings: 'lightnings',\n 'Light Bulps': 'bulps',\n Shields: 'shields',\n Flags: 'flags',\n Pluses: 'pluses',\n };\n let starsV2 = 'stars_v2';\n const typeMapV2 = {\n Hearts: 'hearts_v2',\n 'Stars 2': 'stars2_v2',\n Lightnings: 'lightnings_v2',\n 'Light Bulps': 'bulps_v2',\n Shields: 'shields_v2',\n Flags: 'flags_v2',\n Pluses: 'pluses_v2',\n };\n\n if (typeof typeMap[prop.starStyle.value] !== 'undefined') {\n stars = typeMap[prop.starStyle.value];\n }\n\n if (typeof typeMap[prop.starStyle.value] !== 'undefined') {\n starsV2 = typeMapV2[prop.starStyle.value];\n }\n\n return {\n stars: prop.themeVersion === 'v2' ? starsV2 : stars\n };\n};\n\nRating.getScript = (prop) => {\n const state = Rating.getState(prop);\n let script = `\n $('${prop.qid.value}').rating({stars:'${prop.stars.value}',\n inputClassName:'${addValidation(classNames.textbox, prop)}',\n imagePath: '${prop.cdnconfig.CDN}images/${state.stars}.png',\n cleanFirst:true, value:'${prop.defaultValue.value}'});\\n`;\n script += `$('${prop.qid.value}').setAttribute('role','radiogroup');\\n`;\n\n if (prop.id && prop.id.value) {\n script += `$('${prop.qid.value}').setAttribute('aria-labelledby','label_${prop.id.value}');\\n`;\n }\n\n script += `\n Array.from($('${prop.qid.value}').children).map(function(e, i){e.setAttribute('tabindex',0);\n if(i<${prop.stars.value || 0}) {e.setAttribute('aria-label',(i+1)+' out of ${prop.stars.value || 0}');}\n e.setAttribute('role','radio');\n e.setAttribute('aria-checked','false');\n e.setAttribute('aria-describedby', 'label_${prop.id.value}');\n e.classList.add('form-star-rating-star', '${prop.starStyle.value.replace(/\\s/g, '')}');\n e.onkeypress = function(k){if(k.keyCode == 13 || k.keyCode == 32)e.click()}});\\n`;\n\n return script;\n};\n","/* eslint no-eval:0 */\n\nimport PropTypes from 'prop-types';\n\nimport React, { Component } from 'react';\nimport QuestionProps from '../helpers/QuestionProps';\nimport SubLabel from '../helpers/SubLabel';\n\nexport default class Rating extends Component {\n render() {\n const {\n stars, subLabel, qid, type, qname, passive, inlineEditClass, text\n } = this.props;\n const ratingOptions = [];\n\n for (let i = 1; i <= stars.value; i++) {\n ratingOptions.push();\n }\n\n return (\n \n { this.comp = ref; }}\n id={qid.value}\n name={qname.value}\n key={passive ? `${Math.round(Math.random() * 100000)}` : null}\n data-component=\"rating\"\n data-version=\"v2\"\n >\n \n \n \n );\n }\n}\n\nRating.propTypes = {\n qid: PropTypes.shape({\n value: PropTypes.string\n }),\n qname: PropTypes.shape({\n value: PropTypes.string\n }),\n stars: PropTypes.shape({\n value: PropTypes.string\n }),\n starStyle: PropTypes.shape({\n value: PropTypes.string\n }),\n defaultValue: PropTypes.shape({\n value: PropTypes.string\n }),\n text: PropTypes.shape({\n value: PropTypes.string\n }),\n subLabel: PropTypes.shape(),\n passive: PropTypes.bool,\n inlineEditClass: PropTypes.elementType,\n type: PropTypes.shape()\n};\n\nRating.defaultProps = {\n subLabel: {},\n qid: {\n value: ''\n },\n qname: {\n value: ''\n },\n stars: {\n value: ''\n },\n starStyle: {\n value: ''\n },\n defaultValue: {\n value: ''\n },\n type: {\n value: ''\n },\n text: {\n value: 'Rate it element'\n },\n passive: false,\n inlineEditClass: undefined\n};\n","import React from 'react';\n\nconst Separator = (prop) => {\n let borderColor = 'rgb(0,0,0)';\n let borderWidth = '1px';\n let borderStyle = 'solid';\n\n if (prop.borderWidth && prop.borderWidth.value) {\n borderWidth = prop.borderWidth.value;\n }\n if (prop.borderStyle && prop.borderStyle.value) {\n borderStyle = prop.borderStyle.value;\n }\n if (prop.borderColor && prop.borderColor.value) {\n borderColor = prop.borderColor.value;\n }\n\n const separatorStyle = {\n borderTop: `${borderWidth} ${borderStyle} ${borderColor}`,\n clear: 'both'\n };\n\n return
    ;\n};\n\nexport default Separator;\n","/* eslint no-eval:0 */\nimport PropTypes from 'prop-types';\n\nimport React, { Component } from 'react';\nimport { addValidation, classNames } from '../helpers/Utils';\n\nexport default class Slider extends Component {\n\n componentDidMount() {\n eval(Slider.getScript(this.props));\n }\n\n componentDidUpdate() {\n // disabled this for now\n // this component is being rendered twice\n // I guess its parent should use shouldComponentUpdate\n // to handle rerenders\n // when the scripts evaluated twice\n // two sliders will be appened\n // eval(Slider.getScript(this.props));\n }\n\n render() {\n return (\n
    \n \n
    \n );\n }\n}\n\nSlider.getState = (prop) => {\n return {\n qid: prop.qid.value,\n width: prop.width.value,\n maxValue: prop.maxValue.value,\n defaultValue: prop.defaultValue.value\n };\n};\n\nSlider.getScript = (prop) => {\n const state = Slider.getState(prop);\n /* eslint max-len:0 */\n return ` $('${state.qid}').slider({width:'${state.width}', maxValue: '${state.maxValue}', value: '${state.defaultValue.trim()}'});\\n`;\n /* eslint max-len:1 */\n};\n\nSlider.propTypes = {\n qid: PropTypes.shape({\n value: PropTypes.string\n }),\n qname: PropTypes.shape({\n value: PropTypes.string\n }),\n inlineEditClass: PropTypes.elementType\n};\n","/* eslint no-eval:0 */\n\nimport PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport { ariaLabelledBy} from '@jotforminc/form-common';\n\nimport BaseInput from '../helpers/BaseInput';\nimport SubLabel from '../helpers/SubLabel';\nimport { addValidation, classNames, subLabelSingle } from '../helpers/Utils';\nimport QuestionProps from '../helpers/QuestionProps';\n\nexport default class Spinner extends Component {\n\n componentDidMount() {\n eval(Spinner.getScript(this.props));\n }\n\n componentDidUpdate() {\n eval(Spinner.getScript(this.props));\n }\n\n render() {\n const additionalClass = addValidation(classNames.textbox, this.props);\n const maxValue = this.props.maxValue && this.props.maxValue.value ? this.props.maxValue.value : null;\n const minVal = this.props.minValue && this.props.minValue.value ? this.props.minValue.value : null;\n const minValue = (this.props.allowMinus.value === 'Yes') ? minVal : Math.max(minVal, 0);\n\n const decimalClass = this.props.disallowDecimals && this.props.disallowDecimals.value && this.props.disallowDecimals.value === 'Yes' ? 'disallowDecimals' : '';\n const { value: qidValue } = this.props.qid;\n const subLabelObj = subLabelSingle(this.props, qidValue);\n return (\n \n \n \n );\n }\n}\n\nSpinner.getState = (prop) => {\n return {\n imgPath: 'images/',\n width: prop.width.value,\n maxValue: prop.maxValue.value,\n minValue: prop.minValue.value,\n allowNegative: (prop.allowMinus.value === 'Yes'),\n addAmount: prop.addAmount.value,\n value: prop.defaultValue.value,\n disallowDecimals: (prop.disallowDecimals.value === 'Yes')\n };\n};\n\nSpinner.getScript = (prop) => {\n const state = Spinner.getState(prop);\n let script = ` if(typeof $('${prop.qid.value}').spinner !== 'undefined') {$('${prop.qid.value}').spinner({ imgPath:'${prop.cdnconfig.CDN}images/', width: '${state.width}', maxValue:'${state.maxValue}', minValue:'${state.minValue}', allowNegative: ${(state.allowNegative) ? 'true' : 'false'}, addAmount: ${parseFloat(state.addAmount) || 1}, value:'${state.value}' });}\\n`;\n script += ` $('${prop.qid.value}').up(2).setAttribute('tabindex','');\\n`;\n /* eslint max-len:0 */\n return script;\n /* eslint max-len:1 */\n};\n\nSpinner.propTypes = {\n qid: PropTypes.shape({\n value: PropTypes.string\n }),\n qname: PropTypes.shape({\n value: PropTypes.string\n }),\n subLabel: PropTypes.shape({\n value: PropTypes.string\n }),\n minValue: PropTypes.shape({\n value: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.number\n ])\n }),\n maxValue: PropTypes.shape({\n value: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.number\n ])\n }),\n decimalClass: PropTypes.shape({\n value: PropTypes.string\n }),\n addAmount: PropTypes.shape({\n value: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.number\n ])\n }),\n disallowDecimals: PropTypes.shape(),\n type: PropTypes.shape(),\n};\n\n","/* eslint no-eval:0 */\n\nimport PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport { ariaLabelledBy, htmlDecode } from '@jotforminc/form-common';\n\nimport SubLabel from '../helpers/SubLabel';\nimport {\n addValidation, subLabelSingle, sanitize, newlineToEntities\n} from '../helpers/Utils';\nimport QuestionProps from '../helpers/QuestionProps';\n\nexport default class Textarea extends Component {\n componentDidMount() {\n eval(Textarea.getScript(this.props));\n }\n\n componentWillReceiveProps(nextProps) {\n if (this.props.hint && this.props.hint.value) {\n if (nextProps.hint.value !== this.props.hint.value) {\n eval(Textarea.getScript(nextProps));\n }\n } else {\n eval(Textarea.getScript(nextProps));\n }\n }\n\n componentDidUpdate(prevProps) {\n const { hint, wysiwyg } = this.props;\n\n const isEditorModeChanged = prevProps.wysiwyg && wysiwyg && prevProps.wysiwyg.value !== wysiwyg.value;\n if (hint && hint.value && isEditorModeChanged) {\n eval(Textarea.getScript(this.props));\n }\n }\n\n render() {\n const wideArea = this.props.wysiwyg && this.props.wysiwyg.value === 'Widearea';\n const richText = this.props.wysiwyg && this.props.wysiwyg.value === 'Enable';\n const fullScreenIcon = \"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23434A60' viewBox='0 0 24 24' class='w-32 h-32'%3E%3Cpath fill-rule='evenodd' d='M7 2H3a1 1 0 0 0-1 1v4a1 1 0 0 0 1.707.707L5 6.414l3.293 3.293a1 1 0 0 0 1.414-1.414L6.414 5l1.293-1.293A1 1 0 0 0 7 2Zm10 0a1 1 0 0 0-.707 1.707L17.586 5l-3.293 3.293a1 1 0 0 0 1.414 1.414L19 6.414l1.293 1.293A1 1 0 0 0 22 7V3a1 1 0 0 0-1-1h-4ZM9.707 15.707a1 1 0 0 0-1.414-1.414L5 17.586l-1.293-1.293A1 1 0 0 0 2 17v4a1 1 0 0 0 1 1h4a1 1 0 0 0 .707-1.707L6.414 19l3.293-3.293Zm4.586-1.414a1 1 0 0 1 1.414 0L19 17.586l1.293-1.293A1 1 0 0 1 22 17v4a1 1 0 0 1-1 1h-4a1 1 0 0 1-.707-1.707L17.586 19l-3.293-3.293a1 1 0 0 1 0-1.414Z' clip-rule='evenodd'%3E%3C/path%3E%3C/svg%3E\";\n const { value: qidValue } = this.props.qid;\n const subLabelObj = subLabelSingle(this.props, qidValue);\n let extraStyle = {};\n if (wideArea && !this.props.inlineEditClass) {\n // add script\n extraStyle = { overflowY: 'hidden' };\n } else if (wideArea && this.props.inlineEditClass) {\n extraStyle = {\n overflow: 'auto', backgroundImage: `url(\"${fullScreenIcon}\")`, backgroundSize: '24px', backgroundRepeat: 'no-repeat', backgroundPosition: 'right 4px top 4px'\n };\n } else if (richText && !this.props.inlineEditClass) {\n extraStyle = { minWidth: '353px', minHeight: '150px', backgroundColor: 'white' };\n }\n\n if (this.props.themeVersion === 'v2' && this.props.cols && this.props.cols.value && this.props.rows && this.props.rows.value) {\n extraStyle.width = `${this.props.cols.value}px`;\n extraStyle.height = `${this.props.rows.value}px`;\n }\n\n let className = '';\n const hasSubLabel = subLabelObj && subLabelObj.text;\n // const maxLength = this.props.maxsize && this.props.maxsize.value && this.props.maxsize.value > 0;\n\n const maxEntry = this.props.entryLimit.value.split('-');\n const minEntry = this.props.entryLimitMin.value.split('-');\n const addLimits = (minEntry[1] > 1 && minEntry[0] !== 'None') || (maxEntry[1] >= 1 && maxEntry[0] !== 'None');\n\n const limit = maxEntry[1] && maxEntry[1] >= 1 ? maxEntry[1] : -1;\n const minimum = minEntry[1] && minEntry[1] > 1 ? minEntry[1] : -1;\n\n let readOnly = null;\n let required = null;\n let tabIndex = null;\n\n if (this.props.readonly && this.props.readonly.value === 'Yes') {\n readOnly = 'readOnly';\n tabIndex = -1;\n className += 'form-readonly ';\n }\n\n if (this.props.required && this.props.required.value === 'Yes') {\n required = 'required';\n }\n\n className += addValidation('form-textarea', this.props);\n\n let defaultValue = null;\n if (this.props.defaultValue && this.props.defaultValue.value) {\n defaultValue = (this.props.passive === true) ? this.props.defaultValue.value : htmlDecode(newlineToEntities(this.props.defaultValue.value));\n } else if (this.props.passive) {\n defaultValue = '';\n }\n\n if (addLimits) {\n return (\n
    \n \n {richText && this.props.inlineEditClass\n ? (\n
    \n {'Rich\n