PageSourceSearch

https://my.eval.org/bundles/js/custom.js?v=aaMyWwcoUtuntAXa1seld7Tc-qort3iZRmcJtMZhGac1

js eval.org collected 2026-09-24 09:01:56 UTC 403,594 bytes, 8,420 lines download raw bytes

1/* Minification failed. Returning unminified contents.
2(7310,5,7328,6): run-time error JS1314: Implicit property name must be identifier: containsCreditCardNumber(input) {
3        if (!input || typeof input !== 'string') {
4            return false;
5        }
6
7        const sanitizedInput = input.replace(/[- ]/g, "");
8
9        const numbersMatched = sanitizedInput.match(/\d{13,}/g); // Match numbers with 13+ digits
10
11        if (numbersMatched) {
12            for (const matchedNumber of numbersMatched) {
13                if (this.CreditCardPatterns.some(pattern => pattern.test(matchedNumber))) {
14                    return true; // Return true if any pattern matches
15                }
16            }
17        }
18        return false; // Return false if no matches
19
20    }
21(7330,5,7332,6): run-time error JS1314: Implicit property name must be identifier: validateTextFieldForCreditNumber(sender, e) {
22        e.IsValid = !regexUtility.containsCreditCardNumber(e.Value);
23    }
24(7336,5,7342,6): run-time error JS1314: Implicit property name must be identifier: ValidateSequence(sender, args) {
25        const input = args.Value;
26        if (!input || typeof input !== 'string') {
27            args.IsValid = false;
28        }
29        args.IsValid = !(/t/i.test(input)); // Regular expression for case-insensitive match
30    }
31 */
32/**
33Core script to handle the entire theme and core functions
34**/
35var App = function () {
36
37    // IE mode
38    var isRTL = false;
39    var isIE8 = false;
40    var isIE9 = false;
41    var isIE10 = false;
42
43    var sidebarWidth = 225;
44    var sidebarCollapsedWidth = 35;
45
46    var responsiveHandlers = [];
47
48    // theme layout color set
49    var layoutColorCodes = {
50        'blue': '#4b8df8',
51        'red': '#e02222',
52        'green': '#35aa47',
53        'purple': '#852b99',
54        'grey': '#555555',
55        'light-grey': '#fafafa',
56        'yellow': '#ffb848'
57    };
58
59    // To get the correct viewport width based on  http://andylangton.co.uk/articles/javascript/get-viewport-size-javascript/
60    var _getViewPort = function () {
61        var e = window, a = 'inner';
62        if (!('innerWidth' in window)) {
63            a = 'client';
64            e = document.documentElement || document.body;
65        }
66        return {
67            width: e[a + 'Width'],
68            height: e[a + 'Height']
69        };
70    };
71
72    // initializes main settings
73    var handleInit = function () {
74
75        if ($('body').css('direction') === 'rtl') {
76            isRTL = true;
77        }
78
79        isIE8 = !!navigator.userAgent.match(/MSIE 8.0/);
80        isIE9 = !!navigator.userAgent.match(/MSIE 9.0/);
81        isIE10 = !!navigator.userAgent.match(/MSIE 10.0/);
82
83        if (isIE10) {
84            jQuery('html').addClass('ie10'); // detect IE10 version
85        }
86
87        if (isIE10 || isIE9 || isIE8) {
88            jQuery('html').addClass('ie'); // detect IE10 version
89        }
90
91        var deviceAgent = navigator.userAgent.toLowerCase();
92        if (deviceAgent.match(/(iphone|ipod|ipad)/)) {
93            $(document).on('focus', 'input, textarea', function () {
94                $('.header').hide();
95                $('.footer').hide();
96            });
97            $(document).on('blur', 'input, textarea', function () {
98                $('.header').show();
99                $('.footer').show();
100            });
101        }
102    };
103
104    var handleSidebarState = function () {
105        // remove sidebar toggler if window width smaller than 992(for tablet and phone mode)
106        var viewport = _getViewPort();
107        if (viewport.width < 992) {
108            $('body').removeClass("page-sidebar-closed");
109
110            // move sidebar before user-defined header
111            $('.site-template-header').insertAfter('.page-sidebar');
112        }
113        else {
114            // move sidebar after user-defined header
115            $('.page-sidebar').insertAfter('.site-template-header');
116        }
117    };
118
119
120    var runResponsiveHandlers = function () {
121        // reinitialize other subscribed elements
122        for (var i in responsiveHandlers) {
123            var each = responsiveHandlers[i];
124            each.call();
125        }
126    };
127
128    // reinitialize the layout on window resize
129    var handleResponsive = function () {
130        handleSidebarState();
131        handleSidebarAndContentHeight();
132        handleFixedSidebar();
133        runResponsiveHandlers();
134    };
135
136    // initialize the layout on page load
137    var handleResponsiveOnInit = function () {
138        handleSidebarState();
139        handleSidebarAndContentHeight();
140    };
141
142    // handle the layout reinitialization on window resize
143    var handleResponsiveOnResize = function () {
144        var resize;
145        if (isIE8) {
146            var currheight;
147            $(window).resize(function () {
148                if (currheight == document.documentElement.clientHeight) {
149                    return; //quite event since only body resized not window.
150                }
151                if (resize) {
152                    clearTimeout(resize);
153                }
154                resize = setTimeout(function () {
155                    handleResponsive();
156                }, 50); // wait 50ms until window resize finishes.                
157                currheight = document.documentElement.clientHeight; // store last body client height
158            });
159        }
160        else {
161            $(window).resize(function () {
162                if (resize) {
163                    clearTimeout(resize);
164                }
165                resize = setTimeout(function () {
166                    handleResponsive();
167                }, 50); // wait 50ms until window resize finishes.
168            });
169        }
170    };
171
172    //* BEGIN:CORE HANDLERS *//
173    // this function handles responsive layout on screen size resize or mobile device rotate.
174
175    // Set proper height for sidebar and content. The content and sidebar height must be synced always.
176    var handleSidebarAndContentHeight = function () {
177        var content = $('.page-content');
178        var sidebar = $('.page-sidebar');
179        var body = $('body');
180        var height;
181
182        if (body.hasClass("page-footer-fixed") === true && body.hasClass("page-sidebar-fixed") === false) {
183            var available_height = $(window).height() - $('.footer').outerHeight();
184            if (content.height() < available_height) {
185                content.attr('style', 'min-height:' + available_height + 'px !important');
186            }
187        }
188        else {
189            if (body.hasClass('page-sidebar-fixed')) {
190                height = _calculateFixedSidebarViewportHeight();
191            }
192            else {
193                height = sidebar.height() + 20;
194            }
195            if (height >= content.height()) {
196                content.attr('style', 'min-height:' + height + 'px !important');
197            }
198        }
199    };
200
201    // Handle sidebar menu
202    var handleSidebarMenu = function () {
203        jQuery('.page-sidebar').on('click', 'li > a, li > span > a', function (e) {
204            if ($(this).next().hasClass('sub-menu') == false) {
205                if ($('.btn-navbar').hasClass('collapsed') == false) {
206                    $('.btn-navbar').click();
207                }
208                return;
209            }
210
211            if ($(this).next().hasClass('sub-menu.always-open')) {
212                return;
213            }
214
215            var parent = $(this).parent().parent();
216            var the = $(this);
217
218            parent.children('li.open').children('span').children('a').children('.arrow').removeClass('open');
219            parent.children('li.open').children('span').children('.sub-menu').slideUp(200);
220
221            parent.children('li.open').children('a').children('.arrow').removeClass('open');
222            parent.children('li.open').children('.sub-menu').slideUp(200);
223            parent.children('li.open').removeClass('open');
224
225            var sub = jQuery(this).next();
226            var slideOffeset = -200;
227            var slideSpeed = 200;
228
229            if (sub.is(":visible")) {
230                jQuery('.arrow', jQuery(this)).removeClass("open");
231                jQuery(this).parent().removeClass("open");
232                jQuery(this).parent('span').parent().removeClass("open");
233                sub.slideUp(slideSpeed, function () {
234                    if ($('body').hasClass('page-sidebar-fixed') == false && $('body').hasClass('page-sidebar-closed') == false) {
235                        App.scrollTo(the, slideOffeset);
236                    }
237                    handleSidebarAndContentHeight();
238                });
239            }
240            else {
241                jQuery('.arrow', jQuery(this)).addClass("open");
242                jQuery(this).parent().addClass("open");
243                jQuery(this).parent('span').parent().addClass("open");
244                sub.slideDown(slideSpeed, function () {
245                    if ($('body').hasClass('page-sidebar-fixed') == false && $('body').hasClass('page-sidebar-closed') == false) {
246                        App.scrollTo(the, slideOffeset);
247                    }
248                    handleSidebarAndContentHeight();
249                });
250            }
251
252            e.preventDefault();
253        });
254    };
255
256    // Helper function to calculate sidebar height for fixed sidebar layout.
257    var _calculateFixedSidebarViewportHeight = function () {
258        var sidebarHeight = $(window).height() - $('.header').height() + 1;
259        if ($('body').hasClass("page-footer-fixed")) {
260            sidebarHeight = sidebarHeight - $('.footer').outerHeight();
261        }
262        return sidebarHeight;
263    };
264
265    // Handles fixed sidebar
266    var handleFixedSidebar = function () {
267        var menu = $('.page-sidebar-menu');
268
269        if (menu.parent('.slimScrollDiv').length === 1) {
270            // destroy existing instance before updating the height
271            menu.slimScroll({
272                destroy: true
273            });
274            menu.removeAttr('style');
275            $('.page-sidebar').removeAttr('style');
276        }
277
278        if ($('.page-sidebar-fixed').length === 0) {
279            handleSidebarAndContentHeight();
280            return;
281        }
282
283        var viewport = _getViewPort();
284        if (viewport.width >= 992) {
285            var sidebarHeight = _calculateFixedSidebarViewportHeight();
286
287            menu.slimScroll({
288                size: '7px',
289                color: '#a1b2bd',
290                opacity: .3,
291                position: isRTL ? 'left' : 'right',
292                height: sidebarHeight,
293                allowPageScroll: false,
294                disableFadeOut: false
295            });
296            handleSidebarAndContentHeight();
297        }
298    };
299
300    // Handles the sidebar menu hover effect for fixed sidebar.
301    var handleFixedSidebarHoverable = function () {
302        if ($('body').hasClass('page-sidebar-fixed') === false) {
303            return;
304        }
305
306        $('.page-sidebar').off('mouseenter').on('mouseenter', function () {
307            var body = $('body');
308
309            if ((body.hasClass('page-sidebar-closed') === false || body.hasClass('page-sidebar-fixed') === false) || $(this).hasClass('page-sidebar-hovering')) {
310                return;
311            }
312
313            body.removeClass('page-sidebar-closed').addClass('page-sidebar-hover-on');
314            $(this).addClass('page-sidebar-hovering');
315            $(this).animate({
316                width: sidebarWidth
317            }, 400, '', function () {
318                $(this).removeClass('page-sidebar-hovering');
319            });
320        });
321
322        $('.page-sidebar').off('mouseleave').on('mouseleave', function () {
323            var body = $('body');
324
325            if ((body.hasClass('page-sidebar-hover-on') === false || body.hasClass('page-sidebar-fixed') === false) || $(this).hasClass('page-sidebar-hovering')) {
326                return;
327            }
328
329            $(this).addClass('page-sidebar-hovering');
330            $(this).animate({
331                width: sidebarCollapsedWidth
332            }, 400, '', function () {
333                $('body').addClass('page-sidebar-closed').removeClass('page-sidebar-hover-on');
334                $(this).removeClass('page-sidebar-hovering');
335            });
336        });
337    };
338
339    // Handles sidebar toggler to close/hide the sidebar.
340    var handleSidebarToggler = function () {
341        var viewport = _getViewPort();
342        if ($.cookie('sidebar_closed') === '1' && viewport.width >= 992) {
343            $('body').addClass('page-sidebar-closed');
344        }
345
346        // handle sidebar show/hide
347        $('.page-sidebar').on('click', '.sidebar-toggler', function (e) {
348            var body = $('body');
349            var sidebar = $('.page-sidebar');
350
351            if ((body.hasClass("page-sidebar-hover-on") && body.hasClass('page-sidebar-fixed')) || sidebar.hasClass('page-sidebar-hovering')) {
352                body.removeClass('page-sidebar-hover-on');
353                sidebar.css('width', '').hide().show();
354                $.cookie('sidebar_closed', '0', { expires: 365, path: '/' });
355                e.stopPropagation();
356                runResponsiveHandlers();
357                return;
358            }
359
360            $(".sidebar-search", sidebar).removeClass("open");
361
362            if (body.hasClass("page-sidebar-closed")) {
363                body.removeClass("page-sidebar-closed");
364                if (body.hasClass('page-sidebar-fixed')) {
365                    sidebar.css('width', '');
366                }
367                $.cookie('sidebar_closed', '0', { expires: 365, path: '/' });
368            }
369            else {
370                body.addClass("page-sidebar-closed");
371                $.cookie('sidebar_closed', '1', { expires: 365, path: '/' });
372            }
373            runResponsiveHandlers();
374        });
375
376        // handle the search bar close
377        $('.page-sidebar').on('click', '.sidebar-search .remove', function (e) {
378            e.preventDefault();
379            $('.sidebar-search').removeClass("open");
380        });
381
382        // handle the search query submit on enter press
383        $('.page-sidebar').on('keypress', '.sidebar-search input', function (e) {
384            if (e.which == 13) {
385                e.preventDefault();
386                var val = $(this).val();
387                // remove leading and trailing spaces, also convert many spaces to just one
388                val = (val == null ? '' : val.replace(/(^\s*)|(\s*$)/g, '').replace(/\s+/g, ' '));
389                if (val != '') {
390                    if (val.length >= 2) {
391                        document.location.href = '/administration/search/?q=' + encodeURIComponent(val).replace(/\%20/g, '\+');
392                    }
393                    else {
394                        dialog.messageBox({
395                            icon: 'Warning',
396                            title: 'Search',
397                            message: 'Please enter at least two characters.',
398                            buttons: 'OK'
399                        });
400                    }
401                }
402                else {
403                    dialog.messageBox({
404                        icon: 'Warning',
405                        title: 'Search',
406                        message: 'Please enter a search keyword.',
407                        buttons: 'OK'
408                    });
409                }
410                return false; //<---- Add this line
411            }
412        });
413
414        // handle the search submit
415        $('.sidebar-search .search-submit').on('click', function (e) {
416            e.preventDefault();
417            if ($('body').hasClass("page-sidebar-closed")) {
418                if ($('.sidebar-search').hasClass('open') == false) {
419                    if ($('.page-sidebar-fixed').length === 1) {
420                        $('.page-sidebar .sidebar-toggler').click();
421                    }
422                    $('.sidebar-search').addClass("open");
423                }
424                else {
425                    var val = $('#siteSearch').val();
426                    // remove leading and trailing spaces, also convert many spaces to just one
427                    val = (val == null ? '' : val.replace(/(^\s*)|(\s*$)/g, '').replace(/\s+/g, ' '));
428                    if (val != '') {
429                        if (val.length >= 2) {
430                            document.location.href = '/administration/search/?q=' + encodeURIComponent(val).replace(/\%20/g, '\+');
431                        }
432                        else {
433                            dialog.messageBox({
434                                icon: 'Warning',
435                                title: 'Search',
436                                message: 'Please enter at least two characters.',
437                                buttons: 'OK'
438                            });
439                        }
440                    }
441                    else {
442                        dialog.messageBox({
443                            icon: 'Warning',
444                            title: 'Search',
445                            message: 'Please enter a search keyword.',
446                            buttons: 'OK'
447                        });
448                    }
449                }
450            }
451            else {
452                var val = $('#siteSearch').val();
453                // remove leading and trailing spaces, also convert many spaces to just one
454                val = (val == null ? '' : val.replace(/(^\s*)|(\s*$)/g, '').replace(/\s+/g, ' '));
455                if (val != '') {
456                    if (val.length >= 2) {
457                        document.location.href = '/administration/search/?q=' + encodeURIComponent(val).replace(/\%20/g, '\+');
458                    }
459                    else {
460                        dialog.messageBox({
461                            icon: 'Warning',
462                            title: 'Search',
463                            message: 'Please enter at least two characters.',
464                            buttons: 'OK'
465                        });
466                    }
467                }
468                else {
469                    dialog.messageBox({
470                        icon: 'Warning',
471                        title: 'Search',
472                        message: 'Please enter a search keyword.',
473                        buttons: 'OK'
474                    });
475                }
476            }
477            return false;
478        });
479    };
480
481    // Handles the horizontal menu
482    var handleHorizontalMenu = function () {
483        //handle hor menu search form toggler click
484        $('.header').on('click', '.hor-menu .hor-menu-search-form-toggler', function (e) {
485            if ($(this).hasClass('off')) {
486                $(this).removeClass('off');
487                $('.header .hor-menu .search-form').hide();
488            }
489            else {
490                $(this).addClass('off');
491                $('.header .hor-menu .search-form').show();
492            }
493            e.preventDefault();
494        });
495
496        //handle hor menu search button click
497        $('.header').on('click', '.hor-menu .search-form .btn', function (e) {
498            $('.form-search').submit();
499            e.preventDefault();
500        });
501
502        //handle hor menu search form on enter press
503        $('.header').on('keypress', '.hor-menu .search-form input', function (e) {
504            if (e.which == 13) {
505                $('.form-search').submit();
506                return false;
507            }
508        });
509    };
510
511    // Handles the go to top button at the footer
512    var handleGoTop = function () {
513        /* set variables locally for increased performance */
514        jQuery('.footer').on('click', '.go-top', function (e) {
515            App.scrollTo();
516            e.preventDefault();
517        });
518    };
519
520    // Handles portlet tools & actions
521    var handlePortletTools = function () {
522        jQuery('body').on('click', '.portlet > .portlet-title > .tools > a.remove', function (e) {
523            e.preventDefault();
524            jQuery(this).closest(".portlet").remove();
525        });
526
527        jQuery('body').on('click', '.portlet > .portlet-title > .tools > .collapse, .portlet .portlet-title > .tools > .expand', function (e) {
528            e.preventDefault();
529            var el = jQuery(this).closest(".portlet").children(".portlet-body");
530            if (jQuery(this).hasClass("collapse")) {
531                jQuery(this).removeClass("collapse").addClass("expand");
532                el.slideUp(200);
533            }
534            else {
535                jQuery(this).removeClass("expand").addClass("collapse");
536                el.slideDown(200);
537            }
538        });
539    };
540
541    // Handles custom checkboxes & radios using jQuery Uniform plugin
542    var handleUniform = function () {
543        if (!jQuery().uniform) {
544            return;
545        }
546        var test = $("input[type='checkbox']:not(.toggle,.make-switch,.make-switch2), input[type='radio']:not(.toggle, .star,.make-switch,.make-switch2)");
547        if (test.length > 0) {
548            test.each(function () {
549                if ($(this).parents(".checker").length == 0) {
550                    $(this).show();
551                    $(this).uniform();
552                }
553            });
554        }
555    };
556
557    // Handles Bootstrap Accordions.
558    var handleAccordions = function () {
559        var lastClicked;
560        //add scrollable class name if you need scrollable panes
561        jQuery('body').on('click', '.accordion.scrollable .accordion-toggle', function () {
562            lastClicked = jQuery(this);
563        }); //move to faq section
564
565        jQuery('body').on('show.bs.collapse', '.accordion.scrollable', function () {
566            jQuery('html,body').animate({
567                scrollTop: lastClicked.offset().top - 150
568            }, 'slow');
569        });
570    };
571
572    // Handles Bootstrap Tabs.
573    var handleTabs = function () {
574        // fix content height on tab click
575        $('body').on('shown.bs.tab', '.nav.nav-tabs', function () {
576            handleSidebarAndContentHeight();
577        });
578
579        //activate tab if tab id provided in the URL
580        if (location.hash) {
581            var tabid = location.hash.substr(1);
582            $('a[href="#' + tabid + '"]').click();
583        }
584    };
585
586    // Handles Bootstrap Modals.
587    var handleModals = function () {
588
589        // fix stackable modal issue: when 2 or more modals opened, closing one of modal will remove .modal
589-open class. 
590        $('body').on('hide.bs.modal', function () {
591            if ($('.modal:visible').length > 1 && $('html').hasClass('modal-open') == false) {
592                $('html').addClass('modal-open');
593            }
594            else if ($('.modal:visible').length <= 1) {
595                $('html').removeClass('modal-open');
596            }
597        });
598    };
599
600    // Handles Bootstrap Tooltips.
601    var handleTooltips = function () {
602        jQuery('.tooltips').tooltip();
603    };
604
605    // Handles Bootstrap Dropdowns
606    var handleDropdowns = function () {
607        // For touch supported devices disable the 
608        // hoverable dropdowns: data-hover="dropdown"  
609        if (App.isTouchDevice()) {
610            $('[data-hover="dropdown"]').each(function () {
611                $(this).parent().off("hover");
612                $(this).off("hover");
613            });
614        }
615        // Hold dropdown on click  
616        $('body').on('click', '.dropdown-menu.hold-on-click', function (e) {
617            e.stopPropagation();
618        });
619    };
620
621    // Handle Hower Dropdowns
622    var handleDropdownHover = function () {
623        $('[data-hover="dropdown"]').dropdownHover();
624    };
625
626    // Handles Bootstrap Popovers
627
628    // last popep popover
629    var lastPopedPopover;
630
631    var handlePopovers = function () {
632        jQuery('.popovers').popover({html:true});
633
634        // close last poped popover
635        $(document).on('click.bs.popover.data-api', function (e) {
636            if (lastPopedPopover) {
637                lastPopedPopover.popover('hide');
638            }
639        });
640    };
641
642    // Handles scrollable contents using jQuery SlimScroll plugin.
643    var handleScrollers = function () {
644        $('.scroller').each(function () {
645            var height;
646            if ($(this).attr("data-height")) {
647                height = $(this).attr("data-height");
648            }
649            else {
650                height = $(this).css('height');
651            }
652            $(this).slimScroll({
653                size: '7px',
654                color: ($(this).attr("data-handle-color") ? $(this).attr("data-handle-color") : '#ccc'),
655                railColor: ($(this).attr("data-rail-color") ? $(this).attr("data-rail-color") : '#333'),
656                position: isRTL ? 'left' : 'right',
657                height: height,
658                alwaysVisible: ($(this).attr("data-always-visible") == "1" ? true : false),
659                railVisible: ($(this).attr("data-rail-visible") == "1" ? true : false),
660                disableFadeOut: true
661            });
662        });
663    };
664
665    // Handles Image Preview using jQuery Fancybox plugin
666    var handleFancybox = function () {
667        if (!jQuery.fancybox) {
668            return;
669        }
670
671        if (jQuery(".fancybox-button").length > 0) {
672            jQuery(".fancybox-button").fancybox({
673                groupAttr: 'data-rel',
674                prevEffect: 'none',
675                nextEffect: 'none',
676                closeBtn: true,
677                helpers: {
678                    title: {
679                        type: 'inside'
680                    }
681                }
682            });
683        }
684    };
685
686    // Fix input placeholder issue for IE8 and IE9
687    var handleFixInputPlaceholderForIE = function () {
688        // fix html5 placeholder attribute for ie7 & ie8
689        if (isIE8 || isIE9) { // ie8 & ie9
690            // this is html5 placeholder fix for inputs, inputs with placeholder-no-fix class will be skipped(e.g: we need this for password fields)
691            jQuery('input[placeholder]:not(.placeholder-no-fix), textarea[placeholder]:not(.placeholder-no-fix)').each(function () {
692
693                var input = jQuery(this);
694
695                if (input.val() == '' && input.attr("placeholder") != '') {
696                    input.addClass("placeholder").val(input.attr('placeholder'));
697                }
698
699                input.focus(function () {
700                    if (input.val() == input.attr('placeholder')) {
701                        input.val('');
702                    }
703                });
704
705                input.blur(function () {
706                    if (input.val() == '' || input.val() == input.attr('placeholder')) {
707                        input.val(input.attr('placeholder'));
708                    }
709                });
710            });
711        }
712    };
713
714    // Handle full screen mode toggle
715    var handleFullScreenMode = function () {
716        // mozfullscreenerror event handler
717
718        // toggle full screen
719        function toggleFullScreen() {
720            if (!document.fullscreenElement &&    // alternative standard method
721                !document.mozFullScreenElement && !document.webkitFullscreenElement) {  // current working methods
722                if (document.documentElement.requestFullscreen) {
723                    document.documentElement.requestFullscreen();
724                }
725                else if (document.documentElement.mozRequestFullScreen) {
726                    document.documentElement.mozRequestFullScreen();
727                }
728                else if (document.documentElement.webkitRequestFullscreen) {
729                    document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
730                }
731            }
732            else {
733                if (document.cancelFullScreen) {
734                    document.cancelFullScreen();
735                }
736                else if (document.mozCancelFullScreen) {
737                    document.mozCancelFullScreen();
738                }
739                else if (document.webkitCancelFullScreen) {
740                    document.webkitCancelFullScreen();
741                }
742            }
743        }
744
745        $('#main_header_topLoginView_trigger_fullscreen').click(function () {
746            toggleFullScreen();
747        });
748    };
749
750    // Handle Select2 Dropdowns
751    var handleSelect2 = function () {
752        if (jQuery().select2) {
753            $('.select2me').select2({
754                placeholder: "Select",
755                allowClear: true
756            });
757        }
758    };
759
760    // Handle Theme Settings
761    var handleTheme = function () {
762
763        var panel = $('.theme-panel');
764
765        if ($('body').hasClass('page-boxed') == false) {
766            $('.layout-option', panel).val("fluid");
767        }
768
769        $('.sidebar-option', panel).val("default");
770        $('.header-option', panel).val("fixed");
771        //$('.footer-option', panel).val("default");
772        $('.footer-option', panel).val("fixed"); //Quattro: use "fixed as default for footer
773
774        // handle theme layout
775        var resetLayout = function () {
776            $("body").
777            removeClass("page-boxed").
778            //removeClass("page-footer-fixed"). //Quattro: use "fixed as default for footer
779            removeClass("page-sidebar-fixed").
780            removeClass("page-header-fixed");
781
782            $('.header > .header-inner').removeClass("container");
783
784            if ($('.page-container').parent(".container").length === 1) {
785                $('.page-container').insertAfter('body > .clearfix');
786            }
787
788            if ($('.footer > .container').length === 1) {
789                $('.footer').html($('.footer > .container').html());
790            }
791            else if ($('.footer').parent(".container").length === 1) {
792                $('.footer').insertAfter('.page-container');
793            }
794
795            $('body > .container').remove();
796        };
797
798        var lastSelectedLayout = '';
799
800        var setLayout = function () {
801
802            var layoutOption = $('.layout-option', panel).val();
803            var sidebarOption = $('.sidebar-option', panel).val();
804            var headerOption = $('.header-option', panel).val();
805            var footerOption = $('.footer-option', panel).val();
806
807            if (sidebarOption == "fixed" && headerOption == "default") {
808                alert('Default Header with Fixed Sidebar option is not supported. Proceed with Fixed Header with Fixed Sidebar.');
809                $('.header-option', panel).val("fixed");
810                $('.sidebar-option', panel).val("fixed");
811                sidebarOption = 'fixed';
812                headerOption = 'fixed';
813            }
814
815            resetLayout(); // reset layout to default state
816
817            if (layoutOption === "boxed") {
818                $("body").addClass("page-boxed");
819
820                // set header
821                $('.header > .header-inner').addClass("container");
822                var cont = $('body > .clearfix').after('<div class="container"></div>');
823
824                // set content
825                $('.page-container').appendTo('body > .container');
826
827                // set footer
828                if (footerOption === 'fixed') {
829                    $('.footer').html('<div class="container">' + $('.footer').html() + '</div>');
830                }
831                else {
832                    $('.footer').appendTo('body > .container');
833                }
834            }
835
836            if (lastSelectedLayout != layoutOption) {
837                // layout changed, run responsive handler:
838                runResponsiveHandlers();
839            }
840            lastSelectedLayout = layoutOption;
841
842            // header
843            if (headerOption === 'fixed') {
844                $("body").addClass("page-header-fixed");
845                $(".header").removeClass("navbar-static-top").addClass("navbar-fixed-top");
846            }
847            else {
848                $("body").removeClass("page-header-fixed");
849                $(".header").removeClass("navbar-fixed-top").addClass("navbar-static-top");
850            }
851
852            // sidebar
853            if (sidebarOption === 'fixed') {
854                $("body").addClass("page-sidebar-fixed");
855            }
856            else {
857                $("body").removeClass("page-sidebar-fixed");
858            }
859
860            // footer 
861            if (footerOption === 'fixed') {
862                $("body").addClass("page-footer-fixed");
863            }
864            else {
865                $("body").removeClass("page-footer-fixed");
866            }
867
868            handleSidebarAndContentHeight();
868 // fix content height            
869            handleFixedSidebar(); // reinitialize fixed sidebar
870            handleFixedSidebarHoverable(); // reinitialize fixed sidebar hover effect
871        };
872
873        var convertRelativeToAbsoluteUrl = function (url) {
874            var div = document.createElement('div');
875            div.innerHTML = "<a></a>";
876            div.firstChild.href = url; // Ensures that the href is properly escaped
877            div.innerHTML = div.innerHTML; // Run the current innerHTML back through the parser
878            return div.firstChild.href;
879        };
880
881        // handle theme colors
882        var setColor = function (color) {
883            $('#main_site_theme').attr("href", convertRelativeToAbsoluteUrl("/assets/css/themes/" + color + ".css"));
884            $.cookie('site_theme', color, { expires: 365, path: '/' });
885        };
886
887        $('.toggler', panel).click(function () {
888            $('.toggler').hide();
889            $('.toggler-close').show();
890            $('.theme-panel > .theme-options').show();
891        });
892
893        $('.toggler-close', panel).click(function () {
894            $('.toggler').show();
895            $('.toggler-close').hide();
896            $('.theme-panel > .theme-options').hide();
897        });
898
899        $('.theme-colors > div > ul > li', panel).click(function () {
900            var color = $(this).attr("data-style");
901            setColor(color);
902            $('ul > li', panel).removeClass("current");
903            $(this).addClass("current");
904        });
905
906        $('.layout-option, .header-option, .sidebar-option, .footer-option', panel).change(setLayout);
907
908        if ($.cookie('site_theme')) {
909            setColor($.cookie('site_theme'));
910        }
911    };
912
913    var handleTouchspin = function () {
914        $(".product-quantity .form-control").TouchSpin({
915            min: 1,
916            max: window.maxCartQuantity,
917            decimals: 0,
918            buttonup_class: "btn quantity-up",
919            buttondown_class: "btn quantity-down"
920        });
921        $(".quantity-down").html("<i class='icon-chevron-down'></i>");
922        $(".quantity-up").html("<i class='icon-chevron-up'></i>");
923    };
924
925    //* END:CORE HANDLERS *//
926
927    return {
928
929        // main function to initiate the theme
930        init: function () {
931            // IMPORTANT!!!: Do not modify the core handlers call order.
932            // QUATTRO: Added try-catch to all calls
933
934            //core handlers
935            try { handleInit(); } catch(ex) { } // initialize core variables
936            try { handleResponsiveOnResize(); } catch(ex) { } // set and handle responsive    
937            try { handleUniform(); } catch(ex) { } // handle custom radio & checkboxes
938            try { handleScrollers(); } catch(ex) { } // handles slim scrolling contents 
939            try { handleResponsiveOnInit(); } catch (ex) { } // handler responsive elements on page load
940            
941            // QUATTRO: Do not execute below code if is in postback
942            if (window.page === undefined || window.page === null || !window.page.isPostBack()) {
943                //layout handlers
944                try { handleFixedSidebar(); } catch(ex) { } // handles fixed sidebar menu
945                try { handleFixedSidebarHoverable(); } catch(ex) { } // handles fixed sidebar on hover effect 
946                try { handleSidebarMenu(); } catch(ex) { } // handles main menu
947                try { handleHorizontalMenu(); } catch(ex) { } // handles horizontal menu
948                try { handleSidebarToggler(); } catch(ex) { } // handles sidebar hide/show            
949                try { handleFixInputPlaceholderForIE(); } catch(ex) { } // fixes/enables html5 placeholder attribute for IE9, IE8
950                try { handleGoTop(); } catch(ex) { } //handles scroll to top functionality in the footer
951                try { handleTheme(); } catch (ex) { } // handles style customer tool
952            }
953
954            //ui component handlers
955            try { handleFancybox(); } catch(ex) { } // handle fancy box
956            try { handleSelect2(); } catch(ex) { } // handle custom Select2 dropdowns
957            try { handlePortletTools(); } catch(ex) { } // handles portlet action bar functionality(refresh, configure, toggle, remove)
958            try { handleDropdowns(); } catch(ex) { } // handle dropdowns
959            try { handleTabs(); } catch(ex) { } // handle tabs
960            try { handleTooltips(); } catch(ex) { } // handle bootstrap tooltips
961            try { handlePopovers(); } catch(ex) { } // handles bootstrap popovers
962            try { handleAccordions(); } catch(ex) { } //handles accordions 
963            try { handleModals(); } catch(ex) { } // handle modals
964            try { handleFullScreenMode(); } catch(ex) { } // handles full screen
965            try { handleTouchspin(); } catch (ex) { }
966        },
967
968        //main function to initiate core javascript after ajax complete
969        //initAjax: function () {
970        //    try { handleSelect2(); } catch(ex) { } // handle custom Select2 dropdowns
971        //    try { handleDropdowns(); } catch(ex) { } // handle dropdowns
972        //    try { handleTooltips(); } catch(ex) { } // handle bootstrap tooltips
973        //    try { handlePopovers(); } catch(ex) { } // handles bootstrap popovers
974        //    try { handleAccordions(); } catch(ex) { } //handles accordions 
975        //    try { handleUniform(); } catch(ex) { } // hanfle custom radio & checkboxes     
976        //    try { handleDropdownHover(); } catch (ex) { } // handles dropdown hover
977        //},
978
979        // public function to fix the sidebar and content height accordingly
980        fixContentHeight: function () {
981            handleSidebarAndContentHeight();
982        },
983
984        // public function to remember last opened popover that needs to be closed on click
985        setLastPopedPopover: function (el) {
986            lastPopedPopover = el;
987        },
988
989        // public function to add callback a function which will be called on window resize
990        addResponsiveHandler: function (func) {
991            responsiveHandlers.push(func);
992        },
993
994        // useful function to make equal height for contacts stand side by side
995        setEqualHeight: function (els) {
996            var tallestEl = 0;
997            els = jQuery(els);
998            els.each(function () {
999                var currentHeight = $(this).height();
1000                if (currentHeight > tallestEl) {
1001                    tallestColumn = currentHeight;
1002                }
1003            });
1004            els.height(tallestEl);
1005        },
1006
1007        // wrapper function to scroll(focus) to an element
1008        scrollTo: function (el, offeset) {
1009            pos = (el && el.length > 0) ? el.offset().top : 0;
1010            jQuery('html,body').animate({
1011                scrollTop: pos + (offeset ? offeset : 0)
1012            }, 'slow');
1013        },
1014
1015        // function to scroll to the top
1016        scrollTop: function () {
1017            App.scrollTo();
1018        },
1019
1020        // initializes uniform elements
1021        initUniform: function (els) {
1022            if (els) {
1023                jQuery(els).each(function () {
1024                    if ($(this).parents(".checker").length == 0) {
1025                        $(this).show();
1026                        $(this).uniform();
1027                    }
1028                });
1029            }
1030            else {
1031                handleUniform();
1032            }
1033        },
1034
1035        // wrapper function to update/sync jquery uniform checkbox & radios
1036        updateUniform: function (els) {
1037            $.uniform.update(els); // update the uniform checkbox & radios UI after the actual input control state changed
1038        },
1039
1040        // public function to initialize the fancybox plugin
1041        initFancybox: function () {
1042            handleFancybox();
1043        },
1044
1045        // public helper function to get actual input value(used in IE9 and IE8 due to placeholder attribute not supported)
1046        getActualVal: function (el) {
1047            var el = jQuery(el);
1048            if (el.val() === el.attr("placeholder")) {
1049                return "";
1050            }
1051            return el.val();
1052        },
1053
1054        // public function to get a paremeter by name from URL
1055        getURLParameter: function (paramName) {
1056            var searchString = window.location.search.substring(1),
1057                i, val, params = searchString.split("&");
1058
1059            for (i = 0; i < params.length; i++) {
1060                val = params[i].split("=");
1061                if (val[0] == paramName) {
1062                    return unescape(val[1]);
1063                }
1064            }
1065            return null;
1066        },
1067
1068        // check for device touch support
1069        isTouchDevice: function () {
1070            try {
1071                document.createEvent("TouchEvent");
1072                return true;
1073            }
1074            catch (e) {
1075                return false;
1076            }
1077        },
1078
1079        // check IE8 mode
1080        isIE8: function () {
1081            return isIE8;
1082        },
1083
1084        // check IE9 mode
1085        isIE9: function () {
1086            return isIE9;
1087        },
1088
1089        //check RTL mode
1090        isRTL: function () {
1091            return isRTL;
1092        },
1093
1094        // get layout color code by color name
1095        getLayoutColorCode: function (name) {
1096            if (layoutColorCodes[name]) {
1097                return layoutColorCodes[name];
1098            }
1099            else {
1100                return '';
1101            }
1102        }
1103    };
1104}();;
1105var FormComponents = function () {
1106
1107    var handleBootstrapMaxlength = function () {
1108        //$('#maxlength_defaultconfig').maxlength({
1109        //    limitReachedClass: "label label-danger",
1110        //});
1111        //$('#maxlength_thresholdconfig').maxlength({
1112        //    limitReachedClass: "label label-danger",
1113        //    threshold: 20
1114        //});
1115        //$('#maxlength_alloptions').maxlength({
1116        //    alwaysShow: true,
1117        //    warningClass: "label label-success",
1118        //    limitReachedClass: "label label-danger",
1119        //    separator: ' out of ',
1120        //    preText: 'You typed ',
1121        //    postText: ' chars available.',
1122        //    validate: true
1123        //});
1124        //$('#maxlength_textarea').maxlength({
1125        //    limitReachedClass: "label label-danger",
1126        //    alwaysShow: true
1127        //});
1128        //$('#maxlength_placement').maxlength({
1129        //    limitReachedClass: "label label-danger",
1130        //    alwaysShow: true,
1131        //    placement: App.isRTL() ? 'top-right' : 'top-left'
1132        //});
1133        $('.form-control[data-maxlength]').each(function () {
1134            $(this).attr('maxlength', $(this).attr('data-maxlength'));
1135        });
1136        $('input[data-maxlength], textarea[data-maxlength]').maxlength({
1137            alwaysShow: true,
1138            validate: true,
1139            placement: 'bottom',
1140            warningClass: 'label label-success',
1141            limitReachedClass: 'label label-danger'
1142        });
1143    };
1144
1145    var handleSpinners = function () {
1146        $('#spinner1').spinner();
1147        $('#spinner2').spinner({ disabled: true });
1148        $('#spinner3').spinner({ value: 0, min: 0, max: 10 });
1149        $('#spinner4').spinner({ value: 0, step: 5, min: 0, max: 200 });
1150    };
1151
1152    var handleWysihtml5 = function () {
1153        if (!jQuery().wysihtml5) {
1154            return;
1155        }
1156
1157        if ($('.wysihtml5').length > 0) {
1158            $('.wysihtml5').each(function () {
1159                if ($(this).attr('data-initialized') != '1') {
1160                    $(this).wysihtml5({
1161                        "html": true,
1162                        "stylesheets": ["/assets/plugins/bootstrap-wysihtml5/wysiwyg-color.css"]
1163                    });
1164
1165                    if ($(this).attr('disabled') == 'disabled') {
1166                        var content = $(this);
1167                        var contentPar = content.parent();
1168                        contentPar.find('.wysihtml5-toolbar').remove();
1169                    }
1170
1171                    $(this).attr('data-initialized', '1');
1172                }
1173            });
1174        }
1175    };
1176
1177    var handleSignature = function () {
1178        if (!jQuery().jSignature) {
1179            return;
1180        }
1181
1182        if ($('.jSignature').length > 0) {
1183            $('.jSignature').each(function () {
1184                if ($(this).attr('data-initialized') != '1') {
1185                    var id = $(this).attr('id');
1186                    if (!id) {
1187                        return;
1188                    }
1189                    var div = $('<div></div>').addClass('jSignaturePad').attr('id', id + 'Pad');
1190                    div.appendTo($(this));
1191
1192                    div.jSignature();
1193                    div.jSignature('setData', 'data:' + $('#' + id + 'Base64').val());
1194
1195                    div.on('change', function (e) {
1196                        $('#' + id + 'IsValid').val('1');
1197                        $('#' + id + 'Base64').val($(this).jSignature('getData', 'image').join(','));
1198                    });
1199
1200                    var btnGroup = $('<div></div>').addClass('btn-group');
1201                    btnGroup.appendTo($(this));
1202
1203                    var button = $('<input type="button" value="Undo">').addClass('btn blue reset');
1204                    button.on('click', function (e) {
1205                        var p = $('#' + id + 'Pad');
1206                        var buffer = p.jSignature('getData', 'native');
1207                        buffer.pop();
1208                        p.jSignature('setData', buffer, 'native');
1209                        $('#' + id + 'IsValid').val((0 in buffer) ? '1' : '');
1210                    });
1211                    button.appendTo(btnGroup);
1212
1213                    button = $('<input type="button" value="Clear">').addClass('btn blue reset');
1214                    button.on('click', function (e) {
1215                        $('#' + id + 'Pad').jSignature('reset');
1216                        $('#' + id + 'IsValid').val('');
1217                    });
1218                    button.appendTo(btnGroup);
1219
1220                    $(this).attr('data-initialized', '1');
1221                }
1222            });
1223        }
1224    }
1225
1226    var handleDatePickers = function () {
1227
1228        if (jQuery().datepicker) {
1229            if ($.fn.datepicker.DPGlobal.template.indexOf('datepicker-runtime-dates') < 0) {
1230                // This allows query builder to offer a "Run-Time Dates" selection
1231                var template = $.fn.datepicker.DPGlobal.template;
1232                template = template.substring(0, template.length - 6);
1233                $.fn.datepicker.DPGlobal.template = template +
1234                    '<span class="datepicker-runtime-dates">' +
1235                    '<span class="datepicker-runtime-dates-title">' +
1236                    '<span class="display-block">Run-Time Dates</span>' +
1237                    '<span class="display-block">(Evaluated at Run-Time):</span>' +
1238                    '</span>' +
1239                    '<span class="datepicker-runtime-dates-btn-group">' +
1240                    '<a href="javascript:void(0);" class="btn btn-xs blue inline" data-value="Today">Today</a>' +
1241                    '<a href="javascript:void(0);" class="btn btn-xs blue inline" data-value="Tomorrow">Tomorrow</a>' +
1242                    '<a href="javascript:void(0);" class="btn btn-xs blue inline" data-value="Yesterday">Yesterday</a>' +
1243                    '</span>' +
1244                    '<span class="datepicker-runtime-dates-btn-group">' +
1245                    '<a href="javascript:void(0);" class="btn btn-xs blue" data-value="FirstDayOfThisWeek">First Day (Mon) of This Week</a>' +
1246                    '</span>' +
1247                    '<span class="datepicker-runtime-dates-btn-group">' +
1248                    '<a href="javascript:void(0);" class="btn btn-xs blue" data-value="LastDayOfThisWeek">Last Day (Sun) of This Week</a>' +
1249                    '</span>' +
1250                    '<span class="datepicker-runtime-dates-btn-group">' +
1251                    '<a href="javascript:void(0);" class="btn btn-xs blue" data-value="FirstDayOfLastWeek">First Day (Mon) of Last Week</a>' +
1252                    '</span>' +
1253                    '<span class="datepicker-runtime-dates-btn-group">' +
1254                    '<a href="javascript:void(0);" class="btn btn-xs blue" data-value="LastDayOfLastWeek">Last Day (Sun) of Last Week</a>' +
1255                    '</span>' +
1256                    '<span class="datepicker-runtime-dates-btn-group">' +
1257                    '<a href="javascript:void(0);" class="btn btn-xs blue" data-value="FirstDayOfThisMonth">First Day of This Month</a>' +
1258                    '</span>' +
1259                    '<span class="datepicker-runtime-dates-btn-group">' +
1260                    '<a href="javascript:void(0);" class="btn btn-xs blue" data-value="LastDayOfThisMonth">Last Day of This Month</a>' +
1261                    '</span>' +
1262                    '<span class="datepicker-runtime-dates-btn-group">' +
1263                    '<a href="javascript:void(0);" class="btn btn-xs blue" data-value="FirstDayOfLastMonth">First Day of Last Month</a>' +
1264                    '</span>' +
1265                    '<span class="datepicker-runtime-dates-btn-group">' +
1266                    '<a href="javascript:void(0);" class="btn btn-xs blue" data-value="LastDayOfLastMonth">Last Day of Last Month</a>' +
1267                    '</span>' +
1268                    '</span>' +
1269                    //'<span class="clearfix"></span>' +
1270                    '</div>';
1271            }
1272            $('.date-picker').datepicker({
1273                rtl: App.isRTL(),
1274                //language: (window.__cultureInfo !== undefined && window.__cultureInfo !== null ? window.__cultureInfo.name : 'en-US'),
1275                format: (window.cultureInfo !== undefined && window.cultureInfo !== null ? window.cultureInfo.dateTimeFormat.ShortDatePattern.toLowerCase() : 'm/d/yyyy'),
1276                orientation: 'top left',
1277                autoclose: true,
1278                multidate: false,
1279                clearBtn: false,
1280                todayBtn: false,
1281                todayHighlight: true
1282            }).on('show', function (e) {
1283                var self = $(this);
1284                if (self.attr('data-is-open') != '1') {
1285                    var runtimeHidden = self.parent().find('input[type="hidden"]');
1286                    self.attr('data-runtime-value', runtimeHidden.val());
1287                    runtimeHidden.val('');
1288                    var todayText = self.find('span.datepicker-runtime-text').css('display', 'none');
1289                    var textbox = self.find('input[type="text"]').keydown(function () {
1290                        $(this).parent().parent().find('span.datepicker-runtime-text').css('display', 'none');
1291                    });
1292                    if (textbox.attr('data-runtime-mode') == '1') {
1293                        $('.datepicker-days, .datepicker-months, .datepicker-years').css('float', 'left');
1294                        $('.datepicker-dropdown .datepicker-runtime-dates').css('display', 'block');
1295                        $('.datepicker-dropdown .datepicker-runtime-dates a').unbind('click').bind('click', function () {
1296                            var value = $(this).attr('data-value');
1297                            runtimeHidden.val(value);
1298                            todayText.css('display', 'block').text('[' + value + ']');
1299                            self.datepicker('clearDates').datepicker('hide');
1300                            textbox.val('').blur();
1301                            if (window.page !== undefined && window.page !== null && textbox.attr('data-auto-postback') == '1') {
1302                                window.setTimeout(function () {
1303                                    page.postback(runtimeHidden.attr('name'), '');
1304                                }, 100);
1305                            }
1306                            e.stopPropagation();
1307                            e.preventDefault();
1308                        });
1309                        $('.datepicker-dropdown').css('width', '');
1310                        if ($('.datepicker-dropdown').width() < 396) {
1311                            $('.datepicker-dropdown').width(198);
1312                        }
1313                        else {
1314                            $('.datepicker-dropdown').width(396);
1315                        }
1316                    }
1317                    else {
1318                        $('.datepicker-days, .datepicker-months, .datepicker-years').css('float', '');
1319                    }
1320                    if (window.dialog !== undefined && window.dialog !== null) {
1321                        dialog.resize('body');
1322                    }
1323                    self.attr('data-is-open', '1');
1324                }
1325            }).on('hide', function (e) {
1326                var self = $(this);
1327                self.attr('data-is-open', '0');
1328                var textbox = self.find('input[type="text"]');
1329                if (textbox.attr('data-auto-postback') == '1' && textbox.val() == '') {
1330                    var runtimeHidden = self.parent().find('input[type="hidden"]');
1331                    if ((runtimeHidden.val() == '' && self.attr('data-runtime-value') != '') || (runtimeHidden.val() != '' && self.attr('data-runtime-value') == '')) {
1332                        self.attr('data-runtime-value', '');
1333                        if (window.page !== undefined && window.page !== null) {
1334                            window.setTimeout(function () {
1335                                page.postback(runtimeHidden.attr('name'), '');
1336                            }, 100);
1337                        }
1338                    }
1339                }
1340                if (window.dialog !== undefined && window.dialog !== null) {
1341                    dialog.resize(null, true);
1342                }
1343            });
1344            $('.date-picker input[type="text"].form-control').blur(function () {
1345                var runtimeHidden = $(this).parent().parent().find('input[type="hidden"]');
1346                if (runtimeHidden.val() == '') {
1347                    var text = $(this).val();
1348                    if (text != '') {
1349                        text = text.replace(/jan/i, 'Jan').replace(/feb/i, 'Feb').replace(/mar/i, 'Mar').replace(/apr/i, 'Apr').replace(/may/i, 'May').replace(/jun/i, 'Jun').replace(/jul/i, 'Jul').replace(/aug/i, 'Aug').replace(/sep/i, 'Sep').replace(/oct/i, 'Oct').replace(/nov/i, 'Nov').replace(/dec/i, 'Dec');
1350                        $(this).val(text);
1351                    }
1352                }
1353                else {
1354                    $(this).val('');
1355                }
1356            });
1357            //$('body').removeClass("modal-open"); // fix bug when inline picker is used in modal
1358        }
1359    };
1360
1361    var handleTimePickers = function () {
1362
1363        if (jQuery().timepicker) {
1364            $('.timepicker-default').timepicker({
1365                minuteStep: 1,
1366                showMeridian: true
1367            });
1368            $('.timepicker-24').timepicker({
1369                minuteStep: 1,
1370                showMeridian: false
1371            });
1372        }
1373    };
1374
1375    var handleSwitch = function () {
1376        $('.make-switch2').each(function () {
1377            if ($(this).data('switch-enabled') != true) {
1378                $(this).bootstrapSwitch();
1379                $(this).data('switch-enabled', true);
1380            }
1381        });
1382    };
1383
1384    var handleAceCodeEditor = function () {
1385        if (window.ace) {
1386            $('.code-editor').each(function () {
1387                if ($(this).attr('data-has-code-editor') !== '1') {
1388                    var id = $(this).attr('id');
1389                    var language = $(this).attr('data-language');
1390                    if (language == null) {
1391                        language = "html";
1392                    }
1393                    // Hack to get the height of the textarea
1394                    var height = $(this).height();
1395                    if (height <= 0 && $(this).attr('rows') != null && parseInt($(this).attr('rows')) > 0) {
1396                        var div = $('<div></div>').css({ 'position': 'absolute', 'top': '-10000px', 'left': '-10000px' }).text('hello').appendTo('body');
1397                        height = parseInt($(this).attr('rows')) * div.height();
1398                        div.remove();
1399                    }
1400                    if (height <= 0) {
1401                        height = 300;
1402                    }
1403                    $('<div id="' + id + '_editor" class="ace-editor" style="min-height:' + height + 'px;"></div>').insertBefore($(this));
1404                    $(this).addClass('display-none');
1405                    ace.config.set('basePath', '/assets/plugins/ace/src-min-noconflict');
1406                    var editor = ace.edit(id + '_editor');
1407                    editor.setTheme('ace/theme/' + (language.toLowerCase() === 'sqlserver' ? 'sqlserver' : 'chrome'));
1408                    var session = editor.getSession();
1409                    session.setMode('ace/mode/' + language.toLowerCase());
1410                    editor.setValue($(this).val(), -1);
1411                    if (language.toLowerCase() === 'html') {
1412                        session.on("changeAnnotation", function () {
1413                            var annotations = session.getAnnotations() || [];
1414                            var len = annotations.length;
1415                            var i = len;
1416                            while (i--) {
1417                                if (/doctype first\. Expected/.test(annotations[i].text)) {
1418                                    annotations.splice(i, 1);
1419                                }
1420                                else if (/Unexpected End of file\. Expected/.test(annotations[i].text)) {
1421                                    annotations.splice(i, 1);
1422                                }
1423                            }
1424                            if (len > annotations.length) {
1425                                session.setAnnotations(annotations);
1426                            }
1427                        });
1428                    }
1429                    $(this).attr('data-has-code-editor', '1');
1430                }
1431            });
1432        }
1433    };
1434
1435    var handleLookupControls = function () {
1436        let canShowExpandSearchText = true;
1437        let canDisplayNoResultsText = true;
1438        let expandedSearchElements = [];
1439        $('input.data-lookup-text').each(function () {
1440            var value = $(this).val();
1441            $(this).val(page.decodeSpecialChars(value));
1442        });
1443        $('select.data-lookup').each(function () {
1444            var self = $(this);
1445            var placeholder = self.attr('data-placeholder');
1446            if (placeholder == null || placeholder === '') {
1447                placeholder = 'Search for Record';
1448            }
1449            var miniumKeyStrokes = self.attr('data-minimum-input-length');
1450            if (miniumKeyStrokes !== "") {
1451                if (!isNaN(parseInt(miniumKeyStrokes))) {
1452                    miniumKeyStrokes = parseInt(miniumKeyStrokes);
1453                }
1454                else {
1455                    miniumKeyStrokes = 2;
1456                }
1457            }
1458            else {
1459                miniumKeyStrokes = 2;
1460            }
1461            // select2 4.x reads data-* attributes and overwrites the JS config with them
1462            // (select2.js Options.fromElement). The control renders an empty data-minimum-input-length
1463            // when none is set, which blanks minimumInputLength and disables the minimum-length gate,
1464            // so an empty query fires on open and renders "No results found". Write the resolved value
1465            // back so select2 keeps the gate ("Please enter N or more characters" until N chars typed).
1466            self.attr('data-minimum-input-length', miniumKeyStrokes);
1467            var textElement = $('#' + self.id().replace('hidLookupValue', 'hidLookupText'));
1468            var valueHFElement = $('#' + self.id().replace('hidLookupValue', 'txtLookupValue'));
1469            var isMultiple = !!+self.attr('data-multiple');
1470
1471            if (self.hasClass('select2-hidden-accessible')) {
1472                self.select2('destroy');
1473            }
1474
1475            self.empty();
1476            if (isMultiple) {
1477                self.attr('multiple', 'multiple');
1478                if (valueHFElement.val()) {
1479                    var textValues = JSON.parse(page.htmlDecode(textElement.val()));
1480                    var values = JSON.parse(valueHFElement.val());
1481                    values.forEach(function (value, i) {
1482                        self.append(new Option(textValues[i], value, true, true));
1483                    });
1484                }
1485            } else {
1486                self.removeAttr('multiple');
1487                self.append(new Option('', ''));
1488                if (valueHFElement.val()) {
1489                    self.append(new Option(page.htmlDecode(textElement.val()), valueHFElement.val(), true, true));
1490                }
1491            }
1492
1493            self.prop('disabled', $('#' + self.id().replace('hidLookupValue', 'hidLookupEnabled')).val() !== '1');
1494            // Tracks whether the user has typed during this open session, so the "enter N characters"
1495            // prompt stays visible when they delete back to empty; reset on close so a fresh open is blank.
1496            var hasTyped = false;
1497            var lastTerm = ''; // current search term, used to underline the match in results (templateResult)
1498            self.select2({
1499                placeholder: placeholder,
1500                allowClear: self.attr('data-required') !== '1',
1501                minimumInputLength: miniumKeyStrokes,
1502                maximumSelectionLength: isMultiple ? (+self.attr('data-maximumSelectionSize') || 1) : 0,
1503                escapeMarkup: function (m) { return m; },
1504                templateResult: function (item) {
1505                    // Underline the typed term within each result - restores select2 3.x's markMatch,
1506                    // which the 4.x default renderer dropped. escapeMarkup above returns the string
1507                    // as-is, so the <span> is rendered rather than escaped.
1508                    var text = item && item.text != null ? String(item.text) : '';
1509                    var term = (lastTerm || '').trim();
1510                    if (!term || item.loading) { return text; }
1511                    var idx = text.toUpperCase().indexOf(term.toUpperCase());
1512                    if (idx < 0) { return text; }
1513                    return text.substring(0, idx)
1514                        + '<span class="select2-match">' + text.substring(idx, idx + term.length) + '</span>'
1515                        + text.substring(idx + term.length);
1516                },
1517                language: {
1518                    // A fresh open shows nothing. Once the user has typed, keep the prompt visible for
1519                    // any sub-minimum length - including after deleting back to empty - and hide it only
1520                    // once the minimum is reached. Runs on every keystroke.
1521                    inputTooShort: function (args) {
1522                        var len = args.input ? args.input.length : 0;
1523                        if (len > 0) { hasTyped = true; }
1524                        // Below the minimum there's no active search, so the "Expand your search" prompt
1525                        // shouldn't linger; drop it and let it reappear on the next real search.
1526                        $('.expanded-search').remove();
1527                        canShowExpandSearchText = true;
1528                        if (len === 0 && !hasTyped) { return ''; }
1529                        var remaining = args.minimum - len;
1530                        return 'Please enter ' + remaining + ' or more character' + (remaining === 1 ? '' : 's');
1531                    }
1532                },
1533                ajax: {
1534                    delay: 500,
1535                    data: function (params) {
1536                        return { term: params.term || '' };
1537                    },
1538                    transport: function (options, success, failure) {
1539                        var term = options.data.term.trim();
1540                        hasTyped = true; // reaching the server means the user has typed (covers paste / fast typing)
1541                        lastTerm = term; // remember it so templateResult can underline the match
1542                        if (term === '') {
1543                            success({ results: [] });
1544                            return;
1545                        }
1546
1547                        var currId = self.attr('id');
1548                        if (canShowExpandSearchText && expandedSearchElements.includes(currId)) {
1549                            canShowExpandSearchText = false;
1550                            $('.expanded-search').remove(); // remove any stale span first so it can never stack
1551                            $(".select2-results").after('<span id="'
1552                                + currId
1553                                + 'spanExpandSearch" class="expanded-search">Don\'t see what you\'re looking for? <a onclick="javascript:$(\'#'
1554                                + currId
1555                                + '\').attr(\'data-expandedsearch\', \'true\'); $(\'.select2-container--open .select2-search__field\').trigger(\'input\'); ">Expand your search</a></span>');
1556                        }
1557
1558                        if (canDisplayNoResultsText && self.attr('data-expandedsearch') !== undefined && self.attr('data-expandedsearch') === "true") {
1559                            canDisplayNoResultsText = false;
1560                            $('.expanded-search').remove();
1561                        }
1562
1563                        page.ajax({
1564                            showProgress: false,
1565                            url: '~/Services/Lookup.asmx/GetLookupValues',
1566                            parameters: {
1567                                'searchTerm': term,
1568                                'assemblyName': self.attr('data-assembly-name'),
1569                                'typeName': self.attr('data-type-name'),
1570                                'methodName': self.attr('data-method-name'),
1571                                'methodParameter': self.attr('data-method-parameter'),
1572                                'methodParameterType': self.attr('data-method-parameter-type'),
1573                                'valueField': self.attr('data-value-field'),
1574                                'textField': self.attr('data-text-field'),
1575                                'isExpandedSearch': self.attr('data-expandedsearch')
1576                            },
1577                            success: function (data) {
1578                                if (data != null) {
1579                                    success({ results: data });
1580                                }
1581                                else {
1582                                    page.displayError('Load Lookup', 'Unable to get list of records for this lookup.');
1583                                    failure();
1584                                }
1585                            },
1586                            error: function (message) {
1587                                page.displayError('Load Lookup', message);
1588                                failure();
1589                            }
1590                        });
1591                    }
1592                }
1593            });
1594            self.on('select2:open', function (e) { 
1595
1596                if (!expandedSearchElements.includes(self.attr('id')) && self.siblings("div.expanded-search-hidden.AllowExpandedSearch").length > 0) {
1597                    expandedSearchElements.push(self.attr('id'));
1598                }
1599
1600                if (window.frameElement && window.parent != null) {
1601                    $('.select2-dropdown').css('position', 'relative'); // hack to calculate height of the dropdown
1602                    dialog.resize('body', false, function () {
1603                        $('.select2-dropdown').css('position', 'absolute'); // now put the absolute positoning back
1604                    });
1605                }
1606            });
1607            self.on('select2:close', function (e) {
1608
1609                hasTyped = false; // reset so the next open starts blank (no prompt until the user types)
1610                $('.expanded-search').remove(); // always clean up; the element-id guard could be skipped (shared/reset array) and leave orphans that stack on reopen
1611
1612                self.attr('data-expandedsearch', 'false');
1613                canShowExpandSearchText = true;
1614                canDisplayNoResultsText = true;
1615                expandedSearchElements = [];
1616
1617                dialog.resize(null, true);
1618            });
1619            self.on('change', function (e) {
1620                var data = self.select2("data");
1621
1622                var autoPostback = !!+$('#' + self.id().replace('hidLookupValue', 'hidLookupAutoPostBack')).val();
1623
1624                if (isMultiple) {
1625                    if (data.length) {
1626                        valueHFElement.val(JSON.stringify(data.map(function (x) {
1627                            return x.id;
1628                        })));
1629                        textElement.val(JSON.stringify(data.map(function (x) {
1630                            return page.htmlEncode(x.text);
1631                        })));
1632
1633                    } else {
1634                        valueHFElement.val('');
1635                        textElement.val('');
1636                    }
1637                } else {
1638                    var item = data && data.length ? data[0] : null;
1639                    valueHFElement.val(item && item.id || '');
1640                    textElement.val(item && page.htmlEncode(item.text) || '');
1641                }
1642
1643                if (autoPostback) {
1644                    page.postback(valueHFElement.id(), '|');
1645                } else {
1646                    var clientEvent = self.attr('data-selection-changed');
1647                    if (clientEvent) {
1648                        var func = page.getFunctionFromString(clientEvent);
1649                        func && func.call(this, self.id(), self.val(), null);
1650                    }
1651                }
1652            });
1653        });
1654    };
1655
1656    var postQuery = function (query, self) {
1657        if (page._lookupTimer != null) {
1658            window.clearTimeout(page._lookupTimer);
1659        }
1660        page._lookupTimer = window.setTimeout(function () {
1661            page.ajax({
1662                showProgress: false,
1663                url: '~/Services/Lookup.asmx/GetLookupValues',
1664                parameters: {
1665                    'searchTerm': query.term.trim(),
1666                    'assemblyName': self.attr('data-assembly-name'),
1667                    'typeName': self.attr('data-type-name'),
1668                    'methodName': self.attr('data-method-name'),
1669                    'methodParameter': self.attr('data-method-parameter'),
1670                    'methodParameterType': self.attr('data-method-parameter-type'),
1671                    'valueField': self.attr('data-value-field'),
1672                    'textField': self.attr('data-text-field'),
1673                    'isExpandedSearch': self.attr('data-expandedsearch')
1674                },
1675                success: function (data) {
1676                    if (data != null) {
1677                        query.callback({ results: data });
1678                    }
1679                    else {
1680                        page.displayError('Load Lookup', 'Unable to get list of records for this lookup.');
1681                    }
1682                },
1683                error: function (message) {
1684                    page.displayError('Load Lookup', message);
1685                }
1686            });
1687            if (page._lookupTimer != null) {
1688                window.clearTimeout(page._lookupTimer);
1689            }
1690            page._lookupTimer = null;
1691        }, 500);
1692    }
1693
1694    var handleMultiSelectControls = function () {
1695        $('select.data-multiselect').each(function () {
1696            var self = $(this);
1697            var placeholder = self.attr('data-placeholder');
1698            if (self.hasClass('select2-hidden-accessible')) {
1699                self.select2('destroy');
1700            }
1701            self.prop('disabled', !+self.attr('data-enabled'));
1702            self.select2({
1703                placeholder: placeholder,
1704                allowClear: !!placeholder && (self.attr('data-required') !== '1'),
1705                minimumResultsForSearch: (self.attr('data-search') !== '1' ? Infinity : 1), // show or hide search - for single select static dropdown only
1706                closeOnSelect: false,
1707                escapeMarkup: function (markup) { return markup; }, // option text may contain HTML (e.g. expertise/discipline markup) - render it instead of escaping
1708                templateResult: function (item) {
1709                    return item.text;
1710                },
1711                templateSelection: function (item) {
1712                    return item.text;
1713                }
1714            });
1715            self.on('select2:open', function (e) {
1716                if (window.frameElement && window.parent != null) {
1717                    $('.select2-dropdown').css('position', 'relative'); // hack to calculate height of the dropdown
1718                    dialog.resize('body', false, function () {
1719                        $('.select2-dropdown').css('position', 'absolute'); // now put the absolute positoning back
1720                    });
1721                }
1722            });
1723            self.on('select2:close', function (e) {
1724                dialog.resize(null, true);
1725            });
1726
1727            var hiddenSelected = $('#' + self.id().replace('lstMultiSelectValue', 'hiddenDataSelected'));
1728            var syncSelected = function () {
1729                var data = self.select2('data');
1730                hiddenSelected.val(data.length ? data.map(function (item) { return '{' + item.id + '}'; }).join(' ') : '');
1731            };
1732            syncSelected();
1733            self.on('change', function (e) {
1734                syncSelected();
1735                if (self.attr('data-autopostback') === '1') {
1736                    page.postback(self.id(), '');
1737                }
1738            });
1739        });
1740    };
1741
1742    var handleCurrencyDropdown = function () {
1743        $('select.data-currency').each(function () {
1744            var self = $(this);
1745            var placeholder = self.attr('data-placeholder');
1746            if (self.hasClass('select2-hidden-accessible')) { 
1747                self.select2('destroy');
1748            }
1749            self.prop('disabled', self.attr('data-enabled') === '0'); 
1750            self.select2({
1751                placeholder: placeholder,
1752                allowClear: !!placeholder && (self.attr('data-required') !== '1'), 
1753                minimumResultsForSearch: Infinity,
1754                closeOnSelect: true,
1755                escapeMarkup: function (markup) { return markup; }, 
1756                templateResult: function (item) { 
1757                    return item.text;
1758                },
1759                templateSelection: function (item) { 
1760                    return item.text;
1761                }
1762            });
1763            self.on('select2:open', function (e) { 
1764                if (window.frameElement && window.parent != null) {
1765                    $('.select2-dropdown').css('position', 'relative'); // hack to calculate height of the dropdown
1766                    dialog.resize('body', false, function () {
1767                        $('.select2-dropdown').css('position', 'absolute'); // now put the absolute positoning back
1768                    });
1769                }
1770            });
1771            self.on('select2:close', function (e) { 
1772                dialog.resize(null, true);
1773            });
1774            self.on('change', function (e) {
1775                if (self.attr('data-autopostback') === '1') {
1776                    page.postback(self.id(), '');
1777                }
1778            });
1779        });
1780    };
1781
1782    var handleSelect2Dropdown = function () {
1783        $('select.data-select2').each(function () {
1784            var self = $(this);
1785            var placeholder = self.attr('data-placeholder');
1786            if (self.hasClass('select2-hidden-accessible')) {
1787                self.select2('destroy');
1788            }
1789            self.prop('disabled', self.attr('data-enabled') === '0'); 
1790            self.select2({
1791                placeholder: placeholder,
1792                allowClear: !!placeholder, 
1793                minimumResultsForSearch: (self.attr('data-search') !== '1' ? Infinity : 1), // show or hide search - for single select static dropdown only
1794                //maximumInputLength: 0,
1795                //multiple: false,
1796                //maximumSelectionLength: 1,
1797                //selectOnClose: true,
1798                //closeOnSelect: true,
1799                escapeMarkup: function (markup) { return markup; }, 
1800                templateResult: function (item) {
1801                    return item.text;
1802                },
1803                templateSelection: function (item) {
1804                    return item.text;
1805                },
1806                //matcher: function (params, data) {
1807                //    return data.text.toUpperCase().indexOf(params.term.toUpperCase()) == 0 ? data : null;
1808                //}
1809            });
1810            self.on('select2:open', function (e) {
1811                if (window.frameElement && window.parent != null) {
1812                    $('.select2-dropdown').css('position', 'relative'); // hack to calculate height of the dropdown
1813                    dialog.resize('body', false, function () {
1814                        $('.select2-dropdown').css('position', 'absolute'); // now put the absolute positoning back
1815                    });
1816                }
1817            });
1818            self.on('select2:close', function (e) {
1819                dialog.resize(null, true);
1820            });
1821            self.on('change', function (e) {
1822                if (page.isIE()) {
1823                    try {
1824                        self.siblings('div.data-lookup').children('.select2-selection').focus();
1825                    }
1826                    catch (ex) { }
1827                }
1828                if (self.attr('data-autopostback') === '1') {
1829                    page.postback(self.id(), '');
1830                }
1831            });
1832        });
1833    };
1834
1835    var handleSelect2DropdownMultiLine = function () {
1836        $('select.data-select2-multiline').each(function () {
1837            var self = $(this);
1838            if (self.hasClass('select2-hidden-accessible')) { 
1839                self.select2('destroy');
1840            }
1841            self.prop('disabled', self.attr('data-enabled') === '0'); 
1842            self.select2({
1843                placeholder: self.attr('data-placeholder'),
1844                allowClear: false,
1845                minimumResultsForSearch: (self.attr('data-search') !== '1' ? Infinity : 1),
1846                templateResult: function (item) { 
1847                    return $('<span>' + item.text + '</span>');
1848                },
1849                templateSelection: function (item) {
1850                    var text = item.text || '';
1851                    return $('<span>' + text.substr(0, 65) + (text.length > 65 ? '...' : '') + '</span>');
1852                }
1853            });
1854            self.on('change', function (e) {
1855                if (page.isIE()) {
1856                    try {
1857                        self.siblings('div.data-lookup').children('.select2-selection').focus();
1858                    }
1859                    catch (ex) { }
1860                }
1861                if (self.attr('data-autopostback') === '1') {
1862                    page.postback(self.id(), '');
1863                }
1864            });
1865        });
1866    };
1867
1868    var handleTagInputControls = function () {
1869        $('select.tag-input-dynamic-creation').each(function () {
1870            var self = $(this);
1871            var hidden = self.siblings('input.tag-input-value');
1872            var data = hidden.attr('data-values') ? JSON.parse(hidden.attr('data-values')) : [];
1873            var selectedValues = hidden.val() ? hidden.val().split('|') : [];
1874
1875            // seed the available options and the current selection as <option>s before init
1876            self.empty();
1877            data.forEach(function (item) {
1878                self.append(new Option(item.text, item.id, false, selectedValues.indexOf(String(item.id)) >= 0));
1879            });
1880            // free-text tags previously typed aren't in data-values; add them as selected options
1881            selectedValues.forEach(function (value) {
1882                if (value !== '' && !self.find('option').filter(function () { return this.value === value; }).length) {
1883                    self.append(new Option(value, value, true, true));
1884                }
1885            });
1886
1887            if (self.hasClass('select2-hidden-accessible')) {
1888                self.select2('destroy');
1889            }
1890            self.select2({
1891                tags: true,
1892                tokenSeparators: ['|'],
1893                placeholder: self.attr('data-placeholder'),
1894                allowClear: !!self.attr('data-placeholder') && self.attr('data-required') !== '1',
1895                minimumResultsForSearch: self.attr('data-search') !== '1' ? Infinity : 1,
1896                closeOnSelect: false
1897            });
1898
1899            var syncHidden = function () {
1900                hidden.val((self.val() || []).join('|'));
1901            };
1902            syncHidden();
1903            self.on('change', syncHidden);
1904            self.on('select2:open', function (e) {
1905                if (window.frameElement && window.parent != null) {
1906                    $('.select2-dropdown').css('position', 'relative'); // hack to calculate height of the dropdown
1907                    dialog.resize('body', false, function () {
1908                        $('.select2-dropdown').css('position', 'absolute'); // now put the absolute positoning back
1909                    });
1910                }
1911            });
1912            self.on('select2:close', function (e) {
1913                dialog.resize(null, true);
1914            });
1915        });
1916    };
1917
1918    var handleToggleButtons = function () {
1919        $('.radiobutton-list > label').on('click', function () {
1920            $(this).children('input[type="radio"]').prop('checked', true);
1921        });
1922        $('.checkbox-list > label').on('click', function () {
1923            $(this).children('input[type="checkbox"]').prop('checked', !(this).children('input[type="checkbox"]').prop('checked'));
1924        });
1925    };
1926
1927    var handleResponsiveGrids = function () {
1928        var timer;
1929        timer = window.setTimeout(function () {
1930            $('.grid-container.table-responsive > div').each(function () {
1931                var table = $(this).children('table');
1932                if (table.length > 0) {
1933                    var text = $(this).parent().children('small');
1934                    if (text.length == 0) {
1935                        text = $('<small></small>').addClass('no-print').css({ 'display': 'none', 'padding': '5px' }).html('<i class="icon-hand-o-up"></i> <i>Scroll/Swipe left or right to view full content:</i>');
1936                        table.parent().before(text);
1937                    }
1938                    if (table[0].scrollWidth > 0 && $(this)[0].offsetWidth > 0) {
1939                        text.css('display', (table[0].scrollWidth > $(this)[0].offsetWidth ? 'block' : 'none'));
1940                    }
1941                }
1942            });
1943            window.clearTimeout(timer);
1944        }, 200);
1945    };
1946
1947    var buildSideBarMenuAutocomplete = function () {
1948
1949        var items = {};
1950        items["Apps"] = [];
1951        items["default"] = [];
1952        var searchValue = "";
1953
1954        $(".page-sidebar-menu > li.page-sidebar-menu-admin > ul.sub-menu > li > ul.sub-menu > li > a").each(function (i, el) {
1955            var type = "<span class='menu-category-name'>" + $(this).parents()[2].children[0].text + "<span class='icon-angle-right'></span></span>";
1956
1957            if (!$(this).next(".sub-menu").length) {
1958                items["Apps"].push({ name: el.innerText, path: el.href, icon: el.firstElementChild.className, type: type, classes: 'menu-name' });
1959            }
1960        });
1961
1962        items["default"].push({ tabName: 'individuals', name: 'in Individuals', path: window.location.origin + "/administration/search/?q=value&tab=individuals", icon: 'icon-user', type: '', classes: 'margin-top-5', isGlobalSearch: true });
1963        items["default"].push({ tabName: 'organizations', name: 'in Organizations', path: window.location.origin + "/administration/search/?q=value&tab=organizations", icon: 'icon-building-o', type: '', isGlobalSearch: true });
1964        items["default"].push({ tabName: 'chapters', name: 'in Chapters', path: window.location.origin + "/administration/search/?q=value&tab=chapters", icon: 'icon-archive', type: '', isGlobalSearch: true });
1965        items["default"].push({ tabName: 'committees', name: 'in Committees', path: window.location.origin + "/administration/search/?q=value&tab=committees", icon: 'icon-briefcase', type: '', isGlobalSearch: true });
1966        items["default"].push({ tabName: 'products', name: 'in Products', path: window.location.origin + "/administration/search/?q=value&tab=products", icon: 'icon-barcode', type: '', isGlobalSearch: true });
1967        items["default"].push({ tabName: 'exhibithalls', name: 'in Exhibit Halls', path: window.location.origin + "/administration/search/?q=value&tab=exhibithalls", icon: 'icon-th', type: '', isGlobalSearch: true });
1968        items["default"].push({ tabName: 'orders', name: 'Order/Invoices', path: window.location.origin + "/administration/search/?q=value&tab=orders", icon: 'icon-file-o', type: '', isGlobalSearch: true });
1969
1970        $("#siteSearch").easyAutocomplete({
1971            data: items, getValue: "name",
1972            minCharNumber: 2,
1973            categoriesAssigned: true,
1974            categories: [
1975                {
1976                    listLocation: "default",
1977                    maxNumberOfElements: 30
1978                },
1979                {
1980                    listLocation: "Apps",
1981                    header: "<div class='easy-autocomplete-header'><i class='icon-th-large'></i> in Apps</div>",
1982                    maxNumberOfElements: 30
1983                }
1984            ],
1985            template: {
1986                type: "custom",
1987                method: function (value, item) {
1988                    if (item.isGlobalSearch) {
1989                        return "<a class='easy-autocomplete-item " + item.classes + "' href='" + item.path + "'><i class='" + item.icon + "'></i><span> " + item.type + "<label class='global-name'>" + value + "</label></span></a>";
1990                    } else {
1991                        return "<a class='easy-autocomplete-item' href='" + item.path + "'><i class='" + item.icon + "'></i><span> " + item.type + "<label class='" + item.classes + "'>" + value + "</label></span></a>";
1992                    }
1993                }
1994            },
1995            list: {
1996                match: {
1997                    enabled: true
1998                },
1999                onLoadEvent: function () {
2000                    let tabName = $.cookie('globalSearchTabSelected');
2001                    if (tabName !== undefined) {
2002                        let element = $("div.easy-autocomplete-container a[href*='" + tabName + "']");
2003                        if (element.length) {
2004                            element.parent().parent().css("background-color", "#ccc");
2005                        }
2006                    }
2007                },
2008                showAnimation: {
2009                    type: "slide", //normal|slide|fade
2010                    time: 100,
2011                    callback: function () { }
2012                },
2013                hideAnimation: {
2014                    type: "slide", //normal|slide|fade
2015                    time: 100,
2016                    callback: function () { }
2017                },
2018                maxNumberOfElements: 30,
2019                onChooseEvent: function () {
2020                    $("#siteSearch").val(searchValue);
2021                    var item = $("#siteSearch").getSelectedItemData();
2022                    $.cookie('globalSearchTabSelected', item.tabName, { expires: 365, path: '/' });
2023                    if (item.path === '#') {
2024                        return;
2025                    }
2026                    window.location.replace(item.path);
2027                },
2028                onSelectItemEvent: function () {
2029                    $("#siteSearch").val(searchValue);
2030                }
2031            }
2032
2033        });
2034
2035        $("#siteSearch").on("keyup", function (e) {
2036            searchValue = $("#siteSearch").val();
2037        });
2038    }
2039
2040    var buildResponsiveGrid = function (isResizing) {
2041        var tables = [];
2042        var tablesSelector = $("table.responsive-gridview").not(".table-responsive table.responsive-gridview table.responsive-gridview");
2043
2044        if (tablesSelector.length) {
2045
2046            $(tablesSelector.get().reverse()).each(function (index, el) {
2047
2048                var table = $(this);
2049                var count = 2;
2050                // resizing tab
2051                if (!isResizing) {
2052
2053                    if (!$.fn.dataTable.isDataTable('#' + table.id())) {
2054                        var pagination = table.find("tr.grid-pagination");
2055
2056                        if (pagination.length) {
2057                            table.find("#pagination_table_" + table.id()).remove();
2058                            var tableClosestDiv = table.closest("div");
2059                            var topTablePaginator = "<table class='table table-striped table-bordered table-hover no-space' id='toppagination_table_" + table.id() + "'><tbody></tbody></table>";
2060                            tableClosestDiv.prepend(topTablePaginator);
2061                            var paginatorsDetach = pagination.detach();
2062                            var topPaginator = paginatorsDetach.get(0);
2063                            $("#toppagination_table_" + table.id() + " tbody").append(topPaginator);
2064
2065                            if (pagination.length > 1) {
2066                                var bottomTablePaginator = "<table class='table table-striped table-bordered table-hover no-space' id='bottompagination_table_" + table.id() + "'><tbody></tbody></table>";
2067                                tableClosestDiv.append(bottomTablePaginator);
2068                                var bottomPaginator = paginatorsDetach.get(1);
2069                                $("#bottompagination_table_" + table.id() + " tbody").append(bottomPaginator);
2070                            }
2071
2072                        }
2073
2074                        //add thead
2075                        var thead = table.find(".dataTable-thead_" + table.id());
2076
2077                        if (thead.length) {
2078                            thead.remove();
2079                        }
2080
2081                        table.prepend("<thead class='dataTable-thead_" + table.id() + "'></thead>");
2082                        table.find("> tbody > tr:first-child").prepend("<th></th>").detach().appendTo(".dataTable-thead_" + table.id());
2083
2084                        // add an aditional cell to each row for responsive handler
2085                        table.find("> tbody > tr").each(function () {
2086                            var tr = $(this);
2087                            tr.prepend("<td></td>");
2088                        });
2089
2090                        // it gets the first row in order to get the type of element inside each cell
2091                        var firstRow = $(table.find("tbody").children()[0]).children().get(); //$(table.find("thead.dataTable-thead_" + index).next("tbody").children()[0]).children().get();
2092
2093                        // it gets the number of priority columns
2094                        var numberOfPriorityColumns = 0;
2095
2096                        firstRow.forEach(function (el) {
2097
2098                            if (el.children.length) {
2099                                var node = el.children[0];
2100
2101                                if (node.nodeName === 'INPUT' || node.classList[0] === 'has-switch' || node.classList[0] === 'btn') {
2102                                    numberOfPriorityColumns++;
2103                                }
2104                            }
2105                        });
2106
2107                        // set the priority for each column where the columns with buttons and inputs have hight priority (1)
2108                        var isViewBtnFirst = false;
2109                        table.find("thead tr th").each(function (index) {
2110
2111                            // sortable grids
2112                            if (table.hasClass("ui-sortable") || table.parents("div[class*=sortable]").length) {
2113
2114                                if (index > 2 && firstRow[index]) {
2115
2116                                    if (firstRow[index].children.length) {
2117                                        var node = firstRow[index].children[0];
2118
2119                                        if (node.nodeName === 'INPUT' || node.classList[0] === 'has-switch' || node.classList[0] === 'btn') {
2120                                            $(this).attr("data-priority", ++count);
2121                                            $(this).addClass("all"); // this means that the columns will always be display
2122                                        } else {
2123                                            $(this).attr("data-priority", index + numberOfPriorityColumns);
2124
2125                                            //  this validate if the grid is inside a modal
2126                                            if (table.parents(".dialog-body").length) {
2127                                                $(this).addClass("desktop tablet");  // this means that the columns will only be displayed in desktop and tablet view
2128                                            } else {
2129                                                $(this).addClass("desktop");  // this means that the columns will only be displayed in desktop view
2130                                            }
2131                                        }
2132                                    }
2133                                    else {
2134                                        $(this).attr("data-priority", index + numberOfPriorityColumns);
2135                                        if (table.parents(".dialog-body").length) {
2136                                            $(this).addClass("desktop tablet");  // this means that the columns will only be displayed in desktop and tablet view
2137                                        } else {
2138                                            $(this).addClass("desktop");  // this means that the columns will only be displayed in desktop view
2139                                        }
2140                                    }
2141                                } else if (index === 0 && firstRow[index]) {
2142
2143                                } else if (index === 1 && firstRow[index]) {
2144                                    $(this).attr("data-priority", 1);
2145                                    $(this).addClass("all");
2146                                } else if (index === 2 && firstRow[index]) {
2147                                    $(this).attr("data-priority", 2);
2148                                    $(this).addClass("all");
2149                                }
2150                                // regular grids
2151                            } else {
2152
2153                                if (firstRow[index]) {
2154                                    var node = firstRow[index].children[0];
2155                                    if (node &&
2156                                        (node.nodeName === 'INPUT' || node.classList[0] === 'has-switch' || node.classList[0] === 'btn' || node.classList[0] === 'btn-group')) {
2157
2158                                        $(this).attr("data-priority", count++);
2159                                        $(this).addClass("all");
2160                                        if (index === 1 && (node.classList[0] === 'btn' || node.classList[0] === 'btn-group')) {
2161                                            isViewBtnFirst = true;
2162                                        }
2163                                    }
2164                                    else {
2165                                        if (index === 2 && isViewBtnFirst || index === 1) {
2166                                            $(this).addClass("all");
2167                                        }
2168                                        if (table.parents(".dialog-body").length) {
2169                                            $(this).addClass("desktop tablet");  // this means that the columns will only be displayed in desktop and tablet view
2170                                        } else {
2171                                            $(this).addClass("desktop");  // this means that the columns will only be displayed in desktop view
2172                                        }
2173                                        $(this).attr("data-priority", index + numberOfPriorityColumns);
2174                                    }
2175                                }
2176                            }
2177                        });
2178                    } else {
2179                        table.DataTable().destroy();
2180                    }
2181                } else {
2182                    setTimeout(function () {
2183                        $("#toppagination_table_" + table.id()).width((table.width() - 1) + "px");
2184                        $("#bottompagination_table_" + table.id()).width((table.width() - 1) + "px")
2185                    }, 100);
2186                }
2187                tables.push(table);
2188            });
2189
2190            function hideEmptyHeaderColumns(table) {
2191
2192                if (!table.DataTable().data().any()) {
2193                    table.find("thead tr th.sorting_disabled.control").hide();
2194                    var checkBoxThead = table.find("thead tr th.sorting_disabled");
2195                    checkBoxThead.each(function (index, value) {
2196                        if (value.children && !value.children.length && !value.innerText) {
2197                            $(value).hide();
2198                        }
2199                    });
2200                }
2201            }
2202            if (isResizing) {
2203                tables.reverse().forEach(function (table) {
2204                    hideEmptyHeaderColumns(table);
2205                });
2206                return;
2207            }
2208
2209            // the settimeout
2210            tables.reverse().forEach(function (table) {
2211
2212                setTimeout(function () {
2213
2214                    table.DataTable({
2215                        destroy: true,
2216                        paging: false,
2217                        searching: false,
2218                        info: false,
2219                        sort: false,
2220                        autoWidth: false,
2221                        language: {
2222                            emptyTable: "There are no items to display."
2223                        },
2224                        responsive: {
2225                            details: {
2226                                type: 'column'
2227                            },
2228                            //breakpoints: [
2229                            //  { name: 'desktop', width: Infinity },
2230                            //  { name: 'tablet-l', width: 1024 },
2231                            //  { name: 'tablet-p', width: 768 },
2232                            //  { name: 'mobile-l', width: 615 },
2233                            //  { name: 'mobile-p', width: 320 }
2234                            //]
2235                        },
2236                        columnDefs: [{
2237                            className: 'control',
2238                            orderable: false,
2239                            targets: 0
2240                        }],
2241                        order: [1, 'asc']
2242                    });
2243                    // reinitialize some functionalities
2244                    table.on('responsive-display.dt', function (e, datatable, row, showHide, update) {
2245                        jQuery('.popovers').popover({ html: true });
2246
2247                        var switchControl = $(row.child()).find(".make-switch2");
2248
2249                        if (switchControl.length) {
2250                            switchControl.bootstrapSwitch('destroy');
2251                            switchControl.bootstrapSwitch();
2252                        }
2253                    });
2254
2255                    table.find("thead tr th").css("border", "1px solid #ddd");
2256                    table.find("span.grid-count").addClass("grid-count-datatable");
2257                    $("#toppagination_table_" + table.id()).width((table.width() - 1) + "px");
2258                    $("#bottompagination_table_" + table.id()).width((table.width() - 1) + "px");
2259                    hideEmptyHeaderColumns(table);
2260                });
2261            });
2262        }
2263    }
2264
2265    var handleSortableGrids = function () {
2266        $('table[data-action="sortable"]').each(function () {
2267            var hiddenRowFields,
2268                responsiveTable = $(".responsive-gridview"),
2269                isResponsive = responsiveTable.length ? true : false,
2270                table = isResponsive ? responsiveTable : $(".table-sortable .table");
2271
2272            var hiddenRowFields;
2273            var table = $(this),
2274                isResponsive = table.hasClass("responsive-gridview");
2275            var id = $(this).attr('id');
2276            var url = $(this).attr('data-url');
2277            var postbackId = $(this).attr('data-postback-id');
2278            table.sortable({
2279                items: isResponsive ? 'tbody > tr:not(tr.grid-pagination)' : 'tr:not(tr:first-child)',
2280                // items: 'tr:not(tr:first-child)',
2281                cursor: 'move',
2282                handle: '.cursor-move',
2283                placeholder: 'field-place-holder',
2284                forceHelperSize: true,
2285                revert: true,
2286                helper: function (e, tr) {
2287                    var $originals = tr.children();
2288                    var $helper = tr.clone();
2289                    $helper.children().each(function (index) {
2290                        $(this).width($originals.eq(index).width());
2291                    });
2292                    return $helper;
2293                },
2294                axis: 'y',
2295                update: function (event, ui) {
2296                    var arr = table.sortable('toArray');
2297
2298                    arr = arr.filter(function (item) {
2299                        if (item) {
2300                            return item;
2301                        }
2302                    });
2303
2304                    for (var i = 0; i < arr.length; i++) {
2305                        var str = arr[i];
2306                        var strIndex = str.indexOf(id + "_") + id.length + 1;
2307                        var strId = str.substring(strIndex, str.length);
2308                        arr[i] = strId;
2309                    }
2310                    if (url != null) {
2311                        page.ajax({
2312                            url: url,
2313                            parameters: {
2314                                'positionGuids': arr
2315                            }
2316                        });
2317                    }
2318                    else if (postbackId != null) {
2319                        page.postback(postbackId, arr.join('|'));
2320                    }
2321                },
2322                start: function (event, ui) {
2323                    if (isResponsive) {
2324                        hiddenRowFields = $(ui.item[0]).next(".ui-sortable-placeholder").next("tr.child");
2325                    }
2326                },
2327                stop: function (event, ui) {
2328
2329                    if (isResponsive && hiddenRowFields.length) {
2330                        var child = $(ui.item[0]).next('tr.child');
2331
2332                        if (child.length) {
2333                            $($(ui.item[0])).detach().insertAfter(child);
2334                        }
2335
2336                        $(hiddenRowFields.detach()).insertAfter($(ui.item[0]));
2337                    }
2338                }
2339            }).css('-ms-touch-action', 'none');
2340        });
2341    };
2342
2343    var subscriptionQueriesEllipsis = function () {
2344        $(".ellipsis-content").each(function (index) {
2345            var htmlContent = $(this).find('.hidden-content').text() || $(this).text();
2346            var queries = $(this).text().split(',');
2347            var ellipsisText = '';
2348
2349            if (queries.length > 5) {
2350                queries.forEach(function (query, index) {
2351                    if (index < 5) {
2352                        if (index === 4) {
2353                            ellipsisText += query + '... ';
2354                        } else {
2355                            ellipsisText += query + ', ';
2356                        }
2357                    }
2358                });
2359
2360                $(this).empty();
2361                $(this).append('<p>' + ellipsisText + '</p>');
2362                $(this).append('<a class="ellipsis-toggle-button" id="show-more-button-' + index + '">Show more</a>');
2363                $(this).append('<p class="display-none">' + htmlContent + '</p>');
2364                $(this).append('<a class="display-none ellipsis-toggle-button" id="show-less-button-' + index + '">Show less</a>');
2365            }
2366        });
2367
2368        $(".ellipsis-content").first().parents("tbody").on('click', function (e) {
2369            var type = e.target.id.split('-')[1];
2370
2371            if (e.target && e.target.id.split('-')[1] === 'more') {
2372                toggleEllipsis(e.target, false);
2373            }
2374            else if (e.target && e.target.id.split('-')[1] === 'less') {
2375                toggleEllipsis(e.target, true);
2376            }
2377        });
2378    }
2379
2380    var toggleEllipsis = function (element, allowEllipsis) {
2381
2382        if (allowEllipsis) {
2383            $(element).addClass('display-none').prev().addClass('display-none');
2384            $(element).prev().prev().removeClass('display-none').prev().removeClass('display-none');
2385        } else {
2386            $(element).next('p').removeClass('display-none').next('.ellipsis-toggle-button').removeClass('display-none');
2387            $(element).addClass('display-none').prev().addClass('display-none');
2388        }
2389    }
2390
2391    var handleDropDownPlaceholders = function () {
2392        $('select').each(function () {
2393            var placeholder = $(this).attr('data-placeholder');
2394            if (placeholder != '') {
2395                if (placeholder == '�') {
2396                    placeholder = '';
2397                }
2398                if (this.value == placeholder) {
2399                    $(this).removeClass('normal-color').addClass('disabled-color');
2400                }
2401                else {
2402                    $(this).removeClass('disabled-color').addClass('normal-color');
2403                }
2404            }
2405        });
2406    };
2407
2408    var handleResponsiveContainers = function () {
2409        var makeResponsive = function () {
2410            $('ul.responsive-container').each(function () {
2411                var items = $(this).find('li').length;
2412                if (items > 12) {
2413                    var width = $(this).parent().width();
2414                    var cssClass = '';
2415                    if (width <= 384) cssClass = 'xs';
2416                    else if (width > 384 && width <= 576) cssClass = 'sm';
2417                    else if (width > 576 && width <= 768) cssClass = 'md';
2418                    else if (width > 768 && width <= 960) cssClass = 'lg';
2419                    else if (width > 960) cssClass = 'xl';
2420                    $(this).removeClass('xs').removeClass('sm').removeClass('md').removeClass('lg').removeClass('xl');
2421                    if (cssClass !== '') $(this).addClass(cssClass);
2422                }
2423            });
2424        };
2425        makeResponsive();
2426        if (page != null) {
2427            page.resize(function () {
2428                makeResponsive();
2429            });
2430        }
2431    };
2432
2433    var handleResponsiveCheckBoxLists = function () {
2434        $('.responsive-checkbox-list select').each(function () {
2435            var self = $(this).hide();
2436            var container = $('<ul class="responsive-container row"></ul>').insertBefore(self);
2437            var disabled = '';
2438            if (self.prop('disabled')) {
2439                disabled = ' disabled="disabled"';
2440            }
2441            var options = self.find('option');
2442            for (var i = 0; i < options.length; i++) {
2443                var column = $('<li></li>').appendTo(container);
2444                var option = $(options[i]);
2445                var checked = '';
2446                if (option.prop('selected')) {
2447                    checked = ' checked="checked"';
2448                }
2449                column.append($('<div><label><input type="checkbox"' + checked + disabled + ' data-value="' + option.attr('value') + '"/> ' + option.html() + '</label></div>'));
2450            }
2451        });
2452        $('.responsive-checkbox-list input[type="checkbox"]').uniform().on('click', function () {
2453            var value = $(this).attr('data-value');
2454            var option = $(this).parents('.responsive-checkbox-list').find('select').find('option[value="' + value + '"]');
2455            option.prop('selected', $(this).prop('checked'));
2456        });
2457    };
2458
2459    var handleResponsiveRadioButtonLists = function () {
2460        $('.responsive-radiobutton-list select').each(function () {
2461            var self = $(this).hide();
2462            var container = $('<ul class="responsive-container row"></ul>').insertBefore(self);
2463            var groupName = $(this).parents('.responsive-radiobutton-list').attr('id') + '_radiobuttons';
2464            var disabled = '';
2465            if (self.prop('disabled')) {
2466                disabled = ' disabled="disabled"';
2467            }
2468            var options = self.find('option');
2469            for (var i = 0; i < options.length; i++) {
2470                var column = $('<li></li>').appendTo(container);
2471                var option = $(options[i]);
2472                var checked = '';
2473                if (option.prop('selected')) {
2474                    checked = ' checked="checked"';
2475                }
2476                column.append($('<div><label><input type="radio" name="' + groupName + '" value="' + option.attr('value') + '"' + checked + disabled + '/> ' + option.html() + '</label></div>'));
2477            }
2478        });
2479        $('.responsive-radiobutton-list input[type="radio"]').uniform().on('click', function () {
2480            var value = $(this).attr('value');
2481            var option = $(this).parents('.responsive-radiobutton-list').find('select').find('option[value="' + value + '"]');
2482            option.prop('selected', $(this).prop('checked'));
2483        });
2484    };
2485
2486    return {
2487        init: function () {
2488            handleBootstrapMaxlength();
2489            handleSpinners();
2490            handleWysihtml5();
2491            handleSignature();
2492            handleDatePickers();
2493            handleTimePickers();
2494            handleSwitch();
2495            handleAceCodeEditor();
2496            handleLookupControls();
2497            handleSelect2Dropdown();
2498            handleSelect2DropdownMultiLine();
2499            handleTagInputControls();
2500            handleMultiSelectControls();
2501            handleCurrencyDropdown();
2502            handleToggleButtons();
2503            handleResponsiveCheckBoxLists();
2504            handleResponsiveRadioButtonLists();
2505            handleResponsiveContainers();
2506            handleSortableGrids();
2507            buildResponsiveGrid(false);
2508            handleDropDownPlaceholders();
2509            buildSideBarMenuAutocomplete();
2510            subscriptionQueriesEllipsis();
2511        },
2512        initResponsiveGrids: function (isResizing) {
2513            isResizing = isResizing || true;
2514            buildResponsiveGrid(isResizing);
2515        }
2516    };
2517}();;
2518String.prototype.trimStart = function (charList) {
2519    if (charList === undefined) { charList = '\s'; }
2520    return this.replace(new RegExp('^[' + charList + ']+'), '');
2521};
2522String.prototype.trimEnd = function (charList) {
2523    if (charList === undefined) { charList = '\s'; }
2524    return this.replace(new RegExp('[' + charList + ']+$'), '');
2525};
2526String.prototype.trim = function (charList) {
2527    return this.trimStart(charList).trimEnd(charList);
2528};
2529String.prototype.startsWith = function (input) {
2530    return (this.indexOf(input) === 0);
2531};
2532String.prototype.endsWith = function (input) {
2533    return (this.indexOf(input) === this.length - input.length);
2534};
2535
2536
2537if (!Array.prototype.indexOf) {
2538    Array.prototype.indexOf = function (item) {
2539        if (item && this.length > 0) {
2540            for (var i = 0; i < this.length; i++) {
2541                if (this[i] == item) {
2542                    return i;
2543                }
2544            }
2545        }
2546        return -1;
2547    }
2548}
2549
2550if (!Array.prototype.forEach) {
2551    Array.prototype.forEach = function (func) {
2552        if (func && typeof (func) === 'function' && this.length > 0) {
2553            for (var i = 0; i < this.length; i++) {
2554                func.call(this, this[i], i);
2555            }
2556        }
2557        return;
2558    };
2559}
2560
2561if (!Array.prototype.isArray) {
2562    Array.prototype.isArray = function (arg) {
2563        return Object.prototype.toString.call(arg) === '[object Array]';
2564    };
2565}
2566
2567Object.defineProperties(Array.prototype, {
2568    add: {
2569        value: function (item) {
2570            this[this.length] = item;
2571        }
2572    },
2573    remove: {
2574        value: function (item) {
2575            var index = -1;
2576            if (item && this.length > 0) {
2577                for (var i = 0; i < this.length; i++) {
2578                    if (this[i] == item) {
2579                        index = i;
2580                        break;
2581                    }
2582                }
2583            }
2584            if (index != -1) {
2585                this.splice(index, 1);
2586            }
2587        },
2588        writable: true
2589    },
2590    contains: {
2591        value: function (item) {
2592            if (item && this.length > 0) {
2593                for (var i = 0; i < this.length; i++) {
2594                    if (this[i] == item) {
2595                        return true;
2596                    }
2597                }
2598            }
2599            return false;
2600        }
2601    },
2602    firstOrDefault: {
2603        value: function (func) {
2604            if (this.length > 0) {
2605                if (func && typeof (func) === 'function') {
2606                    for (var i = 0; i < this.length; i++) {
2607                        if (func.call(this, this[i])) {
2608                            return this[i];
2609                        }
2610                    }
2611                }
2612                else if (typeof (func) === 'undefined') {
2613                    return this[0];
2614                }
2615            }
2616            return null;
2617        }
2618    },
2619    lastOrDefault: {
2620        value: function (func) {
2621            if (this.length > 0) {
2622                if (func && typeof (func) === 'function') {
2623                    for (var i = this.length - 1; i >= 0; i--) {
2624                        if (func.call(this, this[i])) {
2625                            return this[i];
2626                        }
2627                    }
2628                }
2629                else if (typeof (func) === 'undefined') {
2630                    return this[this.length - 1];
2631                }
2632            }
2633            return null;
2634        }
2635    },
2636    any: {
2637        value: function (func) {
2638            var result = false;
2639            if (func && typeof (func) === 'function' && this.length > 0) {
2640                for (var i = 0; i < this.length; i++) {
2641                    if (func.call(this, this[i]) == true) {
2642                        result = true;
2643                        break;
2644                    }
2645                }
2646            }
2647            return result;
2648        }
2649    },
2650    all: {
2651        value: function (func) {
2652            var result = true;
2653            if (func && typeof (func) === 'function' && this.length > 0) {
2654                for (var i = 0; i < this.length; i++) {
2655                    if (func.call(this, this[i]) == false) {
2656                        result = false;
2657                        break;
2658                    }
2659                }
2660            }
2661            return result;
2662        }
2663    },
2664    sum: {
2665        value: function (func) {
2666            var result = 0;
2667            if (func && typeof (func) === 'function' && this.length > 0) {
2668                for (var i = 0; i < this.length; i++) {
2669                    var value = func.call(this, this[i]);
2670                    if (!isNaN(value)) {
2671                        result += value;
2672                    }
2673                }
2674            }
2675            return result;
2676        }
2677    },
2678    where: {
2679        value: function (func) {
2680            var results = [];
2681            if (func && typeof (func) === 'function' && this.length > 0) {
2682                for (var i = 0; i < this.length; i++) {
2683                    if (func.call(this, this[i])) {
2684                        results[results.length] = this[i];
2685                    }
2686                }
2687            }
2688            return results;
2689        }
2690    },
2691    select: {
2692        value: function (func) {
2693            var results = [];
2694            if (func && typeof (func) === 'function' && this.length > 0) {
2695                for (var i = 0; i < this.length; i++) {
2696                    results[results.length] = func.call(this, this[i]);
2697                }
2698            }
2699            return results;
2700        },
2701        writable: true
2702    },
2703    orderBy: {
2704        value: function (func) {
2705            var results = [].concat(this);
2706            if (func && typeof (func) === "function" && results.length > 0) {
2707                // Just do a bubble sort
2708                var len = results.length;
2709                for (var i = 0; i < len; i++) {
2710                    for (var j = i + 1; j < len; j++) {
2711                        if (func.call(this, results[i]) > func.call(this, results[j])) {
2712                            var temp = results[i];
2713                            results[i] = results[j];
2714                            results[j] = temp;
2715                        }
2716                    }
2717                }
2718            }
2719            return results;
2720        }
2721    },
2722    orderByDescending: {
2723        value: function (func) {
2724            var results = [].concat(this);
2725            if (func && typeof (func) === "function" && results.length > 0) {
2726                // Just do a bubble sort
2727                var len = results.length;
2728                for (var i = 0; i < len; i++) {
2729                    for (var j = i + 1; j < len; j++) {
2730                        if (func.call(this, results[i]) < func.call(this, results[j])) {
2731                            var temp = results[i];
2732                            results[i] = results[j];
2733                            results[j] = temp;
2734                        }
2735                    }
2736                }
2737            }
2738            return results;
2739        }
2740    },
2741    distinctBy: {
2742        value: function (func) {
2743            var results = [];
2744            if (func && typeof (func) === 'function' && this.length > 0) {
2745                for (var i = 0; i < this.length; i++) {
2746                    var exists = false;
2747                    if (results.length > 0) {
2748                        var sourceValue = func.call(this, this[i]);
2749                        for (var j = 0; j < results.length; j++) {
2750                            var targetValue = func.call(this, results[j]);
2751                            if (sourceValue == targetValue) {
2752                                exists = true;
2753                                break;
2754                            }
2755                        }
2756                    }
2757                    if (!exists) {
2758                        results[results.length] = this[i];
2759                    }
2760                }
2761            }
2762            return results;
2763        }
2764    }
2765})
2766
2767Math.newGuid = function () {
2768    var dash = '-';
2769    var generatePart = function () {
2770        var guidPartNumber = (Math.random() * 0x10000) | 0;
2771        return (guidPartNumber + 0x10000).toString(16).substring(1).toUpperCase();
2772    };
2773    return generatePart() + generatePart() + dash + generatePart() + dash + generatePart() + dash + generatePart() + dash + generatePart() + generatePart() + generatePart();
2774};
2775Math.decimalRound = function (value, decimals) {
2776    return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);
2777};
2778
2779(function ($) {
2780    // Extendng jQuery with the following helpers
2781    $.fn.extend({
2782        id: function (value) {
2783            if (value) {
2784                return $(this).attr('id', value);
2785            }
2786            else {
2787                return $(this).attr('id');
2788            }
2789        },
2790        loaded: function (func) {
2791            //$(this).one("load", func).each(function () {
2792            //    if (this.complete) func.call(this);
2793            //});
2794            $(this).each(function () {
2795                this.addEventListener("load", func, true);
2796            });
2797            return $(this);
2798        },
2799        showProgress: function () {
2800            if ($(this).data('has-progress') != '1') {
2801                return $(this).data('has-progress', '1')
2802                    .append($('<div></div>').addClass('progress-background'))
2803                    .append($('<div></div>').addClass('progress-foreground')
2804                        .append($('<table></table>').append($('<tr></tr>').append($('<td></td>').attr({ 'align': 'center', 'valign': 'middle' })
2805                            .append($('<div></div>').addClass('progress-container')
2806                                .append($('<table></table>').append($('<tr></tr>').append($('<td></td>').attr({ 'align': 'center', 'valign': 'middle' })
2807                                    .append($('<i></i>').addClass('progress-icon icon-refresh icon-spin white')))
2808                                    .append($('<td></td>').attr({ 'align': 'center', 'valign': 'middle' })
2809                                        .append($('<span></span>').addClass('progress-text').text('Please wait ...'))))))))));
2810            }
2811            else {
2812                return $(this);
2813            }
2814        },
2815        hideProgress: function () {
2816            if ($(this).data('has-progress') == '1') {
2817                $(this).data('has-progress', '0');
2818                $(this).children('.progress-background').remove();
2819                $(this).children('.progress-foreground').remove();
2820            }
2821            return $(this);
2822        },
2823        resize: function (maxWidth, maxHeight) {
2824            $(this).each(function () {
2825                if ($(this).data('is-resized') != '1') {
2826                    var actualWidth = $(this).width();
2827                    var actualHeight = $(this).height();
2828                    var size = page.resizeByAspectRatio(actualWidth, actualHeight, maxWidth, maxHeight);
2829                    $(this).css({ 'width': size.width + 'px', 'height': size.height + 'px' });
2830                    $(this).data('is-resized', '1');
2831                }
2832            });
2833            return $(this);
2834        },
2835        getAbsoluteUrl: function (url) {
2836            if (url == null || url == '') { url = '~/'; }
2837            if (window.location.appPath == null) { window.location.appPath == ''; }
2838            return window.location.protocol + "//" + window.location.hostname + url.replace(/^~/, window.location.appPath);
2839        },
2840        preventDoubleClick: function () {
2841            $(this).each(function () {
2842                if (!$(this).data('dbl-click-prevented')) {
2843                    $(this).on('click', function (e) {
2844                        var self = $(this);
2845                        if (self.data('dbl-clicked')) {
2846                            e.preventDefault();
2847                            e.stopPropagation();
2848                        }
2849                        else {
2850                            self.data('dbl-clicked', true);
2851                            var dblTimer = window.setTimeout(function () {
2852                                self.removeData('dbl-clicked');
2853                                window.clearTimeout(dblTimer);
2854                            }, 1000);
2855                        }
2856                    });
2857                    $(this).data('dbl-click-prevented', true);
2858                }
2859            });
2860            return $(this);
2861        },
2862        setChecked: function (checked) {
2863            $(this).each(function () {
2864                var checkbox = $(this);
2865                checkbox.prop('checked', checked);
2866                if (checked) {
2867                    checkbox.parent().addClass('checked');
2868                }
2869                else {
2870                    checkbox.parent().removeClass('checked');
2871                }
2872            });
2873            return $(this);
2874        }
2875    });
2876})(jQuery);;
2877var page = {
2878    _loadArray: [],
2879    _resizeArray: [],
2880    _scrollArray: [],
2881    _progressTimer: null,
2882    _lookupTimer: null,
2883    _feedback: null,
2884    _isSessionTimedOut: false,
2885    _currentSessionTimer: null,
2886    _delayPostbackTimer: null,
2887    _isLocationChanging: false,
2888    _queryString: {},
2889    _customArray: {},
2890    _showProgress: function (noCloseButton) {
2891        var isInvisible = $('#main_prgContent').css('display') === 'none';
2892        $('#main_prgContent > .progress-background').css('opacity', isInvisible ? .25 : .75);
2893        $('#main_prgContent').css('display', 'block');
2894        if (isInvisible) {
2895            $('#main_prgContent > .progress-background').animate({ opacity: .75 }, 1000);
2896        }
2897        if (noCloseButton) {
2898            $('#main_prgContent .progress-cancel').css('display', 'none');
2899        }
2900    },
2901    _hackEventWithinDoPostBack: function () {
2902        var originalEventDescriptor = Object.getOwnPropertyDescriptor(Window.prototype, "event");
2903        var hackEventVariable = false;
2904        var eventPropertyHolder;
2905        Object.defineProperty(window, "event", {
2906            configurable: true,
2907            get: function get() {
2908                var result = originalEventDescriptor ? originalEventDescriptor.get.apply(this, arguments) : eventPropertyHolder;
2909                if (result || !hackEventVariable)
2910                    return result;
2911                return {};
2912            },
2913            set: function set(value) {
2914                if (originalEventDescriptor)
2915                    originalEventDescriptor.set.apply(this, arguments);
2916                else
2917                    eventPropertyHolder = value;
2918            }
2919        });
2920        var originalDoPostBack = window.__doPostBack;
2921        window.__doPostBack = function hackedDoPostBack() {
2922            hackEventVariable = true;
2923            originalDoPostBack.apply(this, arguments);
2924            hackEventVariable = false;
2925        };
2926    },
2927    _setTopAndFocus: function (newRow) {
2928        var defaultRowBg = "bg-color-default";
2929        parentBody = newRow.parentElement;
2930        $(newRow).insertAfter(parentBody.firstChild);
2931        $(newRow).addClass(defaultRowBg);
2932        $(newRow).find("td").filter(":visible:first").find("tr input[type='text']").filter(":visible:first").focus();
2933    },
2934    isPostBack: function () {
2935        return $('#main_isPostBack').val() == '1';
2936    },
2937    isFirstTime: function () {
2938        return $('#main_isFirstTime').val() == '';
2939    },
2940    isInDialogMode: function () {
2941        var isDialog = page.queryString('dialog');
2942        return isDialog != null && (isDialog.toLowerCase() == 'yes' || isDialog.toLowerCase() == 'true' || isDialog == '1');
2943    },
2944    isCmsPage: function () {
2945        return $('body').hasClass('public-body');
2946    },
2947    getValue: function (name) {
2948        return page._customArray[name];
2949    },
2950    setValue: function (name, value) {
2951        page._customArray[name] = value;
2952    },
2953    init: function () {
2954        try {
2955            if (Sys != null && Sys.WebForms != null && Sys.WebForms.PageRequestManager != null) {
2956                var prm = Sys.WebForms.PageRequestManager.getInstance();
2957                if (prm != null) {
2958                    //prm.add_initializeRequest(function () {
2959                    //    page.handleBeforeSubmitEvents();
2960                    //});
2961                    prm.add_beginRequest(function () {
2962                        page.showProgress();
2963                    });
2964                    prm.add_endRequest(function (sender, e) {
2965                        page.hideProgress();
2966                        //if (sender._postBackSettings.panelsToUpdate != null) {
2967                        var ex = e.get_error();
2968                        if (ex != null) {
2969                            //ex = { name, message, description, httpStatusCode };
2970                            var message = ex.message.replace('Sys.WebForms.PageRequestManagerServerErrorException:', '') + (ex.description != null ? '<br/>' + ex.description : '');
2971                            page.displayError('Something went wrong!', message);
2972                            e.set_errorHandled(true);
2973                        }
2974                        //}
2975                    });
2976                }
2977            }
2978        }
2979        catch (x) { }
2980        page._hackEventWithinDoPostBack();
2981        if ($('#__READONLY').val() == '1') {
2982            $('.form-content').find('input:not([type="hidden"]):not([type="submit"]):not([type="button"]):not(.custom-field):not(.custom-field input[type="radio"]):not(.custom-field input[type="checkbox"]):not(.ignore-security), select:not(.grid-page-size-select):not(.custom-field), textarea:not(.custom-field), input[type="hidden"].data-lookup').each(function () {
2983                $(this).prop('disabled', true);
2984                $(this).parent().find('.input-group-btn .btn').removeClass('blue').removeClass('green').removeClass('red').removeClass('yellow').removeClass('purple').removeClass('dark').addClass('default').css('cursor', 'not-allowed').prop('disabled', true);
2985                $(this).parent().removeClass('date').removeClass('date-picker').removeClass('wysihtml5').removeClass('code-editor');
2986            });
2987            //the upload user image button on oveview
2988            $('.form-content').find('.profile-action-button, .profile-button').each(function () {
2989                $(this).css("pointer-events", "none");
2990                $(this).parent().css("cursor", "not-allowed")
2991            });
2992            //for all multiselect
2993            $('.form-content').find('div.multi-select *').each(function () {
2994                $(this).css("pointer-events", "none");
2995                $(this).parent().css("cursor", "not-allowed");
2996            });
2997            //for all save and delete buttons - filtered input type submit & value Save or delete
2998            $('.form-content').find('input[type="submit"][value="Save"], input[type="submit"][value="Delete"]').each(function () {
2999                $(this).prop('disabled', true);
3000                $(this).parent().css("cursor", "not-allowed")
3001            });
3002        }
3003        $('.form-content').find('#main_content_mer_ctlProductInfo_chkRestrictedAccess').click(function () {
3004            debugger;
3005            if ($('input[id="main_content_mer_ctlProductInfo_chkRestrictedAccess"]').is(":checked")) {
3006                $("a:contains('Related Products')").parent().hide();
3007            }
3008            else {
3009                $("a:contains('Related Products')").parent().show();
3010            }
3011        });
3012
3013        //This code enable Quick filter with view access
3014        if ($('#__READONLY').val() == '1') {
3015            $('.form-content').find('.quick-filter-txt , .div-quick-filter').each(function () {
3016                $(this).prop('disabled', false);
3017                $(this).parent().find('.btn-quick-filter').removeClass('default').addClass('blue').css("cursor", "").prop('disabled', false);
3018            });
3019            $('.table-toolbar').find('.query-list-chkShowMine').each(function () {
3020                $(this).removeClass('disabled').prop('disabled', false);
3021                $(this).children().last().prop('disabled', false);
3022            });
3023        }
3024
3025        var e, // This code populates the queryString array with values from the URL
3026            a = /[\+]/g, // /[\+\-]/g,  // Regex for replacing addition (and subtraction) symbols with a space
3027            r = /([^&=]+)=?([^&]*)/g,
3028            d = function (s) { try { return (decodeURIComponent(s.replace(a, ' '))); } catch (x) { return ''; } },
3029            q = window.location.search.substring(1);
3030        while (e = r.exec(q)) {
3031            page._queryString[d(e[1]).toLowerCase()] = d(e[2]);
3032        };
3033        var regEx = /(\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*)/g;
3034        $('.grid-container td, .grid-container td span, .grid-container td label').filter(function () {
3035            if (this.innerHTML != this.innerText) return false;
3036            return this.innerHTML.match(regEx);
3037        }).html(function (index, old) {
3038            if (!(old.indexOf('mailto:') > -1))
3039                return old.replace(regEx, '<a href="mailto:$1">$1</a>');
3040        });
3041        if ($('#MailToIframe').length == 0) {
3042            $('<iframe></iframe>').attr({ 'id': 'MailToIframe', 'name': 'MailToIframe' }).css({ 'display': 'none', 'position': 'absolute', 'top': '-100px', 'left': '-100px', 'width': '0', 'height': '0' }).appendTo($('body'));
3043        }
3044        $('a[href^=mailto], a[href^=tel]').attr('target', 'MailToIframe');
3045        $('.btn').preventDoubleClick();
3046        if (page.isInDialogMode()) {
3047            $('.progress-cancel').css('display', 'none');
3048        }
3049        var url = $('#main_browserNavigationUrl').val();
3050        if (url != null && url != '') {
3051            $('#main_browserNavigationUrl').val('');
3052            $('#main_browserNavigationWarning').val('');
3053            page.navigate(url);
3054            return true;
3055        }
3056        return false;
3057    },
3058    load: function (handler) {
3059        if (handler && typeof (handler) == 'function') {
3060            page._loadArray[page._loadArray.length] = handler;
3061        }
3062    },
3063    resize: function (handler) {
3064        if (handler && typeof (handler) == 'function') {
3065            page._resizeArray[page._resizeArray.length] = handler;
3066        }
3067    },
3068    scroll: function (handler) {
3069        if (handler && typeof (handler) == 'function') {
3070            page._scrollArray[page._scrollArray.length] = handler;
3071        }
3072    },
3073    navigate: function (url) {
3074        if (url == null || url == '') { url = '~/'; }
3075        if (window.location.appPath == null) { window.location.appPath == ''; }
3076        //When hash is present, just reload the page
3077        var hash = url.split('#')[1];
3078        if (hash) {
3079            window.location.reload();
3080        } else {
3081            window.location.href = url.replace(/^~/, window.location.appPath);
3082        }
3083    },
3084    navigateParent: function (url) {
3085        if (window.frameElement && window.parent != null) {
3086            window.parent.page.navigate(url);
3087        }
3088        else {
3089            page.navigate(url);
3090        }
3091    },
3092    showProgress: function (immediately, noCloseButton) {
3093        if (window.frameElement && $(window.frameElement).parents('.modal
3093-body').length === 0 && window.parent != null && window.parent.page && window.parent.page.showProgress) {
3094            // This is an inline iframe, we should show progress on the parent instead
3095            page.disableProgress();
3096            window.parent.page.showProgress(immediately, noCloseButton);
3097        }
3098        else {
3099            if (immediately && immediately === true) {
3100                page._showProgress(noCloseButton);
3101            }
3102            else if (page._progressTimer == null) {
3103                page._progressTimer = window.setTimeout(function () {
3104                    page._showProgress(noCloseButton);
3105                    window.clearTimeout(page._progressTimer);
3106                    page._progressTimer = null;
3107                }, 1000);
3108            }
3109        }
3110    },
3111    hideProgress: function (delayMilliSeconds) {
3112        if (window.frameElement && $(window.frameElement).parents('.modal-body').length === 0 && window.parent != null && window.parent.page && window.parent.page.showProgress) {
3113            // This is an inline iframe, we should show progress on the parent instead
3114            window.parent.page.hideProgress();
3115            page.enableProgress();
3116        }
3117        else {
3118            if (page._progressTimer != null) {
3119                window.clearTimeout(page._progressTimer);
3120                page._progressTimer = null;
3121            }
3122            if (delayMilliSeconds != null && !isNaN(delayMilliSeconds)) {
3123                var pTimer = null;
3124                pTimer = window.setTimeout(function () {
3125                    window.clearTimeout(pTimer);
3126                    pTimer = null;
3127                    $('#main_prgContent').css('display', 'none');
3128                }, delayMilliSeconds);
3129            }
3130            else {
3131                $('#main_prgContent').css('display', 'none');
3132            }
3133        }
3134    },
3135    enableProgress: function () {
3136        $('#main_prgContent').css({ 'visibility': 'visible', 'width': '100% !important', 'height': '1000% !important' });
3137    },
3138    disableProgress: function () {
3139        $('#main_prgContent').css({ 'visibility': 'hidden', 'width': '0 !important', 'height': '0 !important' });
3140    },
3141    abortProgress: function () {
3142        dialog.messageBox({
3143            title: 'Abort/Hide Progress',
3144            icon: 'Warning',
3145            message: 'We apologize, it seems something is taking longer than expected and you have chosen to abort the process or hide the progress wheel.' +
3146                '<br/><br/>Please note that once a process starts, it might still continue running behind the scenes for some time even if we try to abort it.' +
3147                '<br/><br/>Click on the Abort buttons to abort the current process, or click on the Wait button to continue waiting for the process to finish.',
3148            buttons: 'Abort & Refresh,Abort & Go to Home Page,Hide Progress,Wait',
3149            callback: function (args) {
3150                if (args.startsWith('hide')) {
3151                    page.hideProgress();
3152                }
3153                else if (args.startsWith('abort')) {
3154                    if (page._isLocationChanging) {
3155                        if (page.isIE()) {
3156                            try {
3157                                document.execCommand("Stop");
3158                            }
3159                            catch (x) { }
3160                        }
3161                        else {
3162                            try {
3163                                window.stop();
3164                            }
3165                            catch (ex) { }
3166                        }
3167                        page._isLocationChanging = false;
3168                    }
3169                    else if (Sys && Sys.WebForms && Sys.WebForms.PageRequestManager) {
3170                        var prm = Sys.WebForms.PageRequestManager.getInstance();
3171                        if (prm.get_isInAsyncPostBack()) {
3172                            prm.abortPostBack();
3173                        }
3174                    }
3175                    page.hideProgress();
3176                    //$(window).unbind('beforeunload');
3177                    //$(window).unbind('unload');
3178                    $('#main_browserNavigationWarning').val('');
3179                    if (args.endsWith('refresh')) {
3180                        page.refresh(true);
3181                    }
3182                    else {
3183                        page.navigate('~/');
3184                    }
3185                }
3186            }
3187        });
3188    },
3189    showTooltip: function (title, content, x, y) {
3190        var tooltip = $('<div></div>').addClass('page-tooltip');
3191        tooltip.append($('<div></div>').addClass('page-tooltip-title'));
3192        tooltip.append($('<div></div>').addClass('page-tooltip-content'));
3193        if ($('.page-tooltip').length == 0) {
3194            tooltip.css({
3195                position: 'absolute',
3196            }).appendTo('body');
3197            tooltip.fadeIn(200);
3198        }
3199        else {
3200            $('.page-tooltip').css({
3201                display: 'block'
3202            });
3203        }
3204
3205        var windowHeight = $(window).height();
3206        var windowWidth = $(window).width();
3207
3208        $('.page-tooltip').find('.page-tooltip-title').html(title);
3209        $('.page-tooltip').find('.page-tooltip-content').html(content);
3210
3211        $('.page-tooltip').css({
3212            top: Math.min(windowHeight - $('.page-tooltip').height() - 20, Math.max(0, y - 60)),
3213            left: Math.min(windowWidth - $('.page-tooltip').width() - 20, Math.max(0, x - 80)),
3214        });
3215
3216
3217    },
3218    hideTooltip: function () {
3219        $('.page-tooltip').fadeOut(200, function () { $(this).remove(); });
3220    },
3221    replaceQuotes: function (input) {
3222        var result = input;
3223        if (result != null && typeof (result) == 'string') {
3224            result = result.replace(/\'/g, '’').replace(/\"/g, '”').replace('/[\r\n\t]/g', '');
3225        }
3226        return result;
3227    },
3228    submit: function (formContainer) {
3229        if (formContainer != null) {
3230            var formData = '';
3231            $(formContainer).find('input, select, textarea').each(function () {
3232                var id = $(this).attr('id');
3233                if (id != null && id !== '') {
3234                    formData += "&" + id + "=" + $(this).val().replace(/\=/g, '꞊').replace(/\&/g, 'ᶓ');
3235                }
3236            });
3237            if (formData !== '') {
3238                formData = formData.substring(1);
3239            }
3240            window.sessionStorage['impx-form-data'] = formData;
3241        }
3242        document.forms[0].submit();
3243    },
3244    postback: function (eventTarget, eventArgument) {
3245        var hash = window.location.hash;
3246        var action = document.forms[0].action;
3247        try {
3248            // ASP.NET postback loses the hash in the URL
3249            var url = action.replace(hash, '') + hash;
3250            document.forms[0].action = url;
3251        }
3252        catch (ex) {
3253            document.forms[0].action = action;
3254        }
3255        window.__doPostBack(eventTarget, eventArgument);
3256    },
3257    postbackWithDelay: function (eventTarget, eventArgument, delayInMilliSeconds) {
3258        _delayPostbackTimer = window.setTimeout(function () {
3259            page.postback(eventTarget, eventArgument);
3260            window.clearTimeout(_delayPostbackTimer);
3261            _delayPostbackTimer = null;
3262        }, delayInMilliSeconds);
3263    },
3264    refresh: function (removeHash, queryToAdd, queryToRemove) {
3265        var url = window.location.href;
3266        if (removeHash) {
3267            var hash = window.location.hash;
3268            url = url.replace(hash, '');
3269        }
3270        if (queryToRemove && url.toLowerCase().indexOf(queryToRemove.toLowerCase()) > 0) {
3271            url = url.slice(0, url.toLowerCase().indexOf(queryToRemove.toLowerCase()));
3272        }
3273        if (queryToAdd && url.toLowerCase().indexOf(queryToAdd.toLowerCase()) < 0) {
3274            url = url + (url.indexOf('?') > 0 ? '&' : '?') + queryToAdd;
3275        }
3276        page.navigate(url);
3277    },
3278    reload: function () {
3279        window.location.reload();
3280    },
3281    queryString: function (query) {
3282        return page._queryString[query.toLowerCase()];
3283    },
3284    uniqueId: function () {
3285        return Math.newGuid().toUpperCase().replace(/-/g, '');
3286    },
3287    displayInfo: function (title, message) {
3288        if (message != null && message != '') {
3289            dialog.messageBox({
3290                title: title,
3291                icon: 'Information',
3292                message: message,
3293                buttons: 'OK'
3294            });
3295        }
3296    },
3297    displayWarning: function (title, message) {
3298        if (message != null && message != '') {
3299            dialog.messageBox({
3300                title: title,
3301                icon: 'Warning',
3302                message: message,
3303                buttons: 'OK'
3304            });
3305        }
3306    },
3307    displayError: function (title, message) {
3308        if (message != null && message != '') {
3309            dialog.messageBox({
3310                title: title,
3311                icon: 'Error',
3312                message: message,
3313                buttons: 'OK'
3314            });
3315        }
3316    },
3317    displaySuccess: function (title, message) {
3318        if (message != null && message != '') {
3319            dialog.messageBox({
3320                title: title,
3321                icon: 'Success',
3322                message: message,
3323                buttons: 'OK'
3324            });
3325        }
3326    },
3327    postbackOnEnter: function (eventTarget, eventArgument, event) {
3328        if (!event) {
3329            event = window.event;
3330        }
3331        var keyCode = event.keyCode || event.which || event.charCode;
3332        if (keyCode == 13) {
3333            event.preventDefault();
3334            if (eventTarget == 'undefined' || eventTarget == null) {
3335                eventTarget = '';
3336            }
3337            if (eventArgument == 'undefined' || eventArgument == null) {
3338                eventArgument = '';
3339            }
3340            page.postback(eventTarget, eventArgument);
3341            return false;
3342        }
3343        return true;
3344    },
3345    validateRequiredCheckbox: function (sender, e) {
3346        e.IsValid = jQuery(".AcknowledgedStatementName input:checkbox").is(':checked');
3347    },
3348    validateRequiredCheckboxGenric: function (sender, e) {
3349        try {
3350            var inputCheckboxes = jQuery(".Generic-CheckBox-Validator");//.is(':checked');
3351            for (var i = 0; i < inputCheckboxes.length; i++) {
3352                var checkBoxInputClasses = $(inputCheckboxes[i]).attr('class').split(' ');
3353                for (var j = 0; j < checkBoxInputClasses.length; j++) {
3354                    if (sender.id.indexOf(checkBoxInputClasses[j]) >= 0) {
3355                        e.IsValid = jQuery("." + checkBoxInputClasses[j] + " input:checkbox").is(':checked');
3356                    }
3357                }
3358            }
3359        }
3360        catch (ex) {
3361
3362        }
3363    },
3364    cleanupAfterUsingBrowserButtons: function () {
3365        if (!page.isPostBack() && !page.isFirstTime()) {
3366            $('.data-lookup').parent().children('input').val('');
3367        }
3368    },
3369    bindFeedback: function (e) {
3370        if (e != null && e.length > 0 && page._feedback != null) {
3371            e.attr('data-html2canvas-ignore', 'true');
3372            e.click(function () {
3373                if (e.hasClass('dialog-button')) {
3374                    var container = e.parent().parent().parent();
3375                    var dialog = container.find('.modal-dialog');
3376                    var iframe = container.find('iframe');
3377                    if (iframe.length > 0) {
3378                        // This is an iframe-based dialog
3379                        container.removeAttr('tabindex');
3380                        dialog.addClass('modal-full-screen').addClass('margin-0');
3381                        iframe.attr('data-height', iframe.height()).css('height', $(window).height() - dialog.find('.modal-header').height() - 40);
3382                        // Bind an onclose event to reverse the changes
3383                        iframe[0].contentWindow.page._feedback.onClose = function () {
3384                            container.attr('tabindex', '-1');
3385                            dialog.removeClass('modal-full-screen').removeClass('margin-0');
3386                            iframe.css('height', iframe.attr('data-height'));
3387                        };
3388                        iframe[0].contentWindow.page._feedback.open();
3389                    }
3390                    else {
3391                        // This is a div-based dialog
3392                        container.removeAttr('tabindex');
3393                        // Bind an onclose event to reverse the changes
3394                        page._feedback.onClose = function () {
3395                            container.attr('tabindex', '-1');
3396                        };
3397                        page._feedback.open();
3398                    }
3399                }
3400                else {
3401                    page._feedback.open();
3402                }
3403            });
3404        }
3405    },
3406    ajax: function (options) {
3407        try {
3408            if (options.showProgress === undefined || options.showProgress === null) {
3409                options.showProgress = true;
3410            }
3411            if (options.showProgress == true) {
3412                page.showProgress();
3413            }
3414            if (options.url == null || options.url == '') { options.url = '~/'; }
3415            if (window.location.appPath == null) { window.location.appPath == ''; }
3416            $.ajax({
3417                type: 'POST',
3418                url: options.url.replace(/^~/, window.location.appPath),
3419                contentType: 'application/json; charset=utf-8',
3420                dataType: 'json',
3421                data: JSON.stringify(options.parameters),
3422                success: function (data, status, xhr) {
3423                    if (options.success && typeof (options.success) == 'function') {
3424                        options.success.call(this, data.d);
3425                    }
3426                    if (options.showProgress == true) {
3427                        page.hideProgress();
3428                    }
3429                },
3430                error: function (xhr, status, error) {
3431                    if (options.showProgress == true) {
3432                        page.hideProgress();
3433                    }
3434                    if (options.showException == true) {
3435                        var exception = JSON.parse(xhr.responseText);
3436                        if (exception != null && exception.Message) {
3437                            error = exception.Message;
3438                        }
3439                    }
3440                    if (options.error && typeof (options.error) == 'function') {
3441                        options.error.call(this, error);
3442                    }
3443                }
3444            });
3445        }
3446        catch (ex) {
3447            if (options.showProgress == true) {
3448                page.hideProgress();
3449            }
3450            if (options.error && typeof (options.error) == 'function') {
3451                options.error.call(this, ex.message);
3452            }
3453        }
3454    },
3455    addRedirectToUrl: function (targetUrl) {
3456        return page.addRedirectUrlToUrl(targetUrl, document.location.href);
3457    },
3458    addRedirectUrlToUrl: function (targetUrl, redirectUrl) {
3459        if (targetUrl !== undefined && targetUrl !== null && targetUrl !== '') {
3460            if (redirectUrl !== undefined && redirectUrl !== null && redirectUrl !== '') {
3461                redirectUrl = page.convertRelativeToAbsoluteUrl(redirectUrl);
3462            }
3463            else if (redirectUrl === undefined || redirectUrl === null) {
3464                redirectUrl = '';
3465            }
3466            if (targetUrl.indexOf('{{RedirectUrl}}') > 0) {
3467                targetUrl = targetUrl.replace('{{RedirectUrl}}', encodeURIComponent(redirectUrl));
3468            }
3469            else {
3470                targetUrl = targetUrl + (targetUrl.IndexOf('?') < 0 ? '?' : '&') + 'RedirectUrl=' + encodeURIComponent(redirectUrl);
3471            }
3472        }
3473        return targetUrl;
3474    },
3475    convertRelativeToAbsoluteUrl: function (url) {
3476        var div = document.createElement('div');
3477        div.innerHTML = "<a></a>";
3478        div.firstChild.href = url; // Ensures that the href is properly escaped
3479        div.innerHTML = div.innerHTML; // Run the current innerHTML back through the parser
3480        return div.firstChild.href;
3481    },
3482    htmlEncode: function (input) {
3483        var output = $('<div/>').text(input).html();
3484        return page.decodeSpecialChars(output.replace(/&quot;/g, '"'));
3485    },
3486    htmlDecode: function (input) {
3487        var output = $('<div/>').html(input).text();
3488        return output;
3489    },
3490    decodeSpecialChars: function (input) {
3491        return input.replace(/&#(\d+);/g, function (match, str) {
3492            return String.fromCharCode(str);
3493        });
3494    },
3495    handleBeforeSubmitEvents: function () {
3496        if (window.ace) {
3497            $('.ace-editor').each(function () {
3498                var id = $(this).attr('id');
3499                var editor = window.ace.edit(id);
3500                $('#' + id.replace('_editor', '')).val(editor.getValue());
3501            });
3502        }
3503        $('.data-lookup-text').each(function () {
3504            var value = $(this).val();
3505            $(this).val(page.decodeSpecialChars(value));
3506        });
3507        $('#main_lastFocusControl').val($(':focus').attr('id'));
3508    },
3509    initLastFocusControl: function () {
3510        var lastFocusControl = $('#main_lastFocusControl').val();
3511        if (lastFocusControl != null && lastFocusControl !== '') {
3512            var control = $('#' + lastFocusControl.replace(/\$/g, '_'));
3513            if (control.attr('data-datepicker') === '1') {
3514                control = control.parent().find('span.input-group-btn').find('a');
3515            }
3516            else if (page.isIE() && control.attr('id') != null && control.attr('id').endsWith('txtLookupValue')) {
3517                control = control.siblings('div.data-lookup').children('.select2-selection');
3518            }
3519            try { control.focus(); }
3520            catch (ex) { }
3521        }
3522        $('#main_lastFocusControl').val('');
3523    },
3524    initUserImage: function () {
3525        var self = $('img.page-header-user-image');
3526        var size = page.resizeByAspectRatio(self.width(), self.height(), 29, 29);
3527        self.css({ 'width': size.width, 'height': size.height, 'top': '0', 'position': 'static' });
3528    },
3529    initFeedback: function () {
3530        if (window.Feedback && !page.isMobileDevice() && !page.isCmsPage() && $(window).width() > 600) {
3531            page._feedback = window.Feedback({
3532                label: '',
3533                header: 'Send Feedback / Report Issue',
3534                h2cPath: '/assets/plugins/feedback.js/examples/js/html2canvas.js',
3535                url: '~/Services/Feedback.asmx/SendFeedback'
3536            });
3537            page.bindFeedback($('.site-feedback-link'));
3538        }
3539        else {
3540            $('.feedback-container').css('display', 'none');
3541        }
3542    },
3543    initSessionTimeout: function () {
3544        if (window.sessionTimeoutInMinutes !== undefined && window.sessionTimeoutInMinutes !== null && !isNaN(window.sessionTimeoutInMinutes)) {
3545            var timeoutValue = parseInt(window.sessionTimeoutInMinutes) * 60000;
3546            if (page._currentSessionTimer != null) {
3547                window.clearTimeout(page._currentSessionTimer);
3548                page._currentSessionTimer = null;
3549                page._isSessionTimedOut = false;
3550            }
3551            page._currentSessionTimer = window.setTimeout(function () {
3552                if (!page._isSessionTimedOut) {
3553                    dialog.messageBox({
3554                        'title': 'Session Timeout',
3555                        'icon': 'Warning',
3556                        'message': 'Due to inactivity, your session has timed out.<br/>Changes on this page that were not saved will be lost.<br/>Click or tap on OK to refresh the page.',
3557                        'buttons': 'OK',
3558                        'callback': function (args) {
3559                            page.refresh(true);
3560                        }
3561                    });
3562                }
3563                page._isSessionTimedOut = true;
3564                window.clearTimeout(page._currentSessionTimer);
3565                page._currentSessionTimer = null;
3566            }, timeoutValue);
3567        }
3568    },
3569    initAdminDesignMode: function () {
3570        $('.admin-design-container').each(function () {
3571            var self = $(this);
3572            var adminPage = self.parents('.admin-page').first();
3573            var pageAction = adminPage.attr('data-page-action');
3574            var featureId = adminPage.attr('data-feature-id');
3575            var parentFeatureDetailId = adminPage.attr('data-parent-feature-detail-id');
3576            var parentTabId = adminPage.attr('data-parent-tab-id');
3577            var column = self.attr('data-column');
3578            var order = self.attr('data-order');
3579            $('<a></a>').addClass('admin-design-add-link')
3580                .attr({
3581                    'href': 'javascript:void(0);',
3582                    'title': 'Add New Content',
3583                    'onclick': 'javascript:dialog.open({ ' +
3584                        '"url": "~/administration/features/featuredetail.aspx?dialog=yes&action=add&pageAction=' + pageAction + '&featureId=' + featureId + '&parentFeatureDetailId=' + parentFeatureDetailId + '&parentTabId=' + parentTabId + '&column=' + column + '&order=' + order + '", ' +
3585                        '"title": "Add New Content", ' +
3586                        '"width": "wide", ' +
3587                        '"callback": function(args) { if (args != null) page.refresh(false, "ClearCache=Yes"); }' +
3588                        '});'
3589                })
3590                .css({ 'position': 'absolute', 'top': '0', 'left': '0' })
3591                .html('<i class="icon-plus-square"></i>')
3592                .appendTo(self);
3593            self.find('.admin-content').each(function () {
3594                var content = $(this);
3595                var id = content.attr('data-id');
3596                $('<a></a>').addClass('admin-design-edit-link')
3597                    .attr({
3598                        'href': 'javascript:void(0);',
3599                        'title': 'Edit this Content',
3600                        'onclick': 'javascript:dialog.open({ ' +
3601                            '"url": "~/administration/features/featuredetail.aspx?dialog=yes&action=edit&pageAction=' + pageAction + '&featureId=' + featureId + '&parentFeatureDetailId=' + parentFeatureDetailId + '&parentTabId=' + parentTabId + '&column=' + column + '&order=' + order + '&id=' + id + '", ' +
3602                            '"title": "Add New Content", ' +
3603                            '"width": "wide", ' +
3604                            '"callback": function(args) { if (args != null) page.refresh(false, "ClearCache=Yes"); }' +
3605                            '});'
3606                    })
3607                    .css({ 'position': 'absolute', 'top': '0', 'right': '0' })
3608                    .html('<i class="icon-pencil-square"></i>')
3609                    .appendTo(content);
3610            });
3611        });
3612    },
3613    checkBadSsoToken: function () {
3614        var isBadToken = page.queryString('badtoken');
3615        if (isBadToken != null && (isBadToken.toLowerCase() == 'yes' || isBadToken.toLowerCase() == 'true' || isBadToken == '1')) {
3616            dialog.messageBox({
3617                title: 'Login Invalid/Expired',
3618                icon: 'Warning',
3619                buttons: 'OK',
3620                message: 'The application could not log you in. The link you have used has expired.',
3621                callback: function (args) {
3622                    var url = window.location.href;
3623                    url = url.replace(/(&badtoken=[^&\s]+|badtoken=[^&\s]+&?)/gi, '');
3624                    var endChar = url.substring(url.length - 1, 1);
3625                    if (endChar == '?' || endChar == '&') {
3626                        url = url.substring(0, url.length - 1);
3627                    }
3628                    window.location.href = url;
3629                }
3630            });
3631        }
3632    },//Default values with functions is not supported with IE11
3633    initShoppingProducts: function (itemsPerRow) {
3634        if (!itemsPerRow) {
3635            itemsPerRow = 4;
3636        }
3637        $('.pricing-head, .pricing-head h3, .pricing-content').css('height', '');
3638        if ($(window).width() > 1280) {
3639            var l = $('.products .col-md-' + 12 / itemsPerRow).length;
3640            for (var i = 0; i <= l + 1; i += itemsPerRow) {
3641                page.makeSameHeight($('.pricing-head h3').slice(i, i + itemsPerRow));
3642                page.makeSameHeight($('.pricing-head').slice(i, i + itemsPerRow));
3643                page.makeSameHeight($('.pricing-content').slice(i, i + itemsPerRow));
3644            }
3645        }
3646        $('.donation-amounts').each(function () {
3647            var self = $(this);
3648            var textbox = self.siblings('.input-group').find('input[type="text"]');
3649            textbox.focus(function () {
3650                self.find('li:last-child > div.radio > span > input[type="radio"]').prop('checked', true);
3651                self.find('li > div.radio > span').removeClass('checked');
3652                self.find('li:last-child > div.radio > span').addClass('checked');
3653            });
3654            self.find('input[type="radio"]').click(function () {
3655                if ($(this).val() !== '-1') {
3656                    textbox.val(parseFloat($(this).val()).toFixed(2));
3657                }
3658            });
3659        });
3660        $('.product-booth').each(function () {
3661            page.validateBoothSelection(this);
3662        });
3663    },
3664    initSuggestedProducts: function () {
3665        $('.pricing-head, .pricing-head h3, .pricing-content').css('height', '');
3666        if ($(window).width() > 1280) {
3667            page.makeSameHeight($('.pricing-head h3'));
3668            page.makeSameHeight($('.pricing-head'));
3669            page.makeSameHeight($('.pricing-content'));
3670            page.makeSameHeight($('.pricing'));
3671            if ($('.pricing').length > 0) {
3672                $('.carousel-control').css('height', $($('.pricing')[0]).height() + 6);
3673                $('.carousel-control').css('width', 20);
3674            }
3675        }
3676    },
3677    putRowToTop: function (dataCompany, dataContact, dataEmployee) {
3678        if (dataCompany != null) {
3679            var newRowCompany = document.querySelector("tr[" + dataCompany + "]");
3680            if (newRowCompany != null) {
3681                page._setTopAndFocus(newRowCompany);
3682            }
3683        }
3684        if (dataContact != null) {
3685            var newRowContanct = document.querySelector("tr[" + dataContact + "]");
3686            if (newRowContanct != null) {
3687                page._setTopAndFocus(newRowContanct);
3688            }
3689        }
3690        if (dataEmployee != null) {
3691            var newRowEmployee = document.querySelector("tr[" + dataEmployee + "]");
3692            if (newRowEmployee != null) {
3693                page._setTopAndFocus(newRowEmployee);
3694            }
3695        }
3696    },
3697    switchTab: function (link) {
3698        // Baseline tabs do not rely on this script!
3699        // This can be used from HTML and JS to create tabs.
3700        var container = $(link).parents('.tabbable-custom');
3701        var header = container.children('.nav-tabs');
3702        var content = container.children('.tab-content');
3703        var pane = $($(link).attr('href'));
3704        var index = content.index(pane);
3705        //var hidden = container.children('input[type="hidden"]');
3706        //hidden.val(index);
3707        var text = $(link).text();
3708        var icon = $(link).children('i').attr('class');
3709        var responsiveLink = container.children('.navbar-header').children('a');
3710        responsiveLink.children('i:nth-child(2)').removeClass().addClass(icon);
3711        responsiveLink.children('span').html(text);
3712        //cookies.setCookie('Tab', hidden.attr('id'), index);
3713        FormComponents.initResponsiveGrids(true);
3714    },
3715    validateForm: function (formContainer, messageContainer, validationEvent, scrollToTop) {
3716        var messages = [];
3717        if (formContainer != null && $(formContainer).length > 0) {
3718            $(formContainer + ' .form-group').each(function () {
3719                var label = $(this).find('.control-label');
3720                var caption = label.text().replace(':', '');
3721                // required validation
3722                var controls = $(this).find('.form-control.required');
3723                if (controls.length > 0) {
3724                    controls.each(function () {
3725                        var isEmpty = $(this).val().trim() === '';
3726                        if (isEmpty) {
3727                            messages.add(caption + ' is required.');
3728                        }
3729                    });
3730                }
3731                // max length validation
3732                controls = $(this).find('.form-control.max-length');
3733                if (controls.length > 0) {
3734                    controls.each(function () {
3735                        var maxLength = $(this).attr('data-max-length');
3736                        var length = $(this).val().trim().length;
3737                        if (length > maxLength) {
3738                            messages.add(caption + ' must be no more than ' + maxLength + ' characters.');
3739                        }
3740                    });
3741                }
3742                // min length validation
3743                controls = $(this).find('.form-control.min-length');
3744                if (controls.length > 0) {
3745                    controls.each(function () {
3746                        var minLength = $(this).attr('data-min-length');
3747                        var length = $(this).val().trim().length;
3748                        if (length < minLength) {
3749                            messages.add(caption + ' must be ' + minLength + ' or more characters.');
3750                        }
3751                    });
3752                }
3753                // date validation
3754                controls = $(this).find('.form-control.date');
3755                if (controls.length > 0) {
3756                    controls.each(function () {
3757                        var dateValue = $(this).val();
3758                        if (dateValue !== '') {
3759                            var regex = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/;
3760                            var matches = dateValue.match(regex);
3761                            if (matches) {
3762                                // month value between 1 and 12
3763                                if (matches[1] < 1 || matches[1] > 12) {
3764                                    messages.add(caption + ' has an invalid value for month.');
3765                                }
3766                                // day value between 1 and 31
3767                                if (matches[2] < 1 || matches[2] > 31) {
3768                                    messages.add(caption + ' has an invalid value for day.');
3769                                }
3770                                // year value between 1900 and 2100
3771                                if (matches[3] < 1900 || matches[3] > 2100) {
3772                                    messages.add(caption + ' has an invalid value for year.');
3773                                }
3774                            }
3775                            else {
3776                                messages.add(caption + ' is not a valid date value.');
3777                            }
3778                        }
3779                    });
3780                }
3781                // integer validation
3782                controls = $(this).find('.form-control.integer');
3783                if (controls.length > 0) {
3784                    controls.each(function () {
3785                        var integerValue = $(this).val();
3786                        if (integerValue !== '') {
3787                            if (isNaN(integerValue)) {
3788                                messages.add(caption + ' is not a valid integer value.');
3789                            }
3790                            var regex = /^[0-9\-]*$/gm;
3791                            var matches = integerValue.match(regex);
3792                            if (!matches || matches.length === 0) {
3793                                messages.add(caption + ' is not a valid integer value.');
3794                            }
3795                        }
3796                    });
3797                }
3798                // decimal validation
3799                controls = $(this).find('.form-control.decimal');
3800                if (controls.length > 0) {
3801                    controls.each(function () {
3802                        var decimalValue = $(this).val();
3803                        if (decimalValue !== '') {
3804                            if (isNaN(decimalValue)) {
3805                                messages.add(caption + ' is not a valid decimal value.');
3806                            }
3807                            var regex = /^[0-9\-\.]*$/gm;
3808                            var matches = decimalValue.match(regex);
3809                            if (!matches || matches.length === 0) {
3810                                messages.add(caption + ' is not a valid decimal value.');
3811                            }
3812                        }
3813                    });
3814                }
3815                // More validations should come here...
3816            });
3817            if (validationEvent != null && typeof (validationEvent) === 'function') {
3818                messages = validationEvent.call(this, messages);
3819            }
3820            if (messageContainer != null && $(messageContainer).length > 0) {
3821                if (messages != null && messages.length > 0) {
3822                    var html = '<ul>';
3823                    for (var i = 0; i < messages.length; i++) {
3824                        html += '<li>' + messages[i] + '</li>';
3825                    }
3826                    html += '</ul>';
3827                    $(messageContainer).removeClass('display-none').html(html);
3828                    if (scrollToTop == null || scrollToTop == true) {
3829                        page.scrollToTop();
3830                    }
3831                }
3832                else {
3833                    $(messageContainer).addClass('display-none').html('');
3834                }
3835            }
3836        }
3837        return messages.length == 0;
3838    },
3839    populateFormFromRequest: function (formContainer) {
3840        var formData = window.sessionStorage['impx-form-data'];
3841        window.sessionStorage['impx-form-data'] = null;
3842        if (formData != null && formContainer != null && $(formContainer).length > 0) {
3843            var saved = formData.split('&');
3844            var values = [];
3845            for (var i = 0; i < saved.length; i++) {
3846                var nameValue = saved[i].split('=');
3847                values[nameValue[0]] = nameValue[1].replace(/\꞊/g, '=').replace(/\ᶓ/g, '&');
3848            }
3849            $(formContainer).find('input, select, textarea').each(function () {
3850                var id = $(this).attr('id');
3851                if (id != null && id !== '' && values[id] != null) {
3852                    $(this).val(values[id]);
3853                }
3854            });
3855        }
3856    },
3857    showFileDownloadDialog: function (ev, type, id) {
3858        dialog.confirm(ev, {
3859            title: 'Download ' + type,
3860            icon: 'Question',
3861            message: 'Download this ' + type.toLowerCase() + ' to your computer?',
3862            okClicked: function () {
3863                var url = '~/uploads/filedownload.aspx?id=' + id;
3864                if (window.location.appPath == null) { window.location.appPath == ''; }
3865                url = url.replace(/^~/, window.location.appPath);
3866                var downloadInfo = page.getNavigatorDownloadInformation();
3867                $.fileDownload(url)
3868                    .done(function () {
3869                        dialog.messageBox({
3870                            'title': 'Download Started',
3871                            'icon': 'Information',
3872                            'buttons': 'OK',
3873                            'message': 'Download is in progress.<br /><br />' + downloadInfo
3874                        });
3875                    })
3876                    .fail(function () {
3877                        dialog.messageBox({
3878                            'title': 'Download Failed',
3879                            'icon': 'Warning',
3880                            'buttons': 'OK',
3881                            'message': 'An error occured during the download process. Please try again.'
3882                        });
3883                    });
3884            }
3885        });
3886    },
3887    showFileUploadDialog: function (options) {
3888        // type: [Image|File],
3889        // object: [ContactImage|ContactFile|ProductImage|ProductFile|ExhibitorBoothImage|HallDwgFile|CommitteeMinutes]
3890        var defaults = {
3891            type: 'File',
3892            id: '',
3893            folder: '',
3894            object: '',
3895            item: '',
3896            subItem: '',
3897            parent: '', // parent or additional id to pass
3898            sequence: 0,
3899            primary: -1,
3900            category: '',
3901            createFolderIfNotExists: 0,
3902            description: '',
3903            callback: null
3904        };
3905        options = $.extend({}, defaults, options);
3906        if (options.type.toLowerCase() == 'image' || options.type.toLowerCase() == 'file') {
3907            options.type = (options.type.toLowerCase() == 'image' ? 'Image' : 'File');
3908            var idString = (options.id != null && options.id != '' ? '&id=' + options.id : '');
3909            var modeString = (options.id != null && options.id != '' ? '&mode=Edit' : '&mode=Upload');
3910            var folderString = (options.folder != null && options.folder != '' ? '&folder=' + escape(options.folder) : '');
3911            var objectString = (options.object != null && options.object != '' ? '&object=' + escape(options.object) : '');
3912            var itemString = (options.item != null && options.item != '' ? '&item=' + options.item : '');
3913            var subItemString = (options.subItem != null && options.subItem != '' ? '&subitem=' + options.subItem : '');
3914            var parentString = (options.parent != null && options.parent != '' ? '&parent=' + options.parent : '');
3915            var categoryString = (options.category != null && options.category != '' ? '&category=' + escape(options.category) : '');
3916            var primaryString = (options.primary == '0' || options.primary == '1' ? '&primary=' + options.primary : '');
3917            var createFolderIfNotExistsString = (options.createFolderIfNotExists == '0' || options.createFolderIfNotExists == '1' ? '&CreateFolderIfNotExists=' + options.createFolderIfNotExists : '');
3918            var descriptionString = (options.description != null && options.description != '' ? '&description=' + options.description : '');
3919            dialog.open({
3920                url: '~/uploads/fileupload.aspx?dialog=yes&type=' + options.type.toLowerCase() + idString + modeString + folderString + objectString + itemString + subItemString + parentString + categoryString + primaryString + descriptionString + createFolderIfNotExistsString,
3921                title: options.type + ' Upload',
3922                resizeButton: false,
3923                openButton: false,
3924                callback: function (args) {
3925                    if (args !== undefined && args !== null && args !== '' && args.id !== undefined) {
3926                        if (options.callback != null) {
3927                            options.callback(args);
3928                        }
3929                        else {
3930                            page.refresh();
3931                        }
3932                    }
3933                }
3934            });
3935        }
3936    },
3937    switchProfileImages: function (options) {
3938        // type: [Image|File],
3939        // object: [ContactImage|ContactFile|ProductImage|ProductFile|ExhibitorBoothImage|HallDwgFile]
3940        var defaults = {
3941            type: 'Image',
3942            id: '',
3943            folder: '',
3944            object: '',
3945            item: '',
3946            sequence: 0,
3947            primary: 0,
3948            category: '',
3949            sourceImage: '',
3950            targetImage: '',
3951            targetLink: ''
3952        };
3953        options = $.extend({}, defaults, options);
3954        var sourceImageSrc = $('#' + options.sourceImage).attr('src');
3955        $('#' + options.targetImage).attr('src', sourceImageSrc.substring(0, sourceImageSrc.indexOf('?')));
3956        $('#' + options.targetLink).html('edit').attr("onclick", "javascript:page.showFileUploadDialog({ " +
3957            "'type': '" + options.type + "', " +
3958            "'id': '" + options.id + "', " +
3959            "'folder': '" + options.folder.replace(/\'/g, '\\\'') + "', " +
3960            "'object': '" + options.object + "', " +
3961            "'item': '" + options.item + "', " +
3962            "'sequence': '" + options.sequence + "', " +
3963            "'primary': '" + options.primary + "', " +
3964            "'category': '" + options.category.replace(/\'/g, '\\\'') + "' " +
3965            "}); return false;");
3966    },
3967    showHideProfileNotes: function (e) {
3968        var noteLabel = $('#' + $(e).attr('id').replace('lnkMore', 'lblNote'));
3969        var fullNoteLabel = $('#' + $(e).attr('id').replace('lnkMore', 'lblNoteFull'));
3970        if (noteLabel.hasClass('display-inline')) {
3971            noteLabel.removeClass('display-inline').addClass('display-none');
3972            fullNoteLabel.removeClass('display-none').addClass('display-inline');
3973            $(e).html('Less <i class="icon-chevron-up"></i>');
3974        }
3975        else {
3976            noteLabel.removeClass('display-none').addClass('display-inline');
3977            fullNoteLabel.removeClass('display-inline').addClass('display-none');
3978            $(e).html('More <i class="icon-chevron-down"></i>');
3979        }
3980    },
3981    showHideCompleteTermsAndConditions: function () {
3982        try {
3983            $('#pnlexpandedTermsAndConditions').toggle();
3984            $('#pnlShortTermsandCondtions').toggle();
3985        }
3986        catch (e) {
3987
3988        }
3989    },
3990    showHideOpenOrderBatchProducts: function (e) {
3991        var singleLabel = $('#' + $(e).attr('id').replace('lnkMore', 'lblProduct'));
3992        var fullLabel = $('#' + $(e).attr('id').replace('lnkMore', 'lblAllProducts'));
3993        if (singleLabel.hasClass('display-inline')) {
3994            singleLabel.removeClass('display-inline').addClass('display-none');
3995            fullLabel.removeClass('display-none').addClass('display-inline');
3996            $(e).html('Less <i class="icon-chevron-up"></i>');
3997        }
3998        else {
3999            singleLabel.removeClass('display-none').addClass('display-inline');
4000            fullLabel.removeClass('display-inline').addClass('display-none');
4001            $(e).html('More <i class="icon-chevron-down"></i>');
4002        }
4003    },
4004    showImagePreviewDialog: function (src) {
4005        if (!src) { src = '~/'; }
4006        var id = Math.newGuid();
4007        var container = $('<div></div>').id(id).css({ 'position': 'absolute', 'left': '0', 'top': '50000px' }).addClass('content-container margin-top-30').appendTo($('body'));
4008        var div = $('<div></div>').addClass('portlet box').appendTo(container);
4009
4010        var regex = /([0-9a-fA-F]{8}\-([0-9a-fA-F]{4}\-){3}[0-9a-fA-F]{12})/g;
4011        var m, ids = [];
4012        while ((m = regex.exec(src)) !== null) {
4013            if (m.index === regex.lastIndex) {
4014                regex.lastIndex++;
4015            }
4016            ids.push(m[1]);
4017        }
4018
4019        fileId = ids[1] || ids[0];
4020
4021        if (window.location.appPath == null) { window.location.appPath == ''; }
4022        div.append($('<img/>')
4023            .loaded(function () {
4024                var self = $(this);
4025                var timer = null;
4026                timer = window.setTimeout(function () {
4027                    var size = page.resizeByAspectRatio(self.width(), self.height(), 550, 550);
4028                    self.css({ 'width': size.width, 'height': size.height });
4029                    if (size.width < 160) {
4030                        size.width = 160;
4031                    }
4032                    container.css({ 'position': 'static', 'top': '0', 'width': size.width, 'height': size.height + 60 });
4033                    dialog.open({
4034                        id: id,
4035                        title: 'Image Preview',
4036                        callback: function (args) {
4037                            container.remove();
4038                        }
4039                    });
4040                    window.clearTimeout(timer);
4041                }, 200);
4042            }).attr('src', src.replace(/^~/, window.location.appPath)));
4043        container.append($($('<div></div>').addClass('btn-group'))
4044            .append($('<button>')
4045                .addClass('btn blue')
4046                .html('</i><span>Print  </span><i class="icon-print">')
4047                .click(function () {
4048                    page.printImage(src);
4049                    dialog.close();
4050                }))
4051            .append($('<a>', {
4052                href: '/uploads/filedownload.aspx?id=' + fileId
4053                // target: '_blank'
4054            })
4055                .addClass('btn blue')
4056                .attr('download', 'download')
4057                .html('</i><span>Download  </span><i class="icon-download">')
4058                .click(function (e) {
4059                    e.preventDefault();
4060                    var url = $(this).attr('href');
4061                    window.open(url, '_blank');
4062                    dialog.close();
4063                }))
4064            .append($('<button>')
4065                .addClass('btn red')
4066                .html('</i><span>Cancel  </span><i class="icon-times-circle">')
4067                .click(function () {
4068                    dialog.close();
4069                }))
4070        );
4071
4072    },
4073    showToastrNotification: function (type, title, message) {
4074        //"type" can be info, success, warning or error
4075        if (type === '' || type === null || type === undefined) {
4076            type = 'info';
4077        }
4078        type = type.toLowerCase();
4079        toastr.options = {
4080            'closeButton': true,
4081            'debug': false,
4082            'positionClass': 'toast-top-right',
4083            'onclick': null,
4084            'showDuration': '1000',
4085            'hideDuration': '1000',
4086            'timeOut': '5000',
4087            'extendedTimeOut': '1000',
4088            'showEasing': 'swing',
4089            'hideEasing': 'linear',
4090            'showMethod': 'fadeIn',
4091            'hideMethod': 'fadeOut'
4092        };
4093        toastr[type](message, title);
4094    },
4095    initCartItemsCount: function () {
4096        var cartBadges = $('.page-header-user-cart > .badge:not([data-cart-baseline-allow-Ajax])')
4097        if (cartBadges.length > 0) {
4098            page.ajax({
4099                url: '~/Services/ShoppingCart.asmx/GetCartItemsCount',
4100                parameters: {},
4101                showProgress: false,
4102                success: function (data) {
4103                    cartBadges.each(function () {
4104                        $(this).html(data == null || data == '' || isNaN(data) ? '' : parseInt(data))
4105                    });
4106                },
4107                error: function (message) {
4108                    page.displayError('Error', message);
4109                }
4110            });
4111        }
4112    },
4113    showShoppingCartItems: function (isAdminSite) {
4114        $('.cart-popup-title').addClass('display-none');
4115        page.getAllCarts(function (items) {
4116            $('.page-header-cart-scroller').empty();
4117            if (items != null && items.length > 0) {
4118                $('.cart-popup-title').removeClass('display-none');
4119                $('.page-header-cart-link').empty().removeClass('external');
4120                var customerId = items[0].CustomerId;
4121                var individualId = items[0].IndividualId;
4122                var currencyId = items[0].CurrencyId;
4123                var currencySymbol = items[0].CurrencySymbol;
4124                var cartValidation = items[0].CartValidation;
4125                var url, item, totalString, height;
4126                var hasDonation = false;
4127                if (items.length === 1 || items.all(function (c) { return c.CustomerId === customerId && c.IndividualId === individualId && c.CurrencyId === currencyId; })) {
4128                    // Single customer
4129                    var total = 0;
4130                    var totalCount = 0;
4131                    url = window.location.myShoppingCartPath + '?CustomerId=' + customerId + (individualId != null ? '&IndividualId=' + individualId : '') + (currencyId != null ? '&CurrencyId=' + currencyId : '') + '&Cart=1';
4132                    var currentItem = items[0];
4133                    if (currentItem.Items.length > 0) {
4134                        for (var i = 0; i < currentItem.Items.length; i++) {
4135                            var isDonation = currentItem.Items[i].ProductType === 'Fund';
4136                            if (isDonation) {
4137                                hasDonation = true;
4138                            }
4139                            totalString = currentItem.Items[i].Total === 0 && !isDonation ? 'Free' : currencySymbol + parseFloat(currentItem.Items[i].Total).toFixed(2);
4140                            if (window.location.appPath == null) { window.location.appPath == ''; }
4141                            item = '<li>' +
4142                                '<div class="position-relative overflow-hidden">' +
4143                                (currentItem.Items[i].IsRequired ?
4144                                    '<span class="cart-menu-remove-button cart-menu-remove-button-' + i + '" title="Add-On Item">' +
4145                                    '<i class="icon-level-up"></i>' +
4146                                    '</span>' :
4147                                    '<a href="javascript:page.removeCartItem(\'' + customerId + '\', \'' + individualId + '\', \'' + currencyId + '\', \'' + currentItem.Items[i].ProductId + '\', \'' + currentItem.Items[i].CustomerId + '\',\'' + currentItem.Items[i].ParentId + '\', \'' + currentItem.Items[i].GrandParentId + '\');" class="cart-menu-remove-button cart-menu-remove-button-' + i + '" title="Remove Item">' +
4148                                    '<i class="icon-remove"></i>' +
4149                                    '</a>') +
4150                                '<a ' + (cartValidation == null
4151                                    ? 'href="' + url.replace(/^~/, window.location.appPath) + '"'
4152                                    : 'href="javascript:page.applyCartValidation(\'' + cartValidation.Message + '\', \'' + cartValidation.Type + '\', \'' + cartValidation.RedirectUrl + '\')"'
4153                                ) + ' class="cart-menu-button cart-menu-button-' + i + '" > ' +
4154                                '<span class="float-left">' +
4155                                '<span class="label label-sm label-icon label-success"><i class="' + page.getProductIconByProductType(currentItem.Items[i].ProductType) + '"></i></span>' + page.replaceQuotes(currentItem.Items[i].ProductName) +
4156                                '</span>' +
4157                                '<span class="float-right align-right">' +
4158                                '<small class="display-inline-block">Quantity: ' + currentItem.Items[i].Quantity + '<br/>Total: ' + totalString + '</small>' +
4159                                '<div class="clearfix"></div>' +
4160                                '</span>' +
4161                                '<div class="clearfix"></div>' +
4162                                '</a>' +
4163                                '<div class="clearfix"></div>' +
4164                                '</div>' +
4165                                '</li>';
4166                            $('.page-header-cart-scroller').append(item);
4167                            height = $('.page-header-cart-scroller').find('.cart-menu-button-' + i).height();
4168                            $('.page-header-cart-scroller').find('.cart-menu-remove-button-' + i).css({ 'height': height + 50 });
4169                            $('.page-header-cart-scroller').find('.cart-menu-remove-button-' + i + ' i').css({ 'margin-top': (height / 2) });
4170                            total += currentItem.Items[i].Total;
4171                            totalCount += currentItem.Items[i].Quantity;
4172                        }
4173                    }
4174                    totalString = total === 0 && !hasDonation ? 'Free' : currencySymbol + total.toFixed(2);
4175                    $('.page-header-cart-link').addClass('external').append('<div class="align-right padding-left-10 padding-right-10">Total: ' + totalString + '</div>' +
4176                        '<div class="btn-group display-block padding-top-5 padding-left-10 padding-right-10">' +
4177                        '<button type="button" class="btn red btn-sm float-left padding-left-5" onclick="javascript:page.clearCart(\'' + customerId + '\', \'' + individualId + '\', \'' + currencyId + '\');"><i class="icon-remove"></i> Clear</button>' +
4178                        '<button type="button" class="btn green btn-sm float-right margin-right-0 padding-right-0" onclick=' + (cartValidation != null ? '"javascript:page.applyCartValidation(\'' + cartValidation.Message + '\', \'' + cartValidation.Type + '\', \'' + cartValidation.RedirectUrl + '\')"' : '"javascript:page.navigate(\'' + url + '\');"') + '>Checkout <i class="icon-chevron-right"></i></button>' +
4179                        '</div>' +
4180                        '<div class="clearfix"></div>');
4181                    $('.cart-popup-customer').html(page.replaceQuotes(currentItem.CustomerName));
4182                    var isOneItem = totalCount == 1;
4183                    $('.cart-popup-count').html('There ' + (isOneItem ? 'is' : 'are') + ' ' + totalCount + ' item' + (isOneItem ? '' : 's') + ' in your cart.');
4184                }
4185                else {
4186                    // Multiple customers
4187                    var totalCount = 0;
4188                    for (var k = 0; k < items.length; k++) {
4189                        customerId = items[k].CustomerId;
4190                        individualId = items[k].IndividualId;
4191                        currencyId = items[k].CurrencyId;
4192                        currencySymbol = items[k].CurrencySymbol;
4193                        cartValidation = items[k].CartValidation;
4194                        hasDonation = items[k].Items.any(function (c) { return c.ProductType === 'Fund'; });
4195                        url = window.location.myShoppingCartPath + '?CustomerId=' + customerId + (individualId != null ? '&IndividualId=' + individualId : '') + (currencyId != null ? '&CurrencyId=' + currencyId : '') + '&Cart=1';
4196                        var customertotal = parseFloat(items[k].Items.sum(function (c) { return c.Total; })).toFixed(2);
4197                        totalString = customertotal === 0 && !hasDonation ? 'Free' : currencySymbol + customertotal;
4198                        if (window.location.appPath == null) { window.location.appPath == ''; }
4199                        item = '<li>' +
4200                            '<div class="position-relative overflow-hidden">' +
4201                            '<a href="javascript:page.clearCart(\'' + customerId + '\', \'' + individualId + '\', \'' + currencyId + '\');" class="cart-menu-remove-button cart-menu-remove-button-' + k + '">' +
4202                            '<i class="icon-remove"></i></a>' +
4203                            '<a ' + (cartValidation == null
4204                                ? 'href="' + url.replace(/^~/, window.location.appPath) + '"'
4205                                : 'href="javascript:page.applyCartValidation(\'' + cartValidation.Message + '\', \'' + cartValidation.Type + '\', \'' + cartValidation.RedirectUrl + '\')"'
4206                            ) + ' class="cart-menu-button cart-menu-button-' + k + '" > ' +
4207                            '<span class="float-left">' +
4208                            '<span class="label label-sm label-icon label-primary"><i class="icon-' + (items[k].CustomerType === 'O' ? 'building-o' : 'user') + '"></i></span>' +
4209                            page.replaceQuotes(items[k].CustomerName) + (individualId != null ? '<br/><small>By: ' + page.replaceQuotes(items[k].IndividualName) + '</small>' : '') +
4210                            '</span>' +
4211                            '<span class="float-right align-right">' +
4212                            '<small class="display-inline-block">Items: ' + items[k].Items.length + '<br/>Total: ' + totalString + '</small>' +
4213                            '<i class="icon-chevron-right valign-top margin-left-5 margin-top-15"></i>' +
4214                            '<div class="clearfix"></div>' +
4215                            '</span>' +
4216                            '<div class="clearfix"></div>' +
4217                            '</a>' +
4218                            '</div>' +
4219                            '</li>';
4220                        $('.page-header-cart-scroller').append(item);
4221                        height = $('.page-header-cart-scroller').find('.cart-menu-button-' + k).height();
4222                        $('.page-header-cart-scroller').find('.cart-menu-remove-button-' + k).css({ 'height': height + 50 });
4223                        $('.page-header-cart-scroller').find('.cart-menu-remove-button-' + k + ' i').css({ 'margin-top': (height / 2) });
4224                        for (var m = 0; m < items[k].Items.length; m++) {
4225                            totalCount += items[k].Items[m].Quantity;
4226                        }
4227                    }
4228                    $('.cart-popup-customer').html('Multiple Shopping Carts');
4229                    var isOneItem = totalCount == 1;
4230                    var isOneCart = items.length == 1;
4231                    $('.cart-popup-count').html('There ' + (isOneItem ? 'is' : 'are') + ' ' + totalCount + ' item' + (isOneItem ? '' : 's') + ' in ' + items.length + ' cart' + (isOneCart ? '' : 's') + '.');
4232                    $('.page-header-cart-link').addClass('external').append('<div class="btn-group display-block padding-top-5 padding-left-10 padding-right-10">' +
4233                        '<button type="button" class="btn red btn-sm float-right margin-right-0 padding-left-5" onclick="javascript:page.clearAllCarts();"><i class="icon-remove"></i> Clear All</button>' +
4234                        '</div>' +
4235                        '<div class="clearfix"></div>');
4236                }
4237            }
4238            else {
4239                var hadItems = ($('.page-header-user-cart > .badge').length > 0 && $('.page-header-user-cart > .badge').text() !== '');
4240                $('.page-header-user-cart > .badge').empty();
4241                $('.page-sidebar-user-cart > .badge').empty();
4242                $('.dropdown-menu.cart > li:first-child').empty().append($('<p></p>').text('There are 0 items in your cart'));
4243                $('.page-header-cart-scroller').empty().append($('<li class="align-center height-200 padding-top-50"><h4>No Items' + (hadItems ? '<br/><small>(Your cart has expired)</small>' : '') + '</h4></li>'));
4244            }
4245        }, function (message) {
4246            $('.page-header-cart-scroller').empty();
4247            $('.page-header-cart-scroller').append($('<li class="align-center height-200"><span>' + message + '</span></li>'));
4248            if (message) {
4249                page.displayError('Shopping Cart', message);
4250            }
4251        }, false);
4252    },
4253    clearCart: function (customerId, individualId, currencyId, doNotConfirm, doNotRefresh, displayError, successCallback, errorCallback) {
4254        var callService = function (customerId, individualId, currencyId, doNotRefresh, displayError, successCallback, errorCallback) {
4255            page.ajax({
4256                url: '~/Services/ShoppingCart.asmx/ClearCurrentCart',
4257                parameters: {
4258                    'customerId': customerId,
4259                    'individualId': individualId == 'null' ? null : individualId,
4260                    'currencyId': currencyId == 'null' ? null : currencyId
4261                },
4262                showProgress: false,
4263                success: function () {
4264                    $('#main_browserNavigationWarning').val('');
4265                    if (successCallback != null && typeof (successCallback) == 'function') {
4266                        successCallback.call(this);
4267                    }
4268                    if (doNotRefresh != true) {
4269                        page.refresh(true, 'itemRemoved=1');
4270                    }
4271                },
4272                error: function (message) {
4273                    if (errorCallback != null && typeof (errorCallback) == 'function') {
4274                        errorCallback.call(this, message);
4275                    }
4276                    if (displayError == true) {
4277                        page.displayError('Error', message);
4278                    }
4279                }
4280            });
4281        }
4282        if (doNotConfirm == true) {
4283            callService(customerId, individualId, currencyId, doNotRefresh, displayError, successCallback, errorCallback);
4284        }
4285        else {
4286            dialog.confirm(null, {
4287                'title': 'Clear Shopping Cart',
4288                'icon': 'Warning',
4289                'message': 'Are you sure you want to clear your shopping cart?',
4290                'okClicked': function () {
4291                    callService(customerId, individualId, currencyId, doNotRefresh);
4292                }
4293            });
4294        }
4295    },
4296    clearAllCarts: function () {
4297        dialog.confirm(null, {
4298            'title': 'Clear Shopping Cart',
4299            'icon': 'Warning',
4300            'message': 'Are you sure you want to clear all your shopping carts?',
4301            'okClicked': function () {
4302                page.ajax({
4303                    url: '~/Services/ShoppingCart.asmx/ClearAllCarts',
4304                    parameters: {},
4305                    showProgress: false,
4306                    success: function () {
4307                        $('#main_browserNavigationWarning').val('');
4308                        page.refresh(true, 'itemRemoved=1');
4309                    },
4310                    error: function (message) {
4311                        page.displayError('Error', message);
4312                    }
4313                });
4314            }
4315        });
4316    },
4317    updateSuggestedProducts: function (customerId) {
4318        if ($("div[id$='ctlSuggestedProducts']").length > 0) {
4319            page.ajax({
4320                url: '~/Services/ShoppingCart.asmx/UpdateSuggestedItemsByCustomerId',
4321                parameters: {
4322                    customerId: customerId
4323                },
4324                showProgress: false,
4325                success: function (html) {
4326                    var ctl = $("div[id$='ctlSuggestedProducts']");
4327                    if (ctl.length > 0) {
4328                        ctl.html(html);
4329                        if ($("div[id$='divSuggProd']").length > 0 && html !== '') {
4330                            page.initSuggestedProducts();
4331                            if ($('.pricing').length > 4) {
4332                                $("div[id$='divSuggProd']").attr('class', 'carousel slide');
4333                                $("div[id$='divSuggProdItems']").attr('class', 'carousel-inner padding-left-5 padding-right-5');
4334                                $("div[id$='divSuggProd']").carousel({
4335                                    pause: true,
4336                                    interval: false
4337                                });
4338                            }
4339                            else {
4340                                $('.carousel-control').hide();
4341                            }
4342                        }
4343                    }
4344                },
4345                error: function (message) {
4346                    page.displayError('Error', message);
4347                }
4348            });
4349        }
4350    },
4351    isStackableDiscount: function (eventTarget, eventArgument, event) {
4352        var hasStackableAuto = false;
4353        var hasNonStackableAuto = false;
4354
4355        // Find all auto-applied discounts
4356        try {
4357            $("input[name$='[auto_applied]'][value='True']").each(function () {
4358                var discountCode = $(this).data("discount-code");
4359
4360                // Find the corresponding stackable input for the same discount code
4361                var $stackableInput = $("input[data-discount-code='" + $.escapeSelector(discountCode) + "'][name$='[stackable]']");
4362
4363                if ($stackableInput.length) {
4364                    if ($stackableInput.val().toLowerCase() === "true") {
4365                        hasStackableAuto = true;
4366                    } else if ($stackableInput.val().toLowerCase() === "false") {
4367                        hasNonStackableAuto = true;
4368                    }
4369                }
4370            });
4371        } catch (err) {
4372            console.error("Error while checking auto-applied discounts:", err);
4373        }
4374
4375        var txtDiscount = $("[id$='txtDiscountCode']").val();
4376        var hdfDiscountApplied = $("[id$='hdfDiscountApplied']").val();
4377        if (txtDiscount != null && txtDiscount != '' && (hdfDiscountApplied != '' || hasStackableAuto === true || hasNonStackableAuto === true)) {
4378            page.ajax({
4379                url: '~/Services/ShoppingCart.asmx/IsStackableDiscount',
4380                parameters: {
4381                    discountCode: txtDiscount
4382                },
4383                showProgress: true,
4384                success: function (isStackable) {
4385                    // note: hdfDiscountApplied = 0 means there is already a stackable discount manually applied, hdfDiscountApplied = 1 means there is already a non-stackable discount manually applied
4386                    if ((hdfDiscountApplied != '' && (hdfDiscountApplied == "1" || !isStackable)) || // if a discount has aready been manually applied and the new one is non-stackable, then we need to warn the user since the new one may replace the previously manually applied one
4387                                                                                                    // if a discount has already been manually applied and it is non-stackable, then we need to warn the user since the new one may replace the previously manually applied one
4388                        (hasStackableAuto === true && isStackable === false) || // if there is at least one auto-applied stackable discount, and the new one is non-stackable, then we need to warn the user since the new one may replace the auto-applied one
4389                        (hasNonStackableAuto === true && isStackable === true) || // if there is at least one auto-applied non-stackable discount, and the new one is stackable, then we need to warn the user since the new one may replace the auto-applied one
4390                        (hasNonStackableAuto === true && isStackable === false)) // if there is at least one auto-applied non-stackable discount, and the new one is non-stackable, then we need to warn the user since the new one may replace the auto-applied one
4391                            dialog.confirm(event, { icon: 'Warning', title: 'Apply Discount', message: 'This discount may replace any discounts previously applied. Are you sure you want to apply the promo code?' });
4392                    else
4393                        page.postback(eventTarget, eventArgument);
4394                }
4395            });
4396            return false;
4397        }
4398        else
4399            return true;
4400    },
4401    getAllCarts: function (successCallback, errorCallback, displayError) {
4402        if (successCallback != null && typeof (successCallback) == 'function') {
4403            page.ajax({
4404                url: '~/Services/ShoppingCart.asmx/GetCartItems',
4405                parameters: {},
4406                showProgress: false,
4407                success: function (items) {
4408                    successCallback.call(this, items);
4409                },
4410                error: function (message) {
4411                    if (errorCallback != null && typeof (errorCallback) == 'function') {
4412                        errorCallback.call(this, message);
4413                    }
4414                    if (displayError == true) {
4415                        if (message) {
4416                            page.displayError('Shopping Cart', message);
4417                        }
4418                    }
4419                }
4420            });
4421        }
4422    },
4423    getCustomerCart: function (customerId, successCallback, errorCallback, displayError) {
4424        if (successCallback != null && typeof (successCallback) == 'function') {
4425            page.getAllCarts(function (items) {
4426                var item = items.firstOrDefault(function (c) { return c.CustomerId == customerId; });
4427                successCallback.call(this, item);
4428            }, function () {
4429                if (errorCallback != null && typeof (errorCallback) == 'function') {
4430                    errorCallback.call(this, message);
4431                }
4432                if (displayError == true) {
4433                    if (message) {
4434                        page.displayError('Shopping Cart', message);
4435                    }
4436                }
4437            }, false);
4438        }
4439    },
4440    addCartItem: function (customerId, individualId, currencyId, productId, productCustomerId, parentProductId, grandParentProductId, quantity, doNotAddIfExists, doNotPostBack, successCallback, errorCallback, displayError) {
4441        if (customerId != null) {
4442            if (productId != null) {
4443                page.ajax({
4444                    url: '~/Services/ShoppingCart.asmx/AddCartItem',
4445                    parameters: {
4446                        'customerId': customerId,
4447                        'individualId': individualId == null || individualId == 'null' ? null : individualId,
4448                        'currencyId': currencyId == null || currencyId == 'null' ? null : currencyId,
4449                        'productId': productId,
4450                        'productCustomerId': productCustomerId == null || productCustomerId == 'null' ? null : productCustomerId,
4451                        'parentProductId': parentProductId == null || parentProductId == 'null' ? null : parentProductId,
4452                        'grandParentProductId': grandParentProductId == null || grandParentProductId == 'null' ? null : grandParentProductId,
4453                        'quantity': quantity == null || isNaN(quantity) ? 1 : parseInt(quantity),
4454                        'doNotAddIfExists': doNotAddIfExists == null ? false : doNotAddIfExists
4455                    },
4456                    showProgress: false,
4457                    success: function () {
4458                        $('#main_browserNavigationWarning').val('');
4459                        if (successCallback != null && typeof (successCallback) == 'function') {
4460                            successCallback.call(this);
4461                        }
4462                        else if (doNotPostBack != true) {
4463                            page.postback('main_updContent', '');
4464                        }
4465                    },
4466                    error: function (message) {
4467                        if (errorCallback != null && typeof (errorCallback) == 'function') {
4468                            errorCallback.call(this);
4469                        }
4470                        else if (displayError != null && displayError == true) {
4471                            page.displayError('Error', message);
4472                        }
4473                    }
4474                });
4475            }
4476            else {
4477                page.displayError('Add to Cart', 'Unable to add to cart. Unknown product.');
4478            }
4479        }
4480        else {
4481            page.displayError('Add to Cart', 'Unable to add to cart. Unknown customer.');
4482        }
4483    },
4484    removeCartItem: function (customerId, individualId, currencyId, productId, productCustomerId, parentProductId, grandParentProductId, doNotConfirm, doNotRefresh, successCallback, errorCallback, displayError) {
4485        var callService = function (customerId, individualId, currencyId, productId, productCustomerId, parentProductId, grandParentProductId, doNotRefresh, successCallback, errorCallback, displayError) {
4486            page.ajax({
4487                url: '~/Services/ShoppingCart.asmx/RemoveCartItem',
4488                parameters: {
4489                    'customerId': customerId,
4490                    'individualId': individualId == 'null' ? null : individualId,
4491                    'currencyId': currencyId == 'null' ? null : currencyId,
4492                    'productId': productId,
4493                    'productCustomerId': productCustomerId,
4494                    'parentProductId': parentProductId == 'null' ? null : parentProductId,
4495                    'grandParentProductId': grandParentProductId == 'null' ? null : grandParentProductId
4496                },
4497                showProgress: false,
4498                success: function () {
4499                    $('#main_browserNavigationWarning').val('');
4500                    if (successCallback != null && typeof (successCallback) == 'function') {
4501                        successCallback.call(this);
4502                    }
4503                    else if (doNotRefresh != true) {
4504                        page.refresh(true, 'itemRemoved=1');
4505                    }
4506                },
4507                error: function (message) {
4508                    if (errorCallback != null && typeof (errorCallback) == 'function') {
4509                        errorCallback.call(this);
4510                    }
4511                    else if (displayError == null || displayError == true) {
4512                        page.displayError('Error', message);
4513                    }
4514                }
4515            });
4516        }
4517        if (doNotConfirm == true) {
4518            callService(customerId, individualId, currencyId, productId, productCustomerId, parentProductId, grandParentProductId, doNotRefresh, successCallback, errorCallback, displayError);
4519        }
4520        else {
4521            dialog.confirm(null, {
4522                'title': 'Remove Shopping Cart Item',
4523                'icon': 'Warning',
4524                'message': 'Are you sure you want to remove this item from your shopping cart?',
4525                'okClicked': function () {
4526                    callService(customerId, individualId, currencyId, productId, productCustomerId, parentProductId, grandParentProductId, doNotRefresh, successCallback, errorCallback, displayError);
4527                }
4528            });
4529        }
4530    },
4531
4532    validateAmountOnTextChanged: function (textbox, compareValidator, rangeValidator) {
4533
4534        var amountTxt = $(textbox).val();
4535        var isCredit = $("#chkApplyCredit").is(":checked");
4536        var comparevalidatorid = $("[id$='_" + compareValidator + "']").attr('id');
4537        var rangevalidatorid = $("[id$='_" + rangeValidator + "']").attr('id');
4538        var compareValName = document.getElementById(comparevalidatorid);
4539        var rangeValName = document.getElementById(rangevalidatorid);
4540        var currencyDecimalSeparator = $(textbox).attr('data-currency-decimal-separator');
4541        var currencyGroupSeparator = $(textbox).attr('data-currency-group-separator');
4542
4543        const repeatedGroupSeparator = /([","])\1{1,}/;
4544        const repeatedDecimalSeparator = /(["."]).*\1/;
4545
4546        if (currencyDecimalSeparator === ',')
4547            amountTxt = amountTxt.replaceAll(currencyGroupSeparator, '#').replaceAll(currencyDecimalSeparator, '.').replaceAll('#', ',');
4548
4549        if (repeatedGroupSeparator.test(amountTxt.toString()) || repeatedDecimalSeparator.test(amountTxt.toString())) {
4550            ValidatorEnable(compareValName, true);
4551            ValidatorEnable(rangeValName, false);
4552            return;
4553        }
4554
4555        amountTxt = amountTxt.replaceAll(',', '');
4556
4557        if (isNaN(amountTxt)) {
4558            ValidatorEnable(compareValName, true);
4559            ValidatorEnable(rangeValName, false);
4560        } else {
4561            ValidatorEnable(compareValName, false);
4562            if ((amountTxt < 0 && isCredit == true) || (amountTxt <= 0 && isCredit == false))
4563                ValidatorEnable(rangeValName, true);
4564            else
4565                ValidatorEnable(rangeValName, false);
4566        }
4567
4568    },
4569    updateCartNumbers: function (e) {
4570        // update current item
4571        var index = $(e).attr('data-index');
4572        var id = $(e).attr('data-id');
4573        var parentId = $(e).attr('data-parent-id');
4574        var customerId = $(e).attr('data-customer-id');
4575        var productType = $('[data-role="product-type"][data-index="' + index + '"][data-id="' + id + '"][data-parent-id="' + parentId + '"][data-customer-id="' + customerId + '"]').text();
4576        var quantityElement = $('[data-role="quantity"][data-index="' + index + '"][data-id="' + id + '"][data-parent-id="' + parentId + '"][data-customer-id="' + customerId + '"]');
4577        var maxQuantityElement = $('[data-role="max-quantity"][data-index="' + index + '"][data-id="' + id + '"][data-parent-id="' + parentId + '"][data-customer-id="' + customerId + '"]');
4578        var quantity = parseInt(quantityElement.is('input') ? quantityElement.val() : quantityElement.text());
4579        if (quantity > window.maxCartQuantity - 1) {
4580            maxQuantityElement.removeClass('display-none');
4581        }
4582
4583        /* Multi Currency */
4584        var totalElement = $('[data-role="total"][data-index="' + index + '"][data-id="' + id + '"][data-parent-id="' + parentId + '"][data-customer-id="' + customerId + '"]');
4585
4586        var currencySymbol = totalElement.attr('data-currency-symbol');
4587        var currencyFormat = totalElement.attr('data-currency');
4588        var currencyDecimalSeparator = totalElement.attr('data-currency-decimal-separator');
4589        var formatter = new Intl.NumberFormat(currencyFormat, { minimumIntegerDigits: 1, minimumFractionDigits: 2, maximumFractionDigits: 2 });
4590
4591        var priceElement = $('[data-role="price"][data-index="' + index + '"][data-id="' + id + '"][data-parent-id="' + parentId + '"][data-customer-id="' + customerId + '"]');
4592        var nonNumericRegex = new RegExp('[^0-9\\' + currencyDecimalSeparator + ']', 'g');
4593        var priceOriginal = priceElement.is('input') ? priceElement.val().replace(nonNumericRegex, '') : priceElement.text().replace(nonNumericRegex, '');
4594        var price = parseFloat(priceOriginal);
4595        if (currencyDecimalSeparator === ',')
4596            price = parseFloat(priceOriginal.replace(',', '.'));
4597
4598        if (isNaN(price)) {
4599            price = 0;
4600            priceElement.val(formatter.format(price.toFixed(2)));
4601        }
4602        if (isNaN(quantity)) {
4603            quantity = 0;
4604            quantityElement.val(quantity);
4605        }
4606
4607        if (quantity * price === 0) {
4608            totalElement.text(productType === 'Fund' ? currencySymbol + formatter.format(price.toFixed(2)) : 'Free');
4609        }
4610        else {
4611            totalElement.text(currencySymbol + formatter.format((quantity * price).toFixed(2)));
4612        }
4613        // update child items, if any
4614        if (parentId === '') {
4615            $('[data-role="total"][data-parent-id="' + id + '"][data-customer-id="' + customerId + '"]').each(function () {
4616                var childIndex = $(this).attr('data-index');
4617                var childId = $(this).attr('data-id');
4618                var parentQuantityPerItem = $('[data-role="quantity"][data-index="' + childIndex + '"][data-id="' + childId + '"][data-parent-id="' + id + '"][data-customer-id="' + customerId + '"]').attr('data-parent-quantity-per-item');
4619                if (parentQuantityPerItem === '1') {
4620                    $('[data-role="quantity"][data-index="' + childIndex + '"][data-id="' + childId + '"][data-parent-id="' + id + '"][data-customer-id="' + customerId + '"]').text(quantity);
4621                    priceElement = $('[data-role="price"][data-index="' + childIndex + '"][data-id="' + childId + '"][data-parent-id="' + id + '"][data-customer-id="' + customerId + '"]');
4622                    priceOriginal = priceElement.is('input') ? priceElement.val().replace(nonNumericRegex, '') : priceElement.text().replace(nonNumericRegex, '');
4623                    price = parseFloat(priceOriginal);
4624                    if (currencyDecimalSeparator === ',')
4625                        price = parseFloat(priceOriginal.replace(',', '.'));
4626                    if (isNaN(price)) {
4627                        price = 0;
4628                    }
4629                    if (quantity * price === 0) {
4630                        var childProductType = $('[data-role="product-type"][data-index="' + childIndex + '"][data-id="' + childId + '"][data-parent-id="' + id + '"][data-customer-id="' + customerId + '"]').text();
4631                        $(this).text(childProductType === 'Fund' ? currencySymbol + formatter.format(price.toFixed(2)) : 'Free');
4632                    }
4633                    else {
4634                        $(this).text(currencySymbol + formatter.format((quantity * price).toFixed(2)));
4635                    }
4636                }
4637            });
4638        }
4639        // update cart subtotal
4640        var isAnyDonation = false;
4641        var subtotal = parseFloat(0);
4642        $('[data-role="total"]').each(function () {
4643            var index = $(this).attr('data-index');
4644            var id = $(this).attr('data-id');
4645            var parentId = $(this).attr('data-parent-id');
4646            var customerId = $(this).attr('data-customer-id');
4647            var productType = $('[data-role="product-type"][data-index="' + index + '"][data-id="' + id + '"][data-parent-id="' + parentId + '"][data-customer-id="' + customerId + '"]').text();
4648            if (productType === 'Fund') {
4649                isAnyDonation = true;
4650            }
4651
4652            var current = parseFloat($(this).text().replace(nonNumericRegex, ''));
4653            if (currencyDecimalSeparator === ',')
4654                current = parseFloat($(this).text().replace(nonNumericRegex, '').replace(',', '.'));
4655
4656            if (isNaN(current)) {
4657                current = 0;
4658            }
4659            subtotal += current;
4660        });
4661        var subtotalElement = $('[data-role="subtotal"]');
4662        if (subtotal === 0) {
4663            subtotalElement.text(isAnyDonation ? currencySymbol + formatter.format(subtotal.toFixed(2)) : 'Free');
4664        }
4665        else {
4666            subtotalElement.text(currencySymbol + formatter.format(subtotal.toFixed(2)));
4667        }
4668
4669        // show the update cart button
4670        if ($(e).attr('data-role') === 'quantity' || subtotal === 0 || (subtotal > 0 && $('#main_content_ctlCheckout_wizCheckout_ctlCart_ddlBatch').length > 0)) {
4671            $('.btn-cart-update').removeClass('display-none');
4672            $('.btn-cart-checkout').addClass('display-none');
4673            $("[id$='lnkApplyDiscount']").attr('disabled', true);
4674        }
4675        else {
4676            //remove discount text
4677            $("[data-role='product-discount'][data-index='" + index + "'][data-id='" + id + "']").html('');
4678            $('.btn-cart-update').addClass('display-none');
4679            $('.btn-cart-checkout').removeClass('display-none');
4680            $("[id$='lnkApplyDiscount']").attr('disabled', false);
4681        }
4682    },
4683    enableBtnApplyCode: function () {
4684        $("[id$='lnkApplyDiscount']").attr('disabled', false);
4685        return true;
4686    },
4687    updatePaymentWizardTotal: function (e, id, currencyDecimalSeparator, currencySymbol, currencyFormat) {
4688        // update cart subtotal
4689        var subtotalElement = $('[data-role="total"]');
4690        var regex = new RegExp('[^0-9\\' + currencyDecimalSeparator + ']', 'g');
4691        var formatter = new Intl.NumberFormat(currencyFormat, { minimumIntegerDigits: 1, minimumFractionDigits: 2, maximumFractionDigits: 2 });
4692
4693        var currentBalance = parseFloat(subtotalElement.text().replace(regex, ''));
4694        if (currencyDecimalSeparator === ',')
4695            currentBalance = parseFloat(subtotalElement.text().replace(regex, '').replace(',', '.'));
4696        if (isNaN(currentBalance)) {
4697            currentBalance = parseFloat(0);
4698        }
4699        var balance;
4700        if ($(e).is(':checked')) {
4701            balance = $('[data-role="balance"][data-id="' + id + '"]').text().replace(regex, '');
4702            if (currencyDecimalSeparator === ',')
4703                balance = parseFloat($('[data-role="balance"][data-id="' + id + '"]').text().replace(regex, '').replace(',', '.'));
4704            currentBalance += parseFloat(balance);
4705        }
4706        else if (currentBalance !== 0) {
4707            balance = $('[data-role="balance"][data-id="' + id + '"]').text().replace(regex, '');
4708            if (currencyDecimalSeparator === ',')
4709                balance = parseFloat($('[data-role="balance"][data-id="' + id + '"]').text().replace(regex, '').replace(',', '.'));
4710            currentBalance -= parseFloat(balance);
4711        }
4712        if (isNaN(currentBalance)) {
4713            currentBalance = 0;
4714        }
4715        if (currencyDecimalSeparator === ',')
4716            subtotalElement.text(formatter.format(currentBalance.toFixed(2)) + ' ' + currencySymbol);
4717        else
4718            subtotalElement.text(currencySymbol + ' ' + formatter.format(currentBalance.toFixed(2)));
4719    },
4720    updatePaymentWizardTotalPaymentDue: function (e, id, currencyDecimalSeparator) {
4721        var subtotalElement = $('[data-role="total-payment-due"]');
4722        var regex = new RegExp('[^0-9\\' + currencyDecimalSeparator + ']', 'g');
4723        var balance = $('[data-role="payment-due"][data-id="' + id + '"]').val().replace(regex, '');
4724        if (currencyDecimalSeparator === ',')
4725            balance = parseFloat($('[data-role="payment-due"][data-id="' + id + '"]').val().replace(regex, '').replace(',', '.'));
4726        if (isNaN(balance)) {
4727            $('[data-role="payment-due"][data-id="' + id + '"]').val(0);
4728        }
4729        else if (balance < 0) {
4730            $('[data-role="payment-due"][data-id="' + id + '"]').val(0);
4731        }
4732
4733        var currencySymbol = $($('[data-currency-symbol]')[0]).attr('data-currency-symbol');
4734        var currencyFormat = $($('[data-currency]')[0]).attr('data-currency');
4735        var formatter = new Intl.NumberFormat(currencyFormat, { minimumIntegerDigits: 1, minimumFractionDigits: 2, maximumFractionDigits: 2 });
4736
4737        var subtotal = parseFloat(0);
4738        $('[data-role="payment-due"]').each(function () {
4739            var current = parseFloat($(this).val().replace(regex, ''));
4740            if (currencyDecimalSeparator === ',')
4741                current = parseFloat($(this).val().replace(regex, '').replace(',', '.'));
4742            if (isNaN(current)) {
4743                current = 0;
4744            }
4745            subtotal += current;
4746        });
4747        if (currencyDecimalSeparator === ',')
4748            subtotalElement.text(formatter.format(subtotal.toFixed(2)) + ' ' + currencySymbol);
4749        else
4750            subtotalElement.text(currencySymbol + ' ' + formatter.format(subtotal.toFixed(2)));
4751    },
4752    updatePaymentWizardFutureBalance: function (e, id) {
4753
4754        var currencySymbol = $($('[data-currency-symbol]')[0]).attr('data-currency-symbol');
4755        var currencyFormat = $($('[data-currency]')[0]).attr('data-currency');
4756        var currencyDecimalSeparator = $($('[data-currency-decimal-separator]')[0]).attr('data-currency-decimal-separator');
4757        var formatter = new Intl.NumberFormat(currencyFormat, { minimumIntegerDigits: 1, minimumFractionDigits: 2, maximumFractionDigits: 2 });
4758
4759        var regex = new RegExp('[^0-9\\' + currencyDecimalSeparator + ']', 'g');
4760
4761        var curTotal = parseFloat(0);
4762        var futTotal = parseFloat(0);
4763        var paymentAmount = parseFloat($('[data-role="payment-amount"]').val().replace(regex, ''));
4764        if (currencyDecimalSeparator === ',')
4765            paymentAmount = parseFloat($('[data-role="payment-amount"]').val().replace(regex, '').replace(',', '.'));
4766        if (paymentAmount < 0) {
4767            $('[data-role="payment-amount"]').val(0);
4768            paymentAmount = 0;
4769        }
4770
4771        //var creditAmount = parseFloat($('[data-role=total-credit-amount]').val());
4772        //if (isNaN(creditAmount)) {
4773        //    creditAmount = parseFloat(0);
4774        //}
4775
4776        var totalPaymentLabel = $('[data-role="total-payment-amount"]');
4777        var balanceAmount = parseFloat($('[data-role="total-balance-due"]').text().replace("$", "").replace(regex, ''));
4778        if (currencyDecimalSeparator === ',')
4779            balanceAmount = parseFloat($('[data-role="total-balance-due"]').text().replace("$", "").replace(regex, '').replace(',', '.'));
4780
4781        var futureAmountLabel = $('[data-role="total-future-amount"]');
4782        curTotal = paymentAmount; // + creditAmount;
4783        futTotal = balanceAmount - curTotal;
4784        if (isNaN(futTotal)) {
4785            futTotal = parseFloat(0);
4786        }
4787        if (isNaN(curTotal)) {
4788            curTotal = parseFloat(0);
4789        }
4790        if (futTotal < 0) {
4791            futTotal = parseFloat(0);
4792        }
4793
4794        totalPaymentLabel.text(currencySymbol + formatter.format(curTotal.toFixed(2)));
4795        futureAmountLabel.text(currencySymbol + formatter.format(futTotal.toFixed(2)));
4796    },
4797    initProfileInfo: function () {
4798        var lblsOveriewInfo = $('.lblProfileBalance');
4799        lblsOveriewInfo.each(function () {
4800            var lblOveriewInfo = $(this).text();
4801            if (lblOveriewInfo != null && lblOveriewInfo !== '') {
4802                var infoOverview = JSON.parse(lblOveriewInfo);
4803                if (!jQuery.isEmptyObject(infoOverview)) {
4804                    page.showBalanceOnProfile(infoOverview.CustomerId,
4805                        infoOverview.CustomerType,
4806                        infoOverview.IsMyProfile,
4807                        infoOverview.HasSubmitPaymentAccess,
4808                        infoOverview.IsOrgProfileAndStaff,
4809                        lblsOveriewInfo.length > 1,
4810                        true,
4811                        infoOverview.EncryptedToken);
4812                }
4813            }
4814        });
4815
4816        var lblsMembershipProfileInfo = $('.lblMembershipBalance');
4817        lblsMembershipProfileInfo.each(function () {
4818            var lblMembershipProfileInfo = $(this).text();
4819            if (lblMembershipProfileInfo != null && lblMembershipProfileInfo !== '') {
4820                var infoMembership = JSON.parse(lblMembershipProfileInfo);
4821                if (!jQuery.isEmptyObject(infoMembership)) {
4822                    page.showMembershipOnProfile(infoMembership.CustomerId,
4823                        infoMembership.IsStaff,
4824                        infoMembership.IsMyProfile,
4825                        infoMembership.IsOrg,
4826                        lblsMembershipProfileInfo.length > 1,
4827                        infoMembership.EncryptedToken
4828                    );
4829                }
4830            }
4831        });
4832
4833        var lblsProductProfileInfo = $('.lblProductBalance');
4834        lblsProductProfileInfo.each(function () {
4835            var lblProductProfileInfo = $(this).text();
4836            if (lblProductProfileInfo != null && lblProductProfileInfo !== '') {
4837                var infoProduct = JSON.parse(lblProductProfileInfo);
4838                if (!jQuery.isEmptyObject(infoProduct)) {
4839                    $('#divProductSlider').css('display', 'normal');
4840                    page.showProductOnProfile(infoProduct.CustomerId);
4841                }
4842            }
4843        });
4844
4845        var lblsBatchSummaryInfo = $('.lblBatchBalance');
4846        lblsBatchSummaryInfo.each(function () {
4847            var lblBatchSummaryInfo = $(this).text();
4848            if (lblBatchSummaryInfo != null && lblBatchSummaryInfo !== '') {
4849                var infoProduct = JSON.parse(lblBatchSummaryInfo);
4850                if (!jQuery.isEmptyObject(infoProduct)) {
4851                    page.showBatchSummaryOnProfile(infoProduct.BatchId);
4852                }
4853            }
4854        });
4855
4856        var lblsCampaignProfileInfo = $('.lblCampaignGoalSummary');
4857        lblsCampaignProfileInfo.each(function () {
4858            var lblCampaignProfileInfo = $(this).text();
4859            if (lblCampaignProfileInfo != null && lblCampaignProfileInfo !== '') {
4860                var infoProduct = JSON.parse(lblCampaignProfileInfo);
4861                if (!jQuery.isEmptyObject(infoProduct)) {
4862                    page.showCampaignOnProfile(infoProduct.CustomerId);
4863                }
4864            }
4865        });
4866    },
4867    showDiscountSummaryOnProfile: function () {
4868        var discountId = $('#summaryDiscount > input[type=hidden]').val();
4869
4870        var dollarUS = Intl.NumberFormat("en-US", {
4871            style: "currency",
4872            currency: "USD",
4873        });
4874
4875        page.ajax({
4876            url: '~/Services/Profile.asmx/GetDiscountSummary',
4877            parameters: {
4878                'productDiscountId': discountId
4879            },
4880            showProgress: false,
4881            success: function (summary) {
4882                try {
4883                    if (summary.HasTotalLimit === true) {
4884                        $('#lblTotalUsageLimit').html(summary.TotalUsageLimit);
4885                        $('#lblTotalUsesRemaining').html(summary.TotalUsesRemaining);
4886
4887                    } else {
4888                        $('#lblTotalUsageLimit').html('NA');
4889                        $('#lblTotalUsesRemaining').html('NA');
4890                    }
4891
4892                    $('#lblTotalCustomerUsage').html(summary.TotalCustomerUsage);
4893                    $('#lblDistinctCustomerUsage').html(summary.DistinctCustomerUsage);
4894                    $('#lblTotalAmountDiscounted').html(dollarUS.format(summary.TotalAmountDiscounted.Value));
4895                }
4896                catch (e) {
4897                    //do nothing
4898                }
4899            },
4900            error: function (message) {
4901                $('#lblTotalUsageLimit').html('Error calculating value');
4902                $('#lblTotalCustomerUsage').html('Error calculating value');
4903                $('#lblDistinctCustomerUsage').html('Error calculating value');
4904                $('#lblTotalUsesRemaining').html('Error calculating value');
4905                $('#lblTotalAmountDiscounted').html('Error calculating value');
4906            }
4907        });
4908    },
4909    refreshBalanceOnProfile: function () {
4910        var lblsOveriewInfo = $('.lblProfileBalance');
4911        lblsOveriewInfo.each(function () {
4912            var lblOveriewInfo = $(this).text();
4913            if (lblOveriewInfo != null && lblOveriewInfo !== '') {
4914                var infoOverview = JSON.parse(lblOveriewInfo);
4915                if (!jQuery.isEmptyObject(infoOverview)) {
4916                    var currentPage = lblsOveriewInfo.length > 1 ? $('[data-id="' + infoOverview.CustomerId + '"]') : $(document);
4917                    currentPage.find('.profile-balance-header').empty();
4918                    currentPage.find('.profile-balance-header').append('<div class="profile-balance-header align-center"><i class="progress-icon icon-refresh icon-spin"></i></div>');
4919                    $(currentPage.find('.hidProfileBalance').children()).val('');
4920
4921                    if (window.sessionStorage['impx-balance-profile-data-' + location.hostname]) {
4922                        var balanceProfile = JSON.parse(window.sessionStorage['impx-balance-profile-data-' + location.hostname]);
4923                        if (balanceProfile) {
4924                            delete balanceProfile[infoOverview.CustomerId];
4925                        } else {
4926                            balanceProfile = {};
4927                        }
4928                        window.sessionStorage['impx-balance-profile-data-' + location.hostname] = JSON.stringify(balanceProfile);
4929                    }
4930
4931                    page.showBalanceOnProfile(infoOverview.CustomerId,
4932                        infoOverview.CustomerType,
4933                        infoOverview.IsMyProfile,
4934                        infoOverview.HasSubmitPaymentAccess,
4935                        infoOverview.IsOrgProfileAndStaff,
4936                        lblsOveriewInfo.length > 1,
4937                        false,
4938                        infoOverview.EncryptedToken
4939                    );
4940                }
4941            }
4942        });
4943    },
4944    showBalanceOnProfile: function (customerId, customerType, isMyProfile, hasSubmitPaymentAccess, isOrgProfileAndStaff, isPartType, isDenormalized, encryptedToken) {
4945
4946        var currentPage = isPartType ? $('[data-id="' + customerId + '"]') : $(document);
4947        if (currentPage.find('.profile-balance-header').length > 0) {
4948            var ismyprofile = (isMyProfile === true);
4949            var hassubmitpaymentaccess = (hasSubmitPaymentAccess === true);
4950            var isorgprofileandstaff = (isOrgProfileAndStaff === true);
4951            var hiddenDiv = currentPage.find('.hidProfileBalance').children();
4952            var hidden = page.htmlDecode($(hiddenDiv).val());
4953            var balanceProfile = null;
4954            if (!window.sessionStorage['impx-balance-profile-data-' + location.hostname])
4955                balanceProfile = {};
4956            else
4957                balanceProfile = JSON.parse(window.sessionStorage['impx-balance-profile-data-' + location.hostname]);
4958            if (hidden === '' && (!balanceProfile || (balanceProfile && !balanceProfile[customerId]))) {
4959                page.ajax({
4960                    url: '~/Services/Profile.asmx/GetCustomerBalance',
4961                    parameters: {
4962                        'customerId': customerId,
4963                        'isDenormalized': isDenormalized,
4964                        'customerType': customerType,
4965                        'encryptedToken': encryptedToken
4966                    },
4967                    showProgress: false,
4968                    success: function (balanceData) {
4969                        page.displayOpenBalances(balanceData, customerId, ismyprofile, hassubmitpaymentaccess, isorgprofileandstaff, isPartType);
4970                    },
4971                    error: function (message) {
4972                        if (hassubmitpaymentaccess || ismyprofile || isOrgProfileAndStaff) {
4973                            currentPage.find('.profile-balance-header').empty();
4974                            var url = (ismyprofile ? '/account/payment.aspx?CustomerId=' : '/administration/accounting/payment-wizard/?CustomerId=') + customerId;
4975                            var paymentUrlText = isorgprofileandstaff ? "Search for Open Balances" : "Make Payment";
4976                            var html = '<div class="portlet-body"><div class="align-center"><a href="' + url + '" class="btn green"> ' + paymentUrlText + ' <i class="icon-chevron-right"></i></a></div></div>';
4977                            currentPage.find('.profile-balance-header').append(html);
4978                        }
4979                    }
4980                });
4981            } else {
4982                currentPage.find('.profile-balance-header').empty();
4983                var data = null;
4984                if (balanceProfile && balanceProfile[customerId]) {
4985                    data = JSON.parse(balanceProfile[customerId]);
4986                }
4987                if (hidden !== "") {
4988                    data = JSON.parse(hidden);
4989                }
4990                if (data !== null)
4991                    page.displayOpenBalances(data, customerId, ismyprofile, hassubmitpaymentaccess, isorgprofileandstaff, isPartType);
4992            }
4993        }
4994    },
4995    displayOpenBalances: function (balanceData, customerId, ismyprofile, hassubmitpaymentaccess, isorgprofileandstaff, isPartType) {
4996        if (balanceData == 'Invalid Token') {
4997            if (page.getValue('profileBalanceVal')) {
4998                balanceData = page.getValue('profileBalanceVal');
4999            } else {
5000                balanceData = [];
5001            }
5002        } else {
5003            page.setValue('profileBalanceVal', balanceData);
5004        }
5005        var currentPage = isPartType ? $('[data-id="' + customerId + '"]') : $(document);
5006        var hiddenDiv = currentPage.find('.hidProfileBalance').children();
5007        var balancestring = JSON.stringify(balanceData);
5008        var hasBalance = balanceData.length > 0;
5009        var paymentUrlText = !hasBalance && isorgprofileandstaff ? "Search for Open Balances" : "Make Payment";
5010        currentPage.find('.profile-balance-header').empty();
5011        var url = (ismyprofile ? '/account/payment.aspx?CustomerId=' : '/administration/accounting/payment-wizard/?CustomerId=') + customerId;
5012        var html = '<div class="portlet-body"><ul class="list-unstyled">';
5013        for (var i = 0; i < balanceData.length; i++) {
5014            html += '<li><span class="sale-info">' + (balanceData.length === 1 ? 'Unpaid Balances' : balanceData[i].StoreName + ' Store<br/><small class="float-left no-wrap"><i>' + balanceData[i].CurrencyName + '</i></small>') + '</span><span class="sale-num">' + balanceData[i].TotalBalance + '</span></li>';
5015        }
5016        html += '</ul>';
5017        if (hasBalance)
5018            html += '<ul class="list-unstyled"><li><a id="lnkRefreshOpenBalances" onclick="javascript:refreshOpenBalances();" class="btn blue btn-xs float-right margin-left-5" title="Refresh to recalculate open balances for this individual."><i class="icon-refresh"></i></a><small><label id="lblBalanceDate" class="balance-date float-right no-wrap">As of: ' + balanceData[0].BalanceDate + ' </label></small></li></ul>';
5019        html += (hassubmitpaymentaccess ? '<div class="align-center"><a href="' + url + '" class="btn green"> ' + paymentUrlText + ' <i class="icon-chevron-right"></i></a></div>' : '') + '</div>';
5020        if (hasBalance) {
5021            currentPage.find('.profile-balance-header').append(html);
5022        } else if (isorgprofileandstaff) {
5023            currentPage.find('.profile-balance-header').append(html);
5024        } else {
5025            currentPage.find('.profile-balance-header').append('<p class="float-left"><i>No Open Balances</i><p><ul class="list-unstyled"><li><a id="lnkRefreshOpenBalances" onclick="javascript:refreshOpenBalances();" class="btn blue btn-xs float-right margin-left-5" title="Refresh to recalculate open balances for this individual."><i class="icon-refresh"></i></a></li></ul>');
5026        }
5027
5028        var balanceProfile = null;
5029        if (hasBalance) {
5030            currentPage.find(hiddenDiv).val(page.htmlEncode(balancestring));
5031            if (!window.sessionStorage['impx-balance-profile-data-' + location.hostname])
5032                balanceProfile = {};
5033            else
5034                balanceProfile = JSON.parse(window.sessionStorage['impx-balance-profile-data-' + location.hostname]);
5035            //Only save 10 customers
5036            if (balanceProfile) {
5037                if (Object.keys(balanceProfile).length > 9) {
5038                    delete balanceProfile[Object.keys(balanceProfile)[0]];
5039                }
5040            } else {
5041                balanceProfile = {};
5042            }
5043            var balancestringEncoded = page.htmlEncode(balancestring);
5044            if (balancestringEncoded) {
5045                balanceProfile[customerId] = balancestringEncoded;
5046            }
5047
5048        }
5049        else {
5050            currentPage.find(hiddenDiv).val('');
5051            if (window.sessionStorage['impx-balance-profile-data-' + location.hostname]) {
5052                balanceProfile = JSON.parse(window.sessionStorage['impx-balance-profile-data-' + location.hostname]);
5053                if (balanceProfile)
5054                    delete balanceProfile[customerId];
5055                else
5056                    balanceProfile = {};
5057            }
5058        }
5059        if (balanceProfile) {
5060            window.sessionStorage['impx-balance-profile-data-' + location.hostname] = JSON.stringify(balanceProfile);
5061        }
5062    },
5063    processedDeceased: function (event, fullName, previousDeceased) {
5064        var chkchkIsDeceased = $("[name*='chkIsDeceased']");
5065        if ($(chkchkIsDeceased).is(':checked') && (previousDeceased == "False")) {
5066
5067            if (dialog.confirm(event,
5068                {
5069                    icon: 'Warning',
5070                    title: 'Warning',
5071                    message: fullName + ' has been marked as deceased. Click “OK” to automatically terminate and end date any active Memberships, Subscriptions, Committee Memberships, Committee Nominations, and Certifications that ' + fullName + ' has.',
5072                    'okClicked': function okClicked() {
5073                        $("[name*='chkIsDeceased']").prop('checked', true).uniform();
5074                    }
5075                })) {
5076                return true;
5077            }
5078            else {
5079                $(chkchkIsDeceased).prop('checked', true).uniform();
5080                return false;
5081            }
5082        }
5083        else {
5084            if (!$(chkchkIsDeceased).is(':checked') && (previousDeceased == 'True')) {
5085                if (dialog.confirm(event, {
5086                    icon: 'Warning',
5087                    title: 'Warning',
5088                    message: fullName + ' is no longer marked as deceased. If applicable, you must manually update any Certifications, Committee Memberships, Committee Nominations, Memberships, and Subscriptions. Then and notify staff members. Click “OK” to continue.',
5089                    'okClicked': function okClicked() {
5090                        $("[name*='chkIsDeceased']").prop('checked', false).uniform();
5091                    }
5092                })) {
5093                    return true;
5094                }
5095                else {
5096                    $(chkchkIsDeceased).prop('checked', true).uniform();
5097                    return false;
5098                }
5099            }
5100            return true;
5101        }
5102    },
5103    validateInstallmentDates: function () {
5104        if (dialog.confirm(event,
5105            {
5106                icon: 'Warning',
5107                title: 'Warning',
5108                message: 'The edits to the Schedule Date column will cause the installment plan to extend beyond the term’s expiration date. Do you want to save the changes you have made?',
5109                'okClicked': function okClicked() {
5110                    page.postback('overloadInstallmentDate', null);
5111                },
5112                'cancelClicked': function cancelClicked() {
5113                    page.postback('cancelOverloadInstallmentDate', null);
5114                },
5115            })) {
5116            return true;
5117        }
5118        else {
5119            return false;
5120        }
5121    },
5122    refreshMembershipOnProfile: function () {
5123        var lblsMembershipProfileInfo = $('.lblMembershipBalance');
5124        lblsMembershipProfileInfo.each(function () {
5125            var lblMembershipProfileInfo = $(this).text();
5126
5127            if (lblMembershipProfileInfo != null && lblMembershipProfileInfo !== '') {
5128                var infoMembership = JSON.parse(lblMembershipProfileInfo);
5129                if (!jQuery.isEmptyObject(infoMembership)) {
5130                    var currentPage = lblMembershipProfileInfo.length > 1 ? $('[data-id="' + infoMembership.CustomerId + '"]') : $(document);
5131                    $(document).find('.profile-membership-header').empty();
5132                    var htmlDivMembership = '<div class="portlet-title"><div class="caption">Memberships</div></div>';
5133                    htmlDivMembership += '<div class="profile-membership-header-spinner align-center">
5133<i class="progress-icon icon-refresh icon-spin"></i></div>'
5134                    $(document).find('.profile-membership-header').append(htmlDivMembership);
5135                    $($(document).find('.hidMembershipInfo').children()).val('');
5136
5137                    if (window.sessionStorage['impx-membership-profile-data-' + location.hostname]) {
5138                        var membershipProfile = JSON.parse(window.sessionStorage['impx-membership-profile-data-' + location.hostname]);
5139                        if (membershipProfile) {
5140                            delete membershipProfile[infoMembership.CustomerId];
5141                        } else {
5142                            membershipProfile = {};
5143                        }
5144                        // Disabled temporaly to always refresh membership info
5145                        // TODO: Remove session storage readings if its no more needed in future
5146                        // window.sessionStorage['impx-membership-profile-data-' + location.hostname] = JSON.stringify(membershipProfile);
5147                    }
5148
5149                    page.showMembershipOnProfile(infoMembership.CustomerId,
5150                        infoMembership.IsStaff,
5151                        infoMembership.IsMyProfile,
5152                        infoMembership.IsOrg,
5153                        lblsMembershipProfileInfo.length > 1,
5154                        infoMembership.EncryptedToken
5155                    );
5156                }
5157            }
5158        });
5159    },
5160    showMembershipOnProfile: function (customerId, isStaff, ismyprofile, isorg, isPartType, encryptedToken) {
5161        var currentPage = isPartType ? $('[data-id="' + customerId + '"]') : $(document);
5162        if (currentPage.find('.profile-membership-header').length > 0) {
5163            var isstaff = (isStaff === true);
5164            var hiddenDiv = currentPage.find('.hidMembershipInfo').children();
5165            var hidden = page.htmlDecode($(hiddenDiv).val());
5166
5167            var membershipProfile = null;
5168            var data = null;
5169            if (!window.sessionStorage['impx-membership-profile-data-' + location.hostname]) {
5170                membershipProfile = {};
5171            }
5172            else {
5173                membershipProfile = JSON.parse(window.sessionStorage['impx-membership-profile-data-' + location.hostname]);
5174                if (membershipProfile && membershipProfile[customerId]) {
5175                    data = JSON.parse(membershipProfile[customerId]);
5176                    if (data.forStaff !== isStaff)
5177                        membershipProfile = {};
5178                }
5179            }
5180
5181            if (hidden === '' && (!membershipProfile || (membershipProfile && !membershipProfile[customerId]))) {
5182                page.ajax({
5183                    url: '~/Services/Profile.asmx/GetMembershipInformation',
5184                    parameters: {
5185                        'customerId': customerId,
5186                        'ismyprofile': ismyprofile,
5187                        'isorg': isorg,
5188                        'encryptedToken': encryptedToken
5189                    },
5190                    showProgress: false,
5191                    success: function (membershipData) {
5192                        page.displayMembershipInfo(membershipData, customerId, isstaff, ismyprofile, isorg, isPartType);
5193                    },
5194                    error: function (message) {
5195                        currentPage.find('.profile-membership-header').empty();
5196                    }
5197                });
5198            } else {
5199                currentPage.find('.profile-membership-header').empty();
5200                if (membershipProfile && membershipProfile[customerId]) {
5201                    data = JSON.parse(membershipProfile[customerId]);
5202                }
5203                if (hidden !== "") {
5204                    data = JSON.parse(hidden);
5205                }
5206                if (data !== null)
5207                    page.displayMembershipInfo(data, customerId, isStaff, ismyprofile, isorg, isPartType);
5208            }
5209        }
5210    },
5211    displayMembershipInfo: function (membershipData, customerId, isstaff, ismyprofile, isorg, isPartType) {
5212        var currentPage = isPartType ? $('[data-id="' + customerId + '"]') : $(document);
5213        var hiddenDiv = currentPage.find('.hidMembershipInfo').children();
5214        if (membershipData == 'Invalid Token') {
5215            if (page.getValue('profileMembershipBalanceVal')) {
5216                membershipData = page.getValue('profileMembershipBalanceVal');
5217            }
5218        } else {
5219            page.setValue('profileMembershipBalanceVal', membershipData);
5220        }
5221        var membershipstring = JSON.stringify(membershipData);
5222        var hasMembership = membershipData.membershipsInfo.length > 0;
5223
5224        if (membershipData.JoinDate != null) {
5225            currentPage.find('.lCurrentMembership').html(membershipData.JoinDate);
5226            currentPage.find('.lCurrentMembership').addClass('label label-success text-transform-uppercase display-inline-block valign-middle');
5227        } else if (membershipData.receivesBenefits) {
5228            currentPage.find('.lCurrentMembership').html('Receives Membership Benefits');
5229            currentPage.find('.lCurrentMembership').addClass('label label-success text-transform-uppercase display-inline-block valign-middle');
5230        } else {
5231            currentPage.find('.lCurrentMembership').html('No Active Membership');
5232            currentPage.find('.lCurrentMembership').addClass('label label-danger text-transform-uppercase display-inline-block valign-middle');
5233        }
5234        if (membershipData.showInDirectory) {
5235            currentPage.find('.lDirectoryStatus').html('Opted-in to Show in <br/> Member Directory');
5236            currentPage.find('.lDirectoryStatus').addClass('label label-info text-transform-uppercase display-inline-block');
5237        } else {
5238            $('.lDirectoryStatus').html('Not Opted-in to Show <br/> in Member Directory');
5239            $('.lDirectoryStatus').addClass('label label-default text-transform-uppercase display-inline-block');
5240        }
5241        currentPage.find('.profile-membership-refresh-button').removeClass('display-none').addClass('display-inline-block');
5242        if (membershipData.membershipsInfo.length > 0) {
5243            currentPage.find('.profile-membership-header').empty();
5244            $('.lLoadingMembership').hide();
5245            var caption = '<span>' + (membershipData.membershipsInfo.length > 1 ? "Memberships" : "Membership") + '</span>';
5246            if (currentPage.find('.basic-profile').length === 0) {
5247                var queryToAdd = 'tab=activememberships';
5248                var memberUrl = window.location.href;
5249                if (window.location.href.indexOf('tab=activememberships') === -1) {
5250                    if (window.location.href.indexOf('tab=inactivememberships') !== -1)
5251                        memberUrl = memberUrl.replace('tab=inactivememberships', 'tab=activememberships');
5252                    else
5253                        memberUrl = memberUrl + (memberUrl.indexOf('?') > 0 ? '&' : '?') + queryToAdd;
5254                }
5255                caption = '<a href="' + memberUrl + '">' + (membershipData.membershipsInfo.length > 1 ? "Memberships" : "Membership") + '</a>';
5256            }
5257            var html = '<div class="portlet sale-summary"><div class="portlet-title"><div class="caption">' + caption + '</div></div><div class="portlet-body"><ul class="list-unstyled">';
5258            var inactive = 0;
5259            var btnInactive = false;
5260            for (var i = 0; i < membershipData.membershipsInfo.length; i++) {
5261                var payment = (membershipData.membershipsInfo[i].RenewlUrl !== null && (membershipData.membershipsInfo[i].RenewlUrl.toLowerCase().indexOf('/payment-wizard/') !== -1 || membershipData.membershipsInfo[i].RenewlUrl.toLowerCase().indexOf('payment.aspx') !== -1));
5262                if (membershipData.membershipsInfo[i].Active) {
5263                    html += '<li><div><span class="sale-info">' + (isstaff ? ('<a href="' + membershipData.membershipsInfo[i].Url + '">' + membershipData.membershipsInfo[i].Text + '</a>') : ('<span>' + membershipData.membershipsInfo[i].Text + '</span>')) + '</span>' +
5264                        '<span class="sale-num">' + (membershipData.membershipsInfo[i].RenewlUrl !== null ? '<a class="btn bg-accent-amber" href="' + membershipData.membershipsInfo[i].RenewlUrl.replace('~', '') + '">' +
5265                            (payment ? 'Pay' : 'Renew') + ' <i class="icon-chevron-right"></i></a></span>' : "</span>") +
5266                        '</div>';
5267                    if (membershipData.membershipsInfo[i].BenefitText !== null && membershipData.membershipsInfo[i].BenefitUrl !== null) {
5268                        html += '<div class="clearfix"></div><small><p>' + (isstaff ? '<a href="' + membershipData.membershipsInfo[i].BenefitUrl + '">' + membershipData.membershipsInfo[i].BenefitText + '</a>' : '<span>' + membershipData.membershipsInfo[i].BenefitText + '</span>') +
5269                            '</p></small>';
5270                    }
5271                    html += '</li>';
5272                }
5273                else {
5274                    if (membershipData.membershipsInfo[i].RenewlUrl !== null) {
5275                        inactive += 1;
5276                        if (inactive > 5) {
5277                            if (!btnInactive) {
5278                                btnInactive = true;
5279                                var urlProfile = '';
5280                                if (ismyprofile && isorg)
5281                                    urlProfile = '/account/organization.aspx?action=edit&id=' + customerId + '&tab=inactivememberships';
5282                                if (ismyprofile && !isorg)
5283                                    urlProfile = '/account/profile.aspx?tab=inactivememberships';
5284                                if (!ismyprofile && isorg)
5285                                    urlProfile = '/administration/customers/organizations/?action=edit&id=' + customerId + '&tab=inactivememberships';
5286                                if (!ismyprofile && !isorg)
5287                                    urlProfile = '/administration/customers/individuals/?action=edit&id=' + customerId + '&tab=inactivememberships';
5288                                html += '<li><div><span class="sale-num"><a href="' + urlProfile + '"><p><small style="font-size:small;">Click here to see the full list <i class="icon-chevron-right"></small></p></i></a></span>' + '</div></li>';
5289                            }
5290                        }
5291                        else {
5292                            html += '<li><div><span class="sale-info">' + (isstaff ? ('<a href="' + membershipData.membershipsInfo[i].Url + '">' + membershipData.membershipsInfo[i].Text + '</a>') : ('<span>' + membershipData.membershipsInfo[i].Text + '</span>')) + '</span>' +
5293                                '<span class="sale-num">' + (membershipData.membershipsInfo[i].RenewlUrl !== null ? '<a class="btn bg-accent-amber" href="' + membershipData.membershipsInfo[i].RenewlUrl.replace('~', '') + '">' +
5294                                    (payment ? 'Pay' : membershipData.membershipsInfo[i].TerminateDate !== null ? 'Rejoin' : 'Renew') + ' <i class="icon-chevron-right"></i></a></span>' : "</span>") +
5295                                '</div>';
5296                            if (membershipData.membershipsInfo[i].BenefitText !== null && membershipData.membershipsInfo[i].BenefitUrl !== null) {
5297                                html += '<div class="clearfix"></div><small><p>' + (isstaff ? '<a href="' + membershipData.membershipsInfo[i].BenefitUrl + '">' + membershipData.membershipsInfo[i].BenefitText + '</a>' : '<span>' + membershipData.membershipsInfo[i].BenefitText + '</span>') +
5298                                    '</p></small>';
5299                            }
5300                            html += '</li>';
5301                        }
5302                    }
5303                }
5304            }
5305            console.log($('.hfShowRealTimeMembership').val());
5306            if ($('.hfShowRealTimeMembership').val() === 'No') {
5307                if (membershipData.AsOfDate.length > 0) {
5308                    html += '</ul><small><label id="lblLastUpdateMembershipBenefitDate" class="balance-date float-right no-wrap" style="margin-right: 5px;">As of: ' + membershipData.AsOfDate + ' </label></small></div></div>';
5309                }
5310            }
5311            currentPage.find('.profile-membership-header').append(html);
5312        } else {
5313            currentPage.find('.profile-membership-header-spinner').empty();
5314            currentPage.find('.profile-membership-header-spinner').append('<p class="float-left"><i>No Memberships</i><p>');
5315            $('.lLoadingMembership').hide();
5316        }
5317
5318        var membershipProfile = null;
5319        if (hasMembership) {
5320            currentPage.find(hiddenDiv).val(page.htmlEncode(membershipstring));
5321            if (!window.sessionStorage['impx-membership-profile-data-' + location.hostname])
5322                membershipProfile = {};
5323            else
5324                membershipProfile = JSON.parse(window.sessionStorage['impx-membership-profile-data-' + location.hostname]);
5325            //Only save 10 customers
5326            if (membershipProfile) {
5327                if (Object.keys(membershipProfile).length > 9) {
5328                    delete membershipProfile[Object.keys(membershipProfile)[0]];
5329                }
5330            } else {
5331                membershipProfile = {};
5332            }
5333            var membershipstringEncoded = page.htmlEncode(membershipstring);
5334            if (membershipstringEncoded) {
5335                membershipProfile[customerId] = membershipstring;
5336            }
5337
5338        }
5339        else {
5340            currentPage.find(hiddenDiv).val('');
5341            if (window.sessionStorage['impx-membership-profile-data-' + location.hostname]) {
5342                membershipProfile = JSON.parse(window.sessionStorage['impx-membership-profile-data-' + location.hostname]);
5343                if (membershipProfile)
5344                    delete membershipProfile[customerId];
5345                else
5346                    membershipProfile = {};
5347            }
5348        }
5349        // Disabled temporaly to always refresh membership info
5350        // TODO: Remove session storage readings if its no more needed in future
5351        //if (membershipProfile) {
5352        //    window.sessionStorage['impx-membership-profile-data-' + location.hostname] = JSON.stringify(membershipProfile);
5353        //}
5354    },
5355    clearMembershipSession: function () {
5356        if (window.sessionStorage['impx-membership-profile-data-' + location.hostname]) {
5357            window.sessionStorage.removeItem('impx-membership-profile-data-' + location.hostname);
5358            window.sessionStorage['impx-membership-profile-data-' + location.hostname] = null;
5359            return true;
5360        }
5361        return false;
5362    },
5363    showProductOnProfile: function (productId) {
5364        if (productId.length > 0) {
5365            page.ajax({
5366                url: '~/Services/Profile.asmx/GetProductBalance',
5367                parameters: {
5368                    'productId': productId
5369                },
5370                showProgress: false,
5371                success: function (items) {
5372                    page.displayProductInfo(items);
5373                },
5374                error: function (message) {
5375                    $('.profile-product-balance-header').empty();
5376                }
5377            });
5378        }
5379    },
5380    displayProductInfo: function (items) {
5381        var htmlItem = '';
5382        var htmlMenu = '';
5383        var count = 0;
5384
5385        $('.profile-product-balance-header').removeAttr("style").empty();
5386        if (items.length == 0) {
5387            $("div[id$='divProductCurrency']").parent().hide();
5388        } else if (items.length == 1) {
5389            htmlItem += '<div class="item"><div class="portlet-body" style="height:150px;"> <ul class="list-unstyled" runat="server"> <li> <span class="sale-info">Total Sales</span> <span id="lblPurchases" runat="server" class="sale-num">' + items[0].TotalSales + '</span> </li> <li> <span class="sale-info">Unpaid Balances</span> <span id="lblUnpaidBalances" runat="server" class="sale-num">' + items[0].TotalBalance + '</span> </li> <li runat="server" id="liQuantitySold"> <span class="sale-info">Quantity Sold</span> <span id="lblInvoices" runat="server" class="sale-num">' + items[0].QuantitySold + '</span> </li> </ul> </div></div>';
5390        } else {
5391            items.forEach(function (item) {
5392                if (count == 0) {
5393                    htmlMenu += '<li data-target="#divProductCurrency" data-slide-to="' + count + '" class="active"></li>';
5394                    htmlItem += '<div class="item active"><div class="caption-currency-name">' + item.CurrencyName + '</div><div class="portlet-body" style="height:150px;"> <ul class="list-unstyled" runat="server"> <li> <span class="sale-info">Total Sales</span> <span id="lblPurchases" runat="server" class="sale-num">' + item.TotalSales + '</span> </li> <li> <span class="sale-info">Unpaid Balances</span> <span id="lblUnpaidBalances" runat="server" class="sale-num">' + item.TotalBalance + '</span> </li> <li runat="server" id="liQuantitySold"> <span class="sale-info">Quantity Sold</span> <span id="lblInvoices" runat="server" class="sale-num">' + item.QuantitySold + '</span> </li> </ul> </div></div>';
5395                    count++;
5396                } else {
5397                    htmlMenu += '<li data-target="#divProductCurrency" data-sli
5397de-to="' + count + '"></li>';
5398                    htmlItem += '<div class="item"><div class="caption-currency-name">' + item.CurrencyName + '</div><div class="portlet-body" style="height:150px;"> <ul class="list-unstyled" runat="server"> <li> <span class="sale-info">Total Sales</span> <span id="lblPurchases" runat="server" class="sale-num">' + item.TotalSales + '</span> </li> <li> <span class="sale-info">Unpaid Balances</span> <span id="lblUnpaidBalances" runat="server" class="sale-num">' + item.TotalBalance + '</span> </li> <li runat="server" id="liQuantitySold"> <span class="sale-info">Quantity Sold</span> <span id="lblInvoices" runat="server" class="sale-num">' + item.QuantitySold + '</span> </li> </ul> </div></div>';
5399                    count++;
5400                }
5401            });
5402        }
5403
5404        if (count > 1) {
5405            var ol = '<ol class="carousel-indicators">' + htmlMenu + '</ol>';
5406            var content = '<div class="carousel-inner">' + htmlItem + ' </div> <a href="#divProductCurrency" class="left carousel-control" data-slide="prev"> <span class="glyphicon glyphicon-chevron-left"></span> </a> <a href="#divProductCurrency" class="right carousel-control" data-slide="next"> <span class="glyphicon glyphicon-chevron-right"></span> </a>';
5407            $("div[id$='divProductCurrency']").html(ol + content);
5408            $("div[id$='divProductCurrency']").carousel({
5409                pause: true,
5410                interval: false
5411            });
5412        } else if (items.length == 1) {
5413            $("div[id$='divProductCurrency']").html(htmlItem);
5414        }
5415
5416    },
5417    showBatchSummaryOnProfile: function (batchId) {
5418        if (batchId) {
5419            page.ajax({
5420                url: '~/Services/Profile.asmx/GetBatchBalance',
5421                parameters: {
5422                    'batchId': batchId
5423                },
5424                showProgress: false,
5425                success: function (items) {
5426                    page.displayBatchSummary(items);
5427                },
5428                error: function (message) {
5429                    $('.profile-batch-balance-header').empty();
5430                }
5431            })
5432        }
5433    },
5434    displayBatchSummary: function (summary) {
5435        //ulBatchSummaryDetails
5436        $('.profile-batch-balance-header').removeAttr("style").empty();
5437
5438        if (summary) {
5439            var htmlDetails = '';
5440
5441            // Open Orders
5442            htmlDetails += GenDetailListItem('Open Orders', summary.OrdersCount, summary.OrdersAmount);
5443
5444            // Invoices
5445            htmlDetails += GenDetailListItem('Invoices', summary.InvoicesCount, summary.InvoicesAmount);
5446
5447            // Payments
5448            htmlDetails += GenDetailListItem('Payments', summary.PaymentsCount, summary.PaymentsAmount);
5449
5450            // Credits
5451            htmlDetails += GenDetailListItem('Credits', summary.CreditsCount, summary.CreditsAmount);
5452
5453            // Refunds
5454            htmlDetails += GenDetailListItem('Refunds', summary.RefundsCount, summary.RefundsAmount);
5455
5456            // Recognition
5457            htmlDetails += GenDetailListItem('Recognition', summary.RecognitionCount, summary.RecognitionAmount);
5458
5459            // Discounts
5460            htmlDetails += GenDetailListItem('Discounts', summary.DiscountsCount, summary.DiscountsAmount);
5461
5462            $('ul#ulBatchSummaryDetails').empty().append(htmlDetails);
5463        }
5464        else {
5465            $('ul#ulBatchSummaryDetails').removeAttr("style").empty();
5466        }
5467
5468        function GenDetailListItem(title, count, amount) {
5469            return '<li>' +
5470                '<span class="sale-info">' + title + '</span>' +
5471                '<span class="sale-num">' + count + '</span>' +
5472                '<span class="sale-amount">' + amount + '</span>' +
5473                '</li>';
5474        }
5475    },
5476    showCampaignOnProfile: function (campaignId) {
5477        if (campaignId.length > 0) {
5478            page.ajax({
5479                url: '~/Services/Profile.asmx/GetCampaignBalance',
5480                parameters: {
5481                    'campaignId': campaignId
5482                },
5483                showProgress: false,
5484                success: function (items) {
5485                    page.displayCampaignInfo(items);
5486                },
5487                error: function (message) {
5488                    $('.profile-product-balance-header').empty();
5489                }
5490            });
5491        }
5492    },
5493    displayCampaignInfo: function (items) {
5494        var htmlItem = '';
5495        var count = 0;
5496        $('.profile-product-balance-header').removeAttr("style").empty();
5497        if (items.length > 1) {
5498            items.forEach(function (item) {
5499                var isActive = count == 0;
5500                var htmlClass = isActive ? ' active' : '';
5501                htmlItem += '<div class="item' + htmlClass + '">' +
5502                    '<div class="caption-currency-name">' + item.CurrencyName + '</div>' +
5503                    '<div class="portlet-body" style="height:90px;">' +
5504                    '<ul class="list-unstyled" runat="server">' +
5505                    '<li runat="server" id="liQuantitySold">' +
5506                    '<span class="sale-info">Total Orders</span>' +
5507                    '<span id="lblInvoices" runat="server" class="sale-num">' + item.QuantitySold + '</span>' +
5508                    '</li>' +
5509                    '<li>' +
5510                    '<span class="sale-info">Total Amount</span>' +
5511                    '<span id="lblPurchases" runat="server" class="sale-num">' + item.TotalSales + '</span>' +
5512                    '</li>' +
5513                    '</ul>' +
5514                    '</div>' +
5515                    '</div>';
5516                count++;
5517            });
5518        } else if (items.length == 1) {
5519            $('#liCampaignMultiCurrency').css('display', 'none');
5520            $('#divCampaignSummaryValues ul').append('<li runat="server" id="liQuantitySold"><span class="sale-info">Total Orders</span><span id="lblInvoices" runat="server" class="sale-num">' + items[0].QuantitySold + '</span></li>');
5521            $('#divCampaignSummaryValues ul').append('<li><span class="sale-info">Total Amount</span><span id="lblPurchases" runat="server" class="sale-num">' + items[0].TotalSales + '</span></li>');
5522        }
5523
5524        if (count > 1) {
5525            var content = '<div class="carousel-inner">' + htmlItem + ' </div> <a href="#divProductCurrency" class="left carousel-control" data-slide="prev"> <span class="glyphicon glyphicon-chevron-left"></span> </a> <a href="#divProductCurrency" class="right carousel-control" data-slide="next"> <span class="glyphicon glyphicon-chevron-right"></span> </a>';
5526            $("div[id$='divProductCurrency']").html(content);
5527            $("div[id$='divProductCurrency']").carousel({
5528                pause: true,
5529                interval: false
5530            });
5531        } else if (items.length == 1) {
5532            $("div[id$='divProductCurrency']").html(htmlItem);
5533        }
5534    },
5535    verifyCCNumber: function (sender, e) {
5536        var textbox = $('#' + $(sender).attr('id').replace('valCCNumber', 'txtCCNumber'))[0];
5537        e.IsValid = page.verifyCreditCardNumber(textbox, true);
5538    },
5539    verifyCreditCardNumber: function (textbox, showError) {
5540        $(textbox).removeClass('error').removeClass('success');
5541        var label = $('#' + $(textbox).attr('id').replace('txtCCNumber', 'lblCCNumber'));
5542        var cardnumber = $(textbox).val().replace(/[ -]/g, '');
5543        // vault edit
5544        if (cardnumber.length == 8 && cardnumber.substring(0, 1) == '*') {
5545            return true;
5546        }
5547        label.html('');
5548        if (cardnumber.length >= 13) {
5549            // https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9781449327453/ch04s20.html
5550
5551            var matches = [];
5552
5553            if (/^(?:(3[47][0-9]{13}))$/.exec(cardnumber)
5554                && cardnumber.length >= 14) {
5555                matches.push({ type: 'American Express' });
5556            }
5557            if (/^(?:(3(?:0[0-5]|[68][0-9])[0-9]{11}))$/.exec(cardnumber)
5558                && cardnumber.length >= 14) {
5559                matches.push({ type: 'Diners Club' });
5560            }
5561            if (/^(?:(6(?:011|5[0-9]{2})[0-9]{12}))$/.exec(cardnumber)
5562                && cardnumber.length >= 14) {
5563                matches.push({ type: 'Discover' });
5564            }
5565            if (/^(?:(35(2[89]|[3-8][0-9])[0-9]{12}))$/.exec(cardnumber)
5566                && cardnumber.length >= 14) {
5567                matches.push({ type: 'JCB' });
5568            }
5569            if (/^(?:((?:5[1-5][0-9]{14})|(?:2(?:2[2-9]|[3-6][0-9]|7[0-2])[0-9]{13})))$/.exec(cardnumber)
5570                && cardnumber.length >= 14) {
5571                matches.push({ type: 'MasterCard' });
5572            }
5573            if (/^(?:(62[0-9]{11,17})|(81(([0-6][0-9]{10,16})|(7[01][0-9]{9,15}))))$/.exec(cardnumber)) {
5574                matches.push({
5575                    type: 'Union Pay',
5576                    luhnExempt: true
5577                });
5578            }
5579            if (/^(?:(4[0-9]{12}(?:[0-9]{3})?))$/.exec(cardnumber)
5580                && cardnumber.length >= 14) {
5581                matches.push({ type: 'Visa' });
5582            }
5583
5584            for (var i = 0; i < matches.length; i++) {
5585                if (matches[i].luhnExempt || page.checkCCByLuhnAlgorithm(cardnumber)) {
5586                    if ($('img[data-cc-type="' + matches[i].type + '"]').length > 0) {
5587                        $(textbox).addClass('success');
5588                        label.html('<img src="/images/' + matches[i].type.replace(' ', '-') + '.png" class="border-accent-steel" style="width: 30px;"/> <span>' + matches[i].type + '</span>');
5589                        return true;
5590                    }
5591                }
5592            }
5593        }
5594        if (showError) {
5595            $(textbox).addClass('error');
5596            label.html('<span class="accent-red">Invalid Card Number</span>');
5597        }
5598        return false;
5599    },
5600    checkCCByLuhnAlgorithm: function (cardnumber) {
5601        // https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9781449327453/ch04s20.html
5602        // Build an array with the digits in the card number
5603        var digits = cardnumber.split('');
5604        for (var i = 0; i < digits.length; i++) {
5605            digits[i] = parseInt(digits[i], 10);
5606        }
5607        // Run the Luhn algorithm on the array
5608        var sum = 0;
5609        var alt = false;
5610        for (i = digits.length - 1; i >= 0; i--) {
5611            if (alt) {
5612                digits[i] *= 2;
5613                if (digits[i] > 9) {
5614                    digits[i] -= 9;
5615                }
5616            }
5617            sum += digits[i];
5618            alt = !alt;
5619        }
5620        // Check the result
5621        return (sum % 10 == 0);
5622    },
5623    validateBoothSelection: function (e) {
5624        e = $(e);
5625        var parentContainer = e.is('select') ? e.parents('.product-booth').first() : e;
5626        var repeater = parentContainer.children('.product-booth-sizes').first();
5627        var items = repeater.children('div');
5628        if (items.length > 1) {
5629            var subtotal = 0;
5630            var hiddenPrice = parentContainer.find('.product-booth-subtotal > input[type=hidden]');
5631            var labelSubtotal = parentContainer.find('.product-booth-subtotal > span');
5632            // We start at index 1 since the first item is the header
5633            for (var i = 1; i < items.length; i++) {
5634                var item = $(items[i]);
5635                var ddlWidth = item.find('select[id$=ddlBoothWidth]');
5636                var ddlDepth = item.find('select[id$=ddlBoothDepth]');
5637                var ddlQuantity = item.find('select[id$=ddlBoothQuantity]');
5638                if (ddlWidth.val() != '' && ddlDepth.val() != '' && ddlQuantity.val() != '') {
5639                    var width = parseFloat(ddlWidth.val());
5640                    var depth = parseFloat(ddlDepth.val());
5641                    var quantity = parseInt(ddlQuantity.val());
5642                    var price = parseFloat(hiddenPrice.val());
5643                    subtotal += parseFloat((width * depth * quantity * price).toFixed(2));
5644                    ddlWidth.removeClass('error');
5645                    ddlDepth.removeClass('error');
5646                    ddlQuantity.removeClass('error');
5647                }
5648                else if (i > 1) {
5649                    if (ddlWidth.val() != '' || ddlDepth.val() != '' || ddlQuantity.val() != '') {
5650                        ddlWidth.val() != '' ? ddlWidth.removeClass('error') : ddlWidth.addClass('error');
5651                        ddlDepth.val() != '' ? ddlDepth.removeClass('error') : ddlDepth.addClass('error');
5652                        ddlQuantity.val() != '' ? ddlQuantity.removeClass('error') : ddlQuantity.addClass('error');
5653                    }
5654                    else {
5655                        ddlWidth.removeClass('error');
5656                        ddlDepth.removeClass('error');
5657                        ddlQuantity.removeClass('error');
5658                    }
5659                }
5660            }
5661            labelSubtotal.html(subtotal > 0 ? subtotal.toFixed(2) : "FREE");
5662        }
5663    },
5664    changeTheme: function (e, color) {
5665        $('#main_site_theme').attr('href', page.convertRelativeToAbsoluteUrl('/assets/css/themes/' + color + '.css'));
5666        $.cookie('site_theme', color, { expires: 365, path: '/' });
5667        $('.theme-div .theme-ul li a').removeClass('current');
5668        $(e).addClass('current');
5669        page.postback('main_isPostBack', '');
5670    },
5671    getIEVersion: function () {
5672        // http://msdn.microsoft.com/en-us/library/ms537509(v=vs.85).aspx
5673        // Returns the version of Internet Explorer or a -1 (indicating the use of another browser).
5674        var rv = -1; // Return value assumes failure.
5675        if (navigator.appName === 'Microsoft Internet Explorer') {
5676            rv = 0;
5677            var ua = navigator.userAgent;
5678            var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
5679            if (re.exec(ua) != null) {
5680                rv = parseFloat(RegExp.$1);
5681            }
5682        }
5683        else if (rv === -1 && !!window.MSInputMethodContext && !!document.documentMode) {
5684            rv = 11;
5685        }
5686        return rv;
5687    },
5688    isIE: function () {
5689        return page.getIEVersion() > -1;
5690    },
5691    isEdge: function () {
5692        return navigator.userAgent.indexOf('Edge') > -1;
5693    },
5694    isSafari: function () {
5695        return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
5696    },
5697    isFireFox: function () {
5698        return navigator.userAgent.toLowerCase().indexOf('firefox') > - 1;
5699    },
5700    isMobileDevice: function () {
5701        return (
5702            navigator.userAgent.match(/Android/i) ||
5703            navigator.userAgent.match(/BlackBerry/i) ||
5704            navigator.userAgent.match(/iPhone|iPad|iPod/i) ||
5705            navigator.userAgent.match(/Opera Mini/i) ||
5706            navigator.userAgent.match(/IEMobile/i)
5707        );
5708    },
5709    makeSameHeight: function (selector) {
5710        var maxHeight = 0;
5711        if (typeof (selector) == "string") {
5712            selector = $(selector);
5713        }
5714        selector.each(function () {
5715            if (maxHeight < $(this).height()) {
5716                maxHeight = $(this).height();
5717            }
5718        });
5719        if (maxHeight > 0) {
5720            selector.each(function () {
5721                $(this).css('height', maxHeight);
5722            });
5723        }
5724    },
5725    resizeByAspectRatio: function (actualWidth, actualHeight, maxWidth, maxHeight) {
5726        var newWidth = 0;
5727        var newHeight = 0;
5728        if (actualWidth <= maxWidth && actualHeight <= maxHeight) {
5729            newWidth = actualWidth;
5730            newHeight = actualHeight;
5731        }
5732        else {
5733            if (actualWidth > actualHeight) {
5734                newWidth = maxWidth;
5735                newHeight = newWidth * actualHeight / actualWidth;
5736            }
5737            else if (actualWidth < actualHeight) {
5738                newHeight = maxHeight;
5739                newWidth = newHeight * actualWidth / actualHeight;
5740            }
5741            else if (actualWidth == actualHeight) {
5742                newWidth = maxWidth;
5743                newHeight = maxHeight;
5744            }
5745        }
5746        return { width: parseInt(newWidth), height: parseInt(newHeight) };
5747    },
5748    scrollToTop: function (offset) {
5749        if (window.frameElement && window.parent != null) {
5750            window.dialog.scrollToTop(offset);
5751        }
5752        else {
5753            if (offset == null || isNaN(offset) || offset < 0) {
5754                offset = 0;
5755            }
5756            $('html, body').animate({ scrollTop: offset }, 'fast');
5757        }
5758    },
5759    scrollToElement: function (selector, offset) {
5760        if ($(selector).length > 0 && $(selector).offset() != null) {
5761            if (!offset || isNaN(offset)) {
5762                offset = -20;
5763            }
5764            var topUIHeight = $('div.header.navbar.navbar-inverse.navbar-fixed-top').height();
5765            if (topUIHeight == null) {
5766                topUIHeight = 0;
5767            }
5768            var top = $(selector).offset().top - topUIHeight + offset;
5769            $('html, body').animate({ scrollTop: top < 0 ? 0 : top }, 'fast');
5770        }
5771    },
5772    scrollContainerToTop: function (containerSelector, offset) {
5773        if (!offset || isNaN(offset)) {
5774            offset = 0;
5775        }
5776        $(containerSelector).animate({ scrollTop: offset - $(containerSelector).offset().top }, 'fast');
5777    },
5778    scrollContainerToElement: function (containerSelector, elementSelector, offset) {
5779        if (!offset || isNaN(offset)) {
5780            offset = 0;
5781        }
5782        var top = $(containerSelector).scrollTop() - $(containerSelector).offset().top + $(elementSelector).offset().top + offset;
5783        $(containerSelector).animate({ scrollTop: top }, 'fast');
5784    },
5785    fadeElement: function (id, isDialog) {
5786        var timer = window.setTimeout(function () {
5787            $('#' + id).fadeOut('3000');
5788            if (isDialog) {
5789                dialog.resize(null, true);
5790            }
5791            window.clearTimeout(timer);
5792        }, 3000);
5793    },
5794    convertDateStringToLocalDate: function (utc) {
5795        // Create a local date from the date string
5796        var utcTime = utc.replace('/Date(', '').replace(')/', '');
5797        return new Date(parseInt(utcTime));
5798    },
5799    convertUtcStringToLocalDate: function (utc) {
5800        // Create a local date from the UTC string
5801        var utcDate = page.convertDateStringToLocalDate(utc);
5802        return new Date(utcDate.getTime() - (utcDate.getTimezoneOffset() * 60 * 1000));
5803    },
5804    convertStringToBool: function (value) {
5805        return (value && (value == '1' || value.toLowerCase() == 'yes' || value.toLowerCase() == 'true'));
5806    },
5807    getMonthName: function (timestamp) {
5808        var d = new Date(timestamp);
5809        var numericMonth = d.getMonth();
5810        var monthArray = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
5811        if (window.cultureInfo !== undefined && window.cultureInfo !== null) {
5812            monthArray = window.cultureInfo.dateTimeFormat.MonthNames;
5813        }
5814        var alphaMonth = monthArray[numericMonth];
5815        return alphaMonth;
5816    },
5817    getTimeZoneOffset: function () {
5818        var now = new Date();
5819        var jan1 = new Date(now.getFullYear(), 0, 1, 0, 0, 0, 0); // jan 1st
5820        var jun1 = new Date(now.getFullYear(), 6, 1, 0, 0, 0, 0); // jun 1st
5821        var temp = jan1.toGMTString();
5822        var jan2 = new Date(temp.substring(0, temp.lastIndexOf(' ') - 1));
5823        temp = jun1.toGMTString();
5824        var jun2 = new Date(temp.substring(0, temp.lastIndexOf(' ') - 1));
5825        var standardTimeOffset = (jan1 - jan2) / (1000 * 60 * 60);
5826        var daylightTimeOffset = (jun1 - jun2) / (1000 * 60 * 60);
5827        var daylightSavingTime = false;
5828        if (standardTimeOffset != daylightTimeOffset) {
5829            var nowOffset = now.getTimezoneOffset();
5830            // positive is southern, negative is northern hemisphere
5831            var hemisphere = standardTimeOffset - daylightTimeOffset;
5832            if (hemisphere >= 0) {
5833                var janOffset = jan1.getTimezoneOffset();
5834                if (nowOffset == janOffset) {
5835                    // if offset of now is equal to offset of jan in southern hemisphere
5836                    standardTimeOffset = daylightTimeOffset;
5837                    daylightSavingTime = true;
5838                }
5839            }
5840            else {
5841                var junOffset = jun1.getTimezoneOffset();
5842                if (nowOffset == junOffset) {
5843                    // if offset of now is equal to offset of jun in northern hemisphere
5844                    standardTimeOffset = daylightTimeOffset;
5845                    daylightSavingTime = true;
5846                }
5847            }
5848        }
5849        var hours = parseInt(standardTimeOffset);
5850        standardTimeOffset -= parseInt(standardTimeOffset);
5851        standardTimeOffset *= 60;
5852        var mins = parseInt(standardTimeOffset);
5853        standardTimeOffset -= parseInt(standardTimeOffset);
5854        standardTimeOffset *= 60;
5855        var secs = parseInt(standardTimeOffset);
5856        var displayHours = '00';
5857        if (hours > 0) {
5858            displayHours = (hours < 10) ? '+0' + hours : '+' + hours;
5859        }
5860        else if (hours < 0) {
5861            displayHours = (hours > -10) ? '-0' + Math.abs(hours) : hours;
5862        }
5863        mins = (mins < 10) ? '0' + mins : mins;
5864        return { 'offset': displayHours + ':' + mins, 'dst': daylightSavingTime };
5865    },
5866    ensureTimeZoneCookie: function () {
5867        var timezoneIdCookie = "TimeZoneId";
5868        if ($.cookie(timezoneIdCookie) === undefined) {
5869            var timezoneCookie = "TimeZone";
5870            var timezone = page.getTimeZoneOffset();
5871            var timezoneValue = timezone.offset + '|' + (timezone.dst == true ? '1' : '0') + '|0';
5872            if ($.cookie(timezoneCookie) === undefined) {
5873                $.cookie(timezoneCookie, timezoneValue, { expires: 365, path: '/' });
5874                if ($.cookie(timezoneCookie) !== undefined && page.queryString('reload') != 'timezone') {
5875                    page.navigate(window.location.href + (window.location.href.indexOf('?') < 0 ? '?' : '&') + 'reload=timezone');
5876                }
5877            }
5878            else {
5879                var storedOffset = $.cookie(timezoneCookie);
5880                if (storedOffset != timezoneValue && !storedOffset.endsWith('1')) {
5881                    $.cookie(timezoneCookie, timezoneValue, { expires: 365, path: '/' });
5882                    if ($.cookie(timezoneCookie) !== undefined && page.queryString('reload') != 'timezone') {
5883                        page.navigate(window.location.href + (window.location.href.indexOf('?') < 0 ? '?' : '&') + 'reload=timezone');
5884                    }
5885                }
5886            }
5887        }
5888    },
5889    showTimeZonePickerDialog: function () {
5890        dialog.open({
5891            'title': 'Select Your Time Zone',
5892            'url': '~/pages/timezone.aspx?dialog=yes',
5893            'width': 'wide',
5894            'resizeButton': false,
5895            'openButton': false,
5896            'feedbackButton': false,
5897            'callback': function (args) {
5898                if (args != null && args != 'undefined') {
5899                    page.refresh();
5900                }
5901            }
5902        });
5903    },
5904    showCountryPickerDialog: function () {
5905        dialog.open({
5906            'title': 'Select Your Country/Region',
5907            'url': '~/pages/countryregion.aspx?dialog=yes',
5908            'resizeButton': false,
5909            'openButton': false,
5910            'feedbackButton': false,
5911            'callback': function (args) {
5912                if (args != null && args != 'undefined') {
5913                    page.refresh();
5914                }
5915            }
5916        });
5917    },
5918    setCurrency: function (currencyISO) {
5919        page.ajax({
5920            url: '~/Services/ShoppingCart.asmx/SetCurrencyISO',
5921            parameters: {
5922                'currencyISO': currencyISO
5923            },
5924            showProgress: false,
5925            success: function () {
5926                var removeCurrency = "";
5927                if (window.location.href.toLowerCase().indexOf("currencyid=") > 0);
5928                removeCurrency = "currencyid=";
5929                page.refresh(true, "ClearCache=Yes", removeCurrency);
5930            }
5931        });
5932    },
5933    getCurrencies: function () {
5934        page.ajax({
5935            url: '~/Services/ShoppingCart.asmx/GetCurrencies',
5936            showProgress: false,
5937            success: function (items) {
5938                var container = $("[id$='ddlLanguage']");
5939                if (items.length > 0) {
5940                    var html = '<a class="btn blue dropdown-toggle" data-toggle="dropdown" data-close-others="true" href="javascript:void(0);">';
5941                    html += '<img class="page-header-country-image" src="/assets/img/flags/' + items[0].Flag + '.png"><span class="username">' + items[0].CountryName + '</span> <i class="icon-angle-down"></i></a>';
5942                    if (items.length > 1) {
5943                        html += '<ul class="dropdown-menu">';
5944                        for (var i = 1; i < items.length; i++) {
5945                            html += '<li><a onclick="javascript:page.setCurrency(\'' + items[i].CurrencyISO + '\');return false;" href="javascript:void(0);" title="Link: javascript:void(0);">';
5946                            html += '<img class="page-header-country-image" src="/assets/img/flags/' + items[i].Flag + '.png">' + items[i].CountryName + '</a ></li>';
5947                        }
5948                        html += '</ul>';
5949                    }
5950                    container.append(html);
5951                }
5952            }
5953        });
5954    },
5955    searchGrid: function (grdId, txt) {
5956        var val = txt.value.trim().toLowerCase();
5957        var $rows = $('#' + grdId).find("tr:gt(0)");
5958        if (val.length) {
5959            // Use textContent for faster access, and minimize jQuery calls
5960            $rows.each(function () {
5961                // Cache the row and its text content
5962                var row = this;
5963                //$this.text().toLowerCase().indexOf(search) === -1 ? $this.hide() : $this.show();
5964
5965                // var rowText = $(row).text();
5966                // Combine all cell text for the row, using native textContent for speed
5967                var rowText = row.textContent || row.innerText || "";
5968
5969                if (rowText.toLowerCase().indexOf(val) === -1) {
5970                    row.style.display = "none";
5971                } else {
5972                    row.style.display = "";
5973                }
5974            });
5975        } else {
5976            // Show all rows without using .show() for better performance
5977            $rows.each(function () {
5978                this.style.display = "";
5979            });
5980        }
5981    },
5982    getProductIconByProductType: function (productType) {
5983        var icon = 'icon-';
5984        switch (productType) {
5985            case 'Booth': icon += 'square'; break;
5986            case 'Certification': icon += 'certificate'; break;
5987            case 'Class': icon += 'desktop'; break;
5988            case 'Course': icon += 'briefcase'; break;
5989            case 'DigitalAdvertisingProduct': icon += 'bullhorn'; break;
5990            case 'Discount': icon += 'sort-amount-desc'; break;
5991            case 'Downloadable': icon += 'download'; break;
5992            case 'EducationCredit': icon += 'graduation-cap'; break;
5993            case 'Event': icon += 'ticket'; break;
5994            case 'Exam': icon += 'file-text-o'; break;
5995            case 'Exhibit': icon += 'th'; break;
5996            case 'Fund': icon += 'heart'; break;
5997            case 'Membership': icon += 'bookmark'; break;
5998            case 'Merchandise': icon += 'cubes'; break;
5999            case 'Miscellaneous': icon += 'recycle'; break;
6000            case 'ProductGroup': icon += 'cubes'; break;
6001            case 'Publication': icon += 'book'; break;
6002            case 'Session': icon += 'ticket'; break;
6003            case 'Shipping': icon += 'truck'; break;
6004            case 'Sponsorship': icon += 'star'; break;
6005            case 'Subscription': icon += 'inbox'; break;
6006            case 'SubscriptionIssue': icon += 'copy'; break;
6007            case 'Tax': icon += 'institution'; break;
6008            case 'Track': icon += 'ticket'; break;
6009            default: icon += 'cubes'; break;
6010        }
6011        return icon;
6012    },
6013    preventRenewForOpenOrderConfirmDialog: function (options) {
6014        dialog.messageBox({
6015            'title': 'Existing Order Reminder',
6016            'icon': 'Warning',
6017            'message': options.message,
6018            'buttons': 'Continue,Cancel',
6019            'callback': function (args) {
6020                if (args != null) {
6021                    if (args.toLowerCase() == "continue") {
6022                        page.navigate(options.continueUrl);
6023                    }
6024                }
6025            }
6026        });
6027    },
6028    applyCartValidation: function (message, type, redirectUrl) {
6029        if (type == "RenewalOpenOrder") {
6030            page.preventRenewForOpenOrderConfirmDialog({ 'message': message, 'continueUrl': redirectUrl });
6031        }
6032    },
6033    exportConfirmDialog: function (options) {
6034        var type = options.type == null ? 'CSV' : options.type;
6035        var title = options.title == null ? 'Export to ' + type : options.title;
6036        var icon = options.icon == null ? 'Question' : options.icon;
6037        var message = options.message == null ? 'Export to ' + type + ' file and download it ?' : options.message;
6038        var buttons = 'OK,Cancel';
6039        if (options.queryUrl != null && options.actualCount != null && options.limitCount != null) {
6040            buttons = 'Export Now,Cancel';
6041            if (options.actualCount > options.limitCount) {
6042                icon = 'Warning';
6043                message = 'This list contains more than ' + options.limitCount + ' records and it is not recommended to use this feature directly from your browser session. '
6044                    + '<br/><br/>Please use the “<b>Email Query Results</b>” button below (<b>RECOMMENDED</b>) and we will email you the results (as a CSV file attachment) shortly. '
6045                    + '<br/><br/>If you still wish to export directly from your current browser session (<b>NOT RECOMMENDED</b>), use the “Export Now” button below. ';
6046                buttons = 'Email Query Results,Export Now,Cancel';
6047            }
6048        }
6049        var downloadInfo = page.getNavigatorDownloadInformation();
6050        dialog.messageBox({
6051            'title': title,
6052            'icon': icon,
6053            'message': message,
6054            'buttons': buttons,
6055            'callback': function (args) {
6056                if (args != null) {
6057                    if (args.toLowerCase() == "ok" || args.toLowerCase() == "export now") {
6058                        if (window.location.appPath == null) { window.location.appPath == ''; }
6059                        var url = options.url.replace(/^~/, window.location.appPath);
6060                        var fileDownloadSettings = { httpMethod: 'GET' };
6061                        if (options.exportHeader !== undefined && options.exportData !== undefined) {
6062                            fileDownloadSettings.httpMethod = 'POST';
6063                            fileDownloadSettings.data = "exportHeader=" + encodeURIComponent(JSON.stringify(options.exportHeader)) + "&exportData=" + encodeURIComponent(JSON.stringify(options.exportData)) + "&exportDataTypes=" + JSON.stringify(options.exportDataTypes);
6064                        }
6065                        $.fileDownload(url, fileDownloadSettings)
6066                            .done(function () {
6067                                dialog.messageBox({
6068                                    'title': 'Download Started',
6069                                    'icon': 'Information',
6070                                    'buttons': 'OK',
6071                                    'message': 'Download is in progress.<br /><br />' + downloadInfo
6072                                });
6073                            })
6074                            .fail(function () {
6075                                dialog.messageBox({
6076                                    'title': 'Download Failed',
6077                                    'icon': 'Warning',
6078                                    'buttons': 'OK',
6079                                    'message': 'Some error occurred during download process. Please try again.'
6080                                });
6081                            });
6082                    }
6083                    else if (args.toLowerCase() == 'email query results') {
6084                        window.setTimeout(function () {
6085                            dialog.open({
6086                                'url': '~/administration/processes/schedule/?dialog=yes&action=edit&ClearCache=no&JobName=Crm.ScheduledQuery&url=' + escape(options.queryUrl),
6087                                'title': 'Email Query Results',
6088                                'width': 'wide',
6089                                'callback': function (args) { if (args != null && args != '') { page.submit(); } }
6090                            });
6091                        }, 100);
6092                        dialog.close();
6093                    }
6094                }
6095            }
6096        });
6097    },
6098    reportConfirmDialog: function (options) {
6099        if (options.queryUrl != null && options.actualCount != null && options.limitCount != null && options.actualCount > options.limitCount) {
6100            dialog.messageBox({
6101                'title': 'Export to Other Formats',
6102                'icon': 'Warning',
6103                'message': 'This list contains more than ' + options.limitCount + ' records and it is not recommended to use this feature directly from your browser session. '
6104                    + '<br/><br/>Please use the “<b>Email Query Results</b>” button below (<b>RECOMMENDED</b>) and we will email you the results (as a CSV file attachment) shortly. '
6105                    + '<br/><br/>If you still wish to export directly from your current browser session (<b>NOT RECOMMENDED</b>), use the “Export Now” button below. ',
6106                'buttons': 'Email Query Results,Export Now,Cancel',
6107                'callback': function (args) {
6108                    if (args != null) {
6109                        if (args.toLowerCase() == "export now") {
6110                            window.setTimeout(function () {
6111                                dialog.open({
6112                                    'url': options.url,
6113                                    'title': 'Export to Other Formats',
6114                                    'width': 'wide',
6115                                    'refreshParent': false
6116                                });
6117                            }, 100);
6118                            dialog.close();
6119                        }
6120                        else if (args.toLowerCase() == 'email query results') {
6121                            window.setTimeout(function () {
6122                                dialog.open({
6123                                    'url': '~/administration/processes/schedule/?dialog=yes&action=edit&ClearCache=no&JobName=Crm.ScheduledQuery&url=' + escape(options.queryUrl),
6124                                    'title': 'Email Query Results',
6125                                    'width': 'wide',
6126                                    'callback': function (args) { if (args != null && args != '') { page.submit(); } }
6127                                });
6128                            }, 100);
6129                            dialog.close();
6130                        }
6131                    }
6132                }
6133            });
6134        }
6135        else {
6136            dialog.open({
6137                'url': options.url,
6138                'title': 'Export to Other Formats',
6139                'width': 'wide',
6140                'refreshParent': false
6141            });
6142        }
6143    },
6144    getNavigatorFriendlyName: function () {
6145        var browserTarjet = navigator.userAgent.toLowerCase();
6146        var friendlyName = '';
6147        if (browserTarjet.indexOf('firefox') != -1) {
6148            friendlyName = "firefox";
6149        } else if (browserTarjet.indexOf('chrome') != -1) {
6150            friendlyName = "chrome";
6151        } else if (browserTarjet.indexOf('safari') != -1) {
6152            friendlyName = "safari";
6153        } else if (browserTarjet.indexOf('.net') != -1) {
6154            friendlyName = "internet explorer";
6155        }
6156        return friendlyName;
6157    },
6158    getNavigatorDownloadInformation: function () {
6159        var browserName = page.getNavigatorFriendlyName();
6160        var downloadInfo = '';
6161        if (browserName != null && browserName.length > 0) {
6162            var downloadText = '<p>The file will be downloaded to a folder specified in your browser settings. If you are not sure where this folder is, you can find it in your browser menu: <strong>';
6163            if (browserName == 'firefox') {
6164                downloadInfo = downloadText + "Options &gt; General &gt; Downloads &gt; Save files to</strong></p>";
6165            } else if (browserName == 'chrome') {
6166                downloadInfo = downloadText + "Settings &gt; Show Advanced Settings &gt; Downloads &gt; Download Location</strong></p>";
6167            } else if (browserName == 'safari') {
6168                downloadInfo = downloadText + "Settings &gt; Preferences &gt; General &gt; Save downloaded files</strong></p>";
6169            } else if (browserName == 'internet explorer') {
6170                downloadInfo = downloadText + "Tools &gt; View Downloads &gt; Options &gt; Default download location</strong></p>";
6171            }
6172        }
6173        return downloadInfo;
6174    },
6175    discountTotalNumberOfUsage: function () {
6176        page.load(function () {
6177
6178            var checkTotal = $('.jq-total-usage-chk-switch');
6179            var hiddenUsageButton = $('#btnHiddenUsageChanged');
6180            if (checkTotal.prop('checked')) {
6181                $('.txt-total-usage').css('visibility', 'hidden');
6182            } else {
6183                $('.txt-total-usage').css('visibility', 'visible');
6184            }
6185
6186            checkTotal.on('switch-change', function () {
6187
6188                var unlimited = $(this).prop('checked');
6189                if (unlimited) {
6190                    $('.txt-total-usage').css('visibility', 'hidden');
6191                    $('.txt-total-usage').val('');
6192                    $('.label-total-usage').removeClass('required');
6193
6194                    if (hiddenUsageButton.length > 0) {
6195                        hiddenUsageButton.click();
6196                    }
6197                } else {
6198                    $('.txt-total-usage').css('visibility', 'visible');
6199                    $('.label-total-usage').addClass('required');
6200                    if (hiddenUsageButton.length > 0) {
6201                        hiddenUsageButton.click();
6202                    }
6203                }
6204            });
6205        });
6206    },
6207    discountUsagePerCustomer: function () {
6208        page.load(function () {
6209
6210            var checkUsageCustomer = $('.jq-usage-customer-chk-switch');
6211            if (checkUsageCustomer.prop('checked')) {
6212                $('.txt-usage-per-customer').css('visibility', 'hidden');
6213            } else {
6214                $('.txt-usage-per-customer').css('visibility', 'visible');
6215            }
6216
6217            checkUsageCustomer.on('switch-change', function () {
6218
6219                var unlimited = $(this).prop('checked');
6220                if (unlimited) {
6221                    $('.txt-usage-per-customer').css('visibility', 'hidden');
6222                    $('.txt-usage-per-customer').val('');
6223                } else {
6224                    $('.txt-usage-per-customer').css('visibility', 'visible');
6225                }
6226            });
6227        });
6228    },
6229    apiSettingScript: function () {
6230        page.load(function () {
6231            var parentCbs = $('input[data-name*="parent"]');
6232            parentCbs.each(function () {
6233                var name = $(this).attr("data-name").replace("parent", "");
6234                var cbs = $('input[data-name="' + name + '"]');
6235                var allChecked = 0;
6236                cbs.each(function () {
6237                    var value = $(this).attr("checked");
6238                    if (value == "checked") {
6239                        allChecked = allChecked + 1;
6240                    }
6241                });
6242                if (cbs.length == allChecked) {
6243                    $(this).parent().addClass('checked');
6244                }
6245            });
6246            $('.data-setting-search').filter('.select2-hidden-accessible').select2('destroy');
6247            $('.data-setting-search').select2({
6248                placeholder: 'Search',
6249                allowClear: true,
6250                //minimumResultsForSearch: -1,
6251                //closeOnSelect: true
6252            });
6253            $('.data-setting-search').on('change', function (e) {
6254                var id = $(this).val();
6255                if (id != '') {
6256                    var hiddenField = $('input[type="hidden"][value="' + id + '"]');
6257                    var activePanel = parseInt(hiddenField.parents('.data-accordion-panel').attr('data-index'));
6258                    $("#accordion").accordion({
6259                        active: activePanel
6260                    });
6261                    page.scrollToElement(hiddenField.parent('div'));
6262                }
6263            });
6264        });
6265        $(function () {
6266            var icons = {
6267                header: "icon-chevron-right",
6268                activeHeader: "icon-chevron-down"
6269            };
6270            var activePanel = parseInt(getParam('panel'));
6271            $("#accordion").accordion({
6272                collapsible: true,
6273                heightStyle: "content",
6274                active: true,
6275                activate: function (event, ui) {
6276                    if (!$.isEmptyObject(ui.newHeader.offset())) {
6277                        $('html:not(:animated), body:not(:animated)').animate({ scrollTop: ui.newHeader.offset().top - 40 }, 'slow');
6278                    }
6279                },
6280                icons: icons,
6281                beforeActivate: function (event, ui) {
6282                    // The accordion believes a panel is being opened
6283                    if (ui.newHeader[0]) {
6284                        var currHeader = ui.newHeader;
6285                        var currContent = currHeader.next('.ui-accordion-content');
6286                        // The accordion believes a panel is being closed
6287                    } else {
6288                        var currHeader = ui.oldHeader;
6289                        var currContent = currHeader.next('.ui-accordion-content');
6290                    }
6291                    // Since we've changed the default behavior, this detects the actual status
6292                    var isPanelSelected = currHeader.attr('aria-selected') == 'true';
6293                    // Toggle the panel's icon
6294                    currHeader.children('.ui-icon').toggleClass('icon-chevron-right', isPanelSelected).toggleClass('icon-chevron-down', !isPanelSelected);
6295                    // Toggle the panel's header
6296                    currHeader.toggleClass('ui-corner-all', isPanelSelected).toggleClass('accordion-header-active ui-state-active ui-corner-top', !isPanelSelected).attr('aria-selected', 
6296((!isPanelSelected).toString()));
6297                    // Toggle the panel's content
6298                    currContent.toggleClass('accordion-content-active', !isPanelSelected)
6299                    if (isPanelSelected) { currContent.slideUp(); } else { currContent.slideDown(); }
6300                    return false; // Cancel the default action
6301                }
6302            });
6303        });
6304        function getParam(name) {
6305            var query = location.search.substring(1);
6306            if (query.length) {
6307                var parts = query.split('&');
6308                for (var i = 0; i < parts.length; i++) {
6309                    var pos = parts[i].indexOf('=');
6310                    if (parts[i].substring(0, pos) === name) {
6311                        return parts[i].substring(pos + 1);
6312                    }
6313                }
6314            }
6315            return 0;
6316        }
6317    },
6318    downloadReport: function (options) {
6319        var message = options.message == undefined ? 'Download this file to your computer?' : options.message;
6320        var downloadInfo = page.getNavigatorDownloadInformation();
6321        dialog.confirm(null, {
6322            'title': options.title == undefined ? 'Download Report' : options.title,
6323            'icon': options.icon == undefined ? 'Question' : options.icon,
6324            'message': message,
6325            'okClicked': function () {
6326                page.showProgress();
6327                var url = '~/account/downloadReport.aspx';
6328                if (window.location.appPath == null) { window.location.appPath == ''; }
6329                url = url.replace(/^~/, window.location.appPath);
6330                $.fileDownload(url)
6331                    .done(function () {
6332                        page.hideProgress();
6333                        dialog.messageBox({
6334                            'title': 'Download Started',
6335                            'icon': 'Information',
6336                            'buttons': 'OK',
6337                            'message': 'Download is in progress.<br /><br />' + downloadInfo
6338                        });
6339                    })
6340                    .fail(function () {
6341                        page.hideProgress();
6342                        dialog.messageBox({
6343                            'title': 'Download Failed',
6344                            'icon': 'Warning',
6345                            'buttons': 'OK',
6346                            'message': 'Some error occurred during download process. Please try again.'
6347                        });
6348                    });
6349            }
6350        });
6351    },
6352    hideCookiesMessage: function () {
6353        $('.cookie-header').hide();
6354        cookies.setCookie('CookiePolicy', 'Viewed', '1');
6355    },
6356    copyToClipboard: function (id) {
6357        var succeed = false;
6358        if (id != null) {
6359            var elem = null;
6360            if (typeof (id) == 'string') {
6361                elem = document.getElementById(id);
6362            }
6363            else {
6364                elem = id;
6365            }
6366            if (elem != null) {
6367                // create hidden text element, if it doesn't already exist
6368                var targetId = "_hidden_copy_text_";
6369                var isInput = elem.tagName === "INPUT" || elem.tagName === "TEXTAREA";
6370                var origSelectionStart, origSelectionEnd;
6371                if (isInput) {
6372                    // can just use the original source element for the selection and copy
6373                    target = elem;
6374                    origSelectionStart = elem.selectionStart;
6375                    origSelectionEnd = elem.selectionEnd;
6376                }
6377                else {
6378                    // must use a temporary form element for the selection and copy
6379                    target = document.getElementById(targetId);
6380                    if (!target) {
6381                        var target = document.createElement("textarea");
6382                        target.style.position = "absolute";
6383                        target.style.left = "-9999px";
6384                        target.style.top = "0";
6385                        target.id = targetId;
6386                        document.body.appendChild(target);
6387                    }
6388                    target.textContent = elem.textContent;
6389                }
6390                // select the content
6391                var currentFocus = document.activeElement;
6392                target.focus();
6393                target.setSelectionRange(0, target.value.length);
6394                // copy the selection
6395                try {
6396                    succeed = document.execCommand("copy");
6397                }
6398                catch (e) {
6399                    succeed = false;
6400                }
6401                // restore original focus
6402                if (currentFocus && typeof currentFocus.focus === "function") {
6403                    currentFocus.focus();
6404                }
6405                if (isInput) {
6406                    // restore prior selection
6407                    elem.setSelectionRange(origSelectionStart, origSelectionEnd);
6408                }
6409                else {
6410                    // clear temporary content
6411                    target.textContent = "";
6412                }
6413            }
6414        }
6415        return succeed;
6416    },
6417    copyToClipboardValue: function (value) {
6418        if (value != null) {
6419            var str = value;
6420            var el = document.createElement('textarea');
6421            el.value = str;
6422            el.setAttribute('readonly', '');
6423            el.style = { position: 'absolute', left: '-9999px' };
6424            document.body.appendChild(el);
6425            el.select();
6426            document.execCommand('copy');
6427            document.body.removeChild(el);
6428        }
6429    },
6430    setButtonsVisibility: function (value) {
6431        $(".buttons-place-holder").css("visibility", value === false ? "hidden" : "visible");
6432    },
6433    setButtonsVisibilityInChildTabs: function (tabContainerId) {
6434        var tabContainer = $('#' + tabContainerId);
6435        var activeTab = tabContainer.find('ul.navbar-collapse > li.active');
6436        var btnVisible = activeTab.find('a[btnvisible="true"]').length > 0;
6437        page.setButtonsVisibility(btnVisible);
6438    },
6439    printImage: function (src) {
6440        var iframe = document.createElement('iframe');
6441        iframe.onload = function () {
6442            var doc = iframe.contentDocument || iframe.contentWindow.document;
6443            var img = document.createElement('img');
6444            img.onload = function () {
6445                iframe.contentWindow.print();
6446            };
6447            img.src = src;
6448            doc.getElementsByTagName('body')[0].appendChild(img);
6449            iframe.contentWindow.focus();
6450        };
6451        document.getElementsByTagName('body')[0].appendChild(iframe);
6452        $(iframe).hide();
6453    },
6454    printReport: function (reportName, iframeId, params) {
6455        var url = '~/Services/Report.asmx/GetReportPdfData';
6456        if (params) {
6457            url += params;
6458        }
6459
6460        page.ajax({
6461            url: url,
6462            parameters: { 'reportName': reportName },
6463            success: function (data) {
6464                // This is needed else the Blob will not work
6465                var bytes = new Uint8Array(data);
6466                var blob = new Blob([bytes], { type: "application/pdf" });
6467                var objectURL = window.URL.createObjectURL(blob);
6468
6469                // BUG: https://bugzilla.mozilla.org/show_bug.cgi?id=911444
6470                // In Firefox, the PDF.js viewer renders in a different domain, and it
6471                // doesn't allow calling the print method from this context.
6472                if (typeof InstallTrigger !== 'undefined') {
6473                    dialog.confirm(null, {
6474                        'title': 'Download File',
6475                        'icon': 'Information',
6476                        'message': 'Your browser FireFox does not support direct printing of PDF files. Would you like to download the file instead?',
6477                        'okClicked': function okClicked() {
6478                            var a = document.createElement('a');
6479                            a.style.display = 'none';
6480                            a.download = 'report.pdf';
6481                            a.href = objectURL;
6482                            document.body.append(a);
6483                            a.click();
6484                            window.URL.revokeObjectURL(objectURL);
6485                            document.body.removeChild(a);
6486                        }
6487                    });
6488                }
6489                else {
6490                    var iframe = document.getElementById(iframeId);
6491                    iframe.src = objectURL;
6492
6493                    window.setTimeout(function () {
6494                        iframe.contentWindow.focus();
6495                        iframe.contentWindow.print();
6496                    }, 1000);
6497                }
6498            },
6499            error: function (message) {
6500                page.displayError('Error', message);
6501            }
6502        });
6503    },
6504    checkAllInMultiSelect: function (checkbox, listboxId) {
6505        $('#' + listboxId + ' > option').prop('selected', $(checkbox).is(':checked'));
6506        $('#' + listboxId).trigger('change');
6507    },
6508    checkAllInCheckBoxList: function (checkbox, listboxId) {
6509        $('#' + listboxId).parent().find('input[type="checkbox"]').setChecked($(checkbox).is(':checked'));
6510        $('#' + listboxId + ' > option').prop('selected', $(checkbox).is(':checked'));
6511        $('#' + listboxId).trigger('change');
6512    },
6513    // Onload Multiselect
6514
6515    onLoadMultisel: function () {
6516        var divLstExpertise = $('[data-id="dataIdExpertise"],[data-id="dataIdDisciplines"]');
6517        for (var lst = 0; lst < divLstExpertise.length; lst++) {
6518            divLstExpertise[lst].childNodes.forEach(function (value, index, list) {
6519                if (list[index].nodeName === 'DIV') {
6520                    list[index].childNodes.forEach(function (valueNode, indexNode, listNode) {
6521                        if (listNode[indexNode].nodeName === 'DIV') {
6522                            listNode[indexNode].childNodes.forEach(function (valueChildUl, indexChildUl, listChildUl) {
6523                                if (listChildUl[indexChildUl].nodeName === 'UL') {
6524                                    listChildUl[indexChildUl].childNodes.forEach(function (valueli, indexli, listli) {
6525                                        if (listli[indexli].nodeName === 'LI') {
6526                                            listli[indexli].childNodes.forEach(function (valueChild, indexChild, listChild) {
6527                                                if (listChild[indexChild].nodeName === 'DIV') {
6528                                                    listChild[indexChild].childNodes.forEach(
6529                                                        function (ChildValue, IndexChild, ChildNodeObj) {
6530                                                            if (ChildNodeObj[IndexChild].data.toLowerCase().indexOf('<span>') != -1) {
6531                                                                let str = ChildNodeObj[IndexChild].data;
6532                                                                let substr = str.substring(str.indexOf('<span>') + '<span>'.length, str.lastIndexOf('</span>'));
6533                                                                ChildNodeObj[IndexChild].data = substr.trim();
6534                                                                if (str.includes('record-number')) {
6535                                                                    ChildNodeObj[IndexChild].data = ChildNodeObj[IndexChild].data + ' ';
6536                                                                    let substrParent = str.substring(str.indexOf('\'> ') + '\'> '.length, str.lastIndexOf('</i>'));
6537                                                                    let i = document.createElement('i');
6538                                                                    //i.className = 'record-number';
6539                                                                    i.className = 'mu-select';
6540                                                                    //i.innerHTML ='<small>' + substrParent.trim() + '</small>';
6541                                                                    i.innerHTML = substrParent.trim();
6542                                                                    // i.setAttribute('style','padding: 1px 3px;')
6543                                                                    ChildNodeObj[IndexChild].parentNode.appendChild(i);
6544                                                                }
6545                                                            }
6546                                                        }
6547                                                    );
6548                                                }
6549                                            });
6550                                        }
6551                                    });
6552                                }
6553                            });
6554                        }
6555                    });
6556                }
6557            });
6558        }
6559    },
6560
6561    // Multiselect remote parent
6562    checkAllInMultiSelected: function (Id, listboxId) {
6563        let listboxIdSelect = document.getElementById(listboxId);
6564
6565        listboxIdSelect.previousElementSibling.childNodes.forEach(
6566            function (currentValue, currentIndex, listObj) {
6567                if (currentIndex >= 0) {
6568                    listObj[currentIndex].childNodes.forEach(
6569                        function (currentChildValue, currentIndexChild, listChildObj) {
6570                            if (listChildObj[currentIndexChild].textContent) {//strValue was non-empty
6571                                let iscontains = listChildObj[currentIndexChild].textContent.toLowerCase().indexOf('<span>');
6572                                if (iscontains != -1) {
6573                                    listChildObj[currentIndexChild].childNodes.forEac
6573h(
6574                                        function (currentChildNodeValue, currentIndexChildNode, listChildNodeObj) {
6575                                            if (listChildNodeObj[currentIndexChildNode].nodeName = "DIV") {
6576                                                listChildNodeObj[currentIndexChildNode].childNodes.forEach(
6577                                                    function (ChildValue, IndexChild, ChildNodeObj) {
6578                                                        if (ChildNodeObj[IndexChild].data.toLowerCase().indexOf('<span>') != -1) {
6579                                                            let str = ChildNodeObj[IndexChild].data;
6580                                                            let substr = str.substring(str.indexOf('<span>') + '<span>'.length, str.lastIndexOf('</span>'));
6581                                                            ChildNodeObj[IndexChild].data = substr.trim();
6582                                                            if (str.includes('record-number')) {
6583                                                                ChildNodeObj[IndexChild].data = ChildNodeObj[IndexChild].textContent + ' ';
6584                                                                let substrParent = str.substring(str.indexOf('\'> ') + '\'> '.length, str.lastIndexOf('</i>'));
6585                                                                let i = document.createElement('i');
6586                                                                i.className = 'mu-select';
6587                                                                //i.innerHTML = '<small>' + substrParent.trim() + '</small>';
6588                                                                i.innerHTML = substrParent.trim();
6589                                                                ChildNodeObj[IndexChild].parentNode.appendChild(i);
6590                                                            }
6591                                                        }
6592                                                    }
6593                                                );
6594                                            }
6595                                        }
6596                                    );
6597                                }
6598                            }
6599
6600                        }
6601                    );
6602                }
6603
6604            }
6605        );
6606    },
6607    getFunctionFromString: function (string) {
6608        //http://stackoverflow.com/a/12380392
6609        return page.getFunctionFromScopeAndString(window, string);
6610    },
6611    getFunctionFromScopeAndString: function (scope, string) {
6612        //http://stackoverflow.com/a/12380392
6613        var scopeSplit = string.split('.');
6614        for (i = 0; i < scopeSplit.length - 1; i++) {
6615            scope = scope[scopeSplit[i]];
6616            if (scope == undefined) return;
6617        }
6618        return scope[scopeSplit[scopeSplit.length - 1]];
6619    },
6620    validateStartSpace: function (ctrl) {
6621        //Validate if first ch is a space to remove it, receive a input control like parameter
6622        if ($(ctrl).val().charAt(0) == " ") {
6623            var chs = $(ctrl).val().trimLeft();
6624            $(ctrl).val(chs);
6625        }
6626    },
6627    getIconByFileType: function (fileType) {
6628        return page._iconList[fileType] || 'icon-file';
6629    },
6630    putCommitteeRowToTop: function (dataMember) {
6631        /* IMP- 19433 */
6632        if (dataMember != null) {
6633            var newRowMember = document.querySelector("tr[" + dataMember + "]");
6634            if (newRowMember != null) {
6635                page._setTopAndFocus(newRowMember);
6636            }
6637        }
6638    },
6639    uploadButtonCtor: function uploadButton_Component(_ref) {
6640        var controls = _ref.controls,
6641            options = _ref.options;
6642        var _UPLOAD_SOURCE_TYPE_URL = 2;
6643        var _UPLOAD_SOURCE_TYPE_FILE = 1;
6644        var _UPLOAD_FOLDER = 'Customer Files';
6645        var container = $("#".concat(controls.container));
6646        var value = $("#".concat(controls.valueId));
6647        var valueFileParams = $("#".concat(controls.valueFileParamsId));
6648        var defaultActionLink = $("#".concat(controls.defaultActionLink));
6649        var deleteLink = $("#".concat(controls.deleteLink));
6650        var fromPcLink = $("#".concat(controls.fromPcLink));
6651        var fromUrlLink = $("#".concat(controls.fromUrlLink));
6652        var fileNameControl = $("#".concat(controls.fileNameControl));
6653        var dropDownListLink = $("#".concat(controls.dropDownListLink));
6654        $('a', container).each(function (_, o) {
6655            return $(o).attr('href', '#');
6656        });
6657        defaultActionLink.click(function () {
6658            if (!options.enable && options.isNew) {
6659                return;
6660            }
6661
6662            options.isNew || options.isTempFile ? openUploadModal(options.file && options.file.SourceType === _UPLOAD_SOURCE_TYPE_URL ? 'url' : 'file') : openViewMFileModal();
6663        });
6664        fromPcLink.click(function () {
6665            openUploadModal('file');
6666        });
6667        fromUrlLink.click(function () {
6668            openUploadModal('url');
6669        });
6670        deleteLink.click(function () {
6671            dialog.confirm(null, {
6672                'title': 'Remove File',
6673                'icon': 'Warning',
6674                'message': 'Are you sure you want to remove this file?',
6675                'okClicked': function okClicked() {
6676                    deleteFileModal();
6677                }
6678            });
6679        });
6680        showAndHideElements();
6681        return;
6682
6683        function openUploadModal(mode) {
6684            var url;
6685
6686            switch (mode) {
6687                case 'file':
6688                    url = '/uploads/fileupload.aspx';
6689                    break;
6690
6691                case 'url':
6692                    url = '/uploads/fileuploadurl.aspx';
6693                    break;
6694            }
6695
6696            dialog.open({
6697                url: "".concat(url, "?").concat($.param({
6698                    'id': !options.isNew ? value.val() : null,
6699                    isTemp: options.isTemp,
6700                    dialog: 'yes',
6701                    width: 'wide',
6702                    folder: _UPLOAD_FOLDER
6703                })),
6704                title: options.title || "Upload ".concat(mode),
6705                resizeButton: false,
6706                openButton: false,
6707                callback: onClose,
6708                refreshParent: options.AutoPostBack
6709            });
6710            return false;
6711
6712            function onClose(response) {
6713
6714                if (!response || !response.action) {
6715                    return;
6716                }
6717
6718                if (!options.file || options.file.Id !== response.Id) {
6719                    options.isTempFile = true;
6720                }
6721
6722                value.val(response.id);
6723                valueFileParams.val(JSON.stringify(options.file = response.tempFile));
6724                fileNameControl.text(" ".concat(response.text.substring(0, 20)).concat(response.text.length > 20 ? '...' : ''));
6725
6726                switch (response.action) {
6727                    case "created":
6728                    case "edited":
6729                        changeMode('edit');
6730                        break;
6731
6732                    case "deleted":
6733                        changeMode('new');
6734                        break;
6735
6736                    default:
6737                }
6738
6739                propagateEvent(response.action, response.tempFile);
6740                return true;
6741            }
6742        }
6743
6744        function propagateEvent(action, tempFile) {
6745            if (options.autoPostBack) {
6746                __doPostBack(value.attr('name'), '');
6747            } else {
6748                changeIcons(action, tempFile);
6749                showAndHideElements();
6750            }
6751        }
6752
6753        function changeIcons(action, tempFile) {
6754            var defaultIcon = $('i', defaultActionLink);
6755            var defaultText = $('span', defaultActionLink);
6756            var fromPcText = $('span', fromPcLink);
6757            var fromUrlText = $('span', fromUrlLink);
6758            defaultIcon.removeAttr('class');
6759
6760            switch (action) {
6761                case "edited":
6762                case "created":
6763                    defaultIcon.addClass(tempFile.SourceType === _UPLOAD_SOURCE_TYPE_URL ? 'icon-link' : page.getIconByFileType(tempFile.Extension));
6764                    fromPcText.text(' Replace File');
6765                    fromUrlText.text(' Replace Url');
6766                    defaultText.text(' ' + (options.isTempFile ? options.file.SourceType === _UPLOAD_SOURCE_TYPE_FILE ? fromPcText.text() : fromUrlText.text() : 'View'));
6767                    break;
6768
6769                case "deleted":
6770                    defaultIcon.addClass('icon-plus');
6771                    defaultText.text(' Upload');
6772                    fromPcText.text(' File');
6773                    fromUrlText.text(' Url');
6774                    break;
6775            }
6776        }
6777
6778        function openViewMFileModal() {
6779            var url = '/uploads/fileviewer.aspx';
6780            dialog.open({
6781                url: "".concat(url, "?").concat($.param({
6782                    'id': value.val(),
6783                    dialog: 'yes'
6784                })),
6785                title: fileNameControl.text(),
6786                resizeButton: false,
6787                openButton: false
6788            });
6789            return false;
6790        }
6791
6792        function deleteFileModal() {
6793            value.val('');
6794            valueFileParams.val('');
6795            fileNameControl.hide();
6796            changeMode('new');
6797            propagateEvent('deleted');
6798        }
6799
6800        function changeMode(newMode) {
6801            options.isNew = newMode === 'new';
6802        }
6803
6804        function showAndHideElements() {
6805            deleteLink.parent().hide();
6806            fromUrlLink.parent().hide();
6807            fromPcLink.parent().hide();
6808            fileNameControl.hide();
6809            dropDownListLink.hide();
6810
6811            if (options.isNew) {
6812                if (!options.hideUrl) {
6813                    dropDownListLink.show();
6814                }
6815                dropDownListLink.parent().toggleClass("btn-group-dropdown", !options.hideUrl);
6816                fromUrlLink.parent().show();
6817                fromPcLink.parent().show();
6818            } else {
6819                dropDownListLink.parent().toggleClass("btn-group-dropdown", true);
6820                dropDownListLink.show();
6821                deleteLink.parent().show();
6822                fileNameControl.show();
6823
6824                if (options.file.SourceType === _UPLOAD_SOURCE_TYPE_FILE) {
6825                    fromPcLink.parent().show();
6826                } else {
6827                    fromUrlLink.parent().show();
6828                }
6829            }
6830        }
6831    },
6832    activeTabIndexChanged: function (tabClientId, openTabIndex) {
6833        page.ajax({
6834            url: '~/Services/TabControl.asmx/SetOpenTabIndex',
6835            parameters: {
6836                'tabClientId': tabClientId,
6837                'openTabIndex': parseInt(openTabIndex),
6838            },
6839            showProgress: false
6840        });
6841    },
6842    initGlobalSearch: function () {
6843        if ($('.global-search-hidden > input:hidden').length > 0) {
6844
6845            if ($.cookie('globalSearchTypeSelected') !== undefined && $.cookie('globalSearchTypeSelected') !== '') {
6846                page.setDisplayedGlobalSearchType();
6847            }
6848
6849            var txtSearch = $(".global-search-text");
6850            var lnkStartsWith = $('#lnkStartsWith');
6851            var lnkContains = $('#lnkContainsType');
6852            var btnSubmit = $('.global-search-submit');
6853
6854            txtSearch.keypress(function (event) {
6855                var keyCode = (event.keyCode || event.which);
6856                if (keyCode == 13) {
6857                    page.globalSearchSubmit();
6858                }
6859            });
6860            lnkStartsWith.click(function () {
6861                page.setGlobalSearchType(lnkStartsWith.text());
6862            });
6863            lnkContains.click(function () {
6864                page.setGlobalSearchType(lnkContains.text());
6865
6866            });
6867            btnSubmit.click(function () {
6868                page.globalSearchSubmit();
6869            })
6870        }
6871    },
6872    setDisplayedGlobalSearchType: function () {
6873        $('button.product-categories span').text($.cookie('globalSearchTypeSelected'));
6874    },
6875    setGlobalSearchType: function (searchType) {
6876        $.cookie('globalSearchTypeSelected', searchType, { expires: 365, path: '/' });
6877        page.setDisplayedGlobalSearchType();
6878        page.globalSearchSubmit();
6879    },
6880    globalSearchSubmit: function () {
6881        page.navigate('/administration/search/?q='
6882            + escape($('.global-search-text').val().replace(/(^\s*)|(\s*$)/g, '').replace(/\s+/g, ' ').replace(/\s/g, '\+'))
6883            + '&tab='
6884            + $.cookie('globalSearchTabSelected')
6885            + '&refreshGS=false'
6886        );
6887        return false;
6888    },
6889    showDiv: function (div) {
6890        $('#' + div).show();
6891    },
6892    confirmLineItemAmountEdit: function (event, txtAmtControlId, currentAmountTxt, ddlPriceControlId, currentPriceSelectedValue) {
6893        const txtAmountControl = $('#' + txtAmtControlId);
6894        const newAmount = parseFloat((txtAmountControl.length && txtAmountControl.val() != null) ? txtAmountControl.val() : '0');
6895        const currAmount = parseFloat(currentAmountTxt);
6896
6897        const amountSame = newAmount === currAmount;
6898
6899        const ddlPriceControl = $('#' + ddlPriceControlId);
6900        const newPriceSelectedValue = (ddlPriceControl.length && ddlPriceControl.val() != null) ? ddlPriceControl.val() : '';
6901
6902        const priceSame = newPriceSelectedValue === currentPriceSelectedValue;
6903
6904        if (amountSame === false || priceSame === false) {
6905            return dialog.confirm(event, { icon: 'Warning', title: 'Price/Amount Update', message: 'Changing the price/amount will remove the applied discount. Do you want to continue with the price/amount update?' });
6906        }
6907        return true;
6908    },
6909
6910    //variable to track if captcha setInterval was set.
6911    captchaIntervalSet: false,
6912    captchaVersion: 'v3',
6913    
6914    // Load reCAPTCHA script 
6915    /// <param name="path">Path to reCAPTCHA V3 script</param>
6916    /// <param name="pathV2">Path to reCAPTCHA v2 script</param>
6917    // <param name="sitekey">reCAPTCHA V3 site key</param>
6918    /// <param name="userKey">Unique key to identify user session</param>
6919    /// <param name="hiddentGoogleTokenId">ID of hidden input to store reCAPTCHA token</param>
6920    /// <param name="actionName">Action name for reCAPTCHA v3</param>
6921    /// <param name="isV2Configured">Boolean indicating if reCAPTCHA v2 is configured for fallback</param>
6922    /// <param name="requestTokenOnLoad">Boolean indicating if token should be requested on load, this is an old method, should be false; can be removed when the release toggle is removed.</param>
6923    /// <param name="hiddenGoogleBlockedTextBoxId">ID of hidden input to indicate if Google script is blocked</param>
6924    /// <param name="hCaptchaOptions">Object containing hCaptcha configuration (scriptSrc, siteKey, containerId, tokenClientId)</param>
6925    loadRecaptcha: function (path, sitekey, userKey, hiddentGoogleTokenId, actionName,requestTokenOnLoad,hiddenGoogleBlockedTextBoxId,hCaptchaOptions) {
6926        const userTokenKey = "TK_" + userKey;
6927        const timeToRefresh = 100 * 1000; // Refresh token every 100 seconds (Google token expires in 120 seconds)
6928
6929        const loadreCaptchaScript = () => {
6930
6931            //This is in the process of being deprecated, hence wrapped in a temporary release toggle
6932            const initializeAfterLoad = () => {
6933                // request token on load and then generate a new one every 100 seconds - this is not recommended hence wrapped in a temporary release toggle
6934                if (requestTokenOnLoad) {
6935                    grecaptcha.ready(function () {
6936                        if (!page.isTokenPresent(hiddentGoogleTokenId)) {
6937                            page.requestNewToken(sitekey, hiddentGoogleTokenId, userTokenKey, actionName);
6938                        }
6939                    });
6940
6941                    // Prevent setting up multiple intervals
6942                    if (!page.captchaIntervalSet) {
6943                        // Avoid deprecated token every 100 seconds
6944                        setInterval(() => {
6945                            page.requestNewToken(sitekey, hiddentGoogleTokenId, userTokenKey, actionName);
6946                        }, timeToRefresh);
6947                        page.captchaIntervalSet = true;
6948                    }
6949                }
6950            };
6951
6952            // Build single URL with explicit render for both v3 and v2 support
6953            const scriptUrl = path;
6954
6955            // Check if script is already loaded
6956            if (document.querySelector(`script[src^="${path}"]`)) {
6957                initializeAfterLoad();
6958                return;
6959            }
6960
6961            const script = document.createElement('script');
6962
6963            script.onerror = function () {
6964                console.error("Google reCAPTCHA did not load...trying to fall back to hCaptcha");
6965                $('#' + hiddenGoogleBlockedTextBoxId).val('true');//Google captcha script blocked
6966                //check if hCaptchaOptions is not null or if hCaptcha.siteKey is available
6967                if (hCaptchaOptions != null && hCaptchaOptions.siteKey) {
6968                    page.loadHCaptcha(hCaptchaOptions.scriptSrc, hCaptchaOptions.siteKey, hCaptchaOptions.containerId, hCaptchaOptions.tokenClientId);
6969                } else {
6970                    console.log("Google Blocked. hCaptcha is not configured.");
6971                }
6972                return;
6973            };
6974
6975            script.onload = function () {
6976                if (!window["grecaptcha"]) {
6977                    console.error("Captcha source is missing");
6978                    return;
6979                }
6980                initializeAfterLoad();
6981            };
6982
6983         
6984
6985            script.src = scriptUrl;
6986            document.head.appendChild(script);
6987        };
6988
6989        loadreCaptchaScript();
6990    },
6991
6992    attachRecaptchaHandler: function (options) {
6993        // options: { buttonSelector, siteKey, tokenClientId, sessionHash, actionName, fallbackWhenBlocked, hiddenGoogleBlockedClientId }
6994        $(document).ready(function () {
6995            const $button = $(options.buttonSelector);
6996            const buttonId = $button.attr('id');
6997
6998            // Initialize page namespace
6999            //isInProgress: Indicates whether a reCAPTCHA token request is currently in progress for this button. Prevents multiple simultaneous token requests and duplicate form submissions.
7000            //isReady:Indicates whether a valid reCAPTCHA token has been generated and is ready for use for this button. Allows the form to proceed with submission after reCAPTCHA validation.
7001            page.recaptchaState = page.recaptchaState || {};
7002            page.recaptchaState[buttonId] = page.recaptchaState[buttonId] || {
7003                isInProgress: false,
7004                isReady: false
7005            };
7006
7007            const state = page.recaptchaState[buttonId];
7008
7009            function executeRecaptcha() {
7010                try {
7011                    if (typeof grecaptcha !== 'undefined') {
7012                        grecaptcha.ready(function () {
7013                            page.requestNewToken(
7014                                options.siteKey,
7015                                options.tokenClientId,
7016                                options.sessionHash,
7017                                options.actionName
7018                            ).then(function (token) {
7019                                state.isInProgress = false;
7020                                state.isReady = true;
7021                                //console.info('reCAPTCHA token ready, allow to submit form', state);
7022                                $button[0].click();// Allow form to submit
7023                            }).catch(function (error) {
7024                                console.error('Error in reCAPTCHA token generation:', error);
7025                                state.isInProgress = false; // Unlock for retry
7026                            });
7027                        });
7028                    } else {
7029                        console.warn('grecaptcha is not defined');
7030                        state.isInProgress = false;
7031                    }
7032                } catch (error) {
7033                    console.error('Exception during reCAPTCHA execution:', error);
7034                    state.isInProgress = false;
7035                }
7036            }
7037
7038            $button.off('click').on('click', function (e) {
7039                const isGoogleBlocked = $('#' + options.hiddenGoogleBlockedClientId).val() === 'true';
7040
7041                if (isGoogleBlocked && options.fallbackWhenBlocked) 
7042                    return; // Let the button work normally, reCAPTCHA script is blocked; we don't need recaptcha tokens. 
7043
7044                if (state.isReady) {
7045                    state.isReady = false;
7046                    //console.log('reCAPTCHA token ready — proceeding with form submission.');
7047                    return; // Allow normal form postback (ASP.NET server-side handler will run)
7048                }
7049
7050                if (state.isInProgress) {
7051                    //console.info('reCAPTCHA already in progress — click ignored.');
7052                    e.preventDefault();
7053                    return;
7054                }
7055
7056                e.preventDefault(); // Prevent submit on first click
7057                state.isInProgress = true;
7058                executeRecaptcha();
7059            });
7060
7061            // Reset state on full postback/page reload
7062            window.addEventListener('load', function () {
7063                state.isInProgress = false;
7064                state.isReady = false;
7065            });
7066        }
7067        );
7068    },
7069    requestNewToken: function (sitekey, hiddentGoogleTokenId, userTokenKey, actionName) {
7070        return grecaptcha.execute(sitekey, { action: actionName })
7071            .then(function (token) {
7072                const hiddenTokenElement = $('#' + hiddentGoogleTokenId);
7073                hiddenTokenElement.val(token);
7074
7075                console.info('reCAPTCHA token generated');
7076                
7077                sessionStorage[userTokenKey] = token;
7078                return token;
7079            })
7080            .catch(function (error) {
7081                console.error("Failed to generate reCAPTCHA token:", error);
7082            });
7083    },
7084
7085    isTokenPresent: function (hiddentGoogleTokenId) {
7086        const hiddenTokenElement = $('#' + hiddentGoogleTokenId);
7087        return hiddenTokenElement.val().length > 0;
7088    },
7089
7090    showV2Captcha: function (hiddenGoogleTokenId, captchaContainerId, v2siteKey) {
7091        this.captchaVersion = 'v2';
7092        //$('#' + captchaContainerId).show();
7093        const container = document.getElementById(captchaContainerId);
7094        if (!container) {
7095            console.warn('reCAPTCHA container not found:', captchaContainerId);
7096            return;
7097        }
7098
7099        // If an iframe is already rendered inside, skip
7100        if (container.querySelector('iframe')) {
7101            container.style.display = 'block';
7102            return;
7103        }
7104
7105        if (typeof grecaptcha === 'undefined' || !grecaptcha.render) {
7106            console.error('grecaptcha is not loaded.');
7107            return;
7108        }
7109
7110        // Clear any previous widget (same div shared by recaptcha and hcaptcha)
7111        container.innerHTML = '';
7112        container.style.display = 'block';
7113
7114        const widgetId = grecaptcha.render(captchaContainerId, {
7115            'sitekey': v2siteKey,
7116            'callback': function (token) {
7117                $('#' + hiddenGoogleTokenId).val(token);
7118            },
7119            'error-callback': function () {
7120                console.error('The CAPTCHA couldn’t be loaded due to a misconfiguration.');
7121                if (typeof grecaptcha !== 'undefined') {
7122                    grecaptcha.reset(widgetId); // reset using widget ID
7123                }
7124            }
7125        })
7126        sessionStorage.setItem('reCaptchaV2WidgetId_' + captchaContainerId, widgetId);
7127    },
7128    resetV2Captcha: function (captchaContainerId) {
7129        this.captchaVersion = 'v2';
7130        if (typeof grecaptcha === 'undefined') {
7131            console.warn('grecaptcha is not available. Cannot reset.');
7132            return;
7133        }
7134        const widgetId = sessionStorage.getItem('reCaptchaV2WidgetId_' + captchaContainerId);
7135        if (widgetId) {
7136            grecaptcha.reset(widgetId);
7137        } else {
7138            console.warn('No widget ID found for container:', captchaContainerId);
7139        }
7140    }
7141};
7142
7143$(window).bind('resize', function () {
7144    FormComponents.initResponsiveGrids(true);
7145    if (page._resizeArray != undefined && page._resizeArray != null && page._resizeArray.length > 0) {
7146        for (var i = 0; i < page._resizeArray.length; i++) {
7147            if (page._resizeArray[i] && typeof (page._resizeArray[i]) == 'function') {
7148                page._resizeArray[i].call(this);
7149            }
7150        }
7151    }
7152});
7153$(window).bind('scroll', function () {
7154    if (page._scrollArray != undefined && page._scrollArray != null && page._scrollArray.length > 0) {
7155        for (var i = 0; i < page._scrollArray.length; i++) {
7156            if (page._scrollArray[i] && typeof (page._scrollArray[i]) == 'function') {
7157                page._scrollArray[i].call(this);
7158            }
7159        }
7160    }
7161});
7162$(window).bind('beforeunload', function (evt) {
7163    var message = $('#main_browserNavigationWarning').val();
7164    if (message != null && message != '') {
7165        var e = evt || window.event;
7166        if (e && e.returnValue) {
7167            event.returnValue = message;
7168        }
7169        return message;
7170    }
7171    page._isLocationChanging = true;
7172    if (!page.isSafari() && !page.isIE()) {
7173        page.showProgress();
7174    }
7175});
7176$(window).bind('unload', function () {
7177    if (!page.isSafari() && page.isIE()) {
7178        page.showProgress();
7179    }
7180});
7181$(window).bind('load', function () {
7182    page.hideProgress();
7183});
7184if ('onpageshow' in window) {
7185    $(window).bind('pageshow', function () {
7186        //document.forms[0].reset();
7187        //$('.grid-page-size-select option:eq(0)').prop('selected', true);
7188        page.hideProgress();
7189        if (page.isFireFox() && window.performance.navigation.type === 2 && window.location.href.indexOf('reload=bfcache') === -1) {
7190            var url = window.location.href;
7191            if (window.location.href.indexOf('?') < 0) {
7192                url = url.concat("?reload=bfcache");
7193            }
7194            else {
7195                url = url.concat("&reload=bfcache");
7196            }
7197            page.navigate(url);
7198        }
7199    });
7200}
7201$(document).ready(function () {
7202    page.cleanupAfterUsingBrowserButtons();
7203    page.checkBadSsoToken();
7204    page.ensureTimeZoneCookie();
7205    page.initFeedback();
7206    page.hideProgress();
7207    $('#main_isFirstTime').val('no');
7208});
7209function pageLoad() {
7210    var isRedirecting = page.init();
7211    if (!isRedirecting) {
7212        App.init();
7213        FormComponents.init();
7214        page.initSessionTimeout();
7215        page.initAdminDesignMode();
7216        page.initLastFocusControl();
7217        page.initCartItemsCount();
7218        page.initGlobalSearch();
7219        page.initUserImage();
7220        page.hideProgress();
7221        dialog.resize();
7222        if (page._loadArray != undefined && page._loadArray != null && page._loadArray.length > 0) {
7223            for (var i = 0; i < page._loadArray.length; i++) {
7224                if (page._loadArray[i] && typeof (page._loadArray[i]) == 'function') {
7225                    page._loadArray[i].call(this);
7226                }
7227            }
7228        }
7229    }
7230}
7231
7232function ValidateCheckboxCustomFieldRequired(source, arguments) {
7233    var isChecked = $(source).parents('.form-group')
7234        .find('input[type="checkbox"][name$="cf"]')
7235        .is(':checked');
7236    arguments.IsValid = isChecked;
7237}
7238
7239(function captchaBroadcastBehavior() {
7240
7241    if (!window["BroadcastChannel"]) {
7242        return;
7243    }
7244
7245    /*
7246     * Safe and isolated execution
7247     */
7248    var key = "captcha";
7249    var chanel = new BroadcastChannel(key);
7250    chanel.onmessage = reloadPage;
7251
7252    var user = getCurrentUser() || 'X';
7253    var oldUser = localStorage[key] || 'X';
7254    if (user.toUpperCase() !== oldUser.toUpperCase()) {
7255        localStorage[key] = user;
7256        chanel.postMessage("new user login");
7257    }
7258
7259    return;
7260
7261    function getCurrentUser() {
7262        return $.cookie('User')
7263            || $.cookie('USER')
7264            || $.cookie('user')
7265            || 'X';
7266    }
7267
7268    function reloadPage(_event) {
7269        location.reload();
7270    }
7271
7272})();
7273
7274/**
7275* Returns a debounced version of the provided function.
7276* The debounced function delays invoking the original function until after
7277* 'wait' milliseconds have elapsed since the last time it was invoked. 
7278* Also, allows user enough time to type in, before firing for each key stroke.
7279* Useful for limiting the rate at which a function can fire, such as search input.
7280*
7281* @param {Function} func - The function to debounce.
7282* @param {number} wait - The number of milliseconds to delay.
7283* @returns {Function} - The debounced function.
7284*/
7285function debounce(func, wait) {
7286    let timeout;
7287    return function (...args) {
7288        const context = this;
7289        clearTimeout(timeout);
7290        timeout = setTimeout(() => func.apply(context, args), wait);
7291    };
7292};
7293
7294var gridUtility = {
7295
7296    ToggleAllGridCheckboxes: function (source) {
7297        var isChecked = $(source).is(':checked'); // Get the checked state of the main checkbox
7298
7299        $(".chk-item-cle input[type='checkbox']").each(function () {
7300            $(this).prop("checked", isChecked).parent().toggleClass("checked", isChecked);
7301        });
7302    },
7303
7304    SelectGridRowOnChange: function (cbx, gridCell) {
7305
7306        if (gridCell.value > 0) {
7307            var cbxElement = document.getElementById(cbx);
7308            cbxElement.checked = true;
7309            var cbxSpan = cbxElement.closest('span');
7310            if (cbxSpan) {
7311                cbxSpan.classList.add("checked");
7312            }
7313        }
7314
7315
7316    }
7317
7318};
7319
7320const regexUtility = {
7321    PCI_CARD_NUMBER_VISA_IN_FIELD_VIOLATION_EXPRESSION: /4[0-9]{3}(?:[- ]?[0-9]{4}){3}/,
7322    PCI_CARD_NUMBER_AMEX_IN_FIELD_VIOLATION_EXPRESSION: /3[47][0-9]{13}/,
7323    PCI_CARD_NUMBER_DINERS_CLUB_INTERNATIONAL_IN_FIELD_VIOLATION_EXPRESSION: /3(?:0[0-5]|[68][0-9])[0-9]{11}/,
7324    PCI_CARD_NUMBER_DINERS_CLUB_DOMESTIC_IN_FIELD_VIOLATION_EXPRESSION: /5[4-5][0-9]{14}/,
7325    PCI_CARD_NUMBER_DISCOVER_IN_FIELD_VIOLATION_EXPRESSION: /6(?:011|5[0-9]{2})[0-9]{12}/,
7326    PCI_CARD_NUMBER_MASTERCARD_IN_FIELD_VIOLATION_EXPRESSION: /5[1-5][0-9]{14}/,
7327    PCI_CARD_NUMBER_MASTERCARD_SERIES_2_IN_FIELD_VIOLATION_EXPRESSION: /2(?:2(?:2[1-9]|[3-9][0-9])|[3-6][0-9]{2}|7(?:[01][0-9]|20))[0-9]{12}/,
7328
7329    get CreditCardPatterns() {
7330        return [
7331            this.PCI_CARD_NUMBER_VISA_IN_FIELD_VIOLATION_EXPRESSION,
7332            this.PCI_CARD_NUMBER_AMEX_IN_FIELD_VIOLATION_EXPRESSION,
7333            this.PCI_CARD_NUMBER_DINERS_CLUB_INTERNATIONAL_IN_FIELD_VIOLATION_EXPRESSION,
7334            this.PCI_CARD_NUMBER_DINERS_CLUB_DOMESTIC_IN_FIELD_VIOLATION_EXPRESSION,
7335            this.PCI_CARD_NUMBER_DISCOVER_IN_FIELD_VIOLATION_EXPRESSION,
7336            this.PCI_CARD_NUMBER_MASTERCARD_IN_FIELD_VIOLATION_EXPRESSION,
7337            this.PCI_CARD_NUMBER_MASTERCARD_SERIES_2_IN_FIELD_VIOLATION_EXPRESSION
7338        ];
7339    },
7340
7341    containsCreditCardNumber(input) {
7342        if (!input || typeof input !== 'string') {
7343            return false;
7344        }
7345
7346        const sanitizedInput = input.replace(/[- ]/g, "");
7347
7348        const numbersMatched = sanitizedInput.match(/\d{13,}/g); // Match numbers with 13+ digits
7349
7350        if (numbersMatched) {
7351            for (const matchedNumber of numbersMatched) {
7352                if (this.CreditCardPatterns.some(pattern => pattern.test(matchedNumber))) {
7353                    return true; // Return true if any pattern matches
7354                }
7355            }
7356        }
7357        return false; // Return false if no matches
7358
7359    },
7360
7361    validateTextFieldForCreditNumber(sender, e) {
7362        e.IsValid = !regexUtility.containsCreditCardNumber(e.Value);
7363    }
7364};
7365
7366const QueryUtility = {
7367    ValidateSequence(sender, args) {
7368        const input = args.Value;
7369        if (!input || typeof input !== 'string') {
7370            args.IsValid = false;
7371        }
7372        args.IsValid = !(/t/i.test(input)); // Regular expression for case-insensitive match
7373    }
7374};
7375
7376/**
7377* Debounced version of the searchGrid function.
7378* Invokes 'page.searchGrid' with the provided grid ID and search text after a 300ms delay.
7379* Prevents excessive calls to the search function on every key press.
7380*
7381* @param {string} grdId - The ID of the grid to search.
7382* @param {string} txt - The search text.
7383*/
7384const debouncedSearchGrid = debounce(function (grdId, txt) {
7385    page.searchGrid(grdId, txt);
7386}, 300);
7387;
7388var api = {
7389    _defaults: {
7390        url: null,
7391        method: 'GET',
7392        parameters: null,
7393        progress: true,
7394        success: null,
7395        error: null,
7396        no404: false,
7397        isPaginated: false,
7398        pageNumber: null,
7399        data: null
7400    },
7401    _queue: [],
7402    _pageSize: 250,
7403    _pageLimit: 4,
7404    _progressTimer: null,
7405    _hideProgress: function () {
7406        if (api._progressTimer != null) {
7407            window.clearTimeout(api._progressTimer);
7408            api._progressTimer = null;
7409        }
7410        page.hideProgress();
7411    },
7412    _parseData: function (data) {
7413        var json = null;
7414        if (data != null) {
7415            if (data === '') {
7416                json = data;
7417            }
7418            else if (data.d != null) {
7419                if (data.d === '') {
7420                    json = data.d;
7421                }
7422                else {
7423                    try {
7424                        json = JSON.parse(data.d);
7425                    }
7426                    catch (ex) {
7427                        json = data.d;
7428                    }
7429                }
7430            }
7431            else {
7432                try {
7433                    json = JSON.parse(data);
7434                }
7435                catch (ex) {
7436                    json = data;
7437                }
7438            }
7439        }
7440        return json;
7441    },
7442    _tryCall: function () {
7443        if (api._queue.length === 0) {
7444            return;
7445        }
7446        try {
7447            var options = api._queue.shift();
7448            options = $.extend({}, api._defaults, options);
7449            var url = options.url;
7450            if (url != null && url !== '') {
7451                if (options.progress) {
7452                    api._progressTimer = window.setTimeout(function () {
7453                        page.showProgress(true);
7454                        window.clearTimeout(api._progressTimer);
7455                        api._progressTimer = null;
7456                    }, 1000);
7457                }
7458                if (options.isPaginated || url.indexOf('{Page}') > 0) {
7459                    options.isPaginated = true;
7460                    if (options.pageNumber == null) {
7461                        options.pageNumber = 1;
7462                    }
7463                    url = url.replace("{Page}", options.pageNumber.toString());
7464                }
7465                var params = {
7466                    type: 'POST',
7467                    url: '/Services/ProxyApi.asmx/Call',
7468                    headers: {
7469                        'Content-Type': 'application/json',
7470                        'ApiUrl': url,
7471                        'Method': options.method
7472                    },
7473                    crossDomain: false,
7474                    contentType: 'application/json; charset=utf-8',
7475                    dataType: 'json',
7476                    success: function (data, status, xhr) {
7477                        if (options.success != null && typeof (options.success) == 'function') {
7478                            var json = api._parseData(data);
7479                            if (json != null) {
7480                                if (options.isPaginated && json.dataList != null && json.dataList.length > 0) {
7481                                    if (options.data == null) {
7482                                        options.data = [];
7483                                    }
7484                                    options.data = options.data.concat(json.dataList);
7485                                    options.pageNumber++;
7486                                    if (json.dataList.length < api._pageSize || options.pageNumber > api._pageLimit || options.pageNumber > 1000) {
7487                                        options.success.call(this, { dataList: options.data }, status, xhr);
7488                                        if (options.progress) {
7489                                            api._hideProgress();
7490                                        }
7491                                    }
7492                                    else {
7493                                        api.call(options);
7494                                    }
7495                                    return;
7496                                }
7497                                else {
7498                                    if (options.progress) {
7499                                        api._hideProgress();
7500                                    }
7501                                }
7502                            }
7503                            options.success.call(this, json, status, xhr);
7504                        }
7505                        api._tryCall();
7506                    },
7507                    error: function (xhr, status, error) {
7508                        switch (xhr.status) {
7509                            case 429: // 429 Detect rate limiting
7510                                api._queue.add(options);
7511                                var retryAfter = xhr.getResponseHeader("retry-after");
7512                                if (retryAfter != null) {
7513                                    retryAfter = parseInt(retryAfter) * 1000;
7514                                }
7515                                else {
7516                                    retryAfter = 1000;
7517                                }
7518                                setTimeout(function () {
7519                                    api._tryCall();
7520                                }, retryAfter);
7521                                break;
7522                            case 404: // 404 No data returned
7523                                if (options.no404) {
7524                                    if (options.success != null && typeof (options.success) == "function") {
7525                                        options.success.call(this, null, status, xhr);
7526                                    }
7527                                }
7528                                else {
7529                                    if (options.error != null && typeof (options.error) == "function") {
7530                                        options.error.call(this, error, status, xhr);
7531                                    }
7532                                }
7533                                if (options.progress) {
7534                                    api._hideProgress();
7535                                }
7536                                api._tryCall();
7537                                break;
7538                            default: // All other errors
7539                                if (options.error != null && typeof (options.error) == "function") {
7540
7541                                    options.error.call(this, error, status, xhr);
7542                                }
7543                                if (options.progress) {
7544                                    api._hideProgress();
7545                                }
7546                                api._tryCall();
7547                                break;
7548                        }
7549                    }
7550                };
7551                if (options.parameters) {
7552                    params.data = JSON.stringify({ "parameters": JSON.stringify(options.parameters) });
7553                }
7554                else {
7555                    params.data = "\{\"parameters\":null}";
7556                }
7557                $.ajax(params);
7558            }
7559            else {
7560                page.displayError('API Call Error', 'Unable to call API. The URL cannot be null or empty.');
7561            }
7562        }
7563        catch (ex) {
7564            if (options.error != null && typeof (options.error) == "function") {
7565                options.error.call(this, ex.message);
7566            }
7567            if (options.progress) {
7568                api._hideProgress();
7569            }
7570            api._tryCall();
7571        }
7572    },
7573    call: function (options) {
7574        api._queue.push(options);
7575        if (api._queue.length === 1) {
7576            api._tryCall();
7577        }
7578    }
7579};;
7580var cookies = {
7581    getCookie: function (groupName, cookieName) {
7582        var cookieValue = null;
7583        var groupCookies = cookies._getCookieGroupCookies(groupName);
7584        for (var i = 0; i < groupCookies.length; i++) {
7585            if (groupCookies[i].name.toLowerCase().trim() == cookieName.toLowerCase().trim()) {
7586                cookieValue = groupCookies[i].value;
7587                break;
7588            }
7589        }
7590        return cookieValue;
7591    },
7592    setCookie: function (groupName, cookieName, cookieValue) {
7593        var isSet = false;
7594        var groupCookies = cookies._getCookieGroupCookies(groupName);
7595        for (var i = 0; i < groupCookies.length; i++) {
7596            if (groupCookies[i].name.toLowerCase().trim() == cookieName.toLowerCase().trim()) {
7597                groupCookies[i].value = cookieValue;
7598                isSet = true;
7599                break;
7600            }
7601        }
7602        if (!isSet) {
7603            var cookie = {
7604                name: cookieName.trim(),
7605                value: cookieValue.trim()
7606            };
7607            groupCookies.splice(0, 0, cookie);
7608        }
7609        cookies._setCookieGroupCookies(groupName, groupCookies);
7610    },
7611    deleteCookie: function (groupName, cookieName) {
7612        var groupCookies = cookies._getCookieGroupCookies(groupName);
7613        for (var i = 0; i < groupCookies.length; i++) {
7614            if (groupCookies[i].name.toLowerCase().trim() == cookieName.toLowerCase().trim()) {
7615                groupCookies.splice(i, 1);
7616                break;
7617            }
7618        }
7619        cookies._setCookieGroupCookies(groupName, groupCookies);
7620    },
7621    deleteCookieGroup: function (groupName) {
7622        cookies._setCookieGroupCookies(groupName, null);
7623    },
7624    _getCookieGroupCookies: function (groupName) {
7625        var groupCookies = [];
7626        var groupValue = null;
7627        var nameValue;
7628        var allCookies = document.cookie.split(';');
7629        for (var i = 0; i < allCookies.length; i++) {
7630            var currentGroup = allCookies[i].substring(0, allCookies[i].indexOf('='));
7631            if (currentGroup.toLowerCase().trim() == groupName.toLowerCase().trim()) {
7632                groupValue = allCookies[i].substring(allCookies[i].indexOf('=') + 1);
7633                break;
7634            }
7635        }
7636        if (groupValue != null) {
7637            var cookies = groupValue.split('&');
7638            for (var j = 0; j < cookies.length; j++) {
7639                nameValue = cookies[j].split('=');
7640                if (nameValue.length == 2) {
7641                    groupCookies[groupCookies.length] = {
7642                        name: unescape(nameValue[0]).trim(),
7643                        value: unescape(nameValue[1]).trim()
7644                    };
7645                }
7646            }
7647        }
7648        return groupCookies;
7649    },
7650    _setCookieGroupCookies: function (groupName, groupCookies) {
7651        var cookieString = groupName + '=';
7652        if (groupCookies !== undefined && groupCookies !== null && groupCookies.length > 0) {
7653            for (var i = 0; i < groupCookies.length; i++) {
7654                if (i > 0) {
7655                    cookieString += '&';
7656                }
7657                cookieString += escape(groupCookies[i].name) + '=' + escape(groupCookies[i].value);
7658            }
7659        }
7660        var expiration = new Date();
7661        expiration.setMonth(expiration.getMonth() + 1);
7662        cookieString += '; SameSite=Strict; expires=' + expiration.toUTCString() + '; path=/';
7663        document.cookie = cookieString;
7664    }
7665};;
7666page.load(function() {
7667    if (!page.isInDialogMode()) {
7668        if (window.enableSignalR) {
7669            notification.initNotificationHub();
7670        }
7671
7672        notification.initNotifications();
7673        notification.initPendingTasks();
7674    }
7675});
7676var notification = {
7677    _loaded: false,
7678    _tasksLoaded: false,
7679    initNotificationHub: function () {
7680        $.connection.hub.logging = false;
7681        var currentLocation = window.location.href;
7682        if (window.notificationGroup) {
7683            currentLocation = currentLocation + (currentLocation.indexOf('?') > -1 ? '&' : '?') + 'grp=' + window.notificationGroup;
7684        }
7685        $.connection.hub.qs = "loc=" + currentLocation;
7686        if (navigator.userAgent.search("Safari") >= 0 && navigator.userAgent.search("Chrome") < 0) {
7687            $.connection.hub.start({ transport: 'longPolling' });
7688        } else {
7689            $.connection.hub.start();
7690        }
7691        $.connection.hub.error(function (error) {
7692            console.log('SignalR error: ' + error);
7693        });
7694        var notificationHub = $.connection.notificationHub;
7695        if (notificationHub !== undefined && notificationHub !== null) {
7696            notificationHub.client.connected = function() {};
7697            notificationHub.client.disconnected = function() {};
7698            notificationHub.client.showNotification = notification.showNotification;
7699            notificationHub.client.refreshBooth = notification.refreshBooth;
7700        }
7701    },
7702    initNotifications: function () {
7703        $('.page-header-user-notifications').click(function () {
7704            if (notification._loaded == false) {
7705                page.ajax({
7706                    url: '~/Services/Notifications.asmx/GetNotifications',
7707                    parameters: {},
7708                    showProgress: false,
7709                    success: function (notifications) {
7710                        notification.buildNotificationScrollerMenu(notifications);
7711                        notification._loaded = true;
7712                    },
7713                    error: function (message) {
7714                        notification.buildNotificationScrollerMenu(null);
7715                        if (message) {
7716                            page.displayError('Loading Notifications', message);
7717                        }
7718                    }
7719                });
7720            } else {
7721               notification.clearNotificationsContainer()
7722            }
7723        });
7724    },
7725
7726    clearNotificationsContainer: function () { 
7727        var ulNotifications = document.getElementById('ul-page-header-notification'); 
7728        ulNotifications.innerHTML = ''; 
7729        var emptyItem = '<li class="height-200">' +
7730            '<div class="align-center padding-top-50">' +
7731            '<small class="display-block">No New Notifications</small>' +
7732            '</div>' +
7733            '</li>';
7734        $('.page-header-notification-scroller').append(emptyItem);
7735    },
7736
7737    buildNotificationScrollerMenu: function (notifications) { 
7738        $('.page-header-notification-scroller').empty();
7739        if (notifications != null && notifications.length > 0) {
7740            for (var i = 0; i < notifications.length; i++) {
7741                if (window.location.appPath == null) { window.location.appPath == ''; }
7742                var url = window.location.myProfilePath.replace(/^~/, window.location.appPath) + '?tab=notifications';
7743                var localdt = page.convertDateStringToLocalDate(notifications[i].CreatedOn);
7744                var dd = moment(localdt);
7745                if (notifications[i].Url != undefined && notifications[i].Url != null && notifications[i].Url != '') {
7746                    url = notifications[i].Url;
7747                }
7748                var item = '<li>' +
7749                    '<a href="' + url + '">' +
7750                    '<span class="label label-sm label-icon label-danger"><i class="icon-bolt"></i></span>' +
7751                    notifications[i].Message +
7752                    '<br/>' +
7753                    '<span class="time">' + dd.fromNow() + '</span>' +
7754                    '</a>' +
7755                    '</li>';
7756                $('.page-header-notification-scroller').append(item);
7757            }
7758        }
7759        else {
7760            notification.clearNotificationsContainer()
7761        }
7762    },
7763    showNotification: function (msg) {
7764        if (msg.Type == "Task") {
7765            notification._tasksLoaded = false;
7766            notification.incrementCounterByCssClass('page-header-task-count');
7767        }
7768        if (msg.Type != "Alert") {
7769            notification._loaded = false;
7770            notification.incrementCounterByCssClass('page-header-notification-count');
7771        }
7772        if (msg.Action == "IncludeToastr") {
7773            page.showToastrNotification(msg.Icon, msg.Title, msg.Message);
7774        }
7775    },
7776    incrementCounterByCssClass: function (cssClass) {
7777        var counter = $('.' + cssClass);
7778        if (counter != null) {
7779            try {
7780                counter.each(function () {
7781                    $(this).text(parseInt($(this).text(), 10) + 1);
7782                });
7783            }
7784            catch (e) { }
7785            if (counter.is('.hide')) {
7786                counter.removeClass('hide');
7787            }
7788        }
7789    },
7790    initPendingTasks: function () {
7791        $('.page-header-user-tasks').click(function () {
7792            if (notification._tasksLoaded == false) {
7793                page.ajax({
7794                    url: '~/Services/Notifications.asmx/GetPendingTasks',
7795                    parameters: {},
7796                    showProgress: false,
7797                    success: function (tasks) {
7798                        notification.buildTaskScrollerMenu(tasks);
7799                        notification._tasksLoaded = true;
7800                    },
7801                    error: function (message) {
7802                        notification.buildTaskScrollerMenu(null);
7803                        if (message) {
7804                            page.displayError('Loading Tasks', message);
7805                        }
7806                    }
7807                });
7808            }
7809        });
7810    },
7811    buildTaskScrollerMenu: function (tasks) {
7812        $('.page-header-task-scroller').empty();
7813        if (tasks != null && tasks.length > 0) {
7814            for (var i = 0; i < tasks.length; i++) {
7815                if (window.location.appPath == null) { window.location.appPath == ''; }
7816                var url = window.location.myProfilePath.replace(/^~/, window.location.appPath) + '?tab=tasks&TaskId=' + tasks[i].TaskId;
7817                var item = '<li>' +
7818                    '<a href="' + url + '">' +
7819                    '<span class="task">' +
7820                    '<span class="desc">' + tasks[i].Task.Title + '</span>' +
7821                    '<span class="percent">' + tasks[i].Progress + '%</span>' +
7822                    '</span>' +
7823                    '<span class="progress">' +
7824                    '<span style="width: ' + tasks[i].Progress + '%;" class="progress-bar progress-bar-success" aria-valuenow="' + tasks[i].progress + '" aria-valuemin="0" aria-valuemax="100">' +
7825                    '<span class="sr-only">' + tasks[i].Progress + '% Complete</span>' +
7826                    '</span>' +
7827                    '</span>' +
7828                    '</a>' +
7829                    '</li>';
7830                $('.page-header-task-scroller').append(item);
7831            }
7832        }
7833        else {
7834            var emptyItem = '<li class="height-200">' +
7835                '<div class="align-center padding-top-50">' +
7836                '<small class="display-block">No Pending Tasks</small>' +
7837                '</div>' +
7838                '</li>';
7839            $('.page-header-task-scroller').append(emptyItem);
7840        }
7841    },
7842    refreshBooth: function (hallId, boothNumber, type) {
7843        if (!page.isInDialogMode()) {
7844            floorplan.refreshBooth(hallId, boothNumber, type);
7845        }
7846    }
7847};;
7848var dialog = {
7849    _timerId: null,
7850    _clearTimerId: null,
7851    _closeTimerId: null,
7852    _dialogsArray: [],
7853    open: function (options) {
7854        options = $.extend({}, dialog.defaults, options);
7855        if (options._private.win === undefined || options._private.win === null) {
7856            options._private.win = window;
7857        }
7858        if (options._private.doc === undefined || options._private.doc === null) {
7859            options._private.doc = document;
7860        }
7861        if (window.frameElement && window.parent != null) {
7862            if (options.selector !== null && options.selector !== '') {
7863                // Get the current element (in the current document)
7864                options._private.self = $(options.selector);
7865                // Get the current element's parent (in the current document)
7866                options._private.parent = options._private.self.parent();
7867            }
7868            else if (options.id !== null && options.id !== '') {
7869                if (options.id.substring(0, 1) !== '#') {
7870                    options.id = '#' + options.id;
7871                }
7872                // Get the current element (in the current document)
7873                options._private.self = $(options.id);
7874                // Get the current element's parent (in the current document)
7875                options._private.parent = options._private.self.parent();
7876            }
7877            window.parent.dialog.open(options);
7878        }
7879        else {
7880            var parent = null;
7881            if (options.id !== null || options.url !== null) {
7882                var element = null;
7883                if (options._private.self !== null && options._private.parent !== null) {
7884                    element = options._private.self;
7885                    parent = options._private.parent;
7886                }
7887                else {
7888                    if (options.selector !== null && options.selector !== '') {
7889                        element = $(options.selector);
7890                        parent = element.parent();
7891                    }
7892                    else if (options.id !== null && options.id !== '') {
7893                        if (options.id.substring(0, 1) !== '#') {
7894                            options.id = '#' + options.id;
7895                        }
7896                        element = $(options.id);
7897                        parent = element.parent();
7898                    }
7899                    else if (options.url !== null) {
7900                        element = $('<iframe></iframe>').attr({ id: page.uniqueId(), 'frameborder': '0', 'scrolling': 'yes' }).css({ 'z-index': '1000000' });                                                
7901                    }
7902                }
7903                element.css({ 'width': '100%', 'height': '100%' });
7904                var id = page.uniqueId();
7905                var widthClass = '';
7906                switch (options.width) {
7907                    default: case 'normal': widthClass = ''; break;
7908                    case 'wide': widthClass = ' modal-wide'; break;
7909                    case 'xwide': widthClass = ' modal-xwide'; break;
7910                    case 'full': widthClass = ' modal-full'; break;
7911                }
7912                var container = $('<div></div>').attr({ 'id': id, 'tabindex': '-1' }).css({ 'height': 'auto' }).addClass('modal fade')
7913                    .append($('<div></div>').addClass('modal-dialog' + widthClass).css({ 'height': 'auto' })
7914                        .append($('<div></div>').addClass('modal-header')
7915                            .append($('<button></button>').attr({ 'type': 'button', 'aria-hidden': 'true', 'data-dismiss': 'modal' }).addClass('close'))
7916                            .append($('<h4></h4>').addClass('modal-title').html(options.title)))
7917                        .append($('<div></div>').addClass('modal-body').css({ 'height': 'auto' })))
7918                    .appendTo($(options.container));
7919                container.modal('show');
7920
7921                // Adjust position if options.position is not null
7922                if (options.position !== null) {
7923                    if (options.position === 'right') {
7924                        container.css({ 'top': '150px', 'right': '20px', 'left': 'auto' });
7925                    }
7926                }
7927                // This calls the dialog.close when (1) clicking X button (2) clicking outside the modal (3) pressing keyboard ESC key
7928                container.on('hidden.bs.modal', function (ev) {
7929                    ev = (ev || window.event);
7930                    ev.preventDefault();
7931                    $.Event(ev).preventDefault();
7932                    // Make sure we are closing the correct dialog, this was a issue when having dialog on top of dialog
7933                    dialog.close();
7934                });
7935                // This calls the dialog.close 
7936                $('.modal').on('hide.bs.modal', function (ev) {
7937                    var currentDialog = dialog._dialogsArray[dialog._dialogsArray.length - 1];
7938                    if (currentDialog != null && currentDialog.id === id) {
7939                        if (currentDialog.preventClose === true) {
7940                            ev = (ev || window.event);
7941                            ev.preventDefault();
7942                            $.Event(ev).preventDefault();
7943                        }
7944                    }
7945                });
7946                if (options.showProgress === true) {
7947                    page.showProgress();
7948                }
7949                if (options.preventClose === true) {
7950                    $('#' + id + ' button.close[data-dismiss="modal"]').css({ 'display': 'none' });
7951                }
7952                else {
7953                    $('#' + id + ' button.close[data-dismiss="modal"]').attr({ 'title': 'Close' });
7954                }
7955                if (options.feedbackButton && window.Feedback) {
7956                    var feedbackButton = $('<a></a>').addClass('dialog-button').attr({ 'href': 'javascript:void(0);', 'title': 'Feedback' }).append($('<i class="icon-comment-o"></i>'));
7957                    page.bindFeedback(feedbackButton);
7958                    $('#' + id + ' button.close[data-dismiss="modal"]').after(feedbackButton);
7959                }
7960                //$('#' + id + ' button.close[data-dismiss="modal"]').after(openButton);
7961                if (element !== null && element.is('iframe') && options.url !== null && options.url !== '') {
7962                    if (window.location.appPath == null) { window.location.appPath == ''; }
7963                    var url = options.url.replace(/^~/, window.location.appPath);
7964                    if (url.indexOf('isAdminSite=') < 0) {
7965                        url = url + (url.indexOf("?") < 0 ? '?' : '&') + 'isAdminSite=' + $('#__ADMINSITE').val();
7966                    }
7967                    if (url.indexOf('browserId=') < 0) {
7968                        url = url + (url.indexOf("?") < 0 ? '?' : '&') + 'browserId=' + $('#__BROWSERID').val();
7969                    }
7970                    if (options.openButton) {
7971                        var openButton = $('<a></a>').addClass('dialog-button').attr({ 'href': 'javascript:void(0);', 'title': 'Open in New Window' }).click(function () {
7972                            dialog.close();
7973                            window.open(url, 'win' + id, 'titlebar=no, menubar=no, status=no');
7974                        }).append($('<i class="icon-external-link"></i>'));
7975                        $('#' + id + ' button.close[data-dismiss="modal"]').after(openButton);
7976                    }
7977                    if (options.resizeButton) {
7978                        var resizeButton = $('<a></a>').addClass('dialog-button').attr({ 'href': 'javascript:void(0);', 'title': 'Maximize' }).click(function () {
7979                            if ($(this).attr('title') === 'Maximize') {
7980                                $('#' + id + ' .modal-dialog').addClass('modal-full-screen').addClass('margin-0');
7981                                element.attr('data-height', element.height()).css('height', $(window).height() - $('#' + id + ' .modal-dialog').find('.modal
7981-header').height() - 40);
7982                                $(this).find('i').removeClass('icon-plus-square-o').addClass('icon-minus-square-o');
7983                                $(this).attr({ 'title': 'Minimize' });
7984                            }
7985                            else {
7986                                $('#' + id + ' .modal-dialog').removeClass('modal-full-screen').removeClass('margin-0');
7987                                element.css('height', element.attr('data-height'));
7988                                $(this).find('i').removeClass('icon-minus-square-o').addClass('icon-plus-square-o');
7989                                $(this).attr({ 'title': 'Maximize' });
7990                            }
7991                            dialog.resize();
7992                        }).append($('<i class="icon-plus-square-o"></i>'));
7993                        $('#' + id + ' button.close[data-dismiss="modal"]').after(resizeButton);
7994                    }
7995                    element.css({ 'width': '100%', 'height': options.height }).loaded(function () {
7996                        dialog.resize();
7997                        if (options.showProgress === true) {
7998                            page.hideProgress();
7999                        }
8000                    }).attr({ 'src': url });
8001                }
8002                dialog._dialogsArray[dialog._dialogsArray.length] = {
8003                    id: id,
8004                    self: element,
8005                    parent: parent,
8006                    args: options.args,
8007                    callback: (options.callback ? options.callback : null),
8008                    preventClose: (options.preventClose === true ? true : false),
8009                    refreshParent: options.refreshParent,
8010                    _private: options._private
8011                };
8012                $('#' + id + ' .modal-body').append(element);
8013            }
8014        }
8015    },
8016    close: function (args) {
8017             
8018        if (window.opener != null && page.queryString("browserId") != null) {
8019            window.close();
8020            window.opener.document.forms[0].submit();
8021        }
8022        else {
8023            if (window.frameElement && window.parent != null) {
8024                window.parent.dialog.close(args);
8025            }
8026            else if (dialog._dialogsArray !== null && dialog._dialogsArray.length > 0) {
8027                if (dialog._timerId == null) {
8028                    dialog._timerId = setTimeout(function () {
8029                        if (args === undefined) {
8030                            args = null;
8031                        }
8032                        var currentDialog = dialog._dialogsArray[dialog._dialogsArray.length - 1];
8033                        var callback = currentDialog.callback;
8034                        if (callback && typeof (callback) == 'function') {
8035                            callback.call(this, args);
8036                        }
8037                        else {
8038                            // Auto refresh parent
8039                            var shouldRefresh = false;
8040                            var refreshParent = currentDialog.refreshParent;
8041                            if (refreshParent === 'force') {
8042                                shouldRefresh = true;
8043                            }
8044                            else if (refreshParent === true || refreshParent === 'true') {
8045                                shouldRefresh = (args !== undefined && args !== null);
8046                            }
8047                            if (shouldRefresh) {
8048                                var win = currentDialog._private.win;
8049                                if (win != null) {
8050                                    win.page.refresh();
8051                                }
8052                                else {
8053                                    page.refresh();
8054                                }
8055                            }
8056                        }
8057                        var container = $('#' + currentDialog.id);
8058                        container.modal('hide');
8059                        $('.modal-backdrop').last().remove();
8060                        $('body').removeClass('modal-open');
8061                        if (currentDialog.parent !== null) {
8062                            try {
8063                                var currentContent = container.find('.modal
8063-body').children();
8064                                currentDialog.parent.append(currentContent);
8065                                container.remove();
8066                            }
8067                            catch (ex) { }
8068                        }
8069                        else if (dialog._clearTimerId == null) {
8070                            dialog._clearTimerId = setTimeout(function () {
8071                                container.children().remove();
8072                                container.remove();
8073                                clearTimeout(dialog._clearTimerId);
8074                                dialog._clearTimerId = null;
8075                            }, 250, null);
8076                        }
8077                        dialog._dialogsArray.splice(dialog._dialogsArray.length - 1, 1);
8078                        clearTimeout(dialog._timerId);
8079                        dialog._timerId = null;
8080                    }, 250, null);
8081                }
8082            }
8083        }
8084
8085        // for more complicated dialogs where refreshing the parent is needed, but not easily available.
8086        // add a button and make it visible when parent refresh is desired.
8087        // the close operation will find the button and initiate postback/refresh.
8088        try {
8089            var forceReload = $('#btnDialogRefresh');
8090            if (forceReload.length) {
8091                forceReload[0].click();
8092            }
8093        } catch (e) {
8094        }
8095    },
8096    resize: function (selector, isShrinking, callback) {
8097        if (window.frameElement && window.parent != null) {
8098            var timer = null;
8099            timer = window.setTimeout(function () {
8100                if (isShrinking === undefined || isShrinking === null) {
8101                    isShrinking = false;
8102                }
8103                var iframeContent;
8104                var iframeContentHeight = 0;
8105                if (selector && selector != null) {
8106                    iframeContent = $(selector);
8107                    iframeContentHeight = (iframeContent.length > 0 ? isShrinking ? Math.min(iframeContent[0].scrollHeight, document.documentElement.scrollHeight) : Math.max(iframeContent[0].scrollHeight, document.documentElement.scrollHeight) : 0);
8108                }
8109                if (iframeContentHeight === 0) {
8110                    iframeContent = $('form');
8111                    iframeContentHeight = (iframeContent.length > 0 ? isShrinking ? Math.min(iframeContent[0].scrollHeight, document.documentElement.scrollHeight) : Math.max(iframeContent[0].scrollHeight, document.documentElement.scrollHeight) : 0);
8112                    if (iframeContentHeight === 0) {
8113                        iframeContent = $('body');
8114                        iframeContentHeight = (iframeContent.length > 0 ? isShrinking ? Math.min(iframeContent[0].scrollHeight, document.documentElement.scrollHeight) : Math.max(iframeContent[0].scrollHeight, document.documentElement.scrollHeight) : 0);
8115                    }
8116                }
8117                if (iframeContentHeight === 0) {
8118                    iframeContentHeight = 400;
8119                }
8120                if ($(window.frameElement).parents('.modal-body').length > 0) {
8121                    // These are on modal dialog windows, not inline iframes
8122                    $(window.frameElement).animate({ 'height': iframeContentHeight });
8123                }
8124                else {
8125                    // These are inline iframes on main page, no animation and different logic
8126                    //breaks responsiveness
8127                    $('html').css({ 'width': '99%' });
8128                    $(window.frameElement).css({ 'height': iframeContentHeight });
8129                }
8130                if (callback && typeof (callback) == 'function') {
8131                    callback.call(this);
8132                }
8133                window.clearTimeout(timer);
8134            }, 250);
8135        }
8136        else if (callback && typeof (callback) == 'function') {
8137            callback.call(this);
8138        }
8139    },
8140    messageBox: function (options) {
8141        options = $.extend({}, dialog.messageBoxDefaults, options);
8142        options.resizeButton = false;
8143        options.openButton = false;
8144        if (options._private.win === undefined || options._private.win === null) {
8145            options._private.win = window;
8146        }
8147        if (options._private.doc === undefined || options._private.doc === null) {
8148            options._private.doc = document;
8149        }
8150        if (window.frameElement && window.parent != null) {
8151            window.parent.dialog.messageBox(options);
8152        }
8153        else {
8154            var id = page.uniqueId();
8155            var panel = $('<div></div>').attr({ 'id': id }).addClass('alert form-body').appendTo($('body'));
8156            var message = $('<div></div>').addClass('message-box').addClass('alert').appendTo(panel);
8157            switch (options.icon.toLowerCase()) {
8158                case 'success': message.addClass('alert-success'); message.append($('<i></i>').addClass('icon-check-circle')); break;
8159                case 'information': message.addClass('alert-info'); message.append($('<i></i>').addClass('icon-info-circle')); break;
8160                case 'question': message.addClass('alert-info'); message.append($('<i></i>').addClass('icon-question-circle')); break;
8161                case 'warning': message.addClass('alert-warning'); message.append($('<i></i>').addClass('icon-warning')); break;
8162                case 'error': message.addClass('alert-danger'); message.append($('<i></i>').addClass('icon-times-circle')); break;
8163            }
8164            message.append($('<div></div>').addClass('form-group').css('width', '80% ').html(options.message));
8165            var checkbox = null;
8166            if (options.checkbox.id !== '' && options.checkbox.message !== '') {
8167                var checkboxContainer = $('<div></div>').addClass('padding-top-10 padding-bottom-20').appendTo(panel);
8168                checkbox = $('<input></input>').attr({ 'type': 'checkbox', 'data-id': id }).appendTo(checkboxContainer);
8169                $('<span></span>').html(options.checkbox.message).appendTo(checkboxContainer);
8170            }
8171
8172            // used in lot of places where recordinfo may be unavailable 
8173            try {
8174                // create a table to show the CreatedBy and Updated
8175                if (options.recordInfo != null && options.recordInfo.enabled == true) {
8176
8177                    panel.append(dialog.recordInfoForMessageBox(options.recordInfo));
8178                }
8179            }
8180            catch (ex) {
8181                // do nothing.
8182            }
8183
8184            var buttonsContainer = $('<div></div>').addClass('btn-group float-right').appendTo(panel);
8185            panel.append($('<div></div>').addClass('clearfix'));
8186            var buttons = options.buttons.split(',');
8187            var exists = false;
8188            if (buttons.length > 0) {
8189                for (var i = 0; i < buttons.length; i++) {
8190                    var text = buttons[i].trim();
8191                    if (text !== '') {
8192                        buttonsContainer.append($('<button></button>').attr({ 'type': 'button' }).addClass('btn blue').text(text)
8193                            .click(function () {
8194                                dialog.close($(this).text().toLowerCase());
8195                            }));
8196                        exists = true;
8197                    }
8198                }
8199            }
8200            if (!exists) {
8201                buttonsContainer.append($('<button></button>').attr({ 'type': 'button' }).addClass('btn blue').html('Close'))
8202                    .click(function () {
8203                        dialog.close('close');
8204                    });
8205            }
8206            dialog.open({
8207                id: '#' + id,
8208                title: options.title,
8209                width: 'normal',
8210                callback: function (args) {
8211                    if (options.callback && typeof (options.callback) == 'function') {
8212                        options.callback.call(this, (args ? args : ''), checkbox != null ? { 'id': options.checkbox.id, 'checked': checkbox.prop('checked') } : null);
8213                    }
8214                    panel.remove();
8215                }
8216            });
8217        }
8218        return false;
8219    },
8220    recordInfoForMessageBox: function (recordInfoOption)
8221    {
8222        try {
8223            var tableRecordInfo = $('<table></table>').addClass('table-bordered min-width-250 font-size-xsmall');
8224            // tbody
8225            var tbody = $('<tbody></tbody>');
8226            tableRecordInfo.append(tbody);
8227            // Adding a row  1
8228            var trRow1 = $('<tr></tr>');
8229            // Adding a cell 1 the th
8230            var thCreatedLabel = $('<strong>Created</strong>').addClass('white');
8231            var thCreatedContainer = $('<th></th>').addClass('width-50 bg-gray-c valign-text-top padding-left-5 padding-right-5');
8232            // add cell 1 to row 1
8233            thCreatedContainer.append(thCreatedLabel);
8234            // Adding a cell 2 to th
8235            var createdValueCell = "<small>" + recordInfoOption.createdBy
8236                + "</small>" + "<br>" + "<small>" + recordInfoOption.created
8237                + "</small>";
8238
8239            var thCreatedValueContainer = $('<th></th>').addClass('gray-c padding-left-5 padding-right-5');
8240            thCreatedValueContainer.append(createdValueCell);
8241            trRow1.append(thCreatedContainer);
8242            trRow1.append(thCreatedValueContainer);
8243            tableRecordInfo.append(trRow1);
8244            // Adding a row  2
8245            var trRow2 = $('<tr></tr>');
8246            var thModifiedLabel = $('<strong>Modified</strong>').addClass('white');
8247            var thModifiedContainer = $('<th></th>').addClass('width-50 bg-gray-c valign-text-top padding-left-5 padding-right-5');
8248            thModifiedContainer.append(thModifiedLabel);
8249            var modifiedValueCell = "<small>" + recordInfoOption.modifiedBy
8250                + "</small>" + "<br>" + "<small>" + recordInfoOption.modified
8251                + "</small>";
8252            var thModifiedValueContainer = $('<th></th>').addClass('gray-c padding-left-5 padding-right-5');
8253            thModifiedValueContainer.append(modifiedValueCell);
8254            trRow2.append(thModifiedContainer);
8255            trRow2.append(thModifiedValueContainer);
8256
8257            tableRecordInfo.append(trRow2);
8258
8259            return tableRecordInfo;
8260        }
8261        catch (e) {
8262            return $('<div></div>');
8263        }
8264    },
8265    confirm: function (ev, options) {
8266        ev = (ev || window.event);
8267        options = $.extend({}, dialog.confirmDefaults, options);
8268        if (options._private.win === undefined || options._private.win === null) {
8269            options._private.win = window;
8270        }
8271        if (options._private.doc === undefined || options._private.doc === null) {
8272            options._private.doc = document;
8273        }
8274        if (window.frameElement && window.parent != null) {
8275            window.parent.dialog.confirm(ev, options);
8276        }
8277        else {
8278            var sender = ev ? (ev.target || ev.srcElement) : null;
8279            if (sender != null && $(sender).is('i')) {
8280                sender = $(sender).parent()[0];
8281            }
8282            options.buttons = 'OK,Cancel';
8283            var callback = options.callback;
8284            options.callback = function (args) {
8285                args = (args ? args : '');
8286                if (args === 'ok') {
8287                    if (options.okClicked && typeof (options.okClicked) == 'function') {
8288                        options.okClicked.call(this, args);
8289                    }
8290                    if (sender !== null && $(sender).attr('id') != null && $(sender).attr('id') !== '') {
8291                        if ($(sender).is('input[type="submit"]') || $(sender).is('input[type="image"]') || $(sender).is('input[type="button"]') || $(sender).is('button') || $(sender).is('a')) {
8292                            options._private.win.page.postback($(sender).attr('id').replace(/_/g, '$'), '');
8293                        }
8294                    }
8295                }
8296                else if (args === 'cancel' && options.cancelClicked && typeof (options.cancelClicked) == 'function') {
8297                    options.cancelClicked.call(this, args);
8298                }
8299                if (callback && typeof (callback) == 'function') {
8300                    callback.call(this, args);
8301                }
8302            };
8303            dialog.messageBox(options);
8304        }
8305        if (ev) {
8306            $.Event(ev).preventDefault();
8307        }
8308        return false;
8309    },
8310    setTitle: function (title) {
8311        if (window.opener == null || page.queryString("browserId") == null) {
8312            if (window.frameElement && window.parent != null) {
8313                window.parent.dialog.setTitle(title);
8314            }
8315            else if (dialog._dialogsArray !== null && dialog._dialogsArray.length > 0) {
8316                $('#' + dialog._dialogsArray[dialog._dialogsArray.length - 1].id).find('.modal
8316-dialog .modal-header h4').html(title);
8317            }
8318        }
8319    },
8320    getArguments: function () {
8321        if (window.frameElement && window.parent != null) {
8322            return window.parent.dialog.getArguments();
8323        }
8324        else {
8325            return dialog._dialogsArray[dialog._dialogsArray.length - 1].args;
8326        }
8327    },
8328    scrollToTop: function (offset) {
8329        if (window.frameElement && window.parent != null) {
8330            window.parent.dialog.scrollToTop();
8331        }
8332        else if (dialog._dialogsArray !== null && dialog._dialogsArray.length > 0) {
8333            if (offset == null || isNaN(offset) || offset < 0) {
8334                offset = 0;
8335            }
8336            $('#' + dialog._dialogsArray[dialog._dialogsArray.length - 1].id).animate({ scrollTop: offset }, 'fast');
8337        }
8338    },
8339    defaults: {
8340        selector: null,
8341        id: '',
8342        url: '',
8343        title: 'Web Page Dialog',
8344        width: 'normal',
8345        height: '150px',
8346        container: 'body',
8347        resizeButton: true,
8348        openButton: true,
8349        feedbackButton: false,
8350        args: null,
8351        onload: null,
8352        callback: null,
8353        refreshParent: false,
8354        preventClose: false,
8355        showProgress: false,
8356        position: null,
8357        _private: {
8358            win: null,
8359            doc: null,
8360            self: null,
8361            parent: null
8362        }
8363    },
8364    messageBoxDefaults: {
8365        title: 'Web Page Dialog',
8366        icon: 'Information',
8367        message: '',
8368        buttons: '',
8369        checkbox: {
8370            id: '',
8371            message: ''
8372        },
8373        callback: null,
8374        refreshParent: false,
8375        preventClose: false,
8376        _private: {
8377            win: null,
8378            doc: null,
8379            self: null,
8380            parent: null
8381        }
8382    },
8383    confirmDefaults: {
8384        title: 'Web Page Dialog',
8385        icon: 'Information',
8386        message: '',
8387        callback: null,
8388        okClicked: null,
8389        cancelClicked: null,
8390        refreshParent: false,
8391        preventClose: false,
8392        _private: {
8393            win: null,
8394            doc: null,
8395            self: null,
8396            parent: null
8397        }
8398    }
8399};;
8400var PasswordPeek = function () {
8401
8402    return {
8403        showPassword: function (event, passwordInputdId, eyeIconId) {
8404            var passwordControl = $('#' + passwordInputdId);
8405            var currentType = passwordControl.attr('type');
8406            var icon = $('#' + eyeIconId);
8407            if (currentType === 'text') {
8408                passwordControl.attr('type', 'password');
8409                icon.addClass('icon-eye').removeClass('icon-eye-slash');
8410            }
8411            else {
8412                passwordControl.attr('type', 'text');
8413                icon.addClass('icon-eye-slash').removeClass('icon-eye');
8414            }
8415            event.preventDefault();
8416        }
8417    };
8418
8419}();
8420;

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.