PageSourceSearch

https://www.eventeny.com/js/product/product-pricing-2020-12-02.js?v=1790189618

js eventeny.com collected 2026-09-24 08:56:44 UTC 45,827 bytes, 1,020 lines download raw bytes

1function validatePhone(phone) {
2    // Accepts (123) 456-7890, 123-456-7890, 1234567890, 123.456.7890, etc.
3    const phonePattern = /^(\+?\d{1,2}\s?)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/;
4    return phonePattern.test(phone);
5}
6
7function validateEmail(email) {
8    const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
9    return emailPattern.test(email);
10}
11
12// load the mixpanel tracker
13// Guard against mixpanel.js being blocked by ad/tracker blockers - an uncaught ReferenceError here would abort this whole script and disable all click handlers below
14subscriptionMixpanelTracker = typeof subscriptionExperienceTracker !== 'undefined' ? new subscriptionExperienceTracker() : { trackSubscriptionExperienceEvent: () => {} };
15const leadURL = this.location.href;
16const referralURL = document.referrer;
17const pricingData = {
18    usd: {
19        annual: {
20            premium: {
21                totalPrice: '$480',
22                annualPrice: '$5,760',
23                ipadDepositPrice: '$100',
24                ipadRentalPrice: 'First 5 iPads free',
25                hotspotDepositPrice: '$100',
26                hotspotRentalPrice: '1 month free',
27                hotspotActivationPrice: '$150',
28                swivelRentalPrice: '$5/week',
29                chargerRentalPrice: '$5/week'
30            },
31            pro: {
32                totalPrice: '$240',
33                annualPrice: '$2,880',
34                ipadDepositPrice: '$100',
35                ipadRentalPrice: 'First 5 iPads free',
36                hotspotDepositPrice: '$100',
37                hotspotRentalPrice: '1 month free',
38                hotspotActivationPrice: '$150',
39                swivelRentalPrice: '$5/week',
40                chargerRentalPrice: '$5/week'
41            },
42            plus: {
43                totalPrice: '$120',
44                annualPrice: '$1,440',
45                ipadDepositPrice: '$100',
46                ipadRentalPrice: '$125/week',
47                hotspotDepositPrice: '$100',
48                hotspotRentalPrice: '$65/month',
49                hotspotActivationPrice: '$150',
50                swivelRentalPrice: '$5/week',
51                chargerRentalPrice: '$5/week'
52            },
53            starter: {
54                totalPrice: '$60',
55                annualPrice: '$720',
56                chargerRentalPrice: '$5/week'
57            },
58            basic: {
59                totalPrice: '$0'
60            }
61        },
62        monthly: {
63            premium: {
64                totalPrice: '$720',
65                annualPrice: '$8,640'
66            },
67            pro: {
68                totalPrice: '$360',
69                annualPrice: '$4,320'
70            },
71            plus: {
72                totalPrice: '$180',
73                annualPrice: '$2,160'
74            },
75            starter: {
76                totalPrice: '$90',
77                annualPrice: '$1,080'
78            },
79            basic: {
80                totalPrice: '$0'
81            }
82        }
83    },
84    cad: {
85        annual: {
86            premium: {
87                totalPrice: 'C$640',
88                annualPrice: 'C$7,680',
89                ipadDepositPrice: 'C$136',
90                ipadRentalPrice: 'First 5 iPads free',
91                hotspotDepositPrice: 'C$136',
92                hotspotRentalPrice: '1 month free',
93                hotspotActivationPrice: 'C$204',
94                swivelRentalPrice: 'C$6.80/week',
95                chargerRentalPrice: 'C$6.80/week'
96            },
97            pro: {
98                totalPrice: 'C$320',
99                annualPrice: 'C$3,840',
100                ipadDepositPrice: 'C$136',
101                ipadRentalPrice: 'First 5 iPads free',
102                hotspotDepositPrice: 'C$136',
103                hotspotRentalPrice: '1 month free',
104                hotspotActivationPrice: 'C$204',
105                swivelRentalPrice: 'C$6.80/week',
106                chargerRentalPrice: 'C$6.80/week'
107            },
108            plus: {
109                totalPrice: 'C$160',
110                annualPrice: 'C$1,920',
111                ipadDepositPrice: 'C$100',
112                ipadRentalPrice: 'C$125/week',
113                hotspotDepositPrice: 'C$100',
114                hotspotRentalPrice: 'C$65/month',
115                hotspotActivationPrice: 'C$150',
116                swivelRentalPrice: 'C$5/week',
117                chargerRentalPrice: 'C$5/week'
118            },
119            starter: {
120                totalPrice: 'C$80',
121                annualPrice: 'C$960'
122            },
123            basic: {
124                totalPrice: 'C$0'
125            }
126        },
127        monthly: {
128            premium: {
129                totalPrice: 'C$960',
130                annualPrice: 'C$11,520'
131            },
132            pro: {
133                totalPrice: 'C$500',
134                annualPrice: 'C$6,000'
135            },
136            plus: {
137                totalPrice: 'C$250',
138                annualPrice: 'C$3,000'
139            },
140            starter: {
141                totalPrice: 'C$125',
142                annualPrice: 'C$1,500'
143            },
144            basic: {
145                totalPrice: 'C$0'
146            }
147        }
148    }
149};
150
151/*----Load----*/
152$(function () {
153    hidePriceComparisonFeatures();
154  
155    const hash = window.location.hash; // e.g. "#payout-schedule-question"
156  
157    // your existing tracking
158    subscriptionMixpanelData = {
159      URL: "/product/pricing/",
160      Source: "Subscription Pageview",
161      Action: "Enter",
162    };
163    subscriptionMixpanelTracker.trackSubscriptionExperienceEvent('Pageview', subscriptionMixpanelData);
164  
165    resetRecurrenceSwitches();
166    renderPricingTables();
167  
168    const openFirst = () => $('#faq-section label:eq(0)').addClass('checked');
169  
170    const openAndScrollTo = (selector) => {
171      const $t = $(selector);
172      if (!$t.length) return openFirst();
173  
174      // open the question before measuring
175      $t.addClass('checked');
176  
177      // account for sticky header
178      const headerOffset = ($('#eventeny-navbar').outerHeight() || 0) + 16;
179  
180      // wait one frame so layout can settle after "checked" expands content
181      requestAnimationFrame(() => {
182        const top = Math.max(0, $t.offset().top - headerOffset);
183        $('html, body').stop(true).animate({ scrollTop: top }, 400);
184      });
185    };
186  
187    if (hash === '#payout-schedule-question') {
188      // do it now and again on window load in case images/fonts change layout
189      openAndScrollTo(hash);
190      $(window).on('load', () => openAndScrollTo(hash));
191    }
192  });
193
194
195const levels = ['free', 'starter', 'plus', 'pro', 'premium'];
196$('.currency-selector').on('click', function() { //currency selector click handler to update UI element and run change currency function
197    if (!$(this).hasClass('active')) { //only change if the selected target was not already active
198        $('.currency-selector').removeClass('active'); //remove active from all selectors (this is in case there are multiple in the future)
199        $(this).addClass('active'); //add active to selected target
200        selectedCurrency = $(this).data('currency'); //set the currency
201        changeCurrency(selectedCurrency);
202    }
203    setPricingPlanSections();
204});
205
206function changeCurrency(currency) { //this function handles the change in currency for displaying the various plans on the pricing page
207    currencySymbol = currencyCodes[currency]
208    levels.forEach(function(plan, index) { //loop through each level and change the annual/monthly values appropriately
209        $(`.${plan}-annual`).html(currencySymbol + (Math.round(prices[currency][plan]['annual']/12).toLocaleString()))
210        if((Math.round(prices[currency][plan]['annual']/12)) !== prices[currency][plan]['month']){
211            $(`.${plan}-month`).html('*' + currencySymbol + (prices[currency][plan]['month']).toLocaleString() + "/mo if paid monthly")
212        }
213    });
214}
215
216
217/*----Feature comparison section----*/
218function hidePriceComparisonFeatures(){
219    $('#pricing-feature-comparison-section tr:gt(5)').addClass('hide');
220    $('#pricing-feature-comparison-section strong:gt(0)').addClass('hide');
221    $('#pricing-feature-comparison-section tr:eq(5)').addClass('fade-teaser');
222    $('#pricing-feature-comparison-section .fade-toggle').removeClass('show-table').html('See all features');
223}
224function showPriceComparisonFeatures(){
225    $('#pricing-feature-comparison-section tr').removeClass('hide');
226    $('#pricing-feature-comparison-section strong').removeClass('hide');
227    $('#pricing-feature-comparison-section tr').removeClass('fade-teaser');
228    $('#pricing-feature-comparison-section .fade-toggle').addClass('show-table').html('Show less');
229}
230$('#pricing-feature-comparison-section .fade-toggle').on('click', function(e){
231    if($(this).hasClass('show-table')) hidePriceComparisonFeatures();
232    else showPriceComparisonFeatures();
233});
234$('#faq-section label').on('click', function(e){
235    $(this).siblings().removeClass('checked');
236    $(this).toggleClass('checked');
237});
238
239
240/*---- Get Started modal handlers ----*/
241
242// Initialize dropdown and wire up all modal interaction after DOM is ready
243document.addEventListener('DOMContentLoaded', function(){
244    const dropdown = document.querySelector('#account-type-select');
245    if(dropdown){
246        dropdown.setItems([
247            {id: 'EO',       value: 'Event organizer'},
248            {id: 'AVE',      value: 'Artist, vendor, or exhibitor'},
249            {id: 'Attendee', value: 'Attendee'}
250        ]);
251        dropdown.addEventListener('change', function(){
252            const val = dropdown.getSelected();
253            const errorEl = document.querySelector('#get-started-form-start-section .error');
254            if(errorEl) errorEl.innerHTML = '';
255
256            document.querySelector('#eo-form-fields').style.display   = 'none';
257            document.querySelector('#ave-alert').style.display        = 'none';
258            document.querySelector('#attendee-alert').style.display   = 'none';
259            document.querySelector('#ave-footer').style.display       = 'none';
260            document.querySelector('#attendee-footer').style.display  = 'none';
261            document.querySelector('#default-footer').style.display   = 'flex';
262
263            if(val === 'EO'){
264                document.querySelector('#eo-form-fields').style.display = 'flex';
265            } else if(val === 'AVE'){
266                document.querySelector('#ave-alert').style.display      = 'block';
267                document.querySelector('#default-footer').style.display = 'none';
268                document.querySelector('#ave-footer').style.display     = 'flex';
269            } else if(val === 'Attendee'){
270                document.querySelector('#attendee-alert').style.display = 'block';
271                document.querySelector('#default-footer').style.display = 'none';
272                document.querySelector('#attendee-footer').style.display = 'flex';
273            }
274        });
275    }
276
277    // Navigation buttons in AVE / Attendee footers
278    const aveFindAppsBtn = document.querySelector('#ave-find-apps-btn');
279    if(aveFindAppsBtn) aveFindAppsBtn.addEventListener('click', function(){ window.location.href = '/events/applications/'; });
280    const attendeeFindEventsBtn = document.querySelector('#attendee-find-events-btn');
281    if(attendeeFindEventsBtn) attendeeFindEventsBtn.addEventListener('click', function(){ window.location.href = '/events/'; });
282});
283
284// Close modal — Cancel buttons and delegated cancel class
285$('#non-event-organizer-btn').on('click', function(){
286    const modal = document.querySelector('#get-started-modal');
287    if(modal) modal.closeModal();
288});
289$(document).on('click', '.get-started-cancel-btn', function(){
290    const modal = document.querySelector('#get-started-modal');
291    if(modal) modal.closeModal();
292});
293
294// Ok button (EO submit)
295$('#category-ok-btn').on('click', function(){
296    const dropdown     = document.querySelector('#account-type-select');
297    const selectedType = dropdown ? dropdown.getSelected() : null;
298    const modal        = document.querySelector('#get-started-modal');
299    const errorEl      = document.querySelector('#get-started-form-start-section .error');
300    if(errorEl) errorEl.innerHTML = '';
301
302    const showError = function(msg){
303        if(modal) modal.scrollModalTop();
304        if(errorEl) errorEl.innerHTML = msg;
305    };
306
307    if(!selectedType){
308        showError('Please select what best describes you.');
309        return;
310    }
311    if(selectedType !== 'EO') return;
312
313    const firstName = (document.querySelector('#eo-first-name').getValue()  || '').trim();
314    const lastName  = (document.querySelector('#eo-last-name').getValue()   || '').trim();
315    const email     = (document.querySelector('#eo-email').getValue()       || '').trim();
316    const phone     = (document.querySelector('#eo-phone').getValue()       || '').trim();
317    const company   = (document.querySelector('#eo-company').getValue()     || '').trim();
318    const website   = (document.querySelector('#eo-website').getValue()     || '').trim();
319
320    if(!firstName){ showError('Please enter your first name.'); return; }
321    if(!lastName) { showError('Please enter your last name.'); return; }
322    if(!email || !validateEmail(email))  { showError('Please enter a valid email address.'); return; }
323    if(!phone || !validatePhone(phone))  { showError('Please enter a valid phone number.'); return; }
324    if(!website)  { showError('Please enter your website URL.'); return; }
325
326    showLoader();
327
328    subscriptionMixpanelTracker.trackSubscriptionExperienceEvent('Lead Form Submitted', {
329        Page: 'Pricing',
330        'Account Type': selectedType,
331        'Plan Level': planLevel,
332        'Company Filled': !!company,
333        'Logged In': user_login !== 0,
334    });
335
336    if(user_login === 0){
337        // Not logged in: store lead in backend (no account to look up, so send contact info directly), then HubSpot, then redirect to signup with pre-filled fields
338        const params = new FormData();
339        params.append('post_type',      'event_organizer_lead');
340        params.append('level',          planLevel);
341        params.append('url',            leadURL);
342        params.append('referral_url',   referralURL);
343        params.append('account_type',   'EO');
344        params.append('lead_company',   company);
345        params.append('lead_website',   website);
346        params.append('lead_phone',     phone);
347        params.append('lead_first_name', firstName);
348        params.append('lead_last_name',  lastName);
349        params.append('lead_email',      email);
350        baseFuncsContentUpdate('product/pricing-2020-12-02.php', params, function(){}, function(){}, function(){}, false, 0);
351
352        hubSpotLeadNotification(email, firstName, lastName, phone, planLevel, '', website, company)
353            .finally(() => {
354                localStorage.setItem('ev-lead-contact', firstName + ' ' + lastName);
355                localStorage.setItem('ev-lead-phone', phone);
356                localStorage.setItem('ev-lead-company', company);
357                localStorage.setItem('ev-lead-website', website);
358                const ref = '/product/pricing/subscribe/?plan=' + encodeURIComponent(planLevel) + '&currency=' + encodeURIComponent(selectedCurrency);
359                const qs  = new URLSearchParams({ first_name: firstName, last_name: lastName, email: email, type: 'event_organizer', ref: ref });
360                window.location.href = '/users/signup/?' + qs.toString();
361            });
362    } else {
363        // Logged in: store lead in backend, then HubSpot, then subscribe
364        const params = new FormData();
365        params.append('post_type',    'event_organizer_lead');
366        params.append('level',        planLevel);
367        params.append('url',          leadURL);
368        params.append('referral_url', referralURL);
369        params.append('account_type',  'EO');
370        params.append('lead_company',  company);
371        params.append('lead_website',  website);
372        params.append('lead_phone',    phone);
373
374        const successFunc = function(data){
375            const ip = data.user_info.ip || '';
376            hubSpotLeadNotification(email, firstName, data.user_info.last_name || '', phone, planLevel, ip, website, company)
377                .finally(() => {
378                    ['ev-sub-biz-id','ev-sub-biz-name','ev-sub-team-members','ev-sub-previous-payout','ev-sub-skip-team']
379                        .forEach(k => localStorage.removeItem(k));
380                    localStorage.setItem('ev-lead-contact', firstName + ' ' + (data.user_info.last_name || lastName));
381                    localStorage.setItem('ev-lead-phone', phone);
382                    localStorage.setItem('ev-lead-company', company);
383                    localStorage.setItem('ev-lead-website', website);
384                    window.location.href = '/product/pricing/subscribe/?plan=' + encodeURIComponent(planLevel) + '&currency=' + encodeURIComponent(selectedCurrency);
385                });
386            hideLoader();
387        };
388        const errorFunc = function(data){
389            showError(data.err_msg); hideLoader();
390        };
391        const errorServerFunc = function(jqXHR, textStatus){
392            showError(textStatus); hideLoader();
393        };
394        baseFuncsContentUpdate('product/pricing-2020-12-02.php', params, successFunc, errorFunc, errorServerFunc, false, 0);
395    }
396});
397
398$("#get-started-form-start-section").on('submit', function(e){ e.preventDefault(); });
399
400
401$(document).on('click', '#back-to-homepage', function(){
402    showLoader();
403    window.location.href = '/';
404});
405
406$(".custom-dropbtn").on('click', function(e){
407    e.preventDefault();
408});
409function hubSpotLeadNotification(email, firstName, lastName, phoneNumber, planLevel, ip, website, company) {
410    return new Promise((resolve, reject) => {
411        const xhr = new XMLHttpRequest();
412        const url = 'https://api.hsforms.com/submissions/v3/integration/submit/4492849/bb062b34-cdac-4fa1-a768-6ab3e79ea9cf';
413        const fields = [
414            { 'name': 'firstname',          'value': firstName },
415            { 'name': 'lastname',           'value': lastName },
416            { 'name': 'email',              'value': email },
417            { 'name': 'phone',              'value': phoneNumber },
418            { 'name': 'website',            'value': website || '' },
419            { 'name': 'subscription_level', 'value': planLevel.charAt(0).toUpperCase() + planLevel.slice(1) },
420            { 'name': 'i_am_a',             'value': 'Event Organizer' },
421        ];
422        fields.push({ 'name': 'company', 'value': company || '' });
423        const data = {
424            'submittedAt': Date.now(),
425            'fields': fields,
426            'context': Object.assign(
427                { 'pageUri': window.location.href },
428                baseCookieManager('hubspotutk') ? { 'hutk': baseCo
428okieManager('hubspotutk') } : {},
429                ip ? { 'ipAddress': ip } : {}
430            ),
431        };
432        xhr.open('POST', url);
433        xhr.setRequestHeader('Content-Type', 'application/json');
434
435        xhr.onload = function () {
436            if (xhr.status >= 200 && xhr.status < 300) {
437                resolve();
438            } else {
439                console.error('HubSpot submission failed', xhr.status, xhr.responseText);
440                reject(xhr.statusText);
441            }
442        };
443
444        xhr.onerror = function () {
445            console.error('HubSpot submission network error');
446            reject('Network Error');
447        };
448
449        xhr.send(JSON.stringify(data));
450    });
451}
452
453//Pricing recurrence switches
454$(document).on('change', '.label-switch-square input[type="checkbox"]', function() {
455    const isChecked = $(this).prop('checked');
456    const discountStatement = $('#sticky-recurrence-label');
457
458    $('.label-switch-square input[type="checkbox"]').prop('checked', isChecked);
459
460    if(isChecked){
461        setTimeout(function () {
462            $('.label-switch-square .option-1').css('color', 'black');
463            $('.label-switch-square .option-2').css('color', 'white');
464            discountStatement.removeClass('hide');
465        }, 100);
466
467        $('.label-switch-square input[type="checkbox"]').val('monthly');
468    } else {
469        setTimeout(function () {
470            $('.label-switch-square .option-1').css('color', 'white');
471            $('.label-switch-square .option-2').css('color', 'black');
472            discountStatement.addClass('hide');
473        }, 100);
474
475        $('.label-switch-square input[type="checkbox"]').val('annual');
476    }
477
478    $('#close-tooltip-description-btn').click();
479    setPricingPlanSections();
480});
481
482//Event price section arrow
483$('.event-pricing-arrow').on('click', function() {
484    const closestAddOnList = $(this).closest('.add-on-item').next().find('.event-pricing-list');
485
486    if($(this).hasClass('uil-angle-down')){
487        closestAddOnList.show();
488        $('.event-pricing-list').removeClass('hide');
489        $(this).removeClass('uil-angle-down').addClass('uil-angle-up');
490    } else {
491        closestAddOnList.hide();
492        $(this).removeClass('uil-angle-up').addClass('uil-angle-down');
493    }
494});
495
496//Custom map section arrow
497$('.custom-map-arrow').on('click', function() {
498    const closestAddOnList = $(this).closest('.add-on-item').next().find('.custom-map-list');
499
500    if($(this).hasClass('uil-angle-down')){
501        closestAddOnList.show();
502        $('.custom-map-list').removeClass('hide');
503        $(this).removeClass('uil-angle-down').addClass('uil-angle-up');
504    } else {
505        closestAddOnList.hide();
506        $(this).removeClass('uil-angle-up').addClass('uil-angle-down');
507    }
508});
509
510//Tooltip views on mobile, tablet and desktop
511$(document).on('click', 'tooltip-element', function(e) {
512    const stickyRecurrenceContainer = $('#sticky-recurrence-container');
513    const stickyRecurrenceLabel = $('#sticky-recurrence-label');
514    const stickyTooltipDescription = $('#sticky-tooltip-description');
515    const closeTooltipDescriptionBtn = $('#close-tooltip-description-btn');
516
517    ////Dynamic tooltips - mobile/tablet view
518    if(stickyRecurrenceContainer.is(':visible')){
519        const dynamicTooltips = ['starter-onboarding-tooltip', 'plus-onboarding-tooltip', 'pro-onboarding-tooltip'];
520        const tooltipId = this.id;
521        const recurrence = $('.label-switch-square input[type="checkbox"]').val();
522        const monthlyTexts = {
523            'pro-onboarding-tooltip': 'Up to 3 onboarding calls.',
524            'plus-onboarding-tooltip': 'Up to 2 onboarding calls.',
525            'starter-onboarding-tooltip': 'Up to 1 onboarding call.'
526        };
527        let tooltipText = '';
528
529        if (dynamicTooltips.includes(tooltipId)) {
530            tooltipText = (recurrence === 'annual')
531                ? 'Up to 3 onboarding calls with an event specialist.'
532                : monthlyTexts[tooltipId] || '';
533        } else{
534            tooltipText = this.getAttribute('description') || $(this).text().trim();
535            if(stickyRecurrenceLabel.is(':visible')){
536                stickyRecurrenceLabel.addClass('hide');
537            }
538        }
539        stickyTooltipDescription.empty().text(tooltipText).removeClass('hide');
540        closeTooltipDescriptionBtn.removeClass('hide');
541    }
542});
543
544//Tooltip description on mobile and tablet view
545$('#close-tooltip-description-btn').on('click', function() {
546    const stickyTooltipDescription = $('#sticky-tooltip-description');
547    const stickyRecurrenceLabel = $('#sticky-recurrence-label');
548    const closeTooltipDescriptionBtn = $('#close-tooltip-description-btn');
549
550    stickyTooltipDescription.empty().addClass('hide');
551    closeTooltipDescriptionBtn.addClass('hide');
552    
553    if($('.label-switch-square input[type="checkbox"]').is(':checked')){
554        stickyRecurrenceLabel.removeClass('hide');
555    }
556});
557
558//Dynamic tooltips - desktop view
559function updateOnboardingTooltips(recurrence) {
560    const tooltips = [
561        {
562            selector: '#pro-plan-section tooltip-element#pro-onboarding-tooltip',
563            annualText: 'Up to 3 onboarding calls with an event specialist.',
564            monthlyText: 'Up to 3 onboarding calls.'
565        },
566        {
567            selector: '#plus-plan-section tooltip-element#plus-onboarding-tooltip',
568            annualText: 'Up to 3 onboarding calls with an event specialist.',
569            monthlyText: 'Up to 2 onboarding calls.'
570        },
571        {
572            selector: '#starter-plan-section tooltip-element#starter-onboarding-tooltip',
573            annualText: 'Up to 3 onboarding calls with an event specialist.',
574            monthlyText: 'Up to 1 onboarding calls.'
575        }
576    ];
577
578    tooltips.forEach(({ selector, annualText, monthlyText }) => {
579        const tooltip = document.querySelector(selector);
580        if (tooltip && typeof tooltip.setTooltipContent === 'function') {
581            const content = (recurrence === 'annual') ? annualText : monthlyText;
582            tooltip.setTooltipContent(`<p class="line-height-3">${content}</p>`);
583        }
584    });
585}
586
587
588
589function setPricingBorders(currency, recurrence) {
590    const windowWidth = window.innerWidth;
591    const isMobile = windowWidth < 768;
592    const isTablet = windowWidth >= 768 && windowWidth <= 1024;
593    const isDesktop = windowWidth > 1024;
594
595    const baseSelector = '#pricing-plan-section';
596    const planIds = ['basic', 'starter', 'plus', 'pro', 'premium'];
597
598    const applyStyles = (stylesMap) => {
599        for (const [planId, styles] of Object.entries(stylesMap)) {
600            $(`${baseSelector} #${planId}-plan-section`).css(styles);
601        }
602    };
603
604    // No individual card borders — table border is on #plan-template via CSS
605    if (isMobile) {
606        const clearBorder = { border: 'none', 'border-radius': '0' };
607        const styles = Object.fromEntries(planIds.map(id => [id, clearBorder]));
608        return applyStyles(styles);
609    }
610
611    // Define styles for various cases
612    const config = {
613        pageA: {
614            desktop: {
615                annual: {
616                    pro: { border: '1px solid black', 'border-radius': '15px 0 15px 15px' },
617                    plus: { 'border': '1px solid black', 'border-left': '0', 'border-radius': '0 0 15px 15px' },
618                    starter: { 'border': '1px solid black', 'border-left': '0', 'border-radius': '0 0 15px 15px' },
619                    basic: { 'border': '1px solid black', 'border-left': '0', 'border-radius': '0 15px 0 0', 'max-width': '100%'  }
620                },
621                monthly: {
622                    pro: { border: '1px solid black', 'border-radius': '15px 0 0 15px' },
623                    plus: { 'border': '1px solid black', 'border-left': '0', 'border-radius': '0' },
624                    starter: { 'border': '1px solid black', 'border-left': '0', 'border-radius': '0' },
625                    basic: { 'border': '1px solid black', 'border-left': '0', 'border-radius': '0 15px 15px 0', 'max-width': '100%'  }
626                }
627            },
628            tablet: {
629                annual: {
630                    pro: { border: '1px solid black', 'border-radius': '15px 0 15px 15px' },
631                    plus: { border: '1px solid black', 'border-left': '0', 'border-radius': '0 15px 15px 15px' },
632                    starter: { border: '1px solid black', 'border-radius': '15px 0 15px 15px' },
633                    basic: { border: '1px solid black', 'border-left': '1px solid black', 'border-radius': '15px 15px 15px 15px', 'max-width': '50%'  }
634                },
635                monthly: {
636                    pro: { border: '1px solid black', 'border-radius': '15px 0 0 15px' },
637                    plus: { 'border': '1px solid black', 'border-left': '0', 'border-radius': '0 15px 15px 0' },
638                    starter: { border: '1px solid black', 'border-radius': '15px 0 0 15px' },
639                    basic: { border: '1px solid black', 'border-left': '0', 'border-radius': '15px 15px 15px 15px', 'max-width': '50%' }
640                }
641            }
642        },
643        pageB: {
644            desktop: {
645                annual: {
646                    basic: { border: 'none', 'border-radius': '0' },
647                    plus: { border: 'none', 'border-radius': '0' },
648                    pro: { border: 'none', 'border-radius': '0' },
649                    premium: { border: 'none', 'border-radius': '0' }
650                },
651                monthly: {
652                    basic: { border: 'none', 'border-radius': '0' },
653                    plus: { border: 'none', 'border-radius': '0' },
654                    pro: { border: 'none', 'border-radius': '0' },
655                    premium: { border: 'none', 'border-radius': '0' }
656                }
657            },
658            tablet: {
659                annual: {
660                    basic: { border: 'none', 'border-radius': '0' },
661                    plus: { border: 'none', 'border-radius': '0' },
662                    pro: { border: 'none', 'border-radius': '0' },
663                    premium: { border: 'none', 'border-radius': '0' }
664                },
665                monthly: {
666                    basic: { border: 'none', 'border-radius': '0' },
667                    plus: { border: 'none', 'border-radius': '0' },
668                    pro: { border: 'none', 'border-radius': '0' },
669                    premium: { border: 'none', 'border-radius': '0' }
670                }
671            }
672        }
673    };
674
675    let device = isDesktop ? 'desktop' : isTablet ? 'tablet' : 'mobile';
676    if(device === 'mobile') return; //Handled above
677
678    const pageKey = isPageA ? 'pageB' : 'pageB';
679    const styleSet = config[pageKey][device][recurrence];
680
681    applyStyles(styleSet);
682}
683
684//Set pricing sections
685function setPricingPlanSections() {
686    const currency = $('.currency-selector.active').data('currency');
687    const recurrence = $('.label-switch-square input[type="checkbox"]').val();
688    const windowWidth = window.innerWidth;
689    
690    //Pro plan
691    $('#pro-plan-section .discounted-text').html(`${pricingData[currency].monthly.pro.totalPrice}`);
692    $('#pro-plan-section .section-price').html(`${pricingData[currency][recurrence].pro.totalPrice}`);
693    $('#pro-plan-section .ipad-deposit-price').html(`${pricingData[currency][recurrence].pro.ipadDepositPrice}`);
694    $('#pro-plan-section .ipad-rental-price').html(`${pricingData[currency][recurrence].pro.ipadRentalPrice}`);
695    $('#pro-plan-section .hotspot-deposit-price').html(`${pricingData[currency][recurrence].pro.hotspotDepositPrice}`);
696    $('#pro-plan-section .hotspot-rental-price').html(`${pricingData[currency][recurrence].pro.hotspotRentalPrice}`);
697    $('#pro-plan-section .hotspot-activation-price').html(`${pricingData[currency][recurrence].pro.hotspotActivationPrice}`);
698    $('#pro-plan-section .swivel-rental-price').html(`${pricingData[currency][recurrence].pro.swivelRentalPrice}`);
699    $('#pro-plan-section .charger-rental-price').html(`${pricingData[currency][recurrence].pro.chargerRentalPrice}`);
700    if(recurrence === 'annual') $('#pro-plan-section .section-price-description').html(`Billed annually (<span class="annual-price">${pricingData[currency][recurrence].pro.annualPrice}</span>/yr)`);
701    else $('#pro-plan-section .section-price-description').html(`Annually <span class="annual-price">${pricingData[currency][recurrence].pro.annualPrice}</span>/yr`);
702
703    //Plus plan
704    $('#plus-plan-section .discounted-text').html(`${pricingData[currency].monthly.plus.totalPrice}`);
705    $('#plus-plan-section .section-price').html(`${pricingData[currency][recurrence].plus.totalPrice}`);
706    $('#plus-plan-section .ipad-deposit-price').html(`${pricingData[currency][recurrence].plus.ipadDepositPrice}`);
707    $('#plus-plan-section .ipad-rental-price').html(`${pricingData[currency][recurrence].plus.ipadRentalPrice}`);
708    $('#plus-plan-section .hotspot-deposit-price').html(`${pricingData[currency][recurrence].plus.hotspotDepositPrice}`);
709    $('#plus-plan-section .hotspot-rental-price').html(`${pricingData[currency][recurrence].plus.hotspotRentalPrice}`);
710    $('#plus-plan-section .hotspot-activation-price').html(`${pricingData[currency][recurrence].plus.hotspotActivationPrice}`);
711    $('#plus-plan-section .swivel-rental-price').html(`${pricingData[currency][recurrence].plus.swivelRentalPrice}`);
712    $('#plus-plan-section .charger-rental-price').html(`${pricingData[currency][recurrence].plus.chargerRentalPrice}`);
713    if(recurrence === 'annual') $('#plus-plan-section .section-price-description').html(`Billed annually (<span class="annual-price">${pricingData[currency][recurrence].plus.annualPrice}</span>/yr)`);
714    else $('#plus-plan-section .section-price-description').html(`Annually <span class="annual-price">${pricingData[currency][recurrence].plus.annualPrice}</span>/yr`);
715    
716    //Starter plan
717    $('#starter-plan-section .discounted-text').html(`${pricingData[currency].monthly.starter.totalPrice}`);
718    $('#starter-plan-section .section-price').html(`${pricingData[currency][recurrence].starter.totalPrice}`);
719    $('#starter-plan-section .charger-rental-price').html(`${pricingData[currency][recurrence].starter.chargerRentalPrice}`);
720    if(recurrence === 'annual') $('#starter-plan-section .section-price-description').html(`Billed annually (<span class="annual-price">${pricingData[currency][recurrence].starter.annualPrice}</span>/yr)`);
721    else $('#starter-plan-section .section-price-description').html(`Annually <span class="annual-price">${pricingData[currency][recurrence].starter.annualPrice}</span>/yr`);
722    
723    //Premium plan
724    $('#premium-plan-section .discounted-text').html(`${pricingData[currency].monthly.premium.totalPrice}`);
725    $('#premium-plan-section .section-price').html(`${pricingData[currency][recurrence].premium.totalPrice}`);
726    $('#premium-plan-section .ipad-deposit-price').html(`${pricingData[currency][recurrence].premium.ipadDepositPrice}`);
727    $('#premium-plan-section .ipad-rental-price').html(`${pricingData[currency][recurrence].premium.ipadRentalPrice}`);
728    $('#premium-plan-section .hotspot-deposit-price').html(`${pricingData[currency][recurrence].premium.hotspotDepositPrice}`);
729    $('#premium-plan-section .hotspot-rental-price').html(`${pricingData[currency][recurrence].premium.hotspotRentalPrice}`);
730    $('#premium-plan-section .hotspot-activation-price').html(`${pricingData[currency][recurrence].premium.hotspotActivationPrice}`);
731    $('#premium-plan-section .swivel-rental-price').html(`${pricingData[currency][recurrence].premium.swivelRentalPrice}`);
732    $('#premium-plan-section .charger-rental-price').html(`${pricingData[currency][recurrence].premium.chargerRentalPrice}`);
733    if(recurrence === 'annual') $('#premium-plan-section .section-price-description').html(`Billed annually (<span class="annual-price">${pricingData[currency][recurrence].premium.annualPrice}</span>/yr)`);
734    else $('#premium-plan-section .section-price-description').html(`Annually <span class="annual-price">${pricingData[currency][recurrence].premium.annualPrice}</span>/yr`);
735
736    //Basic plan
737    $('#basic-plan-section .section-price').html(`${pricingData[currency][recurrence].basic.totalPrice}`);
738
739    //Reset feature list
740    $('.feature-arrow').removeClass('uil-angle-down').addClass('uil-angle-up');
741    $('.feature-list').removeClass('hi
741de');
742    
743    //Dynamic sections on pricing
744    if(recurrence === 'annual'){
745        $('.discounted-text').removeClass('hide');
746        $('.annual-pill').removeClass('hide');
747        $('#pro-plan-section #pro-onboarding-feature').html(`Personalized onboarding with priority support team access`);
748        $('#plus-plan-section #plus-onboarding-feature').html(`Personalized onboarding with priority support team access`);
749        $('#starter-plan-section #starter-onboarding-feature').html(`Personalized onboarding with priority support team access`);
750        $('.seat-pricing-text').text('5 additional seats at $8/user/month');
751
752        //Show hardware section
753        $('.hardware-section').removeClass('hide');
754        $('.hardware-item-list').removeClass('hide');
755        $('.hardware-arrow').find('i').removeClass('uil-angle-up').addClass('uil-angle-down');
756        if(windowWidth >= 1024){
757            $('.hardware-item-list').removeClass('hide');
758        } else {
759            $('.hardware-item-list').addClass('hide');
760        }
761    }else if(recurrence === 'monthly'){
762        $('.discounted-text').addClass('hide');
763        $('.annual-pill').addClass('hide');
764        $('#pro-plan-section #pro-onboarding-feature').html(`Personalized onboarding with priority support team access`);
765        $('#plus-plan-section #plus-onboarding-feature').html(`Standard onboarding with support team access`);
766        $('#starter-plan-section #starter-onboarding-feature').html(`Standard onboarding`);
767        $('.seat-pricing-text').text('5 additional seats at $10/user/month');
768
769        //Hide hardware section
770        $('.hardware-section').addClass('hide');
771        $('.hardware-item-list').addClass('hide');
772    }
773    
774    //Modify pricing table on tablet view depending on which page
775    if(windowWidth >= 768 && windowWidth <= 1024){
776        if(isPageA){
777            $('#pricing-plan-section .flex-container').css({
778                'flex-wrap': 'wrap'
779            }); 
780        } else {
781            $('#pricing-plan-section .flex-container').css({
782                'flex-direction': 'row',
783                'flex-wrap': 'wrap'
784            }); 
785        }
786    }
787    
788    //Price section responsiveness
789    if(windowWidth > 1024 && recurrence === 'annual'){
790        const isSmallDesktop = windowWidth < 1374;
791        let wrapValue = 'wrap';
792        let marginTop = isSmallDesktop ? '.75rem' : '0rem';
793        let marginLeft = isSmallDesktop ? '0rem' : '.5rem';
794    
795        if(currency === 'cad' && !isSmallDesktop){
796            wrapValue = 'nowrap';
797        }
798    
799        $('.annual-pill').each(function (){
800            this.style.setProperty('margin-top', marginTop, 'important');
801            this.style.setProperty('margin-left', marginLeft, 'important');
802        });
803    
804        $('#pricing-plan-section .section-price-container').css('flex-wrap', wrapValue);
805    } else {
806        if(windowWidth < 768  && recurrence === 'annual'){
807            $('.annual-pill').each(function (){
808                this.style.setProperty('margin-top', '.25rem', 'important');
809                this.style.setProperty('margin-left', '.5rem', 'important');
810            });
811        }
812    }
813    
814    //Page B-specific responsiveness for tables
815    if(windowWidth > 1024){
816        $('#pricing-plan-section')[0].style.setProperty('margin-top', '0', 'important');
817        $('#pro-plan-container')[0].style.setProperty('margin-top', '0', 'important');
818        $('#plus-plan-container')[0].style.setProperty('margin-top', '0rem', 'important');
819        $('#premium-plan-container')[0] && $('#premium-plan-container')[0].style.setProperty('margin-top', '0', 'important');
820        $('#basic-plan-section')[0].style.setProperty('margin-top', '0', 'important');
821    } else if(windowWidth >= 768 && windowWidth <= 1024){
822        $('#pricing-plan-section')[0].style.setProperty('margin-top', '0', 'important');
823        $('#pro-plan-container')[0].style.setProperty('margin-top', '2rem', 'important');
824        $('#plus-plan-container')[0].style.setProperty('margin-top', '2rem', 'important');
825        $('#premium-plan-container')[0] && $('#premium-plan-container')[0].style.setProperty('margin-top', '2rem', 'important');
826        $('#basic-plan-section')[0].style.setProperty('margin-top', '2rem', 'important');
827    } else {
828        $('#pricing-plan-section')[0].style.setProperty('margin-top', '1rem', 'important');
829        $('#pro-plan-container')[0].style.setProperty('margin-top', '0', 'important');
830        $('#plus-plan-container')[0].style.setProperty('margin-top', '0', 'important');
831        $('#premium-plan-container')[0] && $('#premium-plan-container')[0].style.setProperty('margin-top', '0', 'important');
832        $('#basic-plan-section')[0].style.setProperty('margin-top', '0', 'important');
833    }
834    
835    
836    updateOnboardingTooltips(recurrence);
837    setPricingBorders(currency, recurrence);
838}
839
840showLoader();
841//Render A or B Pricing Table. TODO: Remove this, Page B won (02/10/2026)
842function renderPricingTables() {
843    const windowWidth = window.innerWidth;
844    //Recurrence annual/monthly switch
845    $('.label-switch-square input[type="checkbox"]').trigger('change');
846    //Remove tables
847    $('#plan-template').empty();
848    
849    //Check localStorage for pricingPage value
850    let pageExistsInLocalStorage = localStorage.getItem('pricingPage');
851
852    //If not stored yet, randomly assign and store pricingPage value
853    if(pageExistsInLocalStorage === null){
854        isPageA = Math.random() < 0.5;
855        localStorage.setItem('pricingPage', isPageA ? 'A' : 'B');
856    } else {
857        isPageA = pageExistsInLocalStorage === 'A';
858    }
859    
860    //Page B - Desktop
861    if(windowWidth > 1024){
862        $('#plan-template')
863        .append(basic)
864        .append(plus)
865        .append(pro)
866        .append(premium);
867    //Page B - Tablet
868    } else if(windowWidth >= 768 && windowWidth <= 1024){
869        $('#plan-template')
870        .append(basic)
871        .append(plus)
872        .append(pro)
873        .append(premium);
874    //Page B - Mobile
875    } else if (windowWidth < 768){
876        $('#plan-template')
877        .append(basic)
878        .append(plus)
879        .append(pro)
880        .append(premium);
881    }
882    
883    $('#plan-template').removeClass('hide');
884    $('#custom-solution-container').removeClass('hide');
885    setPricingPlanSections();
886    hideLoader();
887}
888
889//Responsiveness for Page A and B
890function getBreakpoint() {
891    const windowWidth = window.innerWidth;
892    if(windowWidth <= 767) return 'mobile';
893    if(windowWidth <= 1024) return 'tablet';
894    return 'desktop';
895}
896
897let currentBreakpoint = getBreakpoint();
898$(window).resize(function() {
899    const newBreakpoint = getBreakpoint();
900    if((newBreakpoint !== currentBreakpoint) && !isPageA){
901        currentBreakpoint = newBreakpoint;
902        
903        //Render new pricing table for page B if breakpoint changes
904        renderPricingTables();
905    } else {
906        setPricingPlanSections();
907    }
908});
909
910//Feature plan arrow (section-level collapse)
911$('#pricing-plan-section').on('click', '.feature-arrow', function() {
912    const closestFeatureList = $(this).closest('.feature-section').find('.feature-list');
913
914    if(closestFeatureList.hasClass('hide')){
915        closestFeatureList.removeClass('hide');
916        $(this).removeClass('uil-angle-down').addClass('uil-angle-up');
917    } else {
918        closestFeatureList.addClass('hide');
919        $(this).removeClass('uil-angle-up').addClass('uil-angle-down');
920    }
921});
922
923//Per-feature item accordion
924$('#pricing-plan-section').on('click', '.feature-item-header', function() {
925    const subList = $(this).next('.sub-feature-list');
926    const arrow = $(this).find('.feature-item-arrow');
927    subList.toggleClass('hide');
928    arrow.toggleClass('uil-angle-down uil-angle-up');
929});
930
931let hardwareArrowTouchMoved = false;
932
933$('#pricing-plan-section')
934  .on('touchstart', '.hardware-arrow', function () {
935    hardwareArrowTouchMoved = false;
936  })
937  .on('touchmove', '.hardware-arrow', function () {
938    hardwareArrowTouchMoved = true;
939  });
940
941$('#pricing-plan-section').on('click', '.hardware-arrow', function (e) {
942    // If the user was scrolling (touchmove happened), ignore the synthetic click
943    if (hardwareArrowTouchMoved) return;
944
945    e.preventDefault();
946    e.stopPropagation();
947
948    const icon = $(this).find('i');
949    const hardwareSection = $(this).closest('.hardware-section');
950    const hardwareList = hardwareSection.find('.hardware-item-list').first();
951    const windowWidth = window.innerWidth;
952
953    //Toggle visibility and icon
954    hardwareList.toggleClass('hide');
955    icon.toggleClass('uil-angle-down uil-angle-up');
956
957    //Tablet-specific logic
958    if(windowWidth >= 768 && windowWidth <= 1024){
959        const isProPlan = $(this).closest('#pro-plan-section').length > 0;
960        const isPlusPlan = $(this).closest('#plus-plan-section').length > 0;
961        const plusHardwareSection = $('#plus-plan-section .hardware-section');
962        const proArrowIcon = $('#pro-plan-section .hardware-arrow i');
963        const plusArrowIcon = $('#plus-plan-section .hardware-arrow i');
964
965        if(isProPlan || isPlusPlan){
966            const iconState = getIconState(icon);
967            const otherIconState = getIconState(isProPlan ? plusArrowIcon : proArrowIcon);
968
969            updateBorders({
970                page: isPageA ? 'A' : 'B',
971                iconState,
972                otherIconState,
973                plusHardwareSection
974            });
975        }
976    }
977
978    function getIconState(icon) {
979        return icon.hasClass('uil-angle-up') ? 'up' : 'down';
980    }
981
982    function updateBorders({ page, iconState, otherIconState, plusHardwareSection }) {
983        const styles = {
984            none: {
985                border: 'none',
986                radius: '0'
987            },
988            black: {
989                border: '1px solid black',
990                radius: '15px'
991            }
992        };
993
994        const side = page === 'A' ? 'left' : 'right';
995        const borderProp = `border-${side}`;
996        const radiusProp = `border-bottom-${side}-radius`;
997        const cssUpdate = {};
998        let style = styles.none;
999
1000        if(iconState === 'up' && otherIconState === 'down'){
1001            style = styles.black;
1002        } else if (iconState === 'down' && otherIconState === 'up'){
1003            style = styles.black;
1004        }
1005
1006        cssUpdate[borderProp] = style.border;
1007        cssUpdate[radiusProp] = style.radius;
1008
1009        plusHardwareSection.css(cssUpdate);
1010    }
1011});
1012
1013function resetRecurrenceSwitches(){
1014    $('.label-switch-square input[type="checkbox"]').prop('checked', false).trigger('change');
1015}
1016
1017//Ensure browser chache does not preserve recurrence switch value
1018window.addEventListener('pageshow', function(event) {
1019    resetRecurrenceSwitches();
1020});

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