[{"id":8,"name":"GOVX","script":" <i data-govx-id=\"s\"><\/i>","script_variable_json":""},{"id":12,"name":"Route","script":"<div class=\"route-div\" multiple-widgets desktop-align=\"center\" disable-reorder><\/div>\n\n<style>\n.rebuy-cart__flyout-item.tag-route {\ndisplay: none;\n}\n<\/style>","script_variable_json":""},{"id":20,"name":"Green Shipping Protection by Corso","script":"<script>\nlet corsoRebuyHasGsp = false;\nlet corsoGspWidgetElement = document.querySelector('#gsp-widget');\nlet corsoRebuyCartParent = document.querySelector('#rebuy-cart');\nif (document.querySelector('#rebuy-cart').contains(document.querySelector('#gsp-widget'))) {\n  corsoRebuyHasGsp = true;         \n}\nif (!corsoRebuyHasGsp && corsoGspWidgetElement) {\n  corsoGspWidgetElement.parentNode.removeChild(corsoGspWidgetElement);\n} \n<\/script>\n<style>\n#corso-wrapper #gsp-widget .gspa {\npadding: 1rem 0;\n}\n<\/style>\n<div id=\"corso-wrapper\">\n<div id=\"corso-protection-placeholder\" style=\"display:none\" at><\/div>\n<\/div>","script_variable_json":""},{"id":27,"name":"Recharge SMS","script":"<div id=\"rcsms-cart-widget\"><\/div>","script_variable_json":null},{"id":28,"name":"Attentive SMS Capture","script":"<!-- CSS -->\n<style>\n    .attentive-sca {\n        padding: 10px 0px;\n    }\n\n    .attentive-sca__header {\n        display: flex;\n        justify-content: space-between;\n        align-items: center;\n        margin-bottom: 5px;\n        cursor: pointer;\n    }\n\n    .attentive-sca__header-title {\n        font-size: 14px;\n        line-height: 17px;\n        font-weight: 600;\n        margin: 0px;\n    }\n\n    .attentive-sca__toggle {\n        border: 0px;\n        background: none;\n        cursor: pointer;\n    }\n\n    .attentive-sca__main {\n        display: flex;\n        flex-direction: column;\n    }\n\n    .attentive-sca__form {\n        display: flex;\n        align-items: center;\n        flex: 1;\n        height: 100%;\n        border: 1px solid black;\n        border-radius: 5px;\n        overflow: hidden;\n    }\n\n    .attentive-sca__form-country {\n        display: flex;\n        align-items: center;\n        margin: 0;\n        padding: 0 10px;\n        list-style: none;\n        height: 100%;\n        position: relative;\n    }\n\n    .attentive-sca__form-country::before {\n        content: \"\";\n        position: absolute;\n        right: 0;\n        height: 80%;\n        width: 1px;\n        background-color: #919191;\n    }\n\n    .attentive-sca__form-input {\n        height: 100%;\n        width: 100%;\n        padding-left: 10px;\n        display: flex;\n        align-items: center;\n    }\n\n    .attentive-sca__form-input span {\n        font-size: 14px;\n        line-height: 17px;\n        color: #000;\n        margin-right: 6px;\n    }\n\n    .attentive-sca__form-input input {\n        height: 100%;\n        width: 100%;\n        border: 0px;\n        font-size: 14px;\n        line-height: 17px;\n        color: #000;\n    }\n\n    .attentive-sca__submit {\n        height: 100%;\n        padding-left: 10px;\n    }\n\n    .attentive-sca__submit button {\n        height: 100%;\n        min-width: 100px;\n        cursor: pointer;\n    }\n\n    .attentive-sca__main-body {\n        display: flex;\n        align-items: center;\n        height: 45px;\n    }\n\n    .attentive-sca__main-body img {\n        display: block;\n        width: 35px;\n        height: auto;\n    }\n\n    .attentive-sca__feedback {\n        margin: 5px 0;\n        font-size: 11px;\n        line-height: 14px;\n    }\n\n    .attentive-sca__feedback.success-text {\n        color: #5cb85c;\n    }\n    .attentive-sca__feedback.error-text {\n        color: #cc0000;\n    }\n\n    .attentive-sca__legal-text {\n        margin: 5px 0;\n        font-size: 12px;\n        line-height: 14px;\n    }\n<\/style>\n\n<!-- Markup -->\n<div class=\"attentive-sca\" style=\"display: none\" data-attentive-phone-app>\n    <div class=\"attentive-sca__header\" onclick=\"attentiveApp.toggle()\">\n        <h3 class=\"attentive-sca__header-title\">{{PROMPT_TEXT}}<\/h3>\n        <div>\n            <button\n                class=\"attentive-sca__toggle\"\n                type=\"button\"\n                data-attentive-phone-expand\n                aria-label=\"Expand SMS signup form\"\n            >\n                <span>\n                    <svg\n                        width=\"12\"\n                        height=\"8\"\n                        viewBox=\"0 0 12 8\"\n                        fill=\"none\"\n                        xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n                        aria-hidden=\"true\"\n                    >\n                        <path\n                            d=\"M10.59 0.589844L6 5.16984L1.41 0.589844L0 1.99984L6 7.99984L12 1.99984L10.59 0.589844Z\"\n                            fill=\"#666E95\"\n                        \/>\n                    <\/svg>\n                <\/span>\n            <\/button>\n\n            <button\n                class=\"attentive-sca__toggle\"\n                type=\"button\"\n                style=\"display: none\"\n                data-attentive-phone-collapse\n                aria-label=\"Collapse SMS signup form\"\n            >\n                <span>\n                    <svg\n                        width=\"12\"\n                        height=\"8\"\n                        viewBox=\"0 0 12 8\"\n                        fill=\"none\"\n                        xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n                        aria-hidden=\"true\"\n                    >\n                        <path\n                            d=\"M10.59 7.40991L6 2.82991L1.41 7.40991L0 5.99991L6 -8.7738e-05L12 5.99991L10.59 7.40991Z\"\n                            fill=\"#666E95\"\n                        \/>\n                    <\/svg>\n                <\/span>\n            <\/button>\n        <\/div>\n    <\/div>\n\n    <div data-attentive-phone-app-body style=\"display: none\">\n        <div class=\"attentive-sca__legal\">\n            <p class=\"attentive-sca__legal-text\">\n                By submitting this form, you agree to receive recurring\n                automated promotional and personalized marketing text messages\n                (e.g. cart reminders) from\n                <span data-attentive-phone-shop-name><\/span> at the cell number\n                used when signing up. Consent is not a condition of any\n                purchase. Reply HELP for help and STOP to cancel. Msg frequency\n                varies. Msg & data rates may apply. View\n                <a href=\"{{TERMS_URL}}\" target=\"_blank\">Terms<\/a> &\n                <a href=\"{{PRIVACY_URL}}\" target=\"_blank\">Privacy<\/a>.\n            <\/p>\n        <\/div>\n\n        <div class=\"attentive-sca__main\">\n            <div class=\"attentive-sca__main-body\">\n                <!-- Input Form -->\n                <div class=\"attentive-sca__form\" aria-label=\"SMS signup form\">\n                    <ul class=\"attentive-sca__form-country\">\n                        <li>\n                            <span>\n                                <!-- United States Flag -->\n                                <img\n                                    width=\"120\"\n                                    height=\"63\"\n                                    src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAA\/CAYAAAArOQwGAAAAAXNSR0IArs4c6QAACbFJREFUeF7tm3lQVdcdx7+XHR\/LY18EBJegSMSlViM0GqvNZEJMY2JpM7bWaCdxQ1tNYorojEKjmdDE4JLMhCR2MYspiUrHacIkLoAxRgNGiAuy7yA7svM6vx\/znu8CMa\/e+2Yu9px\/lHvO\/d5zz+ed3\/n9fudc6YG58QaM4pJQcWYU9976XZfMATs42MHFxRmNjW0jPtndXcfXW1o6Rqz39HRFe3snenr6Rqy3hr4AfOcfiQnw+PEBiIgIga+fBzI\/v4iysjrTnTY2NggM9MKiRTP4Wmbmt6iquomBgQFTm+AQXyxePBN1tU0oKChDUVG17MnW0heALQQcFOSDN1LXobWlAzt2HEJp6W3AJHHffUF4+eVnQPb8zy+9g2vXKmTKISG+2LlrBdzddIiP34\/y8npZvbX0BWALAdvZ2SAu7iE0NLQgOzufTa29vS36+wcwMGCAXu+C+QumwWAATp+6hObmdtjYSLC1tUFvbz+b9ujoqfD2dsMHH5zk++zsbPnpfX39sIY+ab82rtv6C9kofoLJREuSxBAIIMExGAyYPTsc5eV1qKlpYpBUR0WSBtv4+3sgONgX589fBd1Pbaiur2\/w\/qio8YAE5OUWcb3a+tSXkxk7RvHwW7\/rMifL\/HGzfxqO+PgnGFTa2ydw6tQlWW8enD8Nq1c\/wuBS3\/gEX399VbZmz5sXgbXrlvC1A\/uPISenQLZmK9E370jO2b3WH6VR\/IQfBEwe829\/twgB\/p7Yvv0Qz1jzQrN1584VqK5pxN\/\/ljnMsyaPes3ax\/iWgweOD\/PMleob+yIAW7gGUzNnZ0cQmMrKBtja2sLFxQn29nYMhzxmPz89q9XWNoM8a2rb09uHjvYu9Pf3Y+xYb27b2dkNColIj6x6V2c3h05q6gvAlpkV0wyeODEQ0dGR8PJ2wyfpWSgurpGZ3JBgHyx9MoavpadnoaysXmZyw8L88cTSGNxsaEV2zmUUXq+S9cBa+ifefNayN\/0\/bWUC7OOjR+q+dWiob8Xu3e+joqJBNiShoX5ISl7J17YlvIuSklpZfVCQN7Zu\/TV8fNyxfv1+1Nc3y+qtpS\/CJAtNNJniWbMmobX1Fs\/eQTNrzyEOmWcPDxf4+3uyWk1NI5qaKEyy4VCop6eXzS\/NYlc3Z1y8UIje3j4271SM\/1dbn7QFYAsBD23m5OSAhQunc8KjuLgat27J480xYwhoAMaN88UXX+Siq6tHJuHs7IB50VP5Wk52Af9gzItSfaOWAHyXgCdPDsbmzU\/Bzt4Or7zyIb4vKJMpTYkIwQsvxKGvtw8pKR\/jypVyUz2FTlSfkPA0X\/tL8mFOX1LIZSxK9M07IgDfJWDKXMXGzuEZumfPR2yqzQuZ5hdfjENJaS3+nXGOM1vmhcx5bOxcAAZkZJxjs25elOobtQ7FDVoJUUYeAZOTRcDc3MaAnKHCwkqOe2km0qyjtZYyVORoUSEHiyYjrc3GNhQXT5w4lp0rWseN2TBqb8xyqalv\/MGJONjCGRweHoRly+aD1ta0tBO4ceP2bhABmjRpLFY+8zCrvfvOf3D9eqXM5E6YEIBVqx7htfrIkVO4elW+GWEtfQHYQsAE9s23NqKq8iZSUv41LMzx9dVj9+5VnLh4aWsa6uqGh0GbtzyJwAAvPPfc3hGdMmvoC8AWAqbME2WiaAbShj55xbRD1N3dw7tFFCZRIdNM5prCJNptcnR04J0n8ord9ToOl6oqGzhzpdM58T0dHV2c2VJbn7SzTqeI5fcOI\/CDuWjav419bA7P1LzcGzKTTXq0gT99xgTQzM44fg4VFbf3f8mkh4T4YNHiWfzozM8vcObL3ItWom\/+PmmPhgnAdwOYTnBQmKNzccKWzW+hoaFVJkP7vq+mPMt56OTkw3zCw1gIsH+AJ1JSBtOIdH91daMMsBJ9846IMMlCE230dmkTnzxgvV6H6JhIhIX64+DBDN5MIG+aCnnPtBmxZm0sZ72yz1xGc0sH7wfT4QCaqQEBnpg7dwq3\/+qr7xkwgVdL3\/haArAFgGlNdXUdw+ex\/Hz1uHSpiNdVAkLHrgick7M9IiNCWS2\/oARdnb3o6x8AMSegtF5PmzYetXXNfC6rvb0LBsPgFqMk2fDOlJr6bW232B8QgC0ATE2mT5+ATX9cCsOAAa+mfIz8yyUykztz5kRs3LSUr+19PR0XLxbKTO7UqaHYsuUpSDYSXn8tHbm5N2RPtpa+AGwhYJqte\/eu5b1gMsmtrfKjsTRDdyWtYLXExENob+uUKbu56bBmTSwCx3pj08YDMvhG828N\/eMpy4WTZYmTRZksb293DosorKEwh8IaSkHS3wSYTDkVMo1kwsfonOChd+EfBYVBOp0zHJ3s0VDfwqlNPz8Pbl9b28S7Tmrrk7aIgy2cwUOb3X9\/GJb96kG0NHfgzJnLfLDOGObQbKcDeTE\/i2Rn7MhHp\/Hdd8UmCXLGoqLC8Pjj8\/ja0aNnkZdXJDsgoETfvK8C8F0Cps2A7duXw9PLFX9Y\/VdOdpgXmpFvp\/0JjTfbsHPnP4ZtNtD9qfvW8y3xG\/ZxYsS8KNU3agnA\/wNg8pYdHe05m0VZKHKcKN797LMLbHIpW0XHYLs6e9jk\/uLhWXwCJD+\/hM04pTu7u3s5zKLzWuGTg\/npV6+U81ktNfWNr\/Xlp9vEGmzJGkxt6NwUZZhOnszjW4w7RcZ\/Y2Ii+XpW1uVhdXR9wYIozmgVFlaZ6s111NQ3vtMevfwLCkFbPgKmVOWcuVOQlPR7nolJu\/6Jb765ZmpJgOmrhYRtgxv4yUmH+esH89TjrJ9MQmLicp75idve4+SGebGWvgiTLDTRZD43xP8S9XXNOHbsLNqGhEF0jvk3Tz\/Eau8f\/nLYOWhXV2csWfIA7yenpn464jlqa+gLwBYCJs9Xp3PktZZCpKEH3SkMoplMhWbu0E9E6QdCbWht7ujolnnMdI+19AXgHwH884XPj+oPwJ+vzBHL7p2crNLSulEN2KtfnlETtIc4WQZzT0mMzj03ApIAfM8xlb2QAHxv84XUnJc\/qtfge5yP4teTMoJmCMCKh1G7AgKwdtmo0jMBWJVh1K6IAKxdNqr0TDq\/cqNYg1UZSm2KSL1t7QKwNtmo0isRB6syjNoVEYC1y0aVngnAqgyjdkWk8iPHxBqsXT6KeybCJMVDqG0BAVjbfBT3TgBWPITaFhCAtc1Hce+k8g+PCidL8TBqV0CESdplo0rPBGBVhlG7IgKwdtmo0jMBWJVh1K6I9O2GBOFkaZeP4p6JMEnxEGpbQADWNh\/FvROAFQ+htgUEYG3zUdy7\/wL6SdzC1o55iAAAAABJRU5ErkJggg==\"\n                                \/>\n                            <\/span>\n                        <\/li>\n                    <\/ul>\n\n                    <div class=\"attentive-sca__form-input\">\n                        <span>+1<\/span>\n                        <input\n                            placeholder=\"Phone Number\"\n                            type=\"number\"\n                            data-attentive-phone-input\n                            onkeyup=\"attentiveApp.validate(event)\"\n                            aria-label=\"Phone number for SMS updates\"\n                        \/>\n                    <\/div>\n                <\/div>\n\n                <!-- Submit Button -->\n                <div class=\"attentive-sca__submit\">\n                    <button\n                        type=\"button\"\n                        class=\"rebuy-button outline\"\n                        data-attentive-phone-submit\n                        onclick=\"attentiveApp.submit()\"\n                        disabled\n                        aria-label=\"Subscribe to SMS updates\"\n                    >\n                        Submit\n                    <\/button>\n                <\/div>\n            <\/div>\n\n            <div data-attentive-phone-feedback style=\"display: none\">\n                <p\n                    data-attentive-phone-error\n                    class=\"attentive-sca__feedback error-text\"\n                >\n                    <!-- ERROR MESSAGE -->\n                <\/p>\n                <p\n                    data-attentive-phone-success\n                    class=\"attentive-sca__feedback success-text\"\n                >\n                    Submission was successful!\n                <\/p>\n            <\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<!-- JS -->\n<script>\n    \/* Scripts go here *\/\n    (function () {\n        const selectors = {\n            app: \"[data-attentive-phone-app]\",\n            appBody: \"[data-attentive-phone-app-body]\",\n            expand: \"[data-attentive-phone-expand]\",\n            collapse: \"[data-attentive-phone-collapse]\",\n            input: \"[data-attentive-phone-input]\",\n            submit: \"[data-attentive-phone-submit]\",\n            feedback: \"[data-attentive-phone-feedback]\",\n            error: \"[data-attentive-phone-error]\",\n            success: \"[data-attentive-phone-success]\",\n            shopName: \"[data-attentive-phone-shop-name]\",\n        };\n\n        const dom = {};\n        const cacheDom = () => {\n            dom.app = document.querySelector(selectors.app);\n            dom.appBody = document.querySelector(selectors.appBody);\n            dom.expand = document.querySelector(selectors.expand);\n            dom.collapse = document.querySelector(selectors.collapse);\n            dom.input = document.querySelector(selectors.input);\n            dom.submit = document.querySelector(selectors.submit);\n            dom.feedback = document.querySelector(selectors.feedback);\n            dom.error = document.querySelector(selectors.error);\n            dom.success = document.querySelector(selectors.success);\n            dom.shopName = document.querySelector(selectors.shopName);\n        };\n\n        const app = {};\n\n        app.expand = () => {\n            dom.appBody.style.display = \"block\";\n            dom.expand.style.display = \"none\";\n            dom.collapse.style.display = \"block\";\n        };\n\n        app.collapse = () => {\n            dom.appBody.style.display = \"none\";\n            dom.expand.style.display = \"block\";\n            dom.collapse.style.display = \"none\";\n        };\n\n        app.toggle = () => {\n            if (dom.appBody.style.display === \"none\") {\n                app.expand();\n            } else {\n                app.collapse();\n            }\n        };\n\n        app.submit = () => {\n            let phone = dom.input.value;\n\n            if (phone && phone.length > 0) {\n                \/\/ prepend U.S. country code to phone number\n                phone = `+1${phone}`;\n\n                \/\/ hide all feedback\n                dom.error.style.display = \"none\";\n                dom.success.style.display = \"none\";\n                dom.feedback.style.display = \"none\";\n\n                \/\/ enter loading state\n                const submitText = dom.submit.innerText;\n                dom.submit.innerHTML = `<i class=\"rebuy-button-icon prefix fas fa-circle-notch fa-spin\"><\/i>`;\n\n                \/\/ build payload\n                const payload = {\n                    key: Rebuy.shop.api_key,\n                    signUpSourceId:\n                        Rebuy.shop.integrations.attentive.sign_up_source_id,\n                };\n\n                \/\/ send phone number to Klaviyo\n                const options = {\n                    method: \"POST\",\n                    headers: {\n                        \"Content-Type\":\n                            \"application\/x-www-form-urlencoded; charset=UTF-8\",\n                    },\n                    \/\/ append nested payload to query string\n                    body: `${new URLSearchParams(\n                        payload\n                    ).toString()}&user[phone]=${phone}`,\n                };\n\n                const cacheKeyString = Rebuy.shop.cache_key\n                    ? `?cache_key=${Rebuy.shop.cache_key}`\n                    : \"\";\n\n                \/\/ submit payload to attentive\n                fetch(\n                    `https:\/\/rebuyengine.com\/api\/v1\/integration\/attentive\/subscribe${cacheKeyString}`,\n                    options\n                )\n                    .then((response) => response.json())\n                    .then((response) => {\n                        \/\/ handle success \/ error\n                        console.log(response);\n\n                        if (response.value) {\n                            \/\/ show success message\n                            dom.success.style.display = \"block\";\n                            dom.feedback.style.display = \"block\";\n                            dom.input.value = \"\";\n                        } else {\n                            \/\/ set error message\n                            let errorText =\n                                \"Something went wrong. Please try again.\";\n                            \/\/ error - pull error message from response (GuzzleClient returns a large string containing a JSON object)\n                            \/*\n                example error response:\n                  \"Client error: `POST https:\/\/example.com\/example` resulted in a `400 Bad Request` response:\n                  {\"detail\":\"+123409823409823409 is not a valid phone number.\"}\n                  \"\n\n                Unfortunately, the Attentive response keeps getting truncated, so we can't pull the full error message from the response.\n              *\/\n                            if (response.message) {\n                                const responseLower =\n                                    response.message.toLowerCase();\n                                if (\n                                    responseLower.includes(\"error\") &&\n                                    responseLower.includes(\"400 bad request\")\n                                ) {\n                                    errorText =\n                                        \"Bad request. Please check that the phone number is valid and try again.\";\n                                }\n                            }\n                            \/\/ display error message\n                            dom.error.innerText = errorText;\n                            dom.error.style.display = \"block\";\n                            dom.feedback.style.display = \"block\";\n                        }\n                        \/\/ replace loading state\n                        dom.submit.innerHTML = submitText;\n                    })\n                    .catch((err) => console.error(err));\n            }\n        };\n\n        app.validate = (event) => {\n            if (event.target.value !== \"\") {\n                dom.error.style.display = \"none\"; \/\/ clear error\n                dom.submit.disabled = false; \/\/ enable submit\n                \/\/ allow submission with Enter key\n                if (event.code == \"Enter\") {\n                    app.submit();\n                }\n            } else {\n                dom.submit.disabled = true; \/\/ disable submit\n            }\n        };\n\n        cacheDom();\n        app.dom = dom;\n\n        \/\/ fill in shop name\n        const shopName = Rebuy.shop?.shop_name ?? false;\n        if (shopName && app.dom?.shopName) {\n            app.dom.shopName.innerText = shopName;\n        }\n\n        \/\/ Show app only if Rebuy\/Attentive integration is enabled and sign_up_source_id is set\n        if (\n            Rebuy.shop.integrations.attentive &&\n            Rebuy.shop.integrations.attentive.sign_up_source_id\n        ) {\n            dom.app.style.display = \"block\";\n        }\n\n        \/\/ attach to window\n        window.attentiveApp = app;\n    })();\n<\/script>\n","script_variable_json":"{\"PROMPT_TEXT\":{\"label\":\"This short-form message will be shown at the top of the Smart Cart app. (ex. 'Join our SMS Program')\",\"required\":true},\"TERMS_URL\":{\"label\":\"Enter the full URL for your Terms page for SMS handling.\",\"required\":true},\"PRIVACY_URL\":{\"label\":\"Enter the full URL for your Privacy policy page.\",\"required\":true}}"},{"id":32,"name":"Klaviyo SMS Capture","script":"<!-- CSS -->\n<style>\n    \/* Styles go here *\/\n    .klaviyo-sca {\n        padding: 10px 0px;\n    }\n\n    .klaviyo-sca__header {\n        display: flex;\n        justify-content: space-between;\n        align-items: center;\n        margin-bottom: 5px;\n        cursor: pointer;\n    }\n\n    .klaviyo-sca__header-title {\n        font-size: 14px;\n        line-height: 17px;\n        font-weight: 600;\n        margin: 0px;\n    }\n\n    .klaviyo-sca__toggle {\n        border: 0px;\n        background: none;\n        cursor: pointer;\n    }\n\n    .klaviyo-sca__main {\n        display: flex;\n        flex-direction: column;\n    }\n\n    .klaviyo-sca__form {\n        display: flex;\n        align-items: center;\n        flex: 1;\n        height: 100%;\n        border: 1px solid black;\n        border-radius: 5px;\n        overflow: hidden;\n    }\n\n    .klaviyo-sca__form-country {\n        display: flex;\n        align-items: center;\n        margin: 0;\n        padding: 0 10px;\n        list-style: none;\n        height: 100%;\n        position: relative;\n    }\n\n    .klaviyo-sca__form-country::before {\n        content: \"\";\n        position: absolute;\n        right: 0;\n        height: 80%;\n        width: 1px;\n        background-color: #919191;\n    }\n\n    .klaviyo-sca__form-input {\n        height: 100%;\n        width: 100%;\n        padding-left: 10px;\n        display: flex;\n        align-items: center;\n    }\n\n    .klaviyo-sca__form-input span {\n        font-size: 14px;\n        line-height: 17px;\n        color: #000;\n        margin-right: 6px;\n    }\n\n    .klaviyo-sca__form-input input {\n        height: 100%;\n        width: 100%;\n        border: 0px;\n        font-size: 14px;\n        line-height: 17px;\n        color: #000;\n    }\n\n    .klaviyo-sca__submit {\n        height: 100%;\n        padding-left: 10px;\n    }\n\n    .klaviyo-sca__submit button {\n        height: 100%;\n        min-width: 100px;\n        cursor: pointer;\n    }\n\n    .klaviyo-sca__main-body {\n        display: flex;\n        align-items: center;\n        height: 45px;\n    }\n\n    .klaviyo-sca__main-body img {\n        display: block;\n        width: 35px;\n        height: auto;\n    }\n\n    .klaviyo-sca__feedback {\n        margin: 5px 0;\n        font-size: 11px;\n        line-height: 14px;\n    }\n\n    .klaviyo-sca__feedback.success-text {\n        color: #5cb85c;\n    }\n    .klaviyo-sca__feedback.error-text {\n        color: #cc0000;\n    }\n\n    .klaviyo-sca__footer-text {\n        margin: 5px 0;\n        font-size: 12px;\n        line-height: 14px;\n    }\n<\/style>\n\n<!-- MARKUP -->\n<div class=\"klaviyo-sca\" data-klaviyo-phone-app>\n    <div class=\"klaviyo-sca__header\" onclick=\"klaviyoApp.toggle()\">\n        <h3 class=\"klaviyo-sca__header-title\">{{PROMPT_TEXT}}<\/h3>\n        <div>\n            <button\n                class=\"klaviyo-sca__toggle\"\n                type=\"button\"\n                data-klaviyo-phone-expand\n                aria-label=\"Expand SMS signup form\"\n            >\n                <span>\n                    <svg\n                        width=\"12\"\n                        height=\"8\"\n                        viewBox=\"0 0 12 8\"\n                        fill=\"none\"\n                        xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n                        aria-hidden=\"true\"\n                    >\n                        <path\n                            d=\"M10.59 0.589844L6 5.16984L1.41 0.589844L0 1.99984L6 7.99984L12 1.99984L10.59 0.589844Z\"\n                            fill=\"#666E95\"\n                        \/>\n                    <\/svg>\n                <\/span>\n            <\/button>\n\n            <button\n                class=\"klaviyo-sca__toggle\"\n                type=\"button\"\n                style=\"display: none\"\n                data-klaviyo-phone-collapse\n                aria-label=\"Collapse SMS signup form\"\n            >\n                <span>\n                    <svg\n                        width=\"12\"\n                        height=\"8\"\n                        viewBox=\"0 0 12 8\"\n                        fill=\"none\"\n                        xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n                        aria-hidden=\"true\"\n                    >\n                        <path\n                            d=\"M10.59 7.40991L6 2.82991L1.41 7.40991L0 5.99991L6 -8.7738e-05L12 5.99991L10.59 7.40991Z\"\n                            fill=\"#666E95\"\n                        \/>\n                    <\/svg>\n                <\/span>\n            <\/button>\n        <\/div>\n    <\/div>\n\n    <div data-klaviyo-phone-app-body style=\"display: none\">\n        <div class=\"klaviyo-sca__main\">\n            <div class=\"klaviyo-sca__main-body\">\n                <!-- Input Form -->\n                <div class=\"klaviyo-sca__form\" aria-label=\"SMS signup form\">\n                    <ul class=\"klaviyo-sca__form-country\">\n                        <li>\n                            <span>\n                                <!-- United States Flag -->\n                                <img\n                                    width=\"120\"\n                                    height=\"63\"\n                                    src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAA\/CAYAAAArOQwGAAAAAXNSR0IArs4c6QAACbFJREFUeF7tm3lQVdcdx7+XHR\/LY18EBJegSMSlViM0GqvNZEJMY2JpM7bWaCdxQ1tNYorojEKjmdDE4JLMhCR2MYspiUrHacIkLoAxRgNGiAuy7yA7svM6vx\/znu8CMa\/e+2Yu9px\/lHvO\/d5zz+ed3\/n9fudc6YG58QaM4pJQcWYU9976XZfMATs42MHFxRmNjW0jPtndXcfXW1o6Rqz39HRFe3snenr6Rqy3hr4AfOcfiQnw+PEBiIgIga+fBzI\/v4iysjrTnTY2NggM9MKiRTP4Wmbmt6iquomBgQFTm+AQXyxePBN1tU0oKChDUVG17MnW0heALQQcFOSDN1LXobWlAzt2HEJp6W3AJHHffUF4+eVnQPb8zy+9g2vXKmTKISG+2LlrBdzddIiP34\/y8npZvbX0BWALAdvZ2SAu7iE0NLQgOzufTa29vS36+wcwMGCAXu+C+QumwWAATp+6hObmdtjYSLC1tUFvbz+b9ujoqfD2dsMHH5zk++zsbPnpfX39sIY+ab82rtv6C9kofoLJREuSxBAIIMExGAyYPTsc5eV1qKlpYpBUR0WSBtv4+3sgONgX589fBd1Pbaiur2\/w\/qio8YAE5OUWcb3a+tSXkxk7RvHwW7\/rMifL\/HGzfxqO+PgnGFTa2ydw6tQlWW8enD8Nq1c\/wuBS3\/gEX399VbZmz5sXgbXrlvC1A\/uPISenQLZmK9E370jO2b3WH6VR\/IQfBEwe829\/twgB\/p7Yvv0Qz1jzQrN1584VqK5pxN\/\/ljnMsyaPes3ax\/iWgweOD\/PMleob+yIAW7gGUzNnZ0cQmMrKBtja2sLFxQn29nYMhzxmPz89q9XWNoM8a2rb09uHjvYu9Pf3Y+xYb27b2dkNColIj6x6V2c3h05q6gvAlpkV0wyeODEQ0dGR8PJ2wyfpWSgurpGZ3JBgHyx9MoavpadnoaysXmZyw8L88cTSGNxsaEV2zmUUXq+S9cBa+ifefNayN\/0\/bWUC7OOjR+q+dWiob8Xu3e+joqJBNiShoX5ISl7J17YlvIuSklpZfVCQN7Zu\/TV8fNyxfv1+1Nc3y+qtpS\/CJAtNNJniWbMmobX1Fs\/eQTNrzyEOmWcPDxf4+3uyWk1NI5qaKEyy4VCop6eXzS\/NYlc3Z1y8UIje3j4271SM\/1dbn7QFYAsBD23m5OSAhQunc8KjuLgat27J480xYwhoAMaN88UXX+Siq6tHJuHs7IB50VP5Wk52Af9gzItSfaOWAHyXgCdPDsbmzU\/Bzt4Or7zyIb4vKJMpTYkIwQsvxKGvtw8pKR\/jypVyUz2FTlSfkPA0X\/tL8mFOX1LIZSxK9M07IgDfJWDKXMXGzuEZumfPR2yqzQuZ5hdfjENJaS3+nXGOM1vmhcx5bOxcAAZkZJxjs25elOobtQ7FDVoJUUYeAZOTRcDc3MaAnKHCwkqOe2km0qyjtZYyVORoUSEHiyYjrc3GNhQXT5w4lp0rWseN2TBqb8xyqalv\/MGJONjCGRweHoRly+aD1ta0tBO4ceP2bhABmjRpLFY+8zCrvfvOf3D9eqXM5E6YEIBVqx7htfrIkVO4elW+GWEtfQHYQsAE9s23NqKq8iZSUv41LMzx9dVj9+5VnLh4aWsa6uqGh0GbtzyJwAAvPPfc3hGdMmvoC8AWAqbME2WiaAbShj55xbRD1N3dw7tFFCZRIdNM5prCJNptcnR04J0n8ord9ToOl6oqGzhzpdM58T0dHV2c2VJbn7SzTqeI5fcOI\/CDuWjav419bA7P1LzcGzKTTXq0gT99xgTQzM44fg4VFbf3f8mkh4T4YNHiWfzozM8vcObL3ItWom\/+PmmPhgnAdwOYTnBQmKNzccKWzW+hoaFVJkP7vq+mPMt56OTkw3zCw1gIsH+AJ1JSBtOIdH91daMMsBJ9846IMMlCE230dmkTnzxgvV6H6JhIhIX64+DBDN5MIG+aCnnPtBmxZm0sZ72yz1xGc0sH7wfT4QCaqQEBnpg7dwq3\/+qr7xkwgVdL3\/haArAFgGlNdXUdw+ex\/Hz1uHSpiNdVAkLHrgick7M9IiNCWS2\/oARdnb3o6x8AMSegtF5PmzYetXXNfC6rvb0LBsPgFqMk2fDOlJr6bW232B8QgC0ATE2mT5+ATX9cCsOAAa+mfIz8yyUykztz5kRs3LSUr+19PR0XLxbKTO7UqaHYsuUpSDYSXn8tHbm5N2RPtpa+AGwhYJqte\/eu5b1gMsmtrfKjsTRDdyWtYLXExENob+uUKbu56bBmTSwCx3pj08YDMvhG828N\/eMpy4WTZYmTRZksb293DosorKEwh8IaSkHS3wSYTDkVMo1kwsfonOChd+EfBYVBOp0zHJ3s0VDfwqlNPz8Pbl9b28S7Tmrrk7aIgy2cwUOb3X9\/GJb96kG0NHfgzJnLfLDOGObQbKcDeTE\/i2Rn7MhHp\/Hdd8UmCXLGoqLC8Pjj8\/ja0aNnkZdXJDsgoETfvK8C8F0Cps2A7duXw9PLFX9Y\/VdOdpgXmpFvp\/0JjTfbsHPnP4ZtNtD9qfvW8y3xG\/ZxYsS8KNU3agnA\/wNg8pYdHe05m0VZKHKcKN797LMLbHIpW0XHYLs6e9jk\/uLhWXwCJD+\/hM04pTu7u3s5zKLzWuGTg\/npV6+U81ktNfWNr\/Xlp9vEGmzJGkxt6NwUZZhOnszjW4w7RcZ\/Y2Ii+XpW1uVhdXR9wYIozmgVFlaZ6s111NQ3vtMevfwLCkFbPgKmVOWcuVOQlPR7nolJu\/6Jb765ZmpJgOmrhYRtgxv4yUmH+esH89TjrJ9MQmLicp75idve4+SGebGWvgiTLDTRZD43xP8S9XXNOHbsLNqGhEF0jvk3Tz\/Eau8f\/nLYOWhXV2csWfIA7yenpn464jlqa+gLwBYCJs9Xp3PktZZCpKEH3SkMoplMhWbu0E9E6QdCbWht7ujolnnMdI+19AXgHwH884XPj+oPwJ+vzBHL7p2crNLSulEN2KtfnlETtIc4WQZzT0mMzj03ApIAfM8xlb2QAHxv84XUnJc\/qtfge5yP4teTMoJmCMCKh1G7AgKwdtmo0jMBWJVh1K6IAKxdNqr0TDq\/cqNYg1UZSm2KSL1t7QKwNtmo0isRB6syjNoVEYC1y0aVngnAqgyjdkWk8iPHxBqsXT6KeybCJMVDqG0BAVjbfBT3TgBWPITaFhCAtc1Hce+k8g+PCidL8TBqV0CESdplo0rPBGBVhlG7IgKwdtmo0jMBWJVh1K6I9O2GBOFkaZeP4p6JMEnxEGpbQADWNh\/FvROAFQ+htgUEYG3zUdy7\/wL6SdzC1o55iAAAAABJRU5ErkJggg==\"\n                                \/>\n                            <\/span>\n                        <\/li>\n                    <\/ul>\n\n                    <div class=\"klaviyo-sca__form-input\">\n                        <span>+1<\/span>\n                        <input\n                            placeholder=\"Phone Number\"\n                            type=\"number\"\n                            data-klaviyo-phone-input\n                            onkeyup=\"klaviyoApp.validate(event)\"\n                            aria-label=\"Phone number for SMS updates\"\n                        \/>\n                    <\/div>\n                <\/div>\n\n                <!-- Submit Button -->\n                <div class=\"klaviyo-sca__submit\">\n                    <button\n                        type=\"button\"\n                        class=\"rebuy-button outline\"\n                        data-klaviyo-phone-submit\n                        onclick=\"klaviyoApp.submit()\"\n                        disabled\n                        aria-label=\"Subscribe to SMS updates\"\n                    >\n                        Submit\n                    <\/button>\n                <\/div>\n            <\/div>\n\n            <div data-klaviyo-phone-feedback style=\"display: none\">\n                <p\n                    data-klaviyo-phone-error\n                    class=\"klaviyo-sca__feedback error-text\"\n                >\n                    <!-- ERROR MESSAGE -->\n                <\/p>\n                <p\n                    data-klaviyo-phone-success\n                    class=\"klaviyo-sca__feedback success-text\"\n                >\n                    Submission was successful!\n                <\/p>\n            <\/div>\n        <\/div>\n\n        <div class=\"klaviyo-sca__footer\">\n            <p class=\"klaviyo-sca__footer-text\">\n                By submitting this form, you agree to receive recurring\n                automated promotional and personalized marketing text messages\n                (e.g. cart reminders) from\n                <span data-klaviyo-phone-shop-name><\/span> at the cell number\n                used when signing up. Consent is not a condition of any\n                purchase. Reply HELP for help and STOP to cancel. Msg frequency\n                varies. Msg & data rates may apply. View\n                <a href=\"{{TERMS_URL}}\" target=\"_blank\">Terms<\/a> &\n                <a href=\"{{PRIVACY_URL}}\" target=\"_blank\">Privacy<\/a>.\n            <\/p>\n        <\/div>\n    <\/div>\n<\/div>\n\n<!-- JS -->\n<script>\n    \/* Scripts go here *\/\n    (function () {\n        const selectors = {\n            app: \"[data-klaviyo-phone-app]\",\n            appBody: \"[data-klaviyo-phone-app-body]\",\n            expand: \"[data-klaviyo-phone-expand]\",\n            collapse: \"[data-klaviyo-phone-collapse]\",\n            input: \"[data-klaviyo-phone-input]\",\n            submit: \"[data-klaviyo-phone-submit]\",\n            feedback: \"[data-klaviyo-phone-feedback]\",\n            error: \"[data-klaviyo-phone-error]\",\n            success: \"[data-klaviyo-phone-success]\",\n            shopName: \"[data-klaviyo-phone-shop-name]\",\n        };\n\n        const dom = {};\n        const cacheDom = () => {\n            dom.app = document.querySelector(selectors.app);\n            dom.appBody = document.querySelector(selectors.appBody);\n            dom.expand = document.querySelector(selectors.expand);\n            dom.collapse = document.querySelector(selectors.collapse);\n            dom.input = document.querySelector(selectors.input);\n            dom.submit = document.querySelector(selectors.submit);\n            dom.feedback = document.querySelector(selectors.feedback);\n            dom.error = document.querySelector(selectors.error);\n            dom.success = document.querySelector(selectors.success);\n            dom.shopName = document.querySelector(selectors.shopName);\n        };\n\n        const app = {};\n\n        app.expand = () => {\n            dom.appBody.style.display = \"block\";\n            dom.expand.style.display = \"none\";\n            dom.collapse.style.display = \"block\";\n        };\n\n        app.collapse = () => {\n            dom.appBody.style.display = \"none\";\n            dom.expand.style.display = \"block\";\n            dom.collapse.style.display = \"none\";\n        };\n\n        app.toggle = () => {\n            if (dom.appBody.style.display === \"none\") {\n                app.expand();\n            } else {\n                app.collapse();\n            }\n        };\n\n        app.submit = () => {\n            let phone = dom.input.value;\n\n            if (phone && phone.length > 0) {\n                \/\/ prepend U.S. country code to phone number\n                phone = `+1${phone}`;\n\n                \/\/ hide all feedback\n                dom.error.style.display = \"none\";\n                dom.success.style.display = \"none\";\n                dom.feedback.style.display = \"none\";\n\n                \/\/ enter loading state\n                const submitText = dom.submit.innerText;\n                dom.submit.innerHTML = `<i class=\"rebuy-button-icon prefix fas fa-circle-notch fa-spin\"><\/i>`;\n\n                \/\/ build payload\n                const payload = {\n                    key: Rebuy.shop.api_key,\n                    phone: phone,\n                    list_id: \"{{LIST_ID}}\",\n                };\n\n                \/\/ send phone number to Klaviyo\n                const options = {\n                    method: \"POST\",\n                    headers: {\n                        \"Content-Type\":\n                            \"application\/x-www-form-urlencoded; charset=UTF-8\",\n                    },\n                    body: new URLSearchParams(payload),\n                };\n\n                const cacheKeyString = Rebuy.shop.cache_key\n                    ? `?cache_key=${Rebuy.shop.cache_key}`\n                    : \"\";\n\n                fetch(\n                    `https:\/\/rebuyengine.com\/api\/v1\/integration\/klaviyo\/subscribe${cacheKeyString}`,\n                    options\n                )\n                    .then((response) => response.json())\n                    .then((response) => {\n                        \/\/ handle success \/ error\n                        \/*\n            If the list is single opt-in, a successful response will return the user profile object.\n            If the list is double opt-in, a successful response will return an empty array.\n            source: https:\/\/developers.klaviyo.com\/en\/reference\/subscribe\n            *\/\n                        console.log(response);\n                        if (response.data && Array.isArray(response.data)) {\n                            \/\/ success\n                            dom.success.style.display = \"block\";\n                            dom.feedback.style.display = \"block\";\n                            dom.input.value = \"\";\n                        } else {\n                            \/\/ error - pull error message from response (GuzzleClient returns a large string containing a JSON object)\n                            \/*\n                example error response:\n                  \"Client error: `POST https:\/\/a.klaviyo.com\/api\/v2\/list\/RGdzUi\/subscribe` resulted in a `400 Bad Request` response:\n                  {\"detail\":\"+123409823409823409 is not a valid phone number.\"}\n                  \"\n              *\/\n                            let errorText =\n                                \"Something went wrong. Please try again.\";\n                            if (response.message) {\n                                if (\n                                    response.message\n                                        .toLowerCase()\n                                        .includes(\"error\") &&\n                                    response.message.includes(\"response:\")\n                                ) {\n                                    const responseObject = response.message\n                                        .split(\"response:\")[1]\n                                        .replaceAll(\"\\n\", \"\");\n                                    const responseObjectJSON =\n                                        JSON.parse(responseObject);\n                                    if (responseObjectJSON.detail) {\n                                        errorText = responseObjectJSON.detail;\n                                    }\n                                }\n                            }\n\n                            \/\/ set error text\n                            dom.error.innerText = errorText;\n                            dom.error.style.display = \"block\";\n                            dom.feedback.style.display = \"block\";\n                        }\n                        \/\/ replace loading state\n                        dom.submit.innerHTML = submitText;\n                    })\n                    .catch((err) => console.error(err));\n            }\n        };\n\n        app.validate = (event) => {\n            if (event.target.value !== \"\") {\n                dom.error.style.display = \"none\"; \/\/ clear error\n                dom.submit.disabled = false; \/\/ enable submit\n                \/\/ allow submission with Enter key\n                if (event.code == \"Enter\") {\n                    app.submit();\n                }\n            } else {\n                dom.submit.disabled = true; \/\/ disable submit\n            }\n        };\n\n        cacheDom();\n        app.dom = dom;\n\n        \/\/ attach to window\n        window.klaviyoApp = app;\n    })();\n<\/script>\n\n","script_variable_json":"{\"LIST_ID\":{\"label\":\"Klaviyo Target List ID that will collect your SMS Subscribers. To find the List ID, visit https:\\\/\\\/help.klaviyo.com\\\/hc\\\/en-us\\\/articles\\\/115005078647\",\"required\":true},\"PROMPT_TEXT\":{\"label\":\"App Label\\\/Prompt - this will be shown at the top of the Smart Cart app (ex. 'Join our SMS Program')\",\"required\":true},\"TERMS_URL\":{\"label\":\"Enter the full URL for your Terms page for SMS handling\",\"required\":true},\"PRIVACY_URL\":{\"label\":\"Enter the full URL for your Privacy policy page\",\"required\":true}}"},{"id":33,"name":"Okendo Reviews","script":"<!-- CSS -->\n<style>\n    .okendo-sca.rebuy-widget {\n        position: relative;\n        height: 130px;\n        display: none;\n        opacity: 0;\n        overflow: hidden;\n        padding: 0;\n        transition: opacity 0.25s ease-in-out, height 0.5s ease-in-out;\n    }\n    .okendo-sca.rebuy-widget.minimize {\n        height: 28px;\n    }\n    .okendo-sca.rebuy-widget.minimize .okendo-sca__toggle {\n        transform: rotate(180deg);\n    }\n    .okendo-sca.rebuy-widget .flickity-button.previous {\n        display: none;\n    }\n    .okendo-sca.rebuy-widget .flickity-button.next {\n        background: transparent;\n    }\n    .okendo-sca.rebuy-widget .flickity-button:focus {\n        box-shadow: none;\n    }\n    .okendo-sca__carousel {\n        \/* margin-bottom: 10px; *\/\n        height: 130px;\n        overflow: hidden;\n    }\n    .okendo-sca__slide {\n        height: 130px;\n        text-align: left;\n        width: 100%;\n        overflow: hidden;\n        margin-right: 10px;\n    }\n    .okendo-sca__stars {\n        color: #e1ab5b;\n        font-size: 18px;\n    }\n    .okendo-sca__days {\n        color: #ccc;\n        margin-left: 20px;\n    }\n    .okendo-sca__header {\n        display: flex;\n        align-items: center;\n        height: 28px;\n    }\n    .okendo-sca__product {\n        overflow: hidden;\n        text-overflow: ellipsis;\n        white-space: nowrap;\n        font-size: 15px;\n        margin: 0;\n    }\n    .okendo-sca__title {\n        font-size: 14px;\n        line-height: 1.1;\n        font-weight: 500;\n        overflow: hidden;\n        text-overflow: ellipsis;\n        white-space: nowrap;\n        display: block;\n        margin: 4px 0 8px;\n        width: calc(100% - 40px);\n    }\n    .okendo-sca__body {\n        display: -webkit-box;\n        -webkit-box-orient: vertical;\n        -webkit-line-clamp: 3;\n        overflow: hidden;\n        font-size: 12px;\n        line-height: 1.4;\n        margin: 16px 0 0 0;\n    }\n    .okendo-sca.rebuy-widget .flickity-button:disabled {\n        opacity: 0;\n    }\n    .okendo-sca__toggle {\n        position: absolute;\n        top: 5px;\n        right: 5px;\n        background: white;\n        z-index: 10;\n        transition: transform 0.5s ease-in-out;\n    }\n<\/style>\n\n<!-- HTML -->\n<div class=\"okendo-sca rebuy-widget\" data-okendo-app>\n    <button class=\"okendo-sca__toggle\" type=\"button\" data-okendo-toggle aria-label=\"Toggle product reviews\">\n        <svg\n            width=\"12\"\n            height=\"8\"\n            viewBox=\"0 0 12 8\"\n            fill=\"none\"\n            xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n            aria-hidden=\"true\"\n        >\n            <path\n                d=\"M10.59 0.589844L6 5.16984L1.41 0.589844L0 1.99984L6 7.99984L12 1.99984L10.59 0.589844Z\"\n                fill=\"#666E95\"\n            \/>\n        <\/svg>\n    <\/button>\n    <div class=\"okendo-sca__carousel\" data-okendo-carousel aria-label=\"Product reviews carousel\"><\/div>\n<\/div>\n\n<!-- JS -->\n<script>\n    (function () {\n        const devlog = (...args) => {\n            if (window.location.search.includes(\"rebuy_developer\")) {\n                console.log(...args);\n            }\n        };\n\n        \/\/ \/\/ uncomment this for testing\n        \/\/ if (!window.location.search.includes('rebuy_developer')) {\n        \/\/   return;\n        \/\/ }\n\n        \/\/ check that variable interpolation was successful\n        const apiKey = `{{SUBSCRIBER_ID}}`;\n        if (apiKey.includes(\"SUBSCRIBER_ID\")) {\n            console.error(\"Okendo Subscriber ID not set\");\n            return;\n        }\n\n        \/\/ selectors\n        const selectors = {\n            app: \"[data-okendo-app]\",\n            carousel: \"[data-okendo-carousel]\",\n            toggle: \"[data-okendo-toggle]\",\n        };\n\n        \/\/ cache elements on page load\n        const dom = {};\n        const cacheElements = () => {\n            dom.appElement = document.querySelector(selectors.app);\n            dom.carouselElement = document.querySelector(selectors.carousel);\n            dom.toggleElement = document.querySelector(selectors.toggle);\n        };\n\n        \/\/ define app object\n        let app = {\n            loading: false,\n        };\n\n        \/\/ fetch one single review from Okendo\n        const fetchReview = (productId) => {\n            return fetch(\n                `https:\/\/api.okendo.io\/v1\/stores\/{{SUBSCRIBER_ID}}\/products\/shopify-${productId}\/reviews?limit=1&orderBy=rating%20desc`\n            )\n                .then((response) => response.json())\n                .then((response) => {\n                    if (response.reviews) {\n                        const review = response.reviews[0];\n                        return review;\n                    } else {\n                        return null;\n                    }\n                })\n                .catch((err) => console.error(err));\n        };\n\n        \/\/ format date string to 'x days ago'\n        const formatReviewDate = (dateString) => {\n            const date = Date.parse(dateString);\n            const today = Date.now();\n            const diffTime = Math.abs(today - date);\n            const diffDays = Math.ceil(diffTime \/ (1000 * 60 * 60 * 24));\n\n            if (diffDays > 365) {\n                const diffYears = Math.floor(diffDays \/ 365);\n                return `${diffYears} year${diffYears > 1 ? \"s\" : \"\"} ago`;\n            } else if (diffDays > 30) {\n                const diffMonths = Math.floor(diffDays \/ 30);\n                return `${diffMonths} month${diffMonths > 1 ? \"s\" : \"\"} ago`;\n            } else if (diffDays >= 1) {\n                return `${diffDays} day${diffDays > 1 ? \"s\" : \"\"} ago`;\n            } else {\n                return \"Today\";\n            }\n        };\n\n        \/\/ format stars from rating\n        const formatReviewStars = (rating) => {\n            let starString = \"\";\n            for (let i = 1; i <= Math.round(rating); i++) {\n                starString += \"\u2605\";\n            }\n            return starString;\n        };\n\n        \/\/ format markup for review slide\n        const formatSlide = (review) => {\n            return `<div class=\"okendo-sca__slide\">\n        <div class=\"okendo-sca__header\">\n          <span class=\"okendo-sca__stars\" aria-label=\"Rating: ${review.rating} out of 5 stars\">${formatReviewStars(\n              review.rating\n          )}<\/span>\n          <span class=\"okendo-sca__days\" aria-label=\"Review date: ${formatReviewDate(\n              review.dateUpdated\n          )}\">${formatReviewDate(\n              review.dateUpdated\n          )}<\/span>\n        <\/div>\n\n        <h3 class=\"okendo-sca__product\">${review.productName}<\/h3>\n        <span class=\"okendo-sca__title\">${review.title}<\/span>\n        <p class=\"okendo-sca__body\">${review.body}<\/p>\n      <\/div>`;\n        };\n\n        \/\/ show \/ hide app\n        const showApp = () => {\n            const appEl =\n                dom.appElement || document.querySelector(selectors.app);\n            appEl.style.display = \"block\";\n            appEl.style.opacity = \"1\";\n        };\n\n        const hideApp = () => {\n            const appEl =\n                dom.appElement || document.querySelector(selectors.app);\n            appEl.style.display = \"none\";\n            appEl.style.opacity = \"0\";\n        };\n\n        const getCachedReviews = () => {\n            const cachedReviews = sessionStorage.getItem(\"okendo-sca\");\n            if (cachedReviews) {\n                return JSON.parse(cachedReviews);\n            } else {\n                return [];\n            }\n        };\n\n        const setCachedReviews = (reviews) => {\n            sessionStorage.setItem(\"okendo-sca\", JSON.stringify(reviews));\n        };\n\n        const removeStaleReviews = (items) => {\n            devlog(\"removeStaleReviews\");\n\n            const cachedReviews = getCachedReviews();\n\n            \/\/ determine if any items are no longer in the cart, so we can remove them\n            const staleReviews = cachedReviews.filter((review) => {\n                return !items.find(\n                    (item) =>\n                        item.product_id ==\n                        review.productId.replace(\"shopify-\", \"\")\n                );\n            });\n\n            if (staleReviews.length > 0) {\n                devlog(\"stale reviews in cache:\", staleReviews.length);\n                \/\/ remove reviews that are no longer in cart\n                cachedReviews.forEach((review, index) => {\n                    if (\n                        !items.find(\n                            (item) =>\n                                item.product_id ==\n                                review.productId.replace(\"shopify-\", \"\")\n                        )\n                    ) {\n                        cachedReviews.splice(index, 1);\n                    }\n                });\n\n                devlog(\"reviews in cache after removal:\", cachedReviews);\n\n                setCachedReviews(cachedReviews);\n            }\n        };\n\n        const buildCarousel = (items) => {\n            if (app.carousel && app.initialized) {\n                app.carousel.destroy();\n            }\n\n            const cachedReviews = getCachedReviews();\n\n            \/\/ if we have products in cart without cached reviews, fetch them\n            const itemsWithoutCachedReviews = items.filter((item) => {\n                return !cachedReviews.some(\n                    (review) =>\n                        review.productId.replace(\"shopify-\", \"\") ==\n                        item.product_id\n                );\n            });\n\n            devlog(\n                \"items that need reviews:\",\n                itemsWithoutCachedReviews.length,\n                itemsWithoutCachedReviews\n            );\n\n            \/\/ set loading state to prevent long-running fetches from being interrupted\n            app.loading = true;\n\n            \/\/ fetch reviews for new items + rebuild the carousel\n            const promises = itemsWithoutCachedReviews.map((item) =>\n                fetchReview(item.product_id)\n            );\n            app.loading &&\n                Promise.all(promises)\n                    .then((reviews) => {\n                        \/\/ filter out any null reviews\n                        const fetchedReviews = reviews.filter(\n                            (review) => review !== undefined && review !== null\n                        );\n                        devlog(\"fetched reviews\", fetchedReviews);\n\n                        \/\/ add fetched reviews to cached reviews\n                        const newReviews = [\n                            ...cachedReviews,\n                            ...fetchedReviews,\n                        ];\n\n                        devlog(\"cached reviews after fetch\", newReviews);\n\n                        \/\/ 'cache' reviews on app object\n                        setCachedReviews(newReviews);\n\n                        \/\/ sometimes items wont have reviews\n                        if (newReviews.length === 0) {\n                            hideApp();\n                            app.loading = false;\n                            return Promise.reject(\n                                \"No reviews for items in the cart\"\n                            );\n                        }\n\n                        return newReviews;\n                    })\n                    .then((reviews) => {\n                        const carouselElement =\n                            dom.carouselElement ||\n                            document.querySelector(selectors.carousel);\n                        \/\/ update carousel (in reverse order to show review for most recent product first)\n                        carouselElement.innerHTML = reviews\n                            .reverse()\n                            .map((review) => formatSlide(review))\n                            .join(\"\");\n                        return reviews;\n                    })\n                    .then((reviews) => {\n                        \/\/ init carousel\n                        app.carousel = new Rebuy.libraries.Flickity(\n                            selectors.carousel,\n                            {\n                                cellAlign: \"left\",\n                                wrapAround: true,\n                                pageDots: false,\n                                on: {\n                                    ready: function () {\n                                        devlog(\"carousel ready\");\n                                        showApp();\n                                        this.resize();\n\n                                        app.initialized = true;\n                                        app.loading = false;\n                                    },\n                                },\n                            }\n                        );\n                    })\n                    .catch((err) => {\n                        console.error(err);\n                        hideApp();\n                    })\n                    .finally(() => {\n                        app.loading = false;\n                    });\n        };\n\n        \/\/ listener functions\n        const okendoReviewsAppHandleCartChange = (event) => {\n            devlog(\"%c HANDLING CART CHANGE\", \"background: #222; color: #d7f\");\n\n            if (app.loading) {\n                devlog(\"app is loading, skipping update\");\n                return;\n            }\n\n            const newItems = event.detail?.cart?.cart?.items || app.cartItems;\n\n            if (newItems.length === 0) {\n                devlog(\"empty cart - returning\");\n                setCachedReviews([]);\n                return;\n            } else if (newItems.length === 1 && app.cartItems.length === 0) {\n                devlog(\n                    \"first item in cart - returning to allow the app to reinitialize\"\n                );\n                return;\n            }\n\n            if (newItems.length > app.cartItems.length) {\n                \/\/ product was added\n                \/\/ rebuild carousel\n                buildCarousel(newItems);\n            } else if (newItems.length < app.cartItems.length) {\n                \/\/ product was removed\n                \/\/ remove stale reviews from cache\n                removeStaleReviews(newItems);\n                \/\/ rebuild carousel\n                buildCarousel(newItems);\n            }\n\n            \/\/ update cart items\n            app.cartItems = newItems;\n        };\n\n        const okendoReviewsToggleApp = () => {\n            const appElement =\n                dom.appElement || document.querySelector(selectors.app);\n            appElement.classList.toggle(\"minimize\");\n        };\n\n        const setListeners = () => {\n            if (window.okendoReviewsListenersSet) {\n                return;\n            }\n\n            devlog(\"setting listeners\");\n\n            window.okendoReviewsToggleApp = okendoReviewsToggleApp;\n            window.okendoReviewsAppHandleCartChange =\n                okendoReviewsAppHandleCartChange;\n\n            \/\/ click listener to toggle reviews in cart\n            dom.toggleElement.addEventListener(\n                \"click\",\n                window.okendoReviewsToggleApp\n            );\n\n            \/\/ listen for cart updates\n            document.addEventListener(\n                \"rebuy:cart.change\",\n                window.okendoReviewsAppHandleCartChange\n            );\n\n            window.okendoReviewsListenersSet = true;\n        };\n\n        const removeListeners = () => {\n            if (!window.okendoReviewsListenersSet) {\n                return;\n            }\n            devlog(\"removing listeners\");\n            \/\/ click listener to toggle reviews in cart\n            dom.toggleElement &&\n                dom.toggleElement.removeEventListener(\n                    \"click\",\n                    window.okendoReviewsToggleApp\n                );\n\n            \/\/ listen for cart updates\n            document.removeEventListener(\n                \"rebuy:cart.change\",\n                window.okendoReviewsAppHandleCartChange\n            );\n\n            window.okendoReviewsListenersSet = false;\n        };\n\n        const run = () => {\n            devlog(\"RUN FUNCTION CALLED - INITIAL LOAD\");\n\n            \/\/ flickity flag\n            app.initialized = false;\n            \/\/ loading flag\n            app.loading = false;\n\n            \/\/ removing listeners\n            removeListeners();\n\n            if (app.carousel) {\n                app.carousel = null;\n            }\n\n            \/\/ define cart items on page load\n            app.cartItems = Rebuy.Cart.cart.items ?? [];\n            devlog(\"cart items\", app.cartItems);\n\n            if (app.cartItems.length > 0) {\n                buildCarousel(app.cartItems);\n            } else {\n                app.carousel = null;\n                hideApp();\n            }\n\n            cacheElements();\n\n            setListeners();\n\n            window.okendoReviewsApp = app;\n        };\n\n        run();\n    })();\n<\/script>\n","script_variable_json":"{\"SUBSCRIBER_ID\":{\"label\":\"Please enter subscriber ID\",\"required\":true}}"},{"id":35,"name":"Stamped Loyalty","script":"<!-- CSS -->\n<style>\n    .stamped-sca {\n        margin-bottom: 20px;\n    }\n    .stamped-sca__contents {\n        text-align: left;\n    }\n    .stamped-sca__description {\n        font-size: 14px;\n    }\n    .stamped-sca__actions {\n        display: flex;\n        font-size: 15px;\n        margin-top: 15px;\n    }\n    .stamped-sca__title {\n        font-size: 16px;\n        margin-bottom: 0;\n    }\n    .stamped-sca__input {\n        flex: 1;\n        border: 1px solid #000 !important;\n        border-radius: 5px;\n        padding: 10px;\n        margin-right: 20px;\n        letter-spacing: 0.8px;\n    }\n    .stamped-sca__error {\n        display: none;\n        color: red;\n    }\n    .stamped-sca__submit-button {\n        text-transform: uppercase;\n        border: 1px solid #000 !important;\n        border-radius: 5px;\n        letter-spacing: 0.8px;\n        padding: 10px;\n    }\n    .stamped-sca__account {\n        display: none;\n        position: relative;\n        text-align: center;\n    }\n    .stamped-sca__account.toggled .stamped-sca__points {\n        display: flex;\n        justify-content: center;\n        align-items: center;\n    }\n    .stamped-sca__account.toggled .stamped-sca__point {\n        font-size: 20px;\n    }\n    .stamped-sca__account.toggled .stamped-sca__points-label {\n        margin-left: 5px;\n    }\n    .stamped-sca__account.toggled .stamped-sca__email {\n        display: none;\n    }\n    .stamped-sca__points {\n        display: block;\n        font-weight: bold;\n        font-size: 40px;\n    }\n    .stamped-sca__points-label {\n        font-weight: bold;\n        font-size: 12px;\n    }\n    .stamped-sca__email {\n        font-size: 12px;\n    }\n    .stamped-sca__toggle {\n        position: absolute;\n        top: 5px;\n        right: 5px;\n        z-index: 10;\n        transition: transform 0.5s ease-in-out;\n    }\n    .stamped-sca__toggle.toggled {\n        transform: rotate(180deg);\n    }\n<\/style>\n\n<!-- HTML -->\n<div class=\"stamped-sca\" data-stamped-app>\n    <div class=\"stamped-sca__contents\">\n        <div class=\"stamped-sca__login\" data-stamped-login>\n            <h3 class=\"stamped-sca__title\">{{TITLE}}<\/h3>\n            <label class=\"stamped-sca__label\">{{DESCRIPTION}}<\/label>\n\n            <div class=\"stamped-sca__actions\">\n                <input\n                    class=\"stamped-sca__input\"\n                    type=\"email\"\n                    placeholder=\"EMAIL ADDRESS\"\n                    onkeyup=\"stampedApp.validate(event)\"\n                    data-stamped-input\n                    aria-label=\"Email address for loyalty program\"\n                \/>\n                <button\n                    class=\"stamped-sca__submit-button\"\n                    onclick=\"stampedApp.submit()\"\n                    disabled\n                    data-stamped-submit\n                    aria-label=\"Submit email for loyalty points\"\n                >\n                    Submit\n                <\/button>\n            <\/div>\n\n            <span class=\"stamped-sca__error\" data-stamped-error aria-label=\"Error message: Invalid input\"\n                >Invalid input<\/span\n            >\n        <\/div>\n\n        <div class=\"stamped-sca__account\" data-stamped-account>\n            <button\n                class=\"stamped-sca__toggle\"\n                type=\"button\"\n                data-stamped-toggle\n                aria-label=\"Toggle loyalty account view\"\n            >\n                <svg\n                    width=\"12\"\n                    height=\"8\"\n                    viewBox=\"0 0 12 8\"\n                    fill=\"none\"\n                    xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n                    aria-hidden=\"true\"\n                >\n                    <path\n                        d=\"M10.59 0.589844L6 5.16984L1.41 0.589844L0 1.99984L6 7.99984L12 1.99984L10.59 0.589844Z\"\n                        fill=\"#666E95\"\n                    \/>\n                <\/svg>\n            <\/button>\n\n            <div class=\"stamped-sca__points\" data-stamped-points>\n                <div class=\"stamped-sca__point\" data-stamped-point><\/div>\n                <div class=\"stamped-sca__points-label\">YOUR POINTS<\/div>\n            <\/div>\n            <div class=\"stamped-sca__email\" data-stamped-email><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<!-- JS -->\n<script>\n    (function () {\n        const $ = Rebuy.libraries.$;\n        const dom = {};\n        const app = {};\n        const selectors = {\n            app: \"[data-stamped-app]\",\n            input: \"[data-stamped-input]\",\n            submit: \"[data-stamped-submit]\",\n            login: \"[data-stamped-login]\",\n            account: \"[data-stamped-account]\",\n            toggle: \"[data-stamped-toggle]\",\n            points: \"[data-stamped-points]\",\n            point: \"[data-stamped-point]\",\n            email: \"[data-stamped-email]\",\n            error: \"[data-stamped-error]\",\n        };\n\n        const cacheDom = () => {\n            dom.app = document.querySelector(selectors.app);\n            dom.input = document.querySelector(selectors.input);\n            dom.submit = document.querySelector(selectors.submit);\n            dom.login = document.querySelector(selectors.login);\n            dom.account = document.querySelector(selectors.account);\n            dom.points = document.querySelector(selectors.points);\n            dom.point = document.querySelector(selectors.point);\n            dom.email = document.querySelector(selectors.email);\n            dom.error = document.querySelector(selectors.error);\n        };\n\n        $(selectors.toggle).on(\"click\", () => {\n            $(selectors.toggle).toggleClass(\"toggled\");\n            $(selectors.account).toggleClass(\"toggled\");\n        });\n\n        app.validate = (event) => {\n            if (event.target.value !== \"\") {\n                dom.error.style.display = \"none\"; \/\/ clear error\n                dom.submit.disabled = false; \/\/ enable submit\n\n                if (event.code == \"Enter\") app.submit(); \/\/ allow submit with enter\n            } else {\n                dom.submit.disabled = true; \/\/ disable submit\n            }\n        };\n\n        function setCookie(cname, cvalue, exdays) {\n            const d = new Date();\n            d.setTime(d.getTime() + exdays * 24 * 60 * 60 * 1000);\n            let expires = \"expires=\" + d.toUTCString();\n            document.cookie = cname + \"=\" + cvalue + \";\" + expires + \";path=\/\";\n        }\n\n        function getCookie(cname) {\n            let name = cname + \"=\";\n            let ca = document.cookie.split(\";\");\n            for (let i = 0; i < ca.length; i++) {\n                let c = ca[i];\n                while (c.charAt(0) == \" \") {\n                    c = c.substring(1);\n                }\n                if (c.indexOf(name) == 0) {\n                    return c.substring(name.length, c.length);\n                }\n            }\n            return \"\";\n        }\n\n        function showLogin() {\n            let point = getCookie(\"stampedPoints\");\n            email = getCookie(\"stampedEmail\");\n\n            $(selectors.login).hide();\n            $(selectors.account).show();\n            $(selectors.point).text(point);\n            $(selectors.email).text(email);\n        }\n\n        let stampedPoints = getCookie(\"stampedPoints\");\n        let stampedEmail = getCookie(\"stampedEmail\");\n\n        if (stampedPoints !== undefined && stampedEmail) {\n            showLogin();\n        }\n\n        app.submit = (event) => {\n            let email = dom.input.value;\n            let credentials = btoa(\"{{PUBLIC_API_KEY}}:{{PRIVATE_API_KEY}}\");\n\n            const options = {\n                method: \"GET\",\n                headers: {\n                    Authorization: `Basic ${credentials}`,\n                    \"Content-Type\":\n                        \"application\/x-www-form-urlencoded; charset=UTF-8\",\n                },\n            };\n\n            fetch(\n                `https:\/\/stamped.io\/api\/v2\/{{STORE_HASH}}\/dashboard\/customers\/?search=${email}`,\n                options\n            )\n                .then((response) => response.json())\n                .then((response) => {\n                    if (response.results.length) {\n                        console.log(response);\n\n                        setCookie(\n                            \"stampedPoints\",\n                            response.results[0].points,\n                            1\n                        );\n                        setCookie(\"stampedEmail\", email, 1);\n\n                        showLogin();\n                    }\n                })\n                .catch((error) => {\n                    console.error(error);\n                    $(dom.error).show();\n                });\n        };\n\n        cacheDom();\n        app.dom = dom;\n\n        window.stampedApp = app; \/\/ attach to window\n    })();\n<\/script>\n","script_variable_json":"{\"PUBLIC_API_KEY\":{\"label\":\"Enter public API key\",\"required\":true},\"PRIVATE_API_KEY\":{\"label\":\"Enter private API key\",\"required\":true},\"STORE_HASH\":{\"label\":\"Enter store hash\",\"required\":true},\"TITLE\":{\"label\":\"Enter title\",\"required\":true},\"DESCRIPTION\":{\"label\":\"Enter description\",\"required\":true}}"},{"id":40,"name":"nudgem surveys","script":"<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/@nudgem\/nudgem-helper\/dist\/index.min.js\"><\/script>","script_variable_json":""},{"id":44,"name":"YouPay","script":"<style>.rebuy-modal-visible #dummy-chat-button-iframe {display: none;}<\/style>\n<div class=\"youpay-button-group youpay-container\" data-theme=\"vanilla\" data-type=\"flyout\" data-id=\"code\">\n    <button class=\"youpay-button\" type=\"button\">\n        <div class=\"youpay-text-group\">\n            <span class=\"youpay-text\" data-text-3=\"Get it paid for you with\" data-text-2=\"Get it paid for with\" data-text-1=\"Get it paid\">Get it paid for you with<\/span>\n        <\/div>\n        <div class=\"youpay-logo-container\">\n            <svg class=\"youpay-logo youpay-logo-colour\" viewBox=\"0 0 121 22\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n              <path d=\"M44.71 1.993a1.882 1.882 0 0 1-.093.507l-7.06 18.903c-.142.4-.718.601-1.724.601h-.525c-1.232 0-1.848-.2-1.848-.601.001-.177.043-.352.123-.51l1.94-4.766-5.086-13.631c-.059-.164-.1-.334-.123-.507 0-.415.627-.622 1.88-.622h.99c1.007 0 1.582.197 1.726.591l1.818 5.212c.186.528.474 1.664.864 3.408h.122c.412-1.805.7-2.941.864-3.408l1.818-5.212c.145-.4.72-.59 1.727-.59h.74c1.233.002 1.849.21 1.847.625zM46.348 14.447c-1.278-1.313-1.917-3.198-1.915-5.657 0-2.459.64-4.34 1.915-5.64 1.274-1.3 3.133-1.95 5.578-1.95 2.444 0 4.298.65 5.563 1.95 1.265 1.295 1.898 3.176 1.898 5.64 0 2.464-.633 4.35-1.898 5.657-1.263 1.31-3.118 1.964-5.563 1.962-2.446-.001-4.305-.655-5.578-1.962zm7.725-2.426c.462-.723.693-1.8.693-3.231 0-1.431-.231-2.5-.693-3.207-.461-.715-1.176-1.073-2.144-1.073-.967 0-1.686.358-2.157 1.073-.472.716-.709 1.785-.709 3.207 0 2.878.956 4.318 2.866 4.318.962 0 1.676-.362 2.144-1.087zM62.218 15.295c-.74-.743-1.11-1.895-1.11-3.456V2.273c0-.601.617-.902 1.85-.902h.862c1.235 0 1.851.3 1.85.902v8.944c0 .583.144 1.02.432 1.311.287.293.76.438 1.418.438a2.313 2.313 0 0 0 1.464-.488 3.89 3.89 0 0 0 1.002-1.142V2.273c0-.601.617-.902 1.85-.902h.856c1.234 0 1.85.3 1.85.902v8.944c-.01.66.016 1.319.077 1.975.051.452.117.95.198 1.495.055.203.087.412.093.622 0 .3-.416.527-1.248.675a12.43 12.43 0 0 1-2.205.227.785.785 0 0 1-.77-.401 3.613 3.613 0 0 1-.325-.888c-.071-.32-.117-.537-.138-.65a6.004 6.004 0 0 1-1.957 1.524 5.73 5.73 0 0 1-2.635.621c-1.537-.005-2.675-.38-3.414-1.122zM77.722 21.43V5.716c0-1.24-.062-2.129-.184-2.666-.125-.535-.187-.832-.187-.888 0-.227.198-.391.595-.493a4.197 4.197 0 0 1 1.08-.157.658.658 0 0 1 .631.401c.134.275.237.564.307.862.071.3.119.497.139.592 1.475-1.409 3.106-2.113 4.894-2.113a5.33 5.33 0 0 1 3.22.972 6.143 6.143 0 0 1 2.05 2.68c.492 1.242.733 2.571.71 3.909 0 1.604-.264 2.967-.793 4.09a5.794 5.794 0 0 1-2.198 2.581 6.084 6.084 0 0 1-3.266.874 7.114 7.114 0 0 1-2.39-.367c-.719-.26-1.399-.62-2.02-1.07v6.517c0 .413-.41.62-1.231.62h-.125c-.822-.006-1.232-.215-1.232-.628zm9.493-8.52c.7-.903 1.05-2.2 1.048-3.894 0-1.824-.33-3.227-.99-4.21a3.197 3.197 0 0 0-1.208-1.117 3.152 3.152 0 0 0-1.597-.363 5.054 5.054 0 0 0-2.141.507 7 7 0 0 0-2.016 1.429v7.734a6.135 6.135 0 0 0 3.822 1.268c1.351 0 2.378-.451 3.082-1.355zM94.307 15.285c-.967-.716-1.45-1.77-1.45-3.161 0-1.487.488-2.601 1.463-3.344a7.769 7.769 0 0 1 3.592-1.437 37.222 37.222 0 0 1 5.179-.353V5.663a2.129 2.129 0 0 0-.201-.95 2.093 2.093 0 0 0-.601-.756c-.528-.442-1.391-.663-2.589-.663a8.473 8.473 0 0 0-2.377.296c-.576.161-1.143.359-1.695.592-.24.116-.487.215-.741.296-.198 0-.436-.188-.693-.563-.258-.375-.38-.658-.38-.858 0-.243.27-.507.816-.79a9.066 9.066 0 0 1 2.178-.72c.92-.197 1.858-.296 2.799-.294 1.912 0 3.402.39 4.47 1.17 1.069.781 1.603 1.867 1.603 3.258v6.326c0 1.242.062 2.13.186 2.666.123.536.184.832.184.888 0 .227-.198.401-.594.495a4.284 4.284 0 0 1-1.078.155.66.66 0 0 1-.631-.437 4.435 4.435 0 0 1-.309-.918 35.203 35.203 0 0 1-.139-.62c-1.39 1.412-3.114 2.116-5.172 2.115-1.581 0-2.855-.355-3.82-1.066zm6.55-1.496c.8-.385 1.55-.868 2.234-1.439V9.017c-1.541.02-2.799.076-3.775.17a6.219 6.219 0 0 0-2.575.79 2.141 2.141 0 0 0-.84.84c-.197.355-.29.758-.27 1.164 0 .751.221 1.325.662 1.72.441.396 1.094.596 1.96.601a6.145 6.145 0 0 0 2.604-.517v.004zM121 1.854c-.009.138-.04.274-.093.401l-7.923 19.214c-.164.4-.645.601-1.448.601h-.461c-.679 0-1.018-.15-1.018-.45.027-.167.079-.329.154-.48l2.589-5.775-5.393-13.148a1.23 1.23 0 0 1-.093-.363c0-.32.441-.479 1.325-.479h.247c.719 0 1.129.15 1.232.451l3.146 7.646c.327.828.657 1.778.99 2.85h.061c.04-.132.082-.258.123-.38.042-.123.081-.241.123-.354l.766-2.116 3.082-7.65c.103-.3.525-.45 1.266-.45h.091c.823 0 1.234.16 1.234.482z\" fill=\"currentColor\"><\/path>\n              <path d=\"M11.167 11.29V.05H0s7.487 6.537 8.767 17.57c0 0 2.4-1.52 2.4-6.33z\" fill=\"currentColor\"><\/path>\n              <path d=\"M17.511 8.746V.05h-6.338v11.24c0 4.81-2.4 6.33-2.4 6.33a8.73 8.73 0 0 0 6.176-2.614 8.943 8.943 0 0 0 2.562-6.26z\" fill=\"none\"><\/path>\n              <path d=\"M17.96.05h-.454v8.696a8.94 8.94 0 0 1-2.561 6.261 8.726 8.726 0 0 1-6.178 2.613l9.192-.012a8.584 8.584 0 0 0 3.36-.63 8.667 8.667 0 0 0 2.86-1.894 8.786 8.786 0 0 0 1.914-2.864 8.871 8.871 0 0 0 0-6.781 8.786 8.786 0 0 0-1.915-2.865A8.666 8.666 0 0 0 21.32.68a8.584 8.584 0 0 0-3.36-.63z\" fill=\"currentColor\"><\/path>\n            <\/svg>\n        <\/div>\n    <\/button>\n<\/div>","script_variable_json":""},{"id":45,"name":"Inveterate","script":"<style>\n  .inveterate-rebuy {\n    display: none;\n  }\n\n  .inveterate-rebuy.inveterate--visible {\n    display: block;\n  }\n\n  .inveterate--hidden {\n    display: none !important;\n  }\n\n  .inveterate-rebuy__wrapper {\n    display: flex;\n    align-items: flex-start;\n    justify-content: flex-start;\n    flex-direction: column;\n\n    margin: 10px 0;\n    padding: 24px;\n    border: 1px solid #cfcfcf;\n    border-radius: 10px;\n\n    \/* overflow: hidden scroll; *\/\n    overflow: hidden;\n  }\n\n  .inveterate-rebuy__upper-content {\n    display: flex;\n    justify-content: flex-start;\n\n    width: 404px;\n    height: 113px;\n\n    overflow: hidden;\n    gap: 8px;\n  }\n\n  .inveterate-rebuy__image-wrapper {\n    width: 124px;\n    height: 113px;\n\n    max-width: 124px;\n    max-height: 113px;\n\n    overflow: hidden;\n\n    display: flex;\n    flex-direction: column;\n    justify-content: center;\n    align-items: center;\n\n    position: relative;\n  }\n\n  .inveterate-rebuy__image-wrapper > img {\n    height: 113px;\n\n    margin: auto;\n  }\n\n  .inveterate-rebuy__image {\n    max-width: 100%;\n    max-height: 100%;\n\n    border-radius: 6px;\n  }\n\n  .inveterate-rebuy__info {\n    display: flex;\n    flex-direction: column;\n    justify-content: space-between;\n    align-items: stretch;\n\n    width: calc(100% - 125px);\n    height: 113px;\n\n    padding-left: 24px;\n    gap: 8px;\n  }\n\n  .inveterate-rebuy__title {\n    font-size: 20px;\n    margin: -8px 0 0 0 !important;\n  }\n\n  .inveterate-rebuy__title > a {\n    text-decoration: none;\n    color: black;\n  }\n\n  .inveterate-rebuy__pricing-options {\n    display: flex;\n    justify-content: flex-start;\n    align-items: center;\n\n    width: 256px;\n    height: 120px;\n    font-size: 16px;\n\n    margin: -4px 0 0 0 !important;\n\n    \/* overflow: auto hidden; *\/\n    overflow: hidden;\n  }\n\n  .inveterate-rebuy__pricing-options > button {\n    display: flex;\n    flex-direction: row;\n    justify-content: center;\n\n    cursor: pointer;\n\n    font-size: 16px;\n    font-weight: 400;\n    line-height: 21px;\n\n    width: calc(50% - 5px);\n    height: 37px;\n    padding: 8px 16px;\n\n    background: transparent;\n    border: 1px solid #cfcfcf;\n    border-radius: 4px;\n\n    color: #818181;\n\n    transition: all 0.3s ease-in-out;\n  }\n\n  .inveterate-rebuy__pricing-options > button:not(:last-child) {\n    margin-right: 8px;\n  }\n\n  .inveterate-rebuy__pricing-options > button.selected {\n    border: 1px solid #000000;\n    color: #000000;\n  }\n\n  .inveterate-rebuy__pricing-options > button.not-selected {\n    opacity: 70%;\n  }\n\n  .inveterate-rebuy__price_text {\n    margin: 5px 0;\n  }\n\n  .inveterate-rebuy__price {\n    color: grey;\n  }\n\n  .inveterate-rebuy__add-button > button {\n    display: flex;\n    flex-direction: row;\n    justify-content: center;\n    align-items: center;\n\n    cursor: pointer;\n\n    font-size: 14px;\n    font-weight: 500;\n\n    height: 34px;\n    padding: 8px 16px;\n\n    background: #3c3c3c;\n    border: 1px solid #cfcfcf;\n    border-radius: 6px;\n\n    color: white;\n\n    transition: all 0.3s ease-in-out;\n\n    border-radius: 6px;\n\n    \/* Inside auto layout *\/\n\n    flex: none;\n    order: 2;\n    align-self: stretch;\n    flex-grow: 0;\n  }\n\n  .inveterate-rebuy__add-button > button:hover {\n    background: #737373;\n  }\n\n  .inveterate-rebuy__add-button > button:disabled {\n    \/* opacity: 0; *\/\n    cursor: default;\n    color: white;\n    background-color: #8e8e8e;\n  }\n\n  .inveterate-rebuy__add-button > button.wide {\n    min-width: 100%;\n  }\n\n  .inveterate-rebuy__lower-content {\n    height: 50px;\n  }\n\n  .inveterate-rebuy__description {\n    width: 404px;\n    height: 63px;\n\n    \/* Body\/Medium *\/\n\n    \/* font-family: \"Neue Haas Grotesk Text Pro\"; *\/\n    font-style: normal;\n    font-weight: 400;\n    font-size: 16px;\n    line-height: 21px;\n    \/* or 21px *\/\n\n    color: #5c5c5c;\n\n    \/* Inside auto layout *\/\n\n    flex: none;\n    order: 1;\n    align-self: stretch;\n    flex-grow: 0;\n  }\n\n  .inveterate-rebuy__button {\n    appearance: none;\n    background-color: blue;\n    border: 0;\n    color: white;\n    cursor: pointer;\n    padding: 7px 30px;\n  }\n\n  .property-key-_inveterate_rebuy .rebuy-cart__flyout-item-quantity {\n    opacity: 0;\n    pointer-events: none;\n    visibility: hidden;\n  }\n<\/style>\n\n<div class=\"inveterate-rebuy\" data-inveterate-rebuy>\n  <div class=\"inveterate-rebuy__wrapper\">\n    <div class=\"inveterate-rebuy__upper-content\">\n      <div class=\"inveterate-rebuy__image-wrapper\">\n        <a href=\"\/community\/membership\" data-inveterate-rebuy-landing-page-link>\n          <img\n            class=\"inveterate-rebuy__image\"\n            data-inveterate-rebuy-image\n            src=\"\"\n            alt=\"Membership image\"\n          \/>\n        <\/a>\n      <\/div>\n\n      <div class=\"inveterate-rebuy__info\">\n        <div class=\"inveterate-rebuy__title\">\n          <a href=\"\/community\/membership\" data-inveterate-rebuy-landing-page-link>\n            <strong data-inveterate-rebuy-title>Product Title<\/strong>\n          <\/a>\n        <\/div>\n\n        <div class=\"inveterate-rebuy__pricing-options\">\n          <div class=\"inveterate-rebuy__single-pricing-option\">\n            <p class=\"inveterate-rebuy__price_text\"><\/p>\n          <\/div>\n\n          <div class=\"inveterate-rebuy__multiple-pricing-options\">\n            <!-- <button class=\"not-selected\"><\/button> -->\n            <!-- <button class=\"not-selected\"><\/button> -->\n          <\/div>\n        <\/div>\n\n        <div class=\"inveterate-rebuy__add-button\">\n          <button data-inveterate-rebuy-atc><\/button>\n        <\/div>\n      <\/div>\n    <\/div>\n\n    <div class=\"inveterate-rebuy__lower-content\">\n      <div\n        data-inveterate-rebuy-description\n        class=\"inveterate-rebuy__description\"\n      >\n        <p><\/p>\n      <\/div>\n    <\/div>\n  <\/div>\n\n  <script>\n    let counter = 0;\n    const interval = setInterval(() => {\n      if (\n        !window.inveterate ||\n        !window.inveterate.properties ||\n        !window.inveterate.properties.product\n      ) {\n        \/\/ Inveterate is either not enabled in theme or the product doesn't exist on the FE\n        counter += 1;\n        if (counter > 100) clearInterval(interval);\n\n        return;\n      }\n\n      clearInterval(interval);\n\n      const Id = (id) => String(id).split(\"\/\").at(-1);\n      const hidden = \"inveterate--hidden\";\n      const billingFrequencies = {\n        monthly: {\n          noun: \"month\",\n        },\n        quarterly: {\n          noun: \"quarter\",\n        },\n        \"semi-annualy\": {\n          noun: \"semester\",\n        },\n        annually: {\n          noun: \"year\",\n        },\n      };\n\n      const renderSinglePricingOption = () => {\n        const { price, billingFrequency } = inveterateRebuy.product.variants[0];\n        const _price = price \/ 100;\n\n        if (!_price || !billingFrequency)\n          return `\n          <p class=\"inveterate-rebuy__price_text\">Free trial<\/p>\n        `;\n\n        return `\n          <p class=\"inveterate-rebuy__price_text\">$${_price}\/${billingFrequency}<\/p>\n        `;\n      };\n\n      const renderAddToBagButton = () => {\n        const variants = inveterateRebuy.product.variants,\n          [option] = variants,\n          classes = [\n            \"inveterate-rebuy__add-button\",\n            variants.length > 1 ? \"wide\" : \"\",\n          ].join(\" \");\n\n        return `\n          <button\n            data-inveterate-rebuy-atc\n            class=\"${classes}\"\n            ${!option ? \"disabled\" : \"\"}\n            onClick=\"window.inveterateRebuy.addToCart('${option?.id || null}')\"\n          >\n            {{add_to_bag_label}}\n          <\/button>\n        `;\n      };\n\n      const renderMultiplePricingOptions = () => {\n        if (!inveterateRebuy?.product?.variant) {\n          console.warn(\n            \"[Inveterate-Rebuy] Aborting: missing inveterateRebuy.product.variant\",\n            inveterateRebuy\n          );\n          return;\n        }\n\n        const selectedId = Id(inveterateRebuy.product.variant.id),\n          className = (id) =>\n            [\n              selectedId === id ? \"selected\" : selectedId ? \"not-selected\" : \"\",\n            ].join(\" \");\n\n        return inveterateRebuy.product.variants\n          .map(\n            ({ id, price, billingFrequency }) => `\n              <button\n                class=\"${className(id)}\"\n                onClick=\"window.inveterate.setProductVariant('${id}')\"\n              >\n                $${price \/ 100}\/${billingFrequency}\n              <\/button>\n             `\n          )\n          .join(\"\\n\");\n      };\n\n      \/** Multiple pricing options not supported, eventually replaced by tiers feature *\/\n      const renderPricingOptions = () => renderSinglePricingOption();\n\n      \/\/ Begin logic\n      class InveterateRebuy {\n        selectedProductVariantId = null;\n\n        constructor() {\n          if (!window.inveterate?.properties)\n            return console.warn(\"[Inveterate] Object malformed, halting.\");\n\n          document.addEventListener(\"rebuy:cart.change\", () => this.render());\n          this.render();\n        }\n\n        get elements() {\n          return {\n            module: document.querySelector(\"[data-inveterate-rebuy]\"),\n            image: document.querySelector(\"[data-inveterate-rebuy-image]\"),\n            title: document.querySelector(\"[data-inveterate-rebuy-title]\"),\n            atc: document.querySelector(\"[data-inveterate-rebuy-atc]\"),\n            description: document.querySelector(\n              \"[data-inveterate-rebuy-description]\"\n            ),\n\n            halves: {\n              upper: document.querySelector(\".inveterate-rebuy__upper-content\"),\n              lower: document.querySelector(\".inveterate-rebuy__lower-content\"),\n            },\n\n            containers: {\n              prices: {\n                wrapper: document.querySelector(\n                  \".inveterate-rebuy__pricing-options\"\n                ),\n\n                singleOption: document.querySelector(\n                  \".inveterate-rebuy__single-pricing-option\"\n                ),\n\n                multipleOptions: document.querySelector(\n                  \".inveterate-rebuy__multiple-pricing-options\"\n                ),\n              },\n\n              atcButton: document.querySelector(\n                \".inveterate-rebuy__add-button\"\n              ),\n            },\n          };\n        }\n\n        get product() {\n          const { product } = window.inveterate.properties;\n\n          const result = {\n            get variants() {\n              return product.variants\n                .filter((variant) => variant.available)\n                .sort((a, b) => a.price - b.price)\n                .map((variant) => ({\n                  ...variant,\n                  billingFrequency:\n                    billingFrequencies[\n                      product.selling_plan_groups\n                        .find((group) =>\n                          variant.selling_plan_allocations.some(\n                            (allocation) =>\n                              allocation.selling_plan_group_id === group.id\n                          )\n                        )\n                        .options.find(({ name }) => name === \"Billed\")\n                        .values[0].toLowerCase()\n                    ]?.noun || \"unknown\",\n                }));\n            },\n\n            get variant() {\n              return (\n                result.variants.find(\n                  (variant) =>\n                    Id(variant.id) ===\n                    Id(inveterateRebuy.selectedProductVariantId)\n                ) || null\n              );\n            },\n\n            set variant(variantOrId) {\n              if (!variantOrId)\n                throw new Error(\"A variant object or ID is required\");\n\n              const id = Id(variantOrId.id || variantOrId);\n\n              const variant = inveterateRebuy.product.variants.find(\n                (variant) => String(variant.id) === String(id)\n              );\n\n              if (!variant)\n                throw new Error(\"Inveterate product variant not found\");\n\n              inveterateRebuy.selectedProductVariantId = Id(id);\n              inveterateRebuy.render();\n            },\n          };\n\n          return result;\n        }\n\n        get membershipItemInCart() {\n          const result = window.Rebuy.Cart.cart.items.filter(\n            (item) =>\n              !!(window.inveterateRebuy || this).product.variants.some(\n                (variant) => Id(item.id) === Id(variant.id)\n              )\n          );\n\n          if (result.length > 1)\n            throw new Error(\n              \"Invalid state: there are multiple membership items in cart\"\n            );\n\n          if (result.some((item) => item.quantity > 1))\n            throw new Error(\n              \"Invalid state: a membership item has its quantity set to more than 1\"\n            );\n\n          return result[0] || null;\n        }\n\n        addToCart(variantOrId) {\n          if (!variantOrId)\n            throw new Error(\"A variant object or ID is required\");\n\n          const id = Id(variantOrId.id || variantOrId);\n\n          if (id === \"null\") return;\n          if (inveterateRebuy.membershipItemInCart)\n            throw new Error(\"Cart already contains a membership item\");\n\n          const product = window.inveterate.properties.product;\n          const variant = inveterateRebuy.product.variants.find(\n            (variant) => Id(variant.id) === id\n          );\n\n          window.Rebuy.Cart.addItem(\n            {\n              id: variant.id,\n              quantity: 1,\n              selling_plan: product.selling_plan_groups[0].selling_plans[0].id,\n              properties: {\n                _inveterate_subscription: true,\n                _inveterate_rebuy: true,\n              },\n            },\n            () => {\n              inveterateRebuy.elements.module.classList.remove(\n                \"inveterate--visible\"\n              );\n            }\n          );\n        }\n\n        render() {\n          const self = window.inveterateRebuy || this,\n            { elements, membershipItemInCart } = self || {},\n            { product } = window.inveterate.properties || {},\n            singlePricingOption = product?.variants?.length === 1;\n\n          if (\n            [self, elements, product].some(\n              (variable) => !variable \/** variable is not defined *\/\n            )\n          )\n            return;\n\n          window.inveterateRebuy = self;\n\n          elements.image.setAttribute(\n            \"src\",\n            product.featured_image + \"&width=200\"\n          );\n\n          elements.title.innerHTML = product.title;\n\n          if (\n            ![\"\", \"<p><\/p>\"].includes(String(product.description).toLowerCase())\n          )\n            elements.description.innerHTML = product.description;\n          else if (elements.halves.lower) elements.halves.lower?.remove?.();\n\n          if (elements.containers.prices.singleOption)\n            elements.containers.prices.singleOption.classList[\n              !singlePricingOption ? \"add\" : \"remove\"\n            ](\"inveterate--hidden\");\n\n          if (elements.containers.prices.multipleOptions)\n            elements.containers.prices.multipleOptions.classList[\n              singlePricingOption ? \"add\" : \"remove\"\n            ](\"inveterate--hidden\");\n\n          elements.containers.prices.wrapper.innerHTML = renderPricingOptions();\n          elements.containers.atcButton.innerHTML = renderAddToBagButton();\n\n          elements.module.classList[!membershipItemInCart ? \"add\" : \"remove\"](\n            \"inveterate--visible\"\n          );\n        }\n      }\n\n      window.inveterateRebuy = new InveterateRebuy();\n    }, 200);\n  <\/script>\n<\/div>\n","script_variable_json":"{\n  \"add_to_bag_label\": \"Add to bag (e.g. Add Membership)\"\n}\n"},{"id":46,"name":"Yotpo Loyalty","script":"<!-- CSS -->\n<style>\n    .yotpo-sca {\n        margin-bottom: 5px;\n    }\n    .yotpo-sca__contents {\n        text-align: left;\n    }\n    .yotpo-sca__description {\n        font-size: 14px;\n    }\n    .yotpo-sca__actions {\n        display: flex;\n        font-size: 15px;\n        margin-top: 15px;\n    }\n    .yotpo-sca__title {\n        font-size: 16px;\n        margin-bottom: 0;\n    }\n    .yotpo-sca__input {\n        outline: none;\n        box-shadow: none;\n        flex: 1;\n        border: 1px solid #000 !important;\n        border-radius: 5px;\n        padding: 10px;\n        margin-right: 20px;\n        letter-spacing: 0.8px;\n    }\n    .yotpo-sca__error {\n        display: none;\n        color: red;\n    }\n    .yotpo-sca__submit-button {\n        cursor: pointer;\n        text-transform: uppercase;\n        border: 1px solid #000 !important;\n        border-radius: 5px;\n        letter-spacing: 0.8px;\n        padding: 10px;\n    }\n    .yotpo-sca__account {\n        display: none;\n        position: relative;\n        text-align: center;\n    }\n    .yotpo-sca__account.toggled .yotpo-sca__points {\n        display: flex;\n        justify-content: center;\n        align-items: center;\n    }\n    .yotpo-sca__account.toggled .yotpo-sca__point {\n        font-size: 20px;\n    }\n    .yotpo-sca__account.toggled .yotpo-sca__points-label {\n        margin-left: 5px;\n    }\n    .yotpo-sca__account.toggled .yotpo-sca__email {\n        display: none;\n    }\n    .yotpo-sca__points {\n        display: block;\n        line-height: normal;\n        font-weight: bold;\n        font-size: 40px;\n    }\n    .yotpo-sca__points-label {\n        font-weight: bold;\n        font-size: 12px;\n    }\n    .yotpo-sca__email {\n        font-size: 12px;\n    }\n    .yotpo-sca__toggle {\n        cursor: pointer;\n        background: none;\n        border: none;\n        position: absolute;\n        top: 5px;\n        right: 5px;\n        z-index: 10;\n    }\n<\/style>\n\n<!-- HTML -->\n<div class=\"yotpo-sca\" data-yotpo-app>\n    <div class=\"yotpo-sca__contents\">\n        <div class=\"yotpo-sca__login\" data-yotpo-login>\n            <h3 class=\"yotpo-sca__title\">{{TITLE}}<\/h3>\n            <label class=\"yotpo-sca__label\">{{DESCRIPTION}}<\/label>\n\n            <div class=\"yotpo-sca__actions\">\n                <input\n                    class=\"yotpo-sca__input\"\n                    type=\"email\"\n                    placeholder=\"EMAIL ADDRESS\"\n                    data-yotpo-input\n                    aria-label=\"Email address for loyalty program\"\n                \/>\n                <button\n                    class=\"yotpo-sca__submit-button\"\n                    disabled\n                    data-yotpo-submit\n                    aria-label=\"Submit email\"\n                >\n                    Submit\n                <\/button>\n            <\/div>\n\n            <span class=\"yotpo-sca__error\" data-yotpo-error aria-label=\"Error message\">Invalid input<\/span>\n        <\/div>\n\n        <div class=\"yotpo-sca__account\" data-yotpo-account>\n            <button class=\"yotpo-sca__toggle\" type=\"button\" data-yotpo-toggle aria-label=\"Toggle loyalty account view\">\n                <svg\n                    width=\"12\"\n                    height=\"8\"\n                    viewBox=\"0 0 12 8\"\n                    fill=\"none\"\n                    xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n                    aria-hidden=\"true\"\n                >\n                    <path\n                        d=\"M10.59 0.589844L6 5.16984L1.41 0.589844L0 1.99984L6 7.99984L12 1.99984L10.59 0.589844Z\"\n                        fill=\"#666E95\"\n                    \/>\n                <\/svg>\n            <\/button>\n\n            <div class=\"yotpo-sca__points\" data-yotpo-points>\n                <div class=\"yotpo-sca__point\" data-yotpo-point><\/div>\n                <div class=\"yotpo-sca__points-label\">POINTS<\/div>\n            <\/div>\n            <div class=\"yotpo-sca__email\" data-yotpo-email aria-label=\"Email address\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<!-- JS -->\n<script>\n    (() => {\n        \/\/ Selectors for DOM elements\n        const SELECTORS = {\n            app: '[data-yotpo-app]',\n            input: '[data-yotpo-input]',\n            submit: '[data-yotpo-submit]',\n            login: '[data-yotpo-login]',\n            account: '[data-yotpo-account]',\n            toggle: '[data-yotpo-toggle]',\n            point: '[data-yotpo-point]',\n            points: \"[data-yotpo-points]\",\n            email: '[data-yotpo-email]',\n            error: '[data-yotpo-error]',\n        };\n\n        const cacheDomElements = () =>\n            Object.entries(SELECTORS).reduce(\n                (acc, [key, selector]) => ({ ...acc, [key]: document.querySelector(selector) }),\n                {}\n            );\n\n        const parseCookies = () =>\n            document.cookie\n                .split(';')\n                .map((cookie) => cookie.trim())\n                .filter((cookie) => cookie.length > 0)\n                .map((cookie) => {\n                    const equalIndex = cookie.indexOf('=');\n                    return equalIndex === -1\n                        ? [cookie, '']\n                        : [cookie.substring(0, equalIndex), cookie.substring(equalIndex + 1)];\n                });\n\n        const getCookie = (name) => {\n            const match = parseCookies().find(([key]) => key === name);\n            return match ? match[1] : '';\n        };\n\n        const calculateExpirationDate = (days) => {\n            const date = new Date();\n            date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);\n            return date.toUTCString();\n        };\n\n        const formatCookie = (name, value, expirationDate) =>\n            `${name}=${value};expires=${expirationDate};path=\/`;\n\n        const setCookie = (name, value, days) => {\n            document.cookie = formatCookie(name, value, calculateExpirationDate(days));\n        };\n\n        const toggleClass = (element, className) => {\n            element.classList.toggle(className);\n        };\n\n        const showElement = (element) => {\n            element.style.display = 'block';\n        };\n\n        const hideElement = (element) => {\n            element.style.display = 'none';\n        };\n\n        const setTextContent = (element, text) => {\n            element.textContent = text;\n        };\n\n        const showAccountView = (dom) => {\n            const rawPoints = getCookie('yotpoPoints');\n            const points = rawPoints && rawPoints !== 'undefined' ? rawPoints : 0;\n            const email = getCookie('yotpoEmail');\n\n            hideElement(dom.login);\n            showElement(dom.account);\n            setTextContent(dom.point, points);\n            setTextContent(dom.email, email);\n        };\n\n        const buildYotpoApiUrl = (email, guid, apiKey) =>\n            `https:\/\/loyalty.yotpo.com\/api\/v2\/customers?customer_email=${email}&country_iso_code=null&with_referral_code=false&with_history=false&guid=${guid}&api_key=${apiKey}`;\n\n        const fetchCustomerData = async (email, guid, apiKey, dom) => {\n            try {\n                const response = await fetch(buildYotpoApiUrl(email, guid, apiKey));\n                const data = await response.json();\n\n                if (data) {\n                    setCookie('yotpoPoints', data.points_balance ?? 0, 1);\n                    setCookie('yotpoEmail', email, 1);\n\n                    showAccountView(dom);\n                }\n            } catch (error) {\n                console.error(error);\n                showElement(dom.error);\n            }\n        };\n\n        \/\/ Event handler: validate input\n        const handleValidate = (event, dom, submitHandler) => {\n            const hasValue = event.target.value.trim() !== '';\n\n            if (hasValue) {\n                hideElement(dom.error);\n                dom.submit.disabled = false;\n\n                if (event.code === 'Enter') {\n                    submitHandler();\n                }\n            } else {\n                dom.submit.disabled = true;\n            }\n        };\n\n        \/\/ Event handler: submit email\n        const handleSubmit = (dom) => {\n            const email = dom.input.value;\n            fetchCustomerData(email, '{{GUID}}', '{{API_KEY}}', dom);\n        };\n\n        \/\/ Event handler: toggle account view\n        const handleToggle = (dom) => {\n            toggleClass(dom.toggle, 'toggled');\n            toggleClass(dom.account, 'toggled');\n        };\n\n        \/\/ Initialize app\n        const dom = cacheDomElements();\n\n        \/\/ Check for existing session\n        const existingPoints = getCookie('yotpoPoints');\n        const existingEmail = getCookie('yotpoEmail');\n\n        if (existingPoints && existingEmail) {\n            showAccountView(dom);\n        }\n\n        \/\/ Attach event listeners\n        if (dom.input) {\n            dom.input.addEventListener('keyup', (event) => handleValidate(event, dom, () => handleSubmit(dom)));\n        }\n\n        if (dom.submit) {\n            dom.submit.addEventListener('click', () => handleSubmit(dom));\n        }\n\n        if (dom.toggle) {\n            dom.toggle.addEventListener('click', () => handleToggle(dom));\n        }\n    })();\n<\/script>","script_variable_json":"{\"GUID\":{\"label\":\"GUID\",\"required\":true},\"API_KEY\":{\"label\":\"API key\",\"required\":true},\"TITLE\":{\"label\":\"Title (e.g 'Part of our loyalty program?')\",\"required\":true},\"DESCRIPTION\":{\"label\":\"Description (e.g 'Enter your email below to check your points!')\",\"required\":true}}"},{"id":50,"name":"ShipAid - Delivery Guarantee","script":"<shipaid-widget disableRefresh style=\"--shipaid-prompt-margin: 0px 0px 0px auto;\"><\/shipaid-widget>","script_variable_json":""},{"id":51,"name":"Loyalty Lion","script":"<!-- CSS -->\n<style>\n  .loyalty-lion-sca {\n    margin-bottom: 5px;\n  }\n  .loyalty-lion-sca__contents {\n    text-align: left;\n  }\n  .loyalty-lion-sca__description {\n    font-size: 14px;\n  }\n  .loyalty-lion-sca__title {\n    font-size: 16px;\n    margin-bottom: 0;\n  }\n  .loyalty-lion-sca__account {\n    display: none;\n    position: relative;\n    text-align: center;\n  }\n  .loyalty-lion-sca__account.toggled .loyalty-lion-sca__points {\n    display: flex;\n    justify-content: center;\n    align-items: center;\n  }\n  .loyalty-lion-sca__account.toggled .loyalty-lion-sca__point {\n    font-size: 20px;\n  }\n  .loyalty-lion-sca__account.toggled .loyalty-lion-sca__points-label {\n    margin-left: 5px;\n  }\n  .loyalty-lion-sca__account.toggled .loyalty-lion-sca__email {\n    display: none;\n  }\n  .loyalty-lion-sca__points {\n    display: block;\n    line-height: normal;\n    font-weight: bold;\n    font-size: 40px;\n  }\n  .loyalty-lion-sca__points-label {\n    font-weight: bold;\n    font-size: 12px;\n  } \n  .loyalty-lion-sca__email {\n    font-size: 12px;\n  }\n  .loyalty-lion-sca__toggle {\n    cursor: pointer;\n    background: none;\n    border: none;\n    position: absolute;\n    top: 5px;\n    right: 5px;\n    z-index: 10;\n  }\n<\/style>\n\n<!-- HTML -->\n<div class=\"loyalty-lion-sca\" data-loyalty-lion-app>\n  <div class=\"loyalty-lion-sca__contents\">\n    <div class=\"loyalty-lion-sca__login\" data-loyalty-lion-login>\n      <h3 class=\"loyalty-lion-sca__title\">{{TITLE}}<\/h3>\n      <label class=\"loyalty-lion-sca__label\">{{DESCRIPTION}}<\/label>\n    <\/div>\n    \n    <div class=\"loyalty-lion-sca__account\" data-loyalty-lion-account>\n      <button class=\"loyalty-lion-sca__toggle\" type=\"button\" data-loyalty-lion-toggle>\n        <svg width=\"12\" height=\"8\" viewBox=\"0 0 12 8\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n          <path d=\"M10.59 0.589844L6 5.16984L1.41 0.589844L0 1.99984L6 7.99984L12 1.99984L10.59 0.589844Z\" fill=\"#666E95\"\/>\n        <\/svg>\n      <\/button>\n      \n      <div class=\"loyalty-lion-sca__points\" data-loyalty-lion-points>\n        <div class=\"loyalty-lion-sca__point\" data-loyalty-lion-point><\/div>\n        <div class=\"loyalty-lion-sca__points-label\">POINTS<\/div>\n      <\/div>\n      <div class=\"loyalty-lion-sca__email\" data-loyalty-lion-email><\/div>\n    <\/div>\n  <\/div>\n\n<\/div>\n<!-- JS -->\n<script>\n  (function () {\n    const $ = Rebuy.libraries.$;\n    const selectors = {\n      login: '[data-loyalty-lion-login]',\n      account: '[data-loyalty-lion-account]',\n      toggle: '[data-loyalty-lion-toggle]',\n      points: '[data-loyalty-lion-points]',\n      point: '[data-loyalty-lion-point]',\n      email: '[data-loyalty-lion-email]',\n    };\n    \n    $(selectors.toggle).on('click', () => {\n      $(selectors.toggle).toggleClass('toggled');\n      $(selectors.account).toggleClass('toggled');\n    });\n\n    if (window.loyaltylion.customer) {\n      $(selectors.login).hide();\n      $(selectors.account).show();\n      \n      $(selectors.point).text(window.loyaltylion.customer.pointsTotal);\n\t  $(selectors.email).text(window.loyaltylion.customer.email);\n    }\n  })();\n<\/script>","script_variable_json":"{\n  \"TITLE\": \"Title\",\n  \"DESCRIPTION\": \"Description\"\n}"},{"id":52,"name":"Gipht","script":"  <!-- Gipht Checkout Button -->\n              <style>\n                  .gipht-adjust {\n                    margin: 10px 0px 0px 0px;\n                    width: 100% !important;\n                  }\n                  .gipht-text{\n                    font-size: 15px;\n                    text-align: center;\n                  }\n                .gipht-container{\n                    display: grid;\n                    grid-auto-flow: row;\n                    grid-row-gap: 5px;\n                  }\n                <\/style>\n\n               <div class = \"gipht-container\">\n                      <gipht-button\n    button-text=\"Send gift with email\"\n    button-class=\"gipht-inner-button gipht-adjust\"\n    page-location=\"cart\"\n    product-quantity-element-name=\"quantity\">\n  <\/gipht-button>\n                    <div class=\"gipht-text\">No Shipping Address? No Problem!<\/div>\n                <\/div>\n              <!-- End Gipht Checkout Button -->","script_variable_json":"{}"},{"id":54,"name":"Gatsby","script":"    <html>\n      <style>\n      \t.gatsby_rebuy {\n            margin: 4px;\n        }\n        .switch {\n          vertical-align: middle;\n          position: relative;\n          display: inline-block;\n          width: 40px;\n          height: 20px;\n        }\n        .switch input { \n          opacity: 0;\n          width: 0;\n          height: 0;\n        }\n        .slider {\n          position: absolute;\n          cursor: pointer;\n          top: 0;\n          left: 0;\n          right: 0;\n          bottom: 0;\n          background-color: #ccc;\n          -webkit-transition: .4s;\n          transition: .4s;\n        }\n        .slider:before {\n          position: absolute;\n          content: \"\";\n          height: 16px;\n          width: 16px;\n          left: 2.1px;\n          bottom: 2px;\n          background-color: white;\n          -webkit-transition: .4s;\n          transition: .4s;\n        }\n        input:checked + .slider {\n          background-color: #000;\n        }\n        input:focus + .slider {\n          box-shadow: 0 0 1px #2196F3;\n        }\n        input:checked + .slider:before {\n          -webkit-transform: translateX(20px);\n          -ms-transform: translateX(20px);\n          transform: translateX(20px);\n        }\n        \/* Rounded sliders *\/\n        .slider.round {\n          border-radius: 34px;\n        }\n        .slider.round:before {\n          border-radius: 50%;\n        }\n      <\/style>\n      <script>\n        function myFunction() {\n          var x = document.getElementById(\"gatsbyForm\");\n          if (x.style.display === \"none\") {\n            x.style.display = \"block\";\n          } else {\n            x.style.display = \"none\";\n          }\n        }\n      <\/script>\n      <div id=\"gatsbyForm\" style=\"display:none\">\n      <script type=\"text\/javascript\" async=\"\" src=\"{{GatsbyFormScript}}\"><\/script>\n      <div class=\"{{GatsbyFormEmbedded}}\"><\/div>\n      <\/div>\n      <div class=\"gatsby_rebuy\">\n        <b>{{GatsbyKey}}<\/b>\n        <label class=\"switch\">\n          <input type=\"checkbox\" onclick=\"myFunction()\">\n          <span class=\"slider round\"><\/span>\n        <\/label>\n      <\/div>\n    <\/html>","script_variable_json":"{\n  \"GatsbyKey\": \"Description\",\n  \"GatsbyFormScript\" :\"Klaviyo script\",\n  \"GatsbyFormEmbedded\" : \"Klaviyo form\"\n}"},{"id":56,"name":"ID.me Community Verification","script":"<a class=\"idme-btn-unify-rebuy\" href=\"https:\/\/discountify.id.me\/oauth\/checkpoint\/{{store_name_variable}}\" >\n        <img src=\"https:\/\/s3.amazonaws.com\/idme\/developer\/idme-buttons\/assets\/img\/verify.svg\" alt=\"ID.me\" style=\"height:44px\"\/>\n<\/a>\n\n<style> \n.idme-btn-unify-rebuy {\n    padding: 0px 0px 0px 16px;\n}\n<\/style>","script_variable_json":"{\"store_name_variable\":{\"label\":\"Add domain name without myshopify.com. Example: \\\"store-name\\\".\",\"required\":true,\"default\":\"Add domain name without myshopify.com. Example: \\\"store-name\\\".\"}}"},{"id":57,"name":"Card Isle","script":"<script>console.log(\"Card Isle X Rebuy X {{retailer_name}}\");<\/script>\n<script src=\"https:\/\/d9f7qlfbocnas.cloudfront.net\/static\/ecommerce\/shop_embed.js\"><\/script>\n<link href=\"https:\/\/s3.amazonaws.com\/cardisle.web\/static\/ecommerce\/shopify\/rebuy\/cardisle.css\" type=\"text\/css\" rel=\"stylesheet\">\n<script src=\"https:\/\/s3.amazonaws.com\/cardisle.web\/static\/ecommerce\/shopify\/rebuy\/cardisle.js\"><\/script>","script_variable_json":"{\n  \"retailer_name\": \"name\"\n}"},{"id":63,"name":"ShipTection","script":"<div class=\"shiptection-widget\" max-width=\"true\"><\/div>","script_variable_json":"{\n}"},{"id":66,"name":"Beam Impact","script":"<script>\n  const devBeamApiSubdomain = \"dev-api\";\n  const prodBeamApiSubdomain = \"api\";\n  const stagingBeamApiSubdomain = \"api-staging\";\n\n  const version = \"{{version}}\";\n  const inputEnvironment = \"production\";\n\n  const baseUrlSubdomain = inputEnvironment === \"staging\" ? stagingBeamApiSubdomain : prodBeamApiSubdomain;\n\n  const script = document.createElement(\"script\");\n\n  script.src =\n    `https:\/\/sdk.beamimpact.com\/web-sdk\/{{version}}\/dist\/components\/select-nonprofit.esm.js`;\n  script.type = \"module\";\n  script.async = true;\n  script.crossorigin = true;\n  script.defer = true;\n\n  document.head.appendChild(script);\n\n  const widget = document.querySelector(\"beam-select-nonprofit\");\n  widget.baseUrl = `https:\/\/${baseUrlSubdomain}.beamimpact.com`;\n<\/script>\n\n<div class=\"rebuy-beam-cart-widget\">\n  <beam-select-nonprofit\n    apiKey=\"{{api_key}}\"\n    chainId=\"{{chain_id}}\"\n    storeId=\"{{store_id}}\"\n  >\n  <\/beam-select-nonprofit>\n<\/div>","script_variable_json":"{\n  \"version\": \"Beam Version Number\",\n  \"api_key\": \"Beam API Key\",\n  \"store_id\": \"Beam Store Id\",\n  \"chain_id\": \"Beam Chain Id\"\n}"},{"id":67,"name":"+Purpose","script":"<div id=\"ap-widget-smartcart\"><\/div>","script_variable_json":"{ }"},{"id":68,"name":"EcoCart","script":"<eco-rebuy-widget><\/eco-rebuy-widget>","script_variable_json":"{}"},{"id":69,"name":"Giftship","script":"<style>\n  .gs__app-container {\n    margin: 0;\n  }\n  .gs__app-container .gs__wrapper {\n    margin: 0;\n    width: 100%;\n  }\n  #gsReactModalContainer, body .gs__modal-content, .flatpickr-calendar.open {\n    z-index: 9999999999;\n  }\n<\/style>\n<div class=\"gs__app-container\"><\/div>\n<script>\n  (function() {\n\n    const gsDrawer = {\n\n      init: function() {\n\n        if (window.location.pathname.includes(\"a\/gs\/cart\")) {\n          this.proxyEvents();\n          return;\n        }\n\n        this.events();\n\n      },\n\n      state: {\n        drawerInit: false,\n      },\n\n      \/\/ Event listeners for all non-cart pages\n      events: function() {\n\n        document.addEventListener('rebuy:smartcart.init', (e) => {\n          this.setEventState(e);\n        });\n\n        document.addEventListener('rebuy:smartcart.ready', (e) => {\n          this.setEventState(e);\n        });\n\n        document.addEventListener('rebuy:smartcart.show', (e) => {\n          this.setEventState(e);\n\n          if (this.state.drawerInit === true || document.querySelector(\".gs__cart-app-container .gs__wrapper\")) {\n            return; \/\/ Giftship drawer already initialized\n          }\n\n          const items = (e.detail && e.detail.smartcart) ? e.detail.smartcart.items() : [];\n\n          if (items.length) {\n            this.state.drawerInit = true;\n            this.attemptShow(e);\n            this.observeMutations();\n          }\n        });\n\n        document.addEventListener('rebuy:smartcart.product-removed', (e) => {\n          this.setEventState(e);\n\n          const items = (e.detail && e.detail.smartcart) ? e.detail.smartcart.items() : [];\n          \n          if (!items.length) {\n            this.state.drawerInit = false;\n          } \n        });\n\n        document.addEventListener('rebuy:cart.add', (e) => {\n          this.setEventState(e);\n          this.modifyElements(e);\n          this.observeMutations();\n        });\n\n      },\n\n      \/\/ Event listeners for multishipping proxy cart page\n      proxyEvents: function() {\n\n        document.addEventListener('rebuy:smartcart.show', (e) => {\n          this.handleHide(e);\n        });\n\n      },\n\n      \/\/ Event listeners that fire on giftship events\n      giftshipEvents: function() {\n\n        document.addEventListener('giftship.loaded', () => {\n          Gs.state.drawer_cart = true;\n          this.handleCheckoutFlow();\n          this.addMultiShipButton();\n        }, { once: true });\n\n      },\n\n      \/\/ Save the most recent smartcart event in state\n      setEventState: function(e) {\n        this.state.smartcartEvent = e;\n      },\n\n      \/\/ Do not allow the smartcart to open on multishipping proxy page\n      handleHide: function(e) {\n\n        const smartcart = e.detail.smartcart;\n        smartcart.hide();\n\n      },\n\n      \/\/ Observe for changes to the cart item elements and quantities\n      observeMutations: function() {\n\n        const itemsNode = document.querySelector(\"[data-smartcart-items]\");\n        const itemsConfig = {  childList: true };\n\n        const quantityNodes = document.querySelectorAll(\".rebuy-cart__flyout-item-quantity-widget\");\n        const quantityConfig = { subtree: true, childList: true, characterData: true };\n\n        \/\/ Callback function to execute when mutations are observed\n        const callback = (mutationList, observer) => {\n\n          if (typeof(this.state.smartcartEvent) !== 'undefined') {\n            this.modifyElements(this.state.smartcartEvent);\n            this.handleCheckoutFlow();\n          }\n\n        };\n\n        \/\/ Observe itemsNode for items added\/remove from the cart\n        if (itemsNode) {\n          this.state.itemsObserver = new MutationObserver(callback);\n          this.state.itemsObserver.observe(itemsNode, itemsConfig);\n        }\n\n        \/\/ Observe all quantity inputs for quantity change in cart\n        this.state.quantityObservers = [];\n        Array.from(quantityNodes).forEach((node, index) => {\n          this.state.quantityObservers.push(new MutationObserver(callback));\n          this.state.quantityObservers[index].observe(node, quantityConfig);\n        });\n\n      },\n\n      \/\/ Try to show Giftship in the Smart Cart (Re-try up to 5 times if the cart is opened before Giftship loads)\n      attemptShow: function(e, attempts = 0) {\n\n        if (typeof Gs !== 'object' || Gs === null || typeof Gs.drawer === \"undefined\" || typeof Gs.drawer.init !== 'function') {\n\n          if (attempts >= 5) {\n            console.warn(\"Could not load Giftship in drawer cart.\");\n          } else {\n            attempts += 1;\n            setTimeout(() => this.attemptShow(e, attempts), 500);\n          }\n\n          return;\n\n        }\n\n        this.handleShow(e);\n\n      },\n\n      \/\/ Add Giftships features when the cart is shown for the first time\n      handleShow: function(e) {\n\n        if (typeof e !== 'object' || typeof e.detail !== 'object') {\n          console.warn(\"An invalid rebuy event was thrown.\", e);\n          return;\n        }\n\n        this.handleMultishipping(e);\n\n        Gs.drawer.init();\n\n        this.modifyElements(e);\n\n        this.giftshipEvents();\n\n      },\n\n      \/\/ Override removeMultiAddressProps function to keep address data (we are not on cart page)\n      handleMultishipping: function(e) {\n\n        const cartItems = this.getCartItems(e);\n        const gsAddressPresent = cartItems.some((item) => item.properties && Object.keys(item.properties).some((key) => key === \"_gs_a\"));\n\n        if (gsAddressPresent) {\n          Gs.cartPage.actions.removeMultiAddressProps = () => {};\n        };\n\n      },\n\n      \/\/ Update checkout button to handle Giftship events\n      handleCheckoutFlow: function() {\n\n        const checkoutButton = document.querySelector(\".rebuy-cart__checkout-button\");\n\n        if (!checkoutButton) return;\n\n        Gs.config.forceCheckout = true;\n\n        const checkoutCallback = (event) => {\n\n          const cartItems = this.getCartItems(this.state.smartcartEvent);\n          const gsAddressPresent = cartItems.some((item) => item.properties && Object.keys(item.properties).some((key) => key === \"_gs_a\"));\n\n          if (!Gs.cartPage || !Gs.cartPage.actions || typeof Gs.cartPage.actions.submitCart !== \"function\") {\n            (gsAddressPresent) ? this.redirectToMultiShipping() : this.redirectToCheckout();\n            return;\n          }\n\n          const valid = Gs.cartPage.actions.validateCart(event);\n\n          if (valid === false) {\n            GIST.f.stopEvent(event, \"GS cart validation is not valid\");\n            Gs.state.submitting_cart = false;\n            alert(Gs.trans.multishipping.please_complete_required);\n            return false;\n          }\n\n          (gsAddressPresent) ? this.redirectToMultiShipping() : this.redirectToCheckout();\n\n        };\n\n        const checkoutClone = checkoutButton.cloneNode(true);\n        checkoutClone.addEventListener(\"click\", checkoutCallback);\n        checkoutButton.replaceWith(checkoutClone);\n\n      },\n\n      \/\/ Add multiship button below the checkout\/cart buttons if enabled\n      addMultiShipButton: function() {\n\n        if (!Gs.options || !Gs.options.multishipping || Gs.options.multishipping.enable !== 1) {\n          return; \/\/ multishipping is not enabled, do not add button\n        }\n\n        const buttonWrapper = document.querySelector(\".rebuy-cart__flyout-actions\");\n\n        if (!buttonWrapper) {\n          console.warn(\"Could not add multiship button\", buttonWrapper);\n          return;\n        }\n\n        if (buttonWrapper.querySelector(\".gs__view-multiship-button\") !== null) {\n          return; \/\/ multishipping button already added\n        }\n\n        const text = document.createElement(\"span\");\n        text.innerText = (typeof Gs !== \"undefined\" && typeof Gs.trans !== \"undefined\") ? Gs.trans.multishipping.toggle_text : \"Ship to Multiple Addresses\";\n\n        const button = document.createElement(\"button\");\n        button.className = \"rebuy-button rebuy-cart__view-cart-button block outline gs__view-multiship-button\";\n        button.type = \"button\";\n\n        button.addEventListener(\"click\", this.redirectToMultiShipping);\n\n        button.appendChild(text);\n        buttonWrapper.appendChild(button);\n\n      },\n\n      \/\/ Modify pricing related to bundles and add missing bundled items\/line item properties\n      modifyElements: function(e) {\n      \n      \tif (!this.state.drawerInit) {\n          return; \/\/ not finished initializing drawer cart\n        }\n\n        const cartItems = this.getCartItems(e);\n\n        if (cartItems.length === 0 && e.type === \"rebuy:cart.add\") {\n          console.warn(\"An invalid rebuy event was thrown. Cart items are empty. Retrying in 1 second.\");\n          return setTimeout(() => {\n          \tconst smartcart = e.detail.smartcart || window.Rebuy.SmartCart;\n            smartcart.hide();\n            smartcart.show();\n          }, 1000);\n        }\n\n        const bundlePresent = cartItems.some((item) => item.properties && typeof item.properties._gs_bundle_contents !== \"undefined\");\n\n        if (!bundlePresent) return;\n\n        const cartElements = this.getCartElements();\n\n        if (cartItems.length !== cartElements.length) {\n          const smartcart = e.detail.smartcart || window.Rebuy.SmartCart;\n          smartcart.hide();\n          smartcart.show();\n          return;\n        }\n\n        let subtotal = 0;\n\n        \/\/ Add bundle data to cart item elements\n        cartItems.forEach((item, i) => {\n\n          const lp = item.properties || {};\n\n          const bundleContents = Object.entries(lp).find(([k, _]) => k === \"_gs_bundle_contents\");\n          let bundlePrices = Object.entries(lp).find(([k, _]) => k === \"_gs_bundle_prices\");\n          let bundleQuantities = Object.entries(lp).find(([k, _]) => k === \"_gs_bundle_quantities\");\n          let bundleDiscount = Object.entries(lp).find(([k, _]) => k === \"_gs_bundle_discount\");\n\n          if (typeof cartElements[i] !== 'object' || !bundleContents) {\n            subtotal += (item.price * item.quantity);\n            return;\n          };\n\n          this.setLineItemProperties(cartElements[i], bundleContents[1]);\n\n          if (!bundlePrices || !bundlePrices[1] || bundlePrices[1].length === 0) {\n            subtotal += (item.price * item.quantity);\n            return;\n          };\n\n          bundlePrices = bundlePrices[1];\n          bundleQuantities = (bundleQuantities && bundleQuantities[1]) ? bundleQuantities[1] : Array(bundlePrices.length).fill(1);\n          bundleDiscount = (bundleDiscount && bundleDiscount[1]) ? bundleDiscount[1] : 0;\n\n          const itemPrice = this.getItemPrice(item, bundlePrices, bundleQuantities, bundleDiscount);\n\n          subtotal += (itemPrice * item.quantity);\n\n          this.setItemPrice(cartElements[i], itemPrice);\n\n        });\n\n        \/\/ Update the subtotal to include bundle pricing\n        const smartcart = e.detail.smartcart;\n        this.setCartSubtotal(subtotal);\n\n      },\n\n      \/\/ Get cart item data from smartcart\/cart event\n      getCartItems: function(e) {\n\n        const smartcart = e.detail.smartcart || e.detail.cart;\n        const cartItems = smartcart.items();\n\n        if (!Array.isArray(cartItems)) {\n          console.warn(\"An invalid rebuy event was thrown. Cart items is not an array\", cartItems);\n          return [];\n        }\n\n        return cartItems;\n\n      },\n\n      \/\/ Get cart item DOM elements\n      getCartElements: () => {\n\n        const elements = document.querySelectorAll(\"li.rebuy-cart__flyout-item\");\n\n        if (!elements) {\n          console.warn(\"No rebuy cart elements present\");\n          return [];\n        }\n\n        return elements;\n\n      },\n\n      \/\/ Get the price of an item, including any bundled items\n      getItemPrice: function(cartItem, prices, quantities, discount) {\n\n        const itemPrice = cartItem.price;\n\n        if (!prices || !quantities || prices.length !== quantities.length) {\n          return itemPrice;\n        }\n\n        const bundleCost = prices.reduce((total, price, i) =>\n          (price === null || price === \"\") ? total : total + parseInt(price) * parseInt(quantities[i]),\n          0\n        );\n\n        return itemPrice + bundleCost - discount;\n\n      },\n\n      \/\/ Adds bundle line item properties to a given smartcart item element\n      setLineItemProperties: function(currentEl, properties) {\n\n        if (!properties || properties.length === 0) return;\n\n        const variantName = currentEl.querySelector(\".rebuy-cart__flyout-item-variant-title\");\n        const lineItemProperties = document.createElement(\"ul\");\n\n        lineItemProperties.className = \"gs__bundle-contents\";\n\n        properties.forEach((property) => {\n          \/\/ Build list item and append to the ul element\n          const listItem = document.createElement(\"li\");\n          listItem.innerText = property;\n\n          lineItemProperties.appendChild(listItem);\n        });\n\n        \/\/ if the element doesn't exist we insert it\n        if (currentEl.querySelector(\".gs__bundle-contents\") === null) {\n\n          const wrapper = document.createElement(\"span\");\n          wrapper.classList.add(\"gs__cart-properties\");\n          wrapper.style.width = '100%';\n\n          const bundleTitle = document.createElement(\"span\");\n          bundleTitle.innerText = (typeof Gs !== \"undefined\" && typeof Gs.trans !== \"undefined\") ? Gs.trans.global.bundle_contents : \"Bundle Contents\";\n          bundleTitle.setAttribute(\"data-gs-trans\", \"global.bundle_contents\");\n\n          wrapper.appendChild(bundleTitle);\n          wrapper.appendChild(lineItemProperties);\n          variantName.after(wrapper);\n\n        } else {\n          \/\/ otherwise replace it\n          currentEl.querySelector(\".gs__bundle-contents\").replaceWith(lineItemProperties);\n        }\n\n      },\n\n      \/\/ Update item price to include bundle prices\n      setItemPrice: function(currentEl, itemPrice) {\n\n        const finalPrice = window.Rebuy.SmartCart.formatMoney(itemPrice);\n        const moneyEl = currentEl.querySelector(\".rebuy-money\").lastChild;\n\n        moneyEl.innerText = finalPrice;\n\n        const saleEl = currentEl.querySelector(\".rebuy-money.compare-at\");\n        if (saleEl) saleEl.remove();\n\n      },\n\n      \/\/ Update the cart subtotal to include bundle prices\n      setCartSubtotal: function(subtotal) {\n\n        const formattedSubtotal = window.Rebuy.SmartCart.formatMoney(subtotal);\n        const subtotalEl = document.querySelector(\".rebuy-cart__flyout-subtotal-amount\");\n\n        subtotalEl.innerText = formattedSubtotal;\n\n      },\n\n      redirectToMultiShipping: function() {\n\n        const proxyUrl = ((typeof Gs.state !== \"undefined\" && Gs.state.locale) ? Gs.state.locale_root : \"\/\") + \"a\/gs\/cart\/\";\n\n        window.location.href = proxyUrl;\n\n        return false;\n\n      },\n\n      getDiscountCode: function() {\n\n        const discountInput = document.querySelector('#rebuy-discount-input');\n        const appliedDiscount = document.querySelector('.rebuy-cart__flyout-discount-tag-text');\n\n        if (discountInput && discountInput.value !== \"\" && typeof(discountInput.value) != 'undefined') {\n          return discountInput.value;\n        }\n\n        if (appliedDiscount && appliedDiscount.innerText !== \"\" && typeof(appliedDiscount.innerText) != 'undefined') {\n          return appliedDiscount.innerText;\n        }\n\n        return null;\n\n      },\n\n      redirectToCheckout: function() {\n\n        let redirectUrl = (typeof Gs.state !== \"undefined\" && Gs.state.bundle_cart) ? \"\/cart\" : \"\/checkout\";\n        let discountCode = this.getDiscountCode();\n\n        if (discountCode !== null) {\n          redirectUrl = redirectUrl + \"?discount=\" + discountCode;\n        }\n\n        window.location.href = redirectUrl;\n\n        return false;\n\n      },\n\n    };\n\n    gsDrawer.init();\n\n  })();\n<\/script>\n","script_variable_json":"{}"},{"id":71,"name":"ShoppingGives - Merchant Donations","script":"<div id=\"shoppinggives rebuy widget\" class=\"sgrebuytarget\"><\/div>\n<script src=\"https:\/\/cdn.shoppinggives.com\/cc-utilities\/shopify-cart.js?store-id={{shoppinggives_merchant_id}}&template-type=1&target-element=.sgrebuytarget\"> <\/script>\n\n\n","script_variable_json":"{\n\"shoppinggives_merchant_id\": \"Add your ShoppingGives Store ID found within your the ShoppingGives Admin\"\n}"},{"id":72,"name":"ShoppingGives - Customer Add-on Donation","script":"<div id=\"shoppinggives rebuy widget\" class=\"sgrebuytargetaddon\"><\/div>\n<script src=\"https:\/\/cdn.shoppinggives.com\/cc-utilities\/shopify-add-on.js?sid={{shoppinggives_merchant_id}}&variants={{addon_sku_1_dollar}},{{addon_sku_3_dollar}},{{addon_sku_5_dollar}},{{addon_sku_10_dollar}}&target-element=.sgrebuytargetaddon&before=true&reloadBypass=true\"> <\/script>\n\n","script_variable_json":"{\n\"shoppinggives_merchant_id\": \"Add your ShoppingGives Store ID found within your the ShoppingGives Admin\",\n\"addon_sku_1_dollar\": \"Add your variant id for ShoppingGives 1 customer add on donation\",\n\"addon_sku_3_dollar\": \"Add your variant id for ShoppingGives 3 customer add on donation\",\n\"addon_sku_5_dollar\": \"Add your variant id for ShoppingGives 5 customer add on donation\",\n\"addon_sku_10_dollar\": \"Add your variant id for ShoppingGives 10 customer add on donation\"\n}"},{"id":73,"name":"OrderProtection - New Widget","script":"<link rel=\"stylesheet\" href=\"https:\/\/cdn.orderprotection.com\/widget\/shopify\/5.27.0\/style.css\" \/>\n<div class=\"op-rebuy-render-location\"><\/div>\n\n<script>\n    function loadOrderProtectionScript() {\n        const script = document.createElement('script');\n        script.src = 'https:\/\/cdn.orderprotection.com\/widget\/shopify\/5.27.0\/orderprotection.js';\n\n        script.onload = function() {\n            const rebuyWidget = OrderProtection.createOrderProtectionWidget({});\n            rebuyWidget.addRenderLocation({ selector: '.op-rebuy-render-location'})\n            rebuyWidget.init();\n        };\n\n        document.head.appendChild(script);\n    }\n\n    loadOrderProtectionScript();\n<\/script>\n\n<style>\n\t.rebuy-cart__background {\n    \tz-index: 199;\n    }\n    .rebuy-cart__flyout {\n    \tz-index: 1000;\n    }\n<\/style>","script_variable_json":null},{"id":75,"name":"Sprout: Plant Trees Grow Sales","script":"<div class=\"SproutCartBadgeVintage\" id=\"SproutCartBadgeVintage\"><\/div>","script_variable_json":"{}"},{"id":77,"name":"SavedBy Package Protection","script":"<savedby-widget rebuy style=\"display:block;padding-top:12px;\"><\/savedby-widget>","script_variable_json":""},{"id":83,"name":"LABL","script":"<div class=\"lp-widget-global-wrapper\"><\/div>","script_variable_json":"{}"},{"id":84,"name":"Giftnote","script":"<giftnote-button \n\tdata-styles=\"giftnote-rebuy\" \n    data-add=\"{{add_label}}\" \n    data-edit=\"{{edit_label}}\">\n<\/giftnote-button>","script_variable_json":"{\n  \"add_label\": \"Add message label\",\n  \"edit_label\": \"Edit message label\"\n}"},{"id":87,"name":"Guide Shipping Protection","script":"<script>\nwindow.REBUY_GUIDE_INTEGRATION = true;\n<\/script>\n<script src=\"https:\/\/plugin.guideprotection.com\/static\/guide-protection-cart-widget.min.js\">","script_variable_json":"{\n}"},{"id":91,"name":"Yotpo SMS Capture","script":"<!-- CSS -->\n<style>\n    .yotpo-sca {\n        padding: 10px 0px;\n    }\n\n    .yotpo-sca__header {\n        display: flex;\n        justify-content: space-between;\n        align-items: center;\n        margin-bottom: 5px;\n        cursor: pointer;\n    }\n\n    .yotpo-sca__header-title {\n        font-size: 14px;\n        line-height: 17px;\n        font-weight: 600;\n        margin: 0px;\n    }\n\n    .yotpo-sca__toggle {\n        border: 0px;\n        background: none;\n        cursor: pointer;\n    }\n\n    .yotpo-sca__main {\n        display: flex;\n        flex-direction: column;\n    }\n\n    .yotpo-sca__form {\n        display: flex;\n        align-items: center;\n        flex: 1;\n        height: 100%;\n        border: 1px solid black;\n        border-radius: 5px;\n        overflow: hidden;\n    }\n\n    .yotpo-sca__form-country {\n        display: flex;\n        align-items: center;\n        margin: 0;\n        padding: 0 10px;\n        list-style: none;\n        height: 100%;\n        position: relative;\n    }\n\n    .yotpo-sca__form-country::before {\n        content: \"\";\n        position: absolute;\n        right: 0;\n        height: 80%;\n        width: 1px;\n        background-color: #919191;\n    }\n\n    .yotpo-sca__form-input {\n        height: 100%;\n        width: 100%;\n        padding-left: 10px;\n        display: flex;\n        align-items: center;\n    }\n\n    .yotpo-sca__form-input span {\n        font-size: 14px;\n        line-height: 17px;\n        color: #000;\n        margin-right: 6px;\n    }\n\n    .yotpo-sca__form-input input {\n        height: 100%;\n        width: 100%;\n        border: 0px;\n        font-size: 14px;\n        line-height: 17px;\n        color: #000;\n    }\n\n    .yotpo-sca__submit {\n        height: 100%;\n        padding-left: 10px;\n    }\n\n    .yotpo-sca__submit button {\n        height: 100%;\n        min-width: 100px;\n        cursor: pointer;\n    }\n\n    .yotpo-sca__main-body {\n        display: flex;\n        align-items: center;\n        height: 45px;\n    }\n\n    .yotpo-sca__main-body img {\n        display: block;\n        width: 35px;\n        height: auto;\n    }\n\n    .yotpo-sca__feedback {\n        margin: 5px 0;\n        font-size: 11px;\n        line-height: 14px;\n    }\n\n    .yotpo-sca__feedback.success-text {\n        color: #5cb85c;\n    }\n    .yotpo-sca__feedback.error-text {\n        color: #cc0000;\n    }\n\n    .yotpo-sca__legal-text {\n        margin: 5px 0;\n        font-size: 12px;\n        line-height: 14px;\n    }\n<\/style>\n\n<!-- Markup -->\n<div class=\"yotpo-sca\" data-yotpo-phone-app>\n    <div class=\"yotpo-sca__header\" onclick=\"yotpoApp.toggle()\">\n        <h3 class=\"yotpo-sca__header-title\">{{PROMPT_TEXT}}<\/h3>\n        <div>\n            <button\n                class=\"yotpo-sca__toggle\"\n                type=\"button\"\n                data-yotpo-phone-expand\n                aria-label=\"Expand SMS signup form\"\n            >\n                <span>\n                    <svg\n                        width=\"12\"\n                        height=\"8\"\n                        viewBox=\"0 0 12 8\"\n                        fill=\"none\"\n                        xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n                        aria-hidden=\"true\"\n                    >\n                        <path\n                            d=\"M10.59 0.589844L6 5.16984L1.41 0.589844L0 1.99984L6 7.99984L12 1.99984L10.59 0.589844Z\"\n                            fill=\"#666E95\"\n                        \/>\n                    <\/svg>\n                <\/span>\n            <\/button>\n\n            <button\n                class=\"yotpo-sca__toggle\"\n                type=\"button\"\n                style=\"display: none\"\n                data-yotpo-phone-collapse\n                aria-label=\"Collapse SMS signup form\"\n            >\n                <span>\n                    <svg\n                        width=\"12\"\n                        height=\"8\"\n                        viewBox=\"0 0 12 8\"\n                        fill=\"none\"\n                        xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n                        aria-hidden=\"true\"\n                    >\n                        <path\n                            d=\"M10.59 7.40991L6 2.82991L1.41 7.40991L0 5.99991L6 -8.7738e-05L12 5.99991L10.59 7.40991Z\"\n                            fill=\"#666E95\"\n                        \/>\n                    <\/svg>\n                <\/span>\n            <\/button>\n        <\/div>\n    <\/div>\n\n    <div data-yotpo-phone-app-body style=\"display: none\">\n        <div class=\"yotpo-sca__legal\">\n            <p class=\"yotpo-sca__legal-text\">\n                By submitting this form, you agree to receive recurring\n                automated promotional and personalized marketing text messages\n                (e.g. cart reminders) from\n                <span data-yotpo-phone-shop-name><\/span> at the cell number used\n                when signing up. Consent is not a condition of any purchase.\n                Reply HELP for help and STOP to cancel. Msg frequency varies.\n                Msg & data rates may apply. View\n                <a href=\"{{TERMS_URL}}\" target=\"_blank\">Terms<\/a> &\n                <a href=\"{{PRIVACY_URL}}\" target=\"_blank\">Privacy<\/a>.\n            <\/p>\n        <\/div>\n\n        <div class=\"yotpo-sca__main\">\n            <div class=\"yotpo-sca__main-body\">\n                <!-- Input Form -->\n                <div class=\"yotpo-sca__form\" aria-label=\"SMS signup form\">\n                    <ul class=\"yotpo-sca__form-country\">\n                        <li>\n                            <span>\n                                <!-- United States Flag -->\n                                <img\n                                    width=\"120\"\n                                    height=\"63\"\n                                    src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAA\/CAYAAAArOQwGAAAAAXNSR0IArs4c6QAACbFJREFUeF7tm3lQVdcdx7+XHR\/LY18EBJegSMSlViM0GqvNZEJMY2JpM7bWaCdxQ1tNYorojEKjmdDE4JLMhCR2MYspiUrHacIkLoAxRgNGiAuy7yA7svM6vx\/znu8CMa\/e+2Yu9px\/lHvO\/d5zz+ed3\/n9fudc6YG58QaM4pJQcWYU9976XZfMATs42MHFxRmNjW0jPtndXcfXW1o6Rqz39HRFe3snenr6Rqy3hr4AfOcfiQnw+PEBiIgIga+fBzI\/v4iysjrTnTY2NggM9MKiRTP4Wmbmt6iquomBgQFTm+AQXyxePBN1tU0oKChDUVG17MnW0heALQQcFOSDN1LXobWlAzt2HEJp6W3AJHHffUF4+eVnQPb8zy+9g2vXKmTKISG+2LlrBdzddIiP34\/y8npZvbX0BWALAdvZ2SAu7iE0NLQgOzufTa29vS36+wcwMGCAXu+C+QumwWAATp+6hObmdtjYSLC1tUFvbz+b9ujoqfD2dsMHH5zk++zsbPnpfX39sIY+ab82rtv6C9kofoLJREuSxBAIIMExGAyYPTsc5eV1qKlpYpBUR0WSBtv4+3sgONgX589fBd1Pbaiur2\/w\/qio8YAE5OUWcb3a+tSXkxk7RvHwW7\/rMifL\/HGzfxqO+PgnGFTa2ydw6tQlWW8enD8Nq1c\/wuBS3\/gEX399VbZmz5sXgbXrlvC1A\/uPISenQLZmK9E370jO2b3WH6VR\/IQfBEwe829\/twgB\/p7Yvv0Qz1jzQrN1584VqK5pxN\/\/ljnMsyaPes3ax\/iWgweOD\/PMleob+yIAW7gGUzNnZ0cQmMrKBtja2sLFxQn29nYMhzxmPz89q9XWNoM8a2rb09uHjvYu9Pf3Y+xYb27b2dkNColIj6x6V2c3h05q6gvAlpkV0wyeODEQ0dGR8PJ2wyfpWSgurpGZ3JBgHyx9MoavpadnoaysXmZyw8L88cTSGNxsaEV2zmUUXq+S9cBa+ifefNayN\/0\/bWUC7OOjR+q+dWiob8Xu3e+joqJBNiShoX5ISl7J17YlvIuSklpZfVCQN7Zu\/TV8fNyxfv1+1Nc3y+qtpS\/CJAtNNJniWbMmobX1Fs\/eQTNrzyEOmWcPDxf4+3uyWk1NI5qaKEyy4VCop6eXzS\/NYlc3Z1y8UIje3j4271SM\/1dbn7QFYAsBD23m5OSAhQunc8KjuLgat27J480xYwhoAMaN88UXX+Siq6tHJuHs7IB50VP5Wk52Af9gzItSfaOWAHyXgCdPDsbmzU\/Bzt4Or7zyIb4vKJMpTYkIwQsvxKGvtw8pKR\/jypVyUz2FTlSfkPA0X\/tL8mFOX1LIZSxK9M07IgDfJWDKXMXGzuEZumfPR2yqzQuZ5hdfjENJaS3+nXGOM1vmhcx5bOxcAAZkZJxjs25elOobtQ7FDVoJUUYeAZOTRcDc3MaAnKHCwkqOe2km0qyjtZYyVORoUSEHiyYjrc3GNhQXT5w4lp0rWseN2TBqb8xyqalv\/MGJONjCGRweHoRly+aD1ta0tBO4ceP2bhABmjRpLFY+8zCrvfvOf3D9eqXM5E6YEIBVqx7htfrIkVO4elW+GWEtfQHYQsAE9s23NqKq8iZSUv41LMzx9dVj9+5VnLh4aWsa6uqGh0GbtzyJwAAvPPfc3hGdMmvoC8AWAqbME2WiaAbShj55xbRD1N3dw7tFFCZRIdNM5prCJNptcnR04J0n8ord9ToOl6oqGzhzpdM58T0dHV2c2VJbn7SzTqeI5fcOI\/CDuWjav419bA7P1LzcGzKTTXq0gT99xgTQzM44fg4VFbf3f8mkh4T4YNHiWfzozM8vcObL3ItWom\/+PmmPhgnAdwOYTnBQmKNzccKWzW+hoaFVJkP7vq+mPMt56OTkw3zCw1gIsH+AJ1JSBtOIdH91daMMsBJ9846IMMlCE230dmkTnzxgvV6H6JhIhIX64+DBDN5MIG+aCnnPtBmxZm0sZ72yz1xGc0sH7wfT4QCaqQEBnpg7dwq3\/+qr7xkwgVdL3\/haArAFgGlNdXUdw+ex\/Hz1uHSpiNdVAkLHrgick7M9IiNCWS2\/oARdnb3o6x8AMSegtF5PmzYetXXNfC6rvb0LBsPgFqMk2fDOlJr6bW232B8QgC0ATE2mT5+ATX9cCsOAAa+mfIz8yyUykztz5kRs3LSUr+19PR0XLxbKTO7UqaHYsuUpSDYSXn8tHbm5N2RPtpa+AGwhYJqte\/eu5b1gMsmtrfKjsTRDdyWtYLXExENob+uUKbu56bBmTSwCx3pj08YDMvhG828N\/eMpy4WTZYmTRZksb293DosorKEwh8IaSkHS3wSYTDkVMo1kwsfonOChd+EfBYVBOp0zHJ3s0VDfwqlNPz8Pbl9b28S7Tmrrk7aIgy2cwUOb3X9\/GJb96kG0NHfgzJnLfLDOGObQbKcDeTE\/i2Rn7MhHp\/Hdd8UmCXLGoqLC8Pjj8\/ja0aNnkZdXJDsgoETfvK8C8F0Cps2A7duXw9PLFX9Y\/VdOdpgXmpFvp\/0JjTfbsHPnP4ZtNtD9qfvW8y3xG\/ZxYsS8KNU3agnA\/wNg8pYdHe05m0VZKHKcKN797LMLbHIpW0XHYLs6e9jk\/uLhWXwCJD+\/hM04pTu7u3s5zKLzWuGTg\/npV6+U81ktNfWNr\/Xlp9vEGmzJGkxt6NwUZZhOnszjW4w7RcZ\/Y2Ii+XpW1uVhdXR9wYIozmgVFlaZ6s111NQ3vtMevfwLCkFbPgKmVOWcuVOQlPR7nolJu\/6Jb765ZmpJgOmrhYRtgxv4yUmH+esH89TjrJ9MQmLicp75idve4+SGebGWvgiTLDTRZD43xP8S9XXNOHbsLNqGhEF0jvk3Tz\/Eau8f\/nLYOWhXV2csWfIA7yenpn464jlqa+gLwBYCJs9Xp3PktZZCpKEH3SkMoplMhWbu0E9E6QdCbWht7ujolnnMdI+19AXgHwH884XPj+oPwJ+vzBHL7p2crNLSulEN2KtfnlETtIc4WQZzT0mMzj03ApIAfM8xlb2QAHxv84XUnJc\/qtfge5yP4teTMoJmCMCKh1G7AgKwdtmo0jMBWJVh1K6IAKxdNqr0TDq\/cqNYg1UZSm2KSL1t7QKwNtmo0isRB6syjNoVEYC1y0aVngnAqgyjdkWk8iPHxBqsXT6KeybCJMVDqG0BAVjbfBT3TgBWPITaFhCAtc1Hce+k8g+PCidL8TBqV0CESdplo0rPBGBVhlG7IgKwdtmo0jMBWJVh1K6I9O2GBOFkaZeP4p6JMEnxEGpbQADWNh\/FvROAFQ+htgUEYG3zUdy7\/wL6SdzC1o55iAAAAABJRU5ErkJggg==\"\n                                \/>\n                            <\/span>\n                        <\/li>\n                    <\/ul>\n\n                    <div class=\"yotpo-sca__form-input\">\n                        <span>+1<\/span>\n                        <input\n                            placeholder=\"Phone Number\"\n                            type=\"number\"\n                            data-yotpo-phone-input\n                            onkeyup=\"yotpoApp.validate(event)\"\n                            aria-label=\"Phone number for SMS updates\"\n                        \/>\n                    <\/div>\n                <\/div>\n\n                <!-- Submit Button -->\n                <div class=\"yotpo-sca__submit\">\n                    <button\n                        type=\"button\"\n                        class=\"rebuy-button outline\"\n                        data-yotpo-phone-submit\n                        onclick=\"yotpoApp.submit()\"\n                        disabled\n                        aria-label=\"Subscribe to SMS updates\"\n                    >\n                        Submit\n                    <\/button>\n                <\/div>\n            <\/div>\n\n            <div data-yotpo-phone-feedback style=\"display: none\">\n                <p\n                    data-yotpo-phone-error\n                    class=\"yotpo-sca__feedback error-text\"\n                    aria-label=\"Error message\"\n                >\n                    <!-- ERROR MESSAGE -->\n                <\/p>\n                <p\n                    data-yotpo-phone-success\n                    class=\"yotpo-sca__feedback success-text\"\n                    aria-label=\"Success message\"\n                >\n                    Submission was successful!\n                <\/p>\n            <\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<!-- JS -->\n<script>\n    \/* Scripts go here *\/\n    (function () {\n        const selectors = {\n            app: \"[data-yotpo-phone-app]\",\n            appBody: \"[data-yotpo-phone-app-body]\",\n            expand: \"[data-yotpo-phone-expand]\",\n            collapse: \"[data-yotpo-phone-collapse]\",\n            input: \"[data-yotpo-phone-input]\",\n            submit: \"[data-yotpo-phone-submit]\",\n            feedback: \"[data-yotpo-phone-feedback]\",\n            error: \"[data-yotpo-phone-error]\",\n            success: \"[data-yotpo-phone-success]\",\n            shopName: \"[data-yotpo-phone-shop-name]\",\n        };\n\n        const dom = {};\n        const cacheDom = () => {\n            dom.app = document.querySelector(selectors.app);\n            dom.appBody = document.querySelector(selectors.appBody);\n            dom.expand = document.querySelector(selectors.expand);\n            dom.collapse = document.querySelector(selectors.collapse);\n            dom.input = document.querySelector(selectors.input);\n            dom.submit = document.querySelector(selectors.submit);\n            dom.feedback = document.querySelector(selectors.feedback);\n            dom.error = document.querySelector(selectors.error);\n            dom.success = document.querySelector(selectors.success);\n            dom.shopName = document.querySelector(selectors.shopName);\n        };\n\n        const app = {};\n\n        app.expand = () => {\n            dom.appBody.style.display = \"block\";\n            dom.expand.style.display = \"none\";\n            dom.collapse.style.display = \"block\";\n        };\n\n        app.collapse = () => {\n            dom.appBody.style.display = \"none\";\n            dom.expand.style.display = \"block\";\n            dom.collapse.style.display = \"none\";\n        };\n\n        app.toggle = () => {\n            if (dom.appBody.style.display === \"none\") {\n                app.expand();\n            } else {\n                app.collapse();\n            }\n        };\n\n        app.submit = () => {\n            let phone = dom.input.value;\n\n            if (phone && phone.length > 0) {\n                \/\/ prepend U.S. country code to phone number\n                phone = `+1${phone}`;\n\n                \/\/ hide all feedback\n                dom.error.style.display = \"none\";\n                dom.success.style.display = \"none\";\n                dom.feedback.style.display = \"none\";\n\n                \/\/ enter loading state\n                const submitText = dom.submit.innerText;\n                dom.submit.innerHTML = `<i class=\"rebuy-button-icon prefix fas fa-circle-notch fa-spin\"><\/i>`;\n\n                \/\/ build payload\n                const payload = {\n                    list_id: {{LIST_ID}},\n                    phone,\n                };\n\n                \/\/ send phone number to yotpo\n                const options = {\n                    method: \"POST\",\n                    headers: {\n                        \"Content-Type\":\n                            \"application\/x-www-form-urlencoded; charset=UTF-8\",\n                    },\n                    \/\/ append nested payload to query string\n                    body: new URLSearchParams(payload).toString(),\n                };\n\n                \/\/ submit payload to yotpo\n                fetch(\n                    `https:\/\/rebuyengine.com\/api\/v1\/integration\/yotpo\/subscribe?key=${Rebuy.shop.api_key}`,\n                    options\n                )\n                    .then((response) => response.json())\n                    .then((response) => {\n                        dom.success.style.display = \"block\";\n                        dom.feedback.style.display = \"block\";\n                        dom.input.value = \"\";\n                    })\n                    .catch((err) => {\n                        \/\/ set error message\n                        let errorText = \"Something went wrong. Please try again.\";\n\n                        \/\/ error - pull error message from response (GuzzleClient returns a large string containing a JSON object)\n                        \/*\n                            example error response:\n                              \"Client error: `POST https:\/\/example.com\/example` resulted in a `400 Bad Request` response:\n                              {\"detail\":\"+123409823409823409 is not a valid phone number.\"}\n                              \"\n\n                            Unfortunately, the yotpo response keeps getting truncated, so we can't pull the full error message from the response.\n                        *\/\n\n                        if (response.message) {\n                            const responseLower =\n                                response.message.toLowerCase();\n                            if (\n                                responseLower.includes(\"error\") &&\n                                responseLower.includes(\"400 bad request\")\n                            ) {\n                                errorText =\n                                    \"Bad request. Please check that the phone number is valid and try again.\";\n                            }\n                        }\n                        \/\/ display error message\n                        dom.error.innerText = errorText;\n                        dom.error.style.display = \"block\";\n                        dom.feedback.style.display = \"block\";\n                    })\n                    .finally(() => {\n                        \/\/ replace loading state\n                        dom.submit.innerHTML = submitText;\n                    });\n            }\n        };\n\n        app.validate = (event) => {\n            if (event.target.value !== \"\") {\n                dom.error.style.display = \"none\"; \/\/ clear error\n                dom.submit.disabled = false; \/\/ enable submit\n                \/\/ allow submission with Enter key\n                if (event.code == \"Enter\") {\n                    app.submit();\n                }\n            } else {\n                dom.submit.disabled = true; \/\/ disable submit\n            }\n        };\n\n        cacheDom();\n        app.dom = dom;\n\n        \/\/ fill in shop name\n        const shopName = Rebuy.shop?.shop_name ?? false;\n        if (shopName && app.dom?.shopName) {\n            app.dom.shopName.innerText = shopName;\n        }\n\n        \/\/ Show app only if Rebuy\/yotpo integration is enabled and sign_up_source_id is set\n        if (\n            Rebuy.shop.integrations.yotpo &&\n            Rebuy.shop.integrations.yotpo.sign_up_source_id\n        ) {\n            dom.app.style.display = \"block\";\n        }\n\n        \/\/ attach to window\n        window.yotpoApp = app;\n    })();\n<\/script>\n","script_variable_json":"{\"PROMPT_TEXT\":{\"label\":\"Title: E.g. 'Sign up for our SMS list and be the first to receive exclusive updates about sales, discounts, and more!'\",\"required\":true},\"TERMS_URL\":{\"label\":\"Enter the full URL for your Terms page for SMS handling.\",\"required\":true},\"PRIVACY_URL\":{\"label\":\"Enter the full URL for your Privacy policy page.\",\"required\":true},\"LIST_ID\":{\"label\":\"Find the list Id number by clicking on \\u201cview\\u201d next to the list\\u2019s name. The List ID is displayed at the end of the page URL.\",\"required\":true}}"},{"id":95,"name":"Cart Add-On","script":"<div id=\"sca-cart-addon\">\n    <div class=\"sca-cart-addon-container\">\n        <img class=\"product-image-sca\">\n\n        <div class=\"product-info-sca\">\n            <div class=\"product-title-sca\"><\/div>\n            <div class=\"product-price-sca\"><\/div>\n        <\/div>\n\n        <div class=\"product-action-sca\">\n            <input type=\"checkbox\">\n        <\/div>\n    <\/div>\n<\/div>\n\n<script>\n    let variantId;\n    const hasBeenAdded = sessionStorage.getItem(\"smartcart_addon_removed\");\n    const hasItemInCart = Rebuy.Cart.cart.items.some(item => item.properties?._attribution === \"REBUY SHIPPING PROTECTION\");\n    const dataSourceId = \"{{data_source_id}}\";\n\n\n    \/**\n     * Toggles shipping protection item in cart\n     *\n     *\/\n    const toggleShippingProtection = () => {\n        \/\/Prevent Spam Clicking\n        document.querySelector(\".product-action-sca\").classList.add(\"clicked\");\n        setTimeout(() => {\n            document.querySelector(\".product-action-sca\").classList.remove(\"clicked\");\n        }, 600);\n\n        const shippingProtectionItem = Rebuy.Cart.items().find(\n            (item) => item.properties?._attribution === \"REBUY SHIPPING PROTECTION\",\n        );\n\n        if (document.querySelector(\"#sca-cart-addon input\").checked) {\n            if (!shippingProtectionItem) {\n                Rebuy.Cart.addItem({\n                    id: variantId,\n                    quantity: 1,\n                    properties: { _attribution: \"REBUY SHIPPING PROTECTION\" },\n                });\n            }\n        } else {\n            if (shippingProtectionItem) {\n                Rebuy.Cart.removeItem(shippingProtectionItem);\n                sessionStorage.setItem(\"smartcart_addon_removed\", \"true\");\n            }\n        }\n    };\n\n    \/**\n     * removes html from a string to prevent merchant's currency formats from displaying strangely\n     *\n     *\/\n    const removeHtml = (html) => {\n        let newDiv = document.createElement(\"newDiv\");\n        newDiv.innerHTML = html;\n        return newDiv.textContent || newDiv.innerText || \"\";\n    }\n\n    \/**\n     * checks for empty cart and removes the shipping protection item\n     *\n     *\/\n    const checkForEmptyCart = () => {\n        const shippingProtectionItem = Rebuy.Cart.items().find(\n            (item) => item.properties?._attribution === \"REBUY SHIPPING PROTECTION\",\n        );\n\n        shippingProtectionItem ? document.querySelector(\"#sca-cart-addon input\").checked = true : document.querySelector(\"#sca-cart-addon input\").checked = false;\n\n        setTimeout(() => {\n            if (\n                Rebuy.Cart.cart.items.filter(\n                    (item) => item.properties?._attribution !== \"REBUY SHIPPING PROTECTION\",\n                ).length === 0\n            ) {\n                document.querySelector(\"#sca-cart-addon input\").checked = false;\n\n                if (shippingProtectionItem) {\n                    Rebuy.Cart.removeItem(shippingProtectionItem);\n                }\n            }\n\n            \/\/kind of weird but on some themes if there are duplicate add.js events, the shipping protection item might get added twice. adding redundant check to set qty to 1\n            if (shippingProtectionItem && shippingProtectionItem.quantity !== 1) {\n                Rebuy.Cart.setItemQuantity(shippingProtectionItem, 1);\n            }\n        }, 300);\n    };\n\n\n    const sendDataSourceRequest = () => {\n        \/\/ datasource request config object\n        const config = {\n            url: window.location.href,\n        };\n\n        \/\/ pass up cart and product data\n        if (Rebuy.Cart) {\n            const Cart = Rebuy.Cart\n            let items = Cart.items();\n            let line_count = Cart.lineCount();\n            let item_count = Cart.itemCount();\n            let subtotal = Cart.subtotal();\n\n            config.shopify_product_ids = items.map(item => item.product_id).join()\n            config.shopify_variant_ids = items.map(item => item.variant_id).join()\n\n            config.cart_token = Cart.cart.token;\n            config.cart_subtotal = subtotal;\n            config.cart_count = line_count;\n            config.cart_item_count = item_count;\n\n            config.cart = {};\n            config.cart.subtotal = subtotal;\n            config.cart.line_count = line_count;\n            config.cart.item_count = item_count;\n            config.cart.items = [];\n            for (let i = 0, item; i < items.length; i++) {\n                item = {};\n                item.product_id = items[i].product_id;\n                item.variant_id = items[i].variant_id;\n                item.quantity = items[i].quantity;\n\n                \/\/ Add Subscription ID to input products if applicable\n                if (\n                    items[i].properties &&\n                    typeof items[i].properties == 'object' &&\n                    Object.prototype.hasOwnProperty.call(items[i].properties, 'subscription_id')\n                ) {\n                    item.subscription_id = items[i].properties.subscription_id;\n                } else if (\n                    items[i].selling_plan_allocation &&\n                    items[i].selling_plan_allocation.selling_plan &&\n                    items[i].selling_plan_allocation.selling_plan.id\n                ) {\n                    item.subscription_id = items[i].selling_plan_allocation.selling_plan.id;\n                }\n\n                config.cart.items.push(item)\n            }\n\n        }\n\n        \/\/ Function to convert an object into a query string with bracket notation\n        function buildQueryString(params, prefix = '') {\n            const query = Object.keys(params).map(key => {\n                const value = params[key];\n\n                \/\/ Build a recursive path for nested objects\/arrays\n                const fullKey = prefix ? `${prefix}[${key}]` : key;\n\n                if (typeof value === 'object' && !Array.isArray(value)) {\n                    return buildQueryString(value, fullKey);\n                } else if (Array.isArray(value)) {\n                    return value.map((item, index) => buildQueryString(item, `${fullKey}[${index}]`)).join('&');\n                } else {\n                    return `${encodeURIComponent(fullKey)}=${encodeURIComponent(value)}`;\n                }\n            }).join('&');\n\n            return query;\n        }\n\n        const queryString = buildQueryString(config);\n\n        \/\/ send datasource request\n        fetch(\n            `https:\/\/rebuyengine.com\/api\/v1\/custom\/id\/${dataSourceId}?key=${encodeURIComponent(Rebuy.shop.api_key)}&${queryString}`,\n        )\n            .then((response) => response.json())\n            .then((data) => {\n                if (data.data && data.data.length > 0) {\n                    document\n                        .querySelector(\"#sca-cart-addon\").style.display = \"block\";\n                    const hasShippingProtection =\n                        Rebuy.Cart.items().find(\n                            (item) =>\n                                item.properties?._attribution === \"REBUY SHIPPING PROTECTION\",\n                        ) !== undefined;\n                    const product = data.data[0];\n                    variantId = product.variants[0].id;\n                    document\n                        .querySelector(\".sca-cart-addon-container .product-image-sca\")\n                        .setAttribute(\n                            \"src\",\n                            Rebuy.util.itemImage(product, product.variants[0], \"400x400\"),\n                        );\n\n                    document.querySelector(\n                        \".sca-cart-addon-container .product-title-sca\",\n                    ).textContent = product.title;\n\n                    document.querySelector(\n                        \".sca-cart-addon-container .product-price-sca\",\n                    ).textContent =\n                        `${removeHtml(Rebuy.util.formatMoney(Rebuy.util.amountToCents(product.variants[0].price)))}`;\n\n                    document\n                        .querySelector(\"#sca-cart-addon input\")\n                        .addEventListener(\"change\", toggleShippingProtection);\n                } else {\n                    document\n                        .querySelector(\"#sca-cart-addon\").style.display = \"none\";\n                }\n            })\n            .catch((error) => {\n                console.error(\"Fetching data source error: \", error);\n            });\n    }\n\n    sendDataSourceRequest()\n    checkForEmptyCart()\n\n    document.addEventListener('rebuy:cart.change', () => {\n        sendDataSourceRequest()\n        checkForEmptyCart()\n    });\n<\/script>\n\n<style>\n    #sca-cart-addon {\n        margin: 5px 0px;\n    }\n\n    .sca-cart-addon-container {\n        display: flex;\n    }\n\n    .product-info-sca {\n        width: 75%;\n        font-size: 15px;\n        margin-left: 10px;\n        display: flex;\n        flex-direction: column;\n    }\n\n    .product-action-sca {\n        width: 25%;\n        margin-right: 5px;\n        display: flex;\n        justify-content: flex-end;\n        align-items: center;\n    }\n\n    .product-image-sca {\n        height: 65px;\n        width: 65px;\n    }\n\n    .product-title-sca {\n        font-weight: bold;\n        font-size: 17px;\n    }\n\n    #sca-cart-addon input[type=\"checkbox\"] {\n        appearance: none;\n        -webkit-appearance: none;\n        display: flex;\n        align-items: flex-end;\n        outline: none !important;\n        box-shadow: none !important;\n    }\n\n    #sca-cart-addon input[type=\"checkbox\"]:before {\n        position: relative;\n        left: 15px;\n        top: -3px;\n        transition: left .5s;\n        display: inline-block;\n        content: \"\";\n        width: 10px;\n        height: 10px;\n        background: white;\n        border-radius: 100%;\n    }\n\n    #sca-cart-addon input[type=\"checkbox\"]:checked:before {\n        transition: left .5s;\n        left: 36px;\n    }\n\n    #sca-cart-addon input[type=\"checkbox\"]:after {\n        content: \"\";\n        display: inline-block;\n        width: 40px;\n        height: 16px;\n        border-radius: 10px;\n        transition: background .5s;\n        background: lightgrey;\n    }\n\n    #sca-cart-addon input[type=\"checkbox\"]:checked:after {\n        transition: background .5s;\n        background: #44be70;\n    }\n\n    .clicked {\n        pointer-events: none;\n    }\n\n    .property-value-rebuy-shipping-protection {\n        display: none !important;\n    }\n\n    .no-items #sca-cart-addon {\n        display: none !important;\n    }\n<\/style>","script_variable_json":"{\"data_source_id\":{\"label\":\"Data Source ID\",\"required\":true}}"},{"id":99,"name":"Onward VIP Protection+","script":"<script>\n  if (window.OnwardSetup) {\n    document.querySelector('.rebuy-cart__flyout #onward-container')?.remove();\n    const onward = new OnwardSetup();\n    onward.addRebuy();\n  }\n<\/script>","script_variable_json":"{}"},{"id":111,"name":"Quotify","script":"<button class=\"rebuy-button\" onclick=\"window.Rebuy.SmartCart.hide();window.quotifyConvertCart(event);\" data-quotify-convert-cart>\nRequest Quote\n<\/button>","script_variable_json":"{\n}"},{"id":119,"name":"ProtectMyOrder","script":"<style> \n#mule-widget {\n    padding-top: 0px!important;\n    padding-bottom: 0px!important;\n    padding-left: 0px!important;\n    padding-right: 0px!important;\n}\nprotectmyorder {\n  width: 100%;\n}\n<\/style>\n\n<mule-protection><\/mule-protection>","script_variable_json":"{}"},{"id":125,"name":"SWAP Protect","script":"<script>\n    if(!window.SWAP) {\n    \twindow.SWAP = {};\n    }\n    if(!window.SWAP.Currency) {\n    \twindow.SWAP.Currency = {};\n    }\n\n    if(window.Rebuy.Cart.formatMoney) {\n    \tSWAP.Currency.formatMoney = function(ammount, symbol) {\n    \t\treturn window.Rebuy.Cart.formatMoney(ammount);\n    \t};\n    }\n\n\tlet script = document.createElement('script');\n  \t\tscript.type = 'text\/javascript';\n  \t\tscript.async = true;\n        \n  \t\tscript.dataset.insure = \"\";\n  \t\tscript.dataset.platform = \"rebuy\";\n  \t\tscript.dataset.insureProducthandle = \"{{product_handle}}\";\n  \t\tscript.dataset.insureWidgetsmall = \"#swap-protect-target\";\n  \t\tscript.dataset.insureTargetlocks = \"\";\n  \t\tscript.dataset.insureForceinsure = \"{{force_insure}}\";\n  \t\tscript.dataset.insureForcereload = false;\n  \t\tscript.dataset.insureDisplayUsp = \"{{show_usp}}\";\n  \t\tscript.src = 'https:\/\/cdn.weareshift.agency\/insure.js';\n      \n  document.getElementsByTagName('head')[0].appendChild(script);\n<\/script>\n\n<script type=\"text\/json\" data-swap-language=\"en\">\n  {\n  \t\"add\":\"<input type=\\\"checkbox\\\" class=\\\"swap-toggle\\\"><\/input>\",\n  \t\"remove\":\"<input type=\\\"checkbox\\\" class=\\\"swap-toggle\\\" checked><\/input>\"  \n  }\n<\/script>\n            \n<link rel=\"stylesheet\" href=\"https:\/\/cdn.weareshift.agency\/insure.css\">\n\n<style>\n\t[data-app-target=\"above_subtotal\"] swap-insurewidget {\n    \tmargin-top: 0;\n    \tmargin-bottom: 1em;\n    }\n    \n    [data-app-target=\"below_subtotal\"] swap-insurewidget {\n    \tmargin: 1rem 0;\n    }\n    \n    [data-app-target=\"below_checkout\"] swap-insurewidget {\n    \tmargin-top: 2rem;\n    }\n    \n    swap-insure-infomodal {\n    \tz-index: 99999999999999;\n    }\n    \n    \/* Toggle fixes *\/\n    .swap-toggle {\n      -webkit-appearance: none !important;\n      appearance: none !important;\n    }\n\n    .swap-widget-about-title {\n      display: flex;\n      align-items: center;\n    }\n\n    .swap-widget-about-title > span {\n      flex-grow: 1;\n    }\n<\/style>\n\n<div id=\"swap-protect-target\"><\/div>","script_variable_json":"{\n\t\"product_handle\":\"Protect Product Handle (URL).<br><i>Example: swap-protect<\/i>\",\n    \"show_usp\":\"Wether or not the USP Bar should be shown.<br><i>Example: true \/ false<\/i>\",\n\t\"force_insure\":\"If force insure should be used\"\n}"},{"id":126,"name":"Recura Shipping Protection","script":"<div id=\"postpo-widget\" data-shop-domain={{shop_domain}}><\/div>\n","script_variable_json":"{\n  \"shop_domain\": \"Enter your Shop Domain\"\n}"},{"id":129,"name":"Greenspark","script":"<style>\n  .greenspark-widget-target {\n    padding: 16px;\n    display: flex !important;\n    align-items: center;\n    text-align: left;\n    justify-content: center;\n  }\n<\/style>\n<div data-greenspark-script-target><\/div>\n<section\n  data-greenspark-widget-target\n  class=\"greenspark-widget-target\"\n><\/section>\n<script>\n  function runGreenspark() {\n    const locale = window.Shopify?.locale || document.documentElement.getAttribute('lang') || \"en\"\n    const key = \"{{widget_key}}\";\n    const { apiKey, shopUniqueName, type, widgetArgs } = JSON.parse(atob(key));\n\n    function updateCart(cart, widget) {\n      const lineItems = cart.items\n        .filter((i) => Boolean(i.id))\n        .map((i) => ({\n          productId: `${i.product_id}`,\n          quantity: i.quantity,\n        }));\n\n      widget.render({\n        order: {\n          currency: cart.currency,\n          totalPrice: cart.items_subtotal_price,\n          lineItems,\n        },\n      });\n    }\n\n    const greenspark = new window.GreensparkWidgets({\n      apiKey,\n      shopUniqueName,\n      locale\n    });\n\n    const cartWidget = greenspark[type]({\n      ...widgetArgs,\n      containerSelector: \"[data-greenspark-widget-target]\",\n      useShadowDom: false,\n      withPopup: false,\n    });\n\n    document.addEventListener(\"rebuy:cart.change\", (event) => {\n      if (!event.detail?.cart) return;\n      updateCart(event.detail.cart.getCart(), cartWidget);\n    });\n\n    updateCart(window.Rebuy.Cart.getCart(), cartWidget);\n  }\n\n  function loadScript(url) {\n    return new Promise((resolve) => {\n      var script = document.createElement(\"script\");\n      script.type = \"text\/javascript\";\n      script.onload = function () {\n        resolve();\n      };\n\n      script.src = url;\n      document\n        .querySelector(\"[data-greenspark-script-target]\")\n        .appendChild(script);\n    });\n  }\n\n  const packageUrl = \"https:\/\/cdn.getgreenspark.com\/scripts\/widgets%40latest.js\";\n  loadScript(packageUrl).then(runGreenspark);\n<\/script>","script_variable_json":"{\"widget_key\":{\"label\":\"Enter your Greenspark + Rebuy API key that you retrieved from Greenspark's widget page. (https:\\\/\\\/help.getgreenspark.com\\\/en\\\/article\\\/rebuy-smart-cart-app-installation-1e9wnum\\\/)\",\"required\":true}}"},{"id":142,"name":"Rivo","script":"<!-- CSS -->\n<style>\n.rivo-sca {\n  margin-bottom: 5px;\n}\n.rivo-sca__contents {\n  text-align: left;\n}\n.rivo-sca__label {\n  font-size: 14px;\n}\n.rivo-sca__title {\n  font-size: 16px;\n  margin-bottom: 0;\n}\n.rivo-sca__account {\n  display: none;\n  position: relative;\n  text-align: center;\n}\n.rivo-sca__account.toggled .rivo-sca__points {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n}\n.rivo-sca__account.toggled .rivo-sca__point {\n  font-size: 20px;\n}\n.rivo-sca__account.toggled .rivo-sca__points-label {\n  margin-left: 5px;\n}\n.rivo-sca__account.toggled .rivo-sca__email {\n  display: none;\n}\n.rivo-sca__points {\n  display: block;\n  line-height: normal;\n  font-weight: bold;\n  font-size: 40px;\n}\n.rivo-sca__points-label {\n  font-weight: bold;\n  font-size: 12px;\n}\n.rivo-sca__email {\n  font-size: 12px;\n}\n.rivo-sca__toggle {\n  cursor: pointer;\n  background: none;\n  border: none;\n  position: absolute;\n  top: 5px;\n  right: 5px;\n  z-index: 10;\n}\n<\/style>\n<!-- HTML -->\n<div class=\"rivo-sca\" data-rivo-app=\"\">\n  <div class=\"rivo-sca__contents\">\n    <div class=\"rivo-sca__login\" data-rivo-login=\"\">\n      <h3 class=\"rivo-sca__title\">{{title}}<\/h3>\n      <label class=\"rivo-sca__label\">{{description}}<\/label>\n    <\/div>\n\n    <div class=\"rivo-sca__account\" data-rivo-account=\"\">\n      <button class=\"rivo-sca__toggle\" type=\"button\" data-rivo-toggle=\"\">\n        <svg width=\"12\" height=\"8\" viewBox=\"0 0 12 8\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n          <path d=\"M10.59 0.589844L6 5.16984L1.41 0.589844L0 1.99984L6 7.99984L12 1.99984L10.59 0.589844Z\" fill=\"#666E95\"><\/path>\n      <\/svg>\n      <\/button>\n\n      <div class=\"rivo-sca__points\" data-rivo-points=\"\">\n        <div class=\"rivo-sca__point\" data-rivo-point=\"\"><\/div>\n        <div class=\"rivo-sca__points-label\" data-rivo-points-label=\"\">POINTS\/CREDITS<\/div>\n      <\/div>\n      <div class=\"rivo-sca__email\" data-rivo-email=\"\"><\/div>\n    <\/div>\n  <\/div>\n<\/div>\n<!-- JS -->\n<script>\n(function () {\n  const $ = Rebuy.libraries.$;\n  const selectors = {\n    login: '[data-rivo-login]',\n    account: '[data-rivo-account]',\n    toggle: '[data-rivo-toggle]',\n    points: '[data-rivo-points]',\n    pointsLabel: '[data-rivo-points-label]',\n    point: '[data-rivo-point]',\n    email: '[data-rivo-email]',\n  };\n\n  $(selectors.toggle).on('click', () => {\n    $(selectors.toggle).toggleClass('toggled');\n    $(selectors.account).toggleClass('toggled');\n  });\n\n  if (window.Rivo.common.customer) {\n    let balance = window.Rivo.loy_config.credit_mode ? window.Rivo.common.customer.status_credits_tally : window.Rivo.common.customer.status_points_tally;\n    let loyaltyPreference = window.Rivo.loy_config.credit_mode ? \"CREDITS\" : \"POINTS\";\n\n    $(selectors.login).hide();\n    $(selectors.account).show();\n\n    $(selectors.point).text(balance);\n    $(selectors.pointsLabel).text(loyaltyPreference);\n    $(selectors.email).text(window.Rivo.common.customer.email);\n  }\n})();\n<\/script>\n","script_variable_json":"{\n  \"title\": \"Title\",\n  \"description\": \"Description\"\n}\n"},{"id":151,"name":"Inspired","script":"<span style=\"margin-left: {{padding_left}}px; margin-top: {{padding_top}}px; display: flex;\" >\n<inspired-impact-offer \/> \n<\/span>","script_variable_json":"{\n\"padding_left\": \"Widget left padding, 20 is the recommended value.\",\n\"padding_top\": \"Widget top padding, 10 is the recommended value.\"\n}"},{"id":159,"name":"Give & Grow Donations","script":"<link rel='stylesheet' href='https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/font-awesome\/6.4.2\/css\/all.min.css'>\n<style>\n    #pledge-smart-cart-app-container {\n      \/* Scoped CSS variables *\/\n      --pledge-spacing: 16px;\n      --pledge-button-color: #605ca8;\n\n      display: none; \/* Initially hidden, will be shown when product info is fetched *\/\n    }\n\n  #pledge-smart-cart-app-content {\n    padding: 0 var(--pledge-spacing) 0;\n  }\n\n  #pledge-smart-cart-app-heading {\n    margin-bottom: var(--pledge-spacing);\n    display: flex;\n    justify-content: space-between;\n    font-size: 20px;\n    font-weight: 600;\n\n    display: none;\n  }\n\n  #pledge-smart-cart-app-icon-buttons {\n    display: flex;\n    margin-bottom: var(--pledge-spacing);\n  }\n\n  #pledge-smart-cart-app-actions {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n  }\n\n  .pledge-smart-cart-app-org-button {\n    background-color: transparent;\n    color: var(--pledge-button-color);\n    margin: 0 0.25rem;\n    font-size: 20px;\n  }\n\n  .pledge-smart-cart-app-org-button:hover,\n  .pledge-smart-cart-app-org-button.active {\n    background-color: var(--pledge-button-color);\n    border-color: var(--pledge-button-color);\n    color: #fff;\n  }\n\n  #pledge-smart-cart-app-donate-button {\n    width: auto;\n    margin-left: 10px;\n  }\n\n<\/style>\n\n<div id='pledge-smart-cart-app-container'>\n  <div id='pledge-smart-cart-app-content'>\n    <div id='pledge-smart-cart-app-heading' >\n      <div id='pledge-smart-cart-app-title'>Support your favorite nonprofit!<\/div>\n      <div id='pledge-smart-cart-app-amount'>$1<\/div>\n    <\/div>\n    <div id='pledge-smart-cart-app-icon-buttons' role='group' aria-label='Select a nonprofit'><\/div>\n    <div id='pledge-smart-cart-app-actions'>\n      <p id='pledge-smart-cart-app-nonprofit-text' aria-live='polite'><\/p>\n      <button id='pledge-smart-cart-app-donate-button' class='rebuy-button' aria-label='Donate to selected nonprofit'>\n        Donate\n      <\/button>\n    <\/div>\n  <\/div>\n<\/div>\n\n<script>\n  \/\/ --- DOM Elements ---\n  const donateButton = document.getElementById('pledge-smart-cart-app-donate-button');\n  const nonprofitText = document.getElementById('pledge-smart-cart-app-nonprofit-text');\n  const iconButtonContainer = document.getElementById('pledge-smart-cart-app-icon-buttons');\n  const widgetContainer = document.getElementById('pledge-smart-cart-app-container');\n  const heading = document.getElementById('pledge-smart-cart-app-heading');\n\n  \/\/ --- State ---\n  let selectedOrgId = null;\n  let variantTexts = [];\n  const icons = getIconArrFromString('{{icons}}'); \/\/ Provided by merchant\n  const rebuy_api_key = '{{rebuy_api_key}}'; \/\/ Provided by merchant\n  const shopify_product_id = '{{shopify_product_id}}'; \/\/ Provided by merchant\n\n  \/\/ --- Add to Cart ---\n  function addToCart(id) {\n    Rebuy.Cart.addItem({\n      id,\n      variantId: id,\n      quantity: 1\n    }).catch(error => {\n      console.error('Error adding item to cart:', error);\n    });\n  }\n\n  function showWidget() {\n    widgetContainer.style.display = 'block';\n  }\n  function hideWidget() {\n    widgetContainer.style.display = 'none';\n  }\n\n  function getNonprofitName(title) {\n    if (title && title.toLowerCase().startsWith('donation to')) {\n      return title.replace(\/^donation to\\s*\/i, '').trim();\n    }\n    return title;\n  }\n\n  function getIconArrFromString(iconString) {\n    if (!iconString) return [];\n    return iconString.split(',').map(icon => icon.trim());\n  }\n\n  \/\/ --- Render Widget ---\n  function renderWidget(variants, productTitle) {\n    iconButtonContainer.innerHTML = '';\n    let filteredVariants = variants;\n\n    \/\/ Remove 'split among' variant if present\n    if (\n      variants.length > 1 && variants.length <= 5 &&\n      variants[0].option1 &&\n      variants[0].option1.toLowerCase().startsWith('split among')\n    ) {\n      filteredVariants = variants.slice(1);\n    }\n\n    \/\/ Set variantTexts\n    if (filteredVariants.length > 1 ) {\n      variantTexts = filteredVariants.map((variant, idx) => {\n        const nonprofitName = getNonprofitName(variant.title);\n        if (idx === 0 && filteredVariants.length > 4) {\n          return `<p><b>Split donation among nonprofits<\/b><br\/>Split the donation among all ${filteredVariants.length - 1} nonprofits.<\/p>`;\n        }\n        return `<p><b>Donation to ${nonprofitName}<\/b><br\/>Add a donation in support of ${nonprofitName}.<\/p>`;\n      })\n    };\n\n    \/\/ Single variant: show info and button\n    if (filteredVariants.length === 1) {\n      const nonprofitName = getNonprofitName(productTitle);\n      selectedOrgId = filteredVariants[0].id;\n      variantTexts = [`<p><b>Donation to ${nonprofitName}<\/b><br\/>Add a donation in support of ${nonprofitName}.<\/p>`];\n      nonprofitText.innerHTML = variantTexts[0];\n    } else {\n      heading.style.display = 'flex';\n\n      if (filteredVariants.length > 4) {\n        const dropdown = document.createElement('select');\n        dropdown.setAttribute('aria-label', 'Select a nonprofit');\n        dropdown.className = 'rebuy-select';\n        dropdown.id = 'pledge-smart-cart-app-org-dropdown';\n        filteredVariants.forEach((variant, idx) => {\n          const option = document.createElement('option');\n          option.value = variant.id;\n          option.textContent = getNonprofitName(variant.title);\n          if (idx === 0 && filteredVariants.length > 4) {\n            option.textContent = 'Split donation among nonprofits';\n          }\n          dropdown.appendChild(option);\n        });\n        dropdown.addEventListener('change', function() {\n          const idx = filteredVariants.findIndex(v => v.id == dropdown.value);\n          if (idx !== -1) {\n            selectedOrgId = filteredVariants[idx].id;\n            nonprofitText.innerHTML = variantTexts[idx];\n          }\n        });\n\n        \/\/ Set default selected option\n        selectedOrgId = filteredVariants[0].id;\n        nonprofitText.innerHTML = variantTexts[0];\n\n        iconButtonContainer.appendChild(dropdown);\n\n      } else {\n        filteredVariants.forEach((variant, idx) => {\n          const nonprofitName = getNonprofitName(variant.title);\n          const btn = document.createElement('button');\n\n          const icon = icons[idx % icons.length];\n          btn.type = 'button';\n          btn.className = 'pledge-smart-cart-app-org-button rebuy-button';\n          btn.setAttribute('aria-pressed', 'false');\n          btn.setAttribute('aria-label', `Select ${nonprofitName}`);\n          btn.innerHTML = `<i class='fa-solid fa-${icon}'><\/i>`;\n\n\n          btn.addEventListener('click', function() {\n            iconButtonContainer.querySelectorAll('button').forEach(b => b.classList.remove('active'));\n            iconButtonContainer.querySelectorAll('button').forEach(b => b.setAttribute('aria-pressed', 'false'));\n            btn.setAttribute('aria-pressed', 'true');\n            btn.classList.add('active');\n            selectedOrgId = variant.id;\n            nonprofitText.innerHTML = variantTexts[idx];\n          });\n\n          iconButtonContainer.appendChild(btn);\n        });\n\n        \/\/ Activate first button by default\n        const firstBtn = iconButtonContainer.querySelector('button');\n        if (firstBtn) {\n          firstBtn.classList.add('active');\n          selectedOrgId = filteredVariants[0].id;\n          nonprofitText.innerHTML = variantTexts[0];\n        }\n      }\n    }\n    showWidget();\n  }\n\n  \/\/ --- Fetch Product Info ---\n  function fetchProductInfo() {\n    const requestParameters = new URLSearchParams({\n      key: rebuy_api_key,\n      ids: shopify_product_id,\n      metafields: 'yes',\n      bust_cache: 'yes',\n      format: 'pretty'\n    });\n\n    fetch(`https:\/\/rebuyengine.com\/api\/v1\/products\/static?${requestParameters}`)\n      .then(response => response.json())\n      .then(response => {\n        const productInfo = response.data;\n        if (productInfo && productInfo.length > 0) {\n          const variants = productInfo[0].variants;\n          renderWidget(variants, productInfo[0].title);\n        } else {\n          console.error('No product info found');\n          hideWidget();\n        }\n      })\n      .catch(error => {\n        console.error('Error fetching product info:', error);\n        hideWidget();\n      });\n  }\n\n  \/\/ --- Event Listeners ---\n  donateButton.onclick = function() {\n    if (selectedOrgId) addToCart(selectedOrgId);\n  };\n\n  \/\/ --- Init ---\n  fetchProductInfo();\n<\/script>\n","script_variable_json":"{\"shopify_product_id\":{\"label\":\"Enter the product ID of the donation button product in your Shopify store.\",\"required\":true},\"rebuy_api_key\":{\"label\":\"Enter your store's rebuy api key\",\"required\":true},\"icons\":{\"label\":\"List icons you'd like to use in order of how they'll be displayed, separated by commas. This only applies when donating to 2-4 nonprofits.  Ex: heart, star, brain, tree\",\"required\":false,\"default\":\"heart, star, brain, tree\"},\"button_color\":{\"label\":\"Enter the color you'd like your buttons to be. Only applies when you are offering donations to 2-4 nonprofits. Should be in hex format (#RRGGBB).\",\"required\":false,\"default\":\"#605ca8\"}}"},{"id":178,"name":"DailyKarma - Round Up Customer Donations","script":"<script>window.dk_widget_round_up_no_refresh=true;<\/script>\n<div class=\"dk-round-up-popup-static\"><\/div>\n\n\n ","script_variable_json":null},{"id":179,"name":"DailyKarma - Customer Donation Tiers","script":"\t<div class=\"dk-flat-static\"><\/div>","script_variable_json":null},{"id":184,"name":"Joy Loyalty","script":"<div style=\"padding: 16px;\" class=\"joy-redeem-inline\"><\/div>","script_variable_json":null}]