1/*! jQuery Migrate v3.4.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */ 2"undefined"==typeof jQuery.migrateMute&&(jQuery.migrateMute=!0),function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],function(e){return t(e,window)}):"object"==typeof module&&module.exports?module.exports=t(require("jquery"),window):t(jQuery,window)}(function(s,n){"use strict";function e(e){return 0<=function(e,t){for(var r=/^(\d+)\.(\d+)\.(\d+)/,n=r.exec(e)||[],o=r.exec(t)||[],a=1;a<=3;a++){if(+o[a]<+n[a])return 1;if(+n[a]<+o[a])return-1}return 0}(s.fn.jquery,e)}s.migrateVersion="3.4.1";var t=Object.create(null);s.migrateDisablePatches=function(){for(var e=0;e<arguments.length;e++)t[arguments[e]]=!0},s.migrateEnablePatches=function(){for(var e=0;e<arguments.length;e++)delete t[arguments[e]]},s.migrateIsPatchEnabled=function(e){return!t[e]},n.console&&n.console.log&&(s&&e("3.0.0")&&!e("5.0.0")||n.console.log("JQMIGRATE: jQuery 3.x-4.x REQUIRED"),s.migrateWarnings&&n.console.log("JQMIGRATE: Migrate plugin loaded multiple times"),n.console.log("JQMIGRATE: Migrate is installed"+(s.migrateMute?"":" with logging active")+", version "+s.migrateVersion));var o={};function u(e,t){var r=n.console;!s.migrateIsPatchEnabled(e)||s.migrateDeduplicateWarnings&&o[t]||(o[t]=!0,s.migrateWarnings.push(t+" ["+e+"]"),r&&r.warn&&!s.migrateMute&&(r.warn("JQMIGRATE: "+t),s.migrateTrace&&r.trace&&r.trace()))}function r(e,t,r,n,o){Object.defineProperty(e,t,{configurable:!0,enumerable:!0,get:function(){return u(n,o),r},set:function(e){u(n,o),r=e}})}function a(e,t,r,n,o){var a=e[t];e[t]=function(){return o&&u(n,o),(s.migrateIsPatchEnabled(n)?r:a||s.noop).apply(this,arguments)}}function c(e,t,r,n,o){if(!o)throw new Error("No warning message provided");return a(e,t,r,n,o),0}function i(e,t,r,n){return a(e,t,r,n),0}s.migrateDeduplicateWarnings=!0,s.migrateWarnings=[],void 0===s.migrateTrace&&(s.migrateTrace=!0),s.migrateReset=function(){o={},s.migrateWarnings.length=0},"BackCompat"===n.document.compatMode&&u("quirks","jQuery is not compatible with Quirks Mode");var d,l,p,f={},m=s.fn.init,y=s.find,h=/\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/,g=/\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g,v=/^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g;for(d in i(s.fn,"init",function(e){var t=Array.prototype.slice.call(arguments);return s.migrateIsPatchEnabled("selector-empty-id")&&"string"==typeof e&&"#"===e&&(u("selector-empty-id","jQuery( '#' ) is not a valid selector"),t[0]=[]),m.apply(this,t)},"selector-empty-id"),s.fn.init.prototype=s.fn,i(s,"find",function(t){var r=Array.prototype.slice.call(arguments);if("string"==typeof t&&h.test(t))try{n.document.querySelector(t)}catch(e){t=t.replace(g,function(e,t,r,n){return"["+t+r+'"'+n+'"]'});try{n.document.querySelector(t),u("selector-hash","Attribute selector with '#' must be quoted: "+r[0]),r[0]=t}catch(e){u("selector-hash","Attribute selector with '#' was not fixed: "+r[0])}}return y.apply(this,r)},"selector-hash"),y)Object.prototype.hasOwnProperty.call(y,d)&&(s.find[d]=y[d]);c(s.fn,"size",function(){return this.length},"size","jQuery.fn.size() is deprecated and removed; use the .length property"),c(s,"parseJSON",function(){return JSON.parse.apply(null,arguments)},"parseJSON","jQuery.parseJSON is deprecated; use JSON.parse"),c(s,"holdReady",s.holdReady,"holdReady","jQuery.holdReady is deprecated"),c(s,"unique",s.uniqueSort,"unique","jQuery.unique is deprecated; use jQuery.uniqueSort"),r(s.expr,"filters",s.expr.pseudos,"expr-pre-pseudos","jQuery.expr.filters is deprecated; use jQuery.expr.pseudos"),r(s.expr,":",s.expr.pseudos,"expr-pre-pseudos","jQuery.expr[':'] is deprecated; use jQuery.expr.pseudos"),e("3.1.1")&&c(s,"trim",function(e){return null==e?"":(e+"").replace(v,"$1")},"trim","jQuery.trim is deprecated; use String.prototype.trim"),e("3.2.0")&&(c(s,"nodeName",function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},"nodeName","jQuery.nodeName is deprecated"),c(s,"isArray",Array.isArray,"isArray","jQuery.isArray is deprecated; use Array.isArray")),e("3.3.0")&&(c(s,"isNumeric",function(e){var t=typeof e;return("number"==t||"string"==t)&&!isNaN(e-parseFloat(e))},"isNumeric","jQuery.isNumeric() is deprecated"),s.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){f["[object "+t+"]"]=t.toLowerCase()}),c(s,"type",function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?f[Object.prototype.toString.call(e)]||"object":typeof e},"type","jQuery.type is deprecated"),c(s,"isFunction",function(e){return"function"==typeof e},"isFunction","jQuery.isFunction() is deprecated"),c(s,"isWindow",function(e){return null!=e&&e===e.window}
2,"isWindow","jQuery.isWindow() is deprecated")),s.ajax&&(l=s.ajax,p=/(=)\?(?=&|$)|\?\?/,i(s,"ajax",function(){var e=l.apply(this,arguments);return e.promise&&(c(e,"success",e.done,"jqXHR-methods","jQXHR.success is deprecated and removed"),c(e,"error",e.fail,"jqXHR-methods","jQXHR.error is deprecated and removed"),c(e,"complete",e.always,"jqXHR-methods","jQXHR.complete is deprecated and removed")),e},"jqXHR-methods"),e("4.0.0")||s.ajaxPrefilter("+json",function(e){!1!==e.jsonp&&(p.test(e.url)||"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&p.test(e.data))&&u("jsonp-promotion","JSON-to-JSONP auto-promotion is deprecated")}));var j=s.fn.removeAttr,b=s.fn.toggleClass,w=/\S+/g;function x(e){return e.replace(/-([a-z])/g,function(e,t){return t.toUpperCase()})}i(s.fn,"removeAttr",function(e){var r=this,n=!1;return s.each(e.match(w),function(e,t){s.expr.match.bool.test(t)&&r.each(function(){if(!1!==s(this).prop(t))return!(n=!0)}),n&&(u("removeAttr-bool","jQuery.fn.removeAttr no longer sets boolean properties: "+t),r.prop(t,!1))}),j.apply(this,arguments)},"removeAttr-bool"),i(s.fn,"toggleClass",function(t){return void 0!==t&&"boolean"!=typeof t?b.apply(this,arguments):(u("toggleClass-bool","jQuery.fn.toggleClass( boolean ) is deprecated"),this.each(function(){var e=this.getAttribute&&this.getAttribute("class")||"";e&&s.data(this,"__className__",e),this.setAttribute&&this.setAttribute("class",!e&&!1!==t&&s.data(this,"__className__")||"")}))},"toggleClass-bool");var Q,A,R=!1,C=/^[a-z]/,N=/^(?:Border(?:Top|Right|Bottom|Left)?(?:Width|)|(?:Margin|Padding)?(?:Top|Right|Bottom|Left)?|(?:Min|Max)?(?:Width|Height))$/;s.swap&&s.each(["height","width","reliableMarginRight"],function(e,t){var r=s.cssHooks[t]&&s.cssHooks[t].get;r&&(s.cssHooks[t].get=function(){var e;return R=!0,e=r.apply(this,arguments),R=!1,e})}),i(s,"swap",function(e,t,r,n){var o,a,i={};for(a in R||u("swap","jQuery.swap() is undocumented and deprecated"),t)i[a]=e.style[a],e.style[a]=t[a];for(a in o=r.apply(e,n||[]),t)e.style[a]=i[a];return o},"swap"),e("3.4.0")&&"undefined"!=typeof Proxy&&(s.cssProps=new Proxy(s.cssProps||{},{set:function(){return u("cssProps","jQuery.cssProps is deprecated"),Reflect.set.apply(this,arguments)}})),e("4.0.0")?(A={animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},"undefined"!=typeof Proxy?s.cssNumber=new Proxy(A,{get:function(){return u("css-number","jQuery.cssNumber is deprecated"),Reflect.get.apply(this,arguments)},set:function(){return u("css-number","jQuery.cssNumber is deprecated"),Reflect.set.apply(this,arguments)}}):s.cssNumber=A):A=s.cssNumber,Q=s.fn.css,i(s.fn,"css",function(e,t){var r,n,o=this;return e&&"object"==typeof e&&!Array.isArray(e)?(s.each(e,function(e,t){s.fn.css.call(o,e,t)}),this):("number"==typeof t&&(r=x(e),n=r,C.test(n)&&N.test(n[0].toUpperCase()+n.slice(1))||A[r]||u("css-number",'Number-typed values are deprecated for jQuery.fn.css( "'+e+'", value )')),Q.apply(this,arguments))},"css-number");var S,P,k,H,E=s.data;i(s,"data",function(e,t,r){var n,o,a;if(t&&"object"==typeof t&&2===arguments.length){for(a in n=s.hasData(e)&&E.call(this,e),o={},t)a!==x(a)?(u("data-camelCase","jQuery.data() always sets/gets camelCased names: "+a),n[a]=t[a]):o[a]=t[a];return E.call(this,e,o),t}return t&&"string"==typeof t&&t!==x(t)&&(n=s.hasData(e)&&E.call(this,e))&&t in n?(u("data-camelCase","jQuery.data() always sets/gets camelCased names: "+t),2<arguments.length&&(n[t]=r),n[t]):E.apply(this,arguments)},"data-camelCase"),s.fx&&(k=s.Tween.prototype.run,H=function(e){return e},i(s.Tween.prototype,"run",function(){1<s.easing[this.easing].length&&(u("easing-one-arg","'jQuery.easing."+this.easing.toString()+"' should use only one argument"),s.easing[this.easing]=H),k.apply(this,arguments)},"easing-one-arg"),S=s.fx.interval,P="jQuery.fx.interval is deprecated",n.requestAnimationFrame&&Object.defineProperty(s.fx,"interval",{configurable:!0,enumerable:!0,get:function(){return n.document.hidden||u("fx-interval",P),s.migrateIsPatchEnabled("fx-interval")&&void 0===S?13:S},set:function(e){u("fx-interval",P),S=e}}));var M=s.fn.load,q=s.event.add,O=s.event.fix;s.event.props=[],s.event.fixHooks={}
2,r(s.event.props,"concat",s.event.props.concat,"event-old-patch","jQuery.event.props.concat() is deprecated and removed"),i(s.event,"fix",function(e){var t,r=e.type,n=this.fixHooks[r],o=s.event.props;if(o.length){u("event-old-patch","jQuery.event.props are deprecated and removed: "+o.join());while(o.length)s.event.addProp(o.pop())}if(n&&!n._migrated_&&(n._migrated_=!0,u("event-old-patch","jQuery.event.fixHooks are deprecated and removed: "+r),(o=n.props)&&o.length))while(o.length)s.event.addProp(o.pop());return t=O.call(this,e),n&&n.filter?n.filter(t,e):t},"event-old-patch"),i(s.event,"add",function(e,t){return e===n&&"load"===t&&"complete"===n.document.readyState&&u("load-after-event","jQuery(window).on('load'...) called after load event occurred"),q.apply(this,arguments)},"load-after-event"),s.each(["load","unload","error"],function(e,t){i(s.fn,t,function(){var e=Array.prototype.slice.call(arguments,0);return"load"===t&&"string"==typeof e[0]?M.apply(this,e):(u("shorthand-removed-v3","jQuery.fn."+t+"() is deprecated"),e.splice(0,0,t),arguments.length?this.on.apply(this,e):(this.triggerHandler.apply(this,e),this))},"shorthand-removed-v3")}),s.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,r){c(s.fn,r,function(e,t){return 0<arguments.length?this.on(r,null,e,t):this.trigger(r)},"shorthand-deprecated-v3","jQuery.fn."+r+"() event shorthand is deprecated")}),s(function(){s(n.document).triggerHandler("ready")}),s.event.special.ready={setup:function(){this===n.document&&u("ready-event","'ready' event is deprecated")}},c(s.fn,"bind",function(e,t,r){return this.on(e,null,t,r)},"pre-on-methods","jQuery.fn.bind() is deprecated"),c(s.fn,"unbind",function(e,t){return this.off(e,null,t)},"pre-on-methods","jQuery.fn.unbind() is deprecated"),c(s.fn,"delegate",function(e,t,r,n){return this.on(t,e,r,n)},"pre-on-methods","jQuery.fn.delegate() is deprecated"),c(s.fn,"undelegate",function(e,t,r){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",r)},"pre-on-methods","jQuery.fn.undelegate() is deprecated"),c(s.fn,"hover",function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)},"pre-on-methods","jQuery.fn.hover() is deprecated");function T(e){var t=n.document.implementation.createHTMLDocument("");return t.body.innerHTML=e,t.body&&t.body.innerHTML}var F=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi;s.UNSAFE_restoreLegacyHtmlPrefilter=function(){s.migrateEnablePatches("self-closed-tags")},i(s,"htmlPrefilter",function(e){var t,r;return(r=(t=e).replace(F,"<$1></$2>"))!==t&&T(t)!==T(r)&&u("self-closed-tags","HTML tags must be properly nested and closed: "+t),e.replace(F,"<$1></$2>")},"self-closed-tags"),s.migrateDisablePatches("self-closed-tags");var D,W,_,I=s.fn.offset;return i(s.fn,"offset",function(){var e=this[0];return!e||e.nodeType&&e.getBoundingClientRect?I.apply(this,arguments):(u("offset-valid-elem","jQuery.fn.offset() requires a valid DOM element"),arguments.length?this:void 0)},"offset-valid-elem"),s.ajax&&(D=s.param,i(s,"param",function(e,t){var r=s.ajaxSettings&&s.ajaxSettings.traditional;return void 0===t&&r&&(u("param-ajax-traditional","jQuery.param() no longer uses jQuery.ajaxSettings.traditional"),t=r),D.call(this,e,t)},"param-ajax-traditional")),c(s.fn,"andSelf",s.fn.addBack,"andSelf","jQuery.fn.andSelf() is deprecated and removed, use jQuery.fn.addBack()"),s.Deferred&&(W=s.Deferred,_=[["resolve","done",s.Callbacks("once memory"),s.Callbacks("once memory"),"resolved"],["reject","fail",s.Callbacks("once memory"),s.Callbacks("once memory"),"rejected"],["notify","progress",s.Callbacks("memory"),s.Callbacks("memory")]],i(s,"Deferred",function(e){var a=W(),i=a.promise();function t(){var o=arguments;return s.Deferred(function(n){s.each(_,function(e,t){var r="function"==typeof o[e]&&o[e];a[t[1]](function(){var e=r&&r.apply(this,arguments);e&&"function"==typeof e.promise?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[t[0]+"With"](this===i?n.promise():this,r?[e]:arguments)})}),o=null}).promise()}return c(a,"pipe",t,"deferred-pipe","deferred.pipe() is deprecated"),c(i,"pipe",t,"deferred-pipe","deferred.pipe() is deprecated"),e&&e.call(a,a),a},"deferred-pipe"),s.Deferred.exceptionHook=W.exceptionHook),s}); 3;/*! 4 * jQuery blockUI plugin 5 * Version 2.70.0-2014.11.23 6 * Requires jQuery v1.7 or later 7 * 8 * Examples at: http://malsup.com/jquery/block/ 9 * Copyright (c) 2007-2013 M. Alsup 10 * Dual licensed under the MIT and GPL licenses: 11 * http://www.opensource.org/licenses/mit-license.php 12 * http://www.gnu.org/licenses/gpl.html 13 * 14 * Thanks to Amir-Hossein Sobhi for some excellent contributions! 15 */ 16 17;(function() { 18 /*jshint eqeqeq:false curly:false latedef:false */ 19 "use strict"; 20 21 function setup($) { 22 $.fn._fadeIn = $.fn.fadeIn; 23 24 var noOp = $.noop || function() {}; 25 26 // this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle 27 // confusing userAgent strings on Vista) 28 var msie = /MSIE/.test(navigator.userAgent); 29 var ie6 = /MSIE 6.0/.test(navigator.userAgent) && ! /MSIE 8.0/.test(navigator.userAgent); 30 var mode = document.documentMode || 0; 31 var setExpr = $.isFunction( document.createElement('div').style.setExpression ); 32 33 // global $ methods for blocking/unblocking the entire page 34 $.blockUI = function(opts) { install(window, opts); }; 35 $.unblockUI = function(opts) { remove(window, opts); }; 36 37 // convenience method for quick growl-like notifications (https://www.google.com/search?q=growl) 38 $.growlUI = function(title, message, timeout, onClose) { 39 var $m = $('<div class="growlUI"></div>'); 40 if (title) $m.append('<h1>'+title+'</h1>'); 41 if (message) $m.append('<h2>'+message+'</h2>'); 42 if (timeout === undefined) timeout = 3000; 43
vendor: 22,248 bytes, lines 44-575
44 // Added by konapun: Set timeout to 30 seconds if this growl is moused over, like normal toast notifications 45 var callBlock = function(opts) { 46 opts = opts || {}; 47 48 $.blockUI({ 49 message: $m, 50 fadeIn : typeof opts.fadeIn !== 'undefined' ? opts.fadeIn : 700, 51 fadeOut: typeof opts.fadeOut !== 'undefined' ? opts.fadeOut : 1000, 52 timeout: typeof opts.timeout !== 'undefined' ? opts.timeout : timeout, 53 centerY: false, 54 showOverlay: false, 55 onUnblock: onClose, 56 css: $.blockUI.defaults.growlCSS 57 }); 58 }; 59 60 callBlock(); 61 var nonmousedOpacity = $m.css('opacity'); 62 $m.mouseover(function() { 63 callBlock({ 64 fadeIn: 0, 65 timeout: 30000 66 }); 67 68 var displayBlock = $('.blockMsg'); 69 displayBlock.stop(); // cancel fadeout if it has started 70 displayBlock.fadeTo(300, 1); // make it easier to read the message by removing transparency 71 }).mouseout(function() { 72 $('.blockMsg').fadeOut(1000); 73 }); 74 // End konapun additions 75 }; 76 77 // plugin method for blocking element content 78 $.fn.block = function(opts) { 79 if ( this[0] === window ) { 80 $.blockUI( opts ); 81 return this; 82 } 83 var fullOpts = $.extend({}, $.blockUI.defaults, opts || {}); 84 this.each(function() { 85 var $el = $(this); 86 if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked')) 87 return; 88 $el.unblock({ fadeOut: 0 }); 89 }); 90 91 return this.each(function() { 92 if ($.css(this,'position') == 'static') { 93 this.style.position = 'relative'; 94 $(this).data('blockUI.static', true); 95 } 96 this.style.zoom = 1; // force 'hasLayout' in ie 97 install(this, opts); 98 }); 99 }; 100 101 // plugin method for unblocking element content 102 $.fn.unblock = function(opts) { 103 if ( this[0] === window ) { 104 $.unblockUI( opts ); 105 return this; 106 } 107 return this.each(function() { 108 remove(this, opts); 109 }); 110 }; 111 112 $.blockUI.version = 2.70; // 2nd generation blocking at no extra cost! 113 114 // override these in your code to change the default behavior and style 115 $.blockUI.defaults = { 116 // message displayed when blocking (use null for no message) 117 message: '<h1>Please wait...</h1>', 118 119 title: null, // title string; only used when theme == true 120 draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded) 121 122 theme: false, // set to true to use with jQuery UI themes 123 124 // styles for the message when blocking; if you wish to disable 125 // these and use an external stylesheet then do this in your code: 126 // $.blockUI.defaults.css = {}; 127 css: { 128 padding: 0, 129 margin: 0, 130 width: '30%', 131 top: '40%', 132 left: '35%', 133 textAlign: 'center', 134 color: '#000', 135 border: '3px solid #aaa', 136 backgroundColor:'#fff', 137 cursor: 'wait' 138 }, 139 140 // minimal style set used when themes are used 141 themedCSS: { 142 width: '30%', 143 top: '40%', 144 left: '35%' 145 }, 146 147 // styles for the overlay 148 overlayCSS: { 149 backgroundColor: '#000', 150 opacity: 0.6, 151 cursor: 'wait' 152 }, 153 154 // style to replace wait cursor before unblocking to correct issue 155 // of lingering wait cursor 156 cursorReset: 'default', 157 158 // styles applied when using $.growlUI 159 growlCSS: { 160 width: '350px', 161 top: '10px', 162 left: '', 163 right: '10px', 164 border: 'none', 165 padding: '5px', 166 opacity: 0.6, 167 cursor: 'default', 168 color: '#fff', 169 backgroundColor: '#000', 170 '-webkit-border-radius':'10px', 171 '-moz-border-radius': '10px', 172 'border-radius': '10px' 173 }, 174 175 // IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w 176 // (hat tip to Jorge H. N. de Vasconcelos) 177 /*jshint scripturl:true */ 178 iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank', 179 180 // force usage of iframe in non-IE browsers (handy for blocking applets) 181 forceIframe: false, 182 183 // z-index for the blocking overlay 184 baseZ: 1000, 185 186 // set these to true to have the message automatically centered 187 centerX: true, // <-- only effects element blocking (page block controlled via css above) 188 centerY: true, 189 190 // allow body element to be stetched in ie6; this makes blocking look better 191 // on "short" pages. disable if you wish to prevent changes to the body height 192 allowBodyStretch: true, 193 194 // enable if you want key and mouse events to be disabled for content that is blocked 195 bindEvents: true, 196 197 // be default blockUI will supress tab navigation from leaving blocking content 198 // (if bindEvents is true) 199 constrainTabKey: true, 200 201 // fadeIn time in millis; set to 0 to disable fadeIn on block 202 fadeIn: 200, 203 204 // fadeOut time in millis; set to 0 to disable fadeOut on unblock 205 fadeOut: 400, 206 207 // time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock 208 timeout: 0, 209 210 // disable if you don't want to show the overlay 211 showOverlay: true, 212 213 // if true, focus will be placed in the first available input field when 214 // page blocking 215 focusInput: true, 216 217 // elements that can receive focus 218 focusableElements: ':input:enabled:visible', 219 220 // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity) 221 // no longer needed in 2012 222 // applyPlatformOpacityRules: true, 223 224 // callback method invoked when fadeIn has completed and blocking message is visible 225 onBlock: null, 226 227 // callback method invoked when unblocking has completed; the callback is 228 // passed the element that has been unblocked (which is the window object for page 229 // blocks) and the options that were passed to the unblock call: 230 // onUnblock(element, options) 231 onUnblock: null, 232 233 // callback method invoked when the overlay area is clicked. 234 // setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used. 235 onOverlayClick: null, 236 237 // don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493 238 quirksmodeOffsetHack: 4, 239 240 // class name of the message block 241 blockMsgClass: 'blockMsg', 242 243 // if it is already blocked, then ignore it (don't unblock and reblock) 244 ignoreIfBlocked: false 245 }; 246 247 // private data and functions follow... 248 249 var pageBlock = null; 250 var pageBlockEls = []; 251 252 function install(el, opts) { 253 var css, themedCSS; 254 var full = (el == window); 255 var msg = (opts && opts.message !== undefined ? opts.message : undefined); 256 opts = $.extend({}, $.blockUI.defaults, opts || {}); 257 258 if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked')) 259 return; 260 261 opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {}); 262 css = $.extend({}, $.blockUI.defaults.css, opts.css || {}); 263 if (opts.onOverlayClick) 264 opts.overlayCSS.cursor = 'pointer'; 265 266 themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {}); 267 msg = msg === undefined ? opts.message : msg; 268 269 // remove the current block (if there is one) 270 if (full && pageBlock) 271 remove(window, {fadeOut:0}); 272 273 // if an existing element is being used as the blocking content then we capture 274 // its current place in the DOM (and current display style) so we can restore 275 // it when we unblock 276 if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) { 277 var node = msg.jquery ? msg[0] : msg; 278 var data = {}; 279 $(el).data('blockUI.history', data); 280 data.el = node; 281 data.parent = node.parentNode; 282 data.display = node.style.display; 283 data.position = node.style.position; 284 if (data.parent) 285 data.parent.removeChild(node); 286 } 287 288 $(el).data('blockUI.onUnblock', opts.onUnblock); 289 var z = opts.baseZ; 290 291 // blockUI uses 3 layers for blocking, for simplicity they are all used on every platform; 292 // layer1 is the iframe layer which is used to supress bleed through of underlying content 293 // layer2 is the overlay layer which has opacity and a wait cursor (by default) 294 // layer3 is the message content that is displayed while blocking 295 var lyr1, lyr2, lyr3, s; 296 if (msie || opts.forceIframe) 297 lyr1 = $('<iframe class="blockUI" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;position:absolute;width:100%;height:100%;top:0;left:0" src="'+opts.iframeSrc+'"></iframe>'); 298 else 299 lyr1 = $('<div class="blockUI" style="display:none"></div>'); 300 301 if (opts.theme) 302 lyr2 = $('<div class="blockUI blockOverlay ui-widget-overlay" style="z-index:'+ (z++) +';display:none"></div>'); 303 else 304 lyr2 = $('<div class="blockUI blockOverlay" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;width:100%;height:100%;top:0;left:0"></div>'); 305 306 if (opts.theme && full) { 307 s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:fixed">'; 308 if ( opts.title ) { 309 s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || ' ')+'</div>'; 310 } 311 s += '<div class="ui-widget-content ui-dialog-content"></div>'; 312 s += '</div>'; 313 } 314 else if (opts.theme) { 315 s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:absolute">'; 316 if ( opts.title ) { 317 s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || ' ')+'</div>'; 318 } 319 s += '<div class="ui-widget-content ui-dialog-content"></div>'; 320 s += '</div>'; 321 } 322 else if (full) { 323 s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage" style="z-index:'+(z+10)+';display:none;position:fixed"></div>'; 324 } 325 else { 326 s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement" style="z-index:'+(z+10)+';display:none;position:absolute"></div>'; 327 } 328 lyr3 = $(s); 329 330 // if we have a message, style it 331 if (msg) { 332 if (opts.theme) { 333 lyr3.css(themedCSS); 334 lyr3.addClass('ui-widget-content'); 335 } 336 else 337 lyr3.css(css); 338 } 339 340 // style the overlay 341 if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/) 342 lyr2.css(opts.overlayCSS); 343 lyr2.css('position', full ? 'fixed' : 'absolute'); 344 345 // make iframe layer transparent in IE 346 if (msie || opts.forceIframe) 347 lyr1.css('opacity',0.0); 348 349 //$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el); 350 var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el); 351 $.each(layers, function() { 352 this.appendTo($par); 353 }); 354 355 if (opts.theme && opts.draggable && $.fn.draggable) { 356 lyr3.draggable({ 357 handle: '.ui-dialog-titlebar', 358 cancel: 'li' 359 }); 360 } 361 362 // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling) 363 var expr = setExpr && (!$.support.boxModel || $('object,embed', full ? null : el).length > 0); 364 if (ie6 || expr) { 365 // give body 100% height 366 if (full && opts.allowBodyStretch && $.support.boxModel) 367 $('html,body').css('height','100%'); 368 369 // fix ie6 issue when blocked element has a border width 370 if ((ie6 || !$.support.boxModel) && !full) { 371 var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth'); 372 var fixT = t ? '(0 - '+t+')' : 0; 373 var fixL = l ? '(0 - '+l+')' : 0; 374 } 375 376 // simulate fixed position 377 $.each(layers, function(i,o) { 378 var s = o[0].style; 379 s.position = 'absolute'; 380 if (i < 2) { 381 if (full) 382 s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"'); 383 else 384 s.setExpression('height','this.parentNode.offsetHeight + "px"'); 385 if (full) 386 s.setExpression('width','jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"'); 387 else 388 s.setExpression('width','this.parentNode.offsetWidth + "px"'); 389 if (fixL) s.setExpression('left', fixL); 390 if (fixT) s.setExpression('top', fixT); 391 } 392 else if (opts.centerY) { 393 if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"'); 394 s.marginTop = 0; 395 } 396 else if (!opts.centerY && full) { 397 var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0; 398 var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"'; 399 s.setExpression('top',expression); 400 } 401 }); 402 } 403 404 // show the message 405 if (msg) { 406 if (opts.theme) 407 lyr3.find('.ui-widget-content').append(msg); 408 else 409 lyr3.append(msg); 410 if (msg.jquery || msg.nodeType) 411 $(msg).show(); 412 } 413 414 if ((msie || opts.forceIframe) && opts.showOverlay) 415 lyr1.show(); // opacity is zero 416 if (opts.fadeIn) { 417 var cb = opts.onBlock ? opts.onBlock : noOp; 418 var cb1 = (opts.showOverlay && !msg) ? cb : noOp; 419 var cb2 = msg ? cb : noOp; 420 if (opts.showOverlay) 421 lyr2._fadeIn(opts.fadeIn, cb1); 422 if (msg) 423 lyr3._fadeIn(opts.fadeIn, cb2); 424 } 425 else { 426 if (opts.showOverlay) 427 lyr2.show(); 428 if (msg) 429 lyr3.show(); 430 if (opts.onBlock) 431 opts.onBlock.bind(lyr3)(); 432 } 433 434 // bind key and mouse events 435 bind(1, el, opts); 436 437 if (full) { 438 pageBlock = lyr3[0]; 439 pageBlockEls = $(opts.focusableElements,pageBlock); 440 if (opts.focusInput) 441 setTimeout(focus, 20); 442 } 443 else 444 center(lyr3[0], opts.centerX, opts.centerY); 445 446 if (opts.timeout) { 447 // auto-unblock 448 var to = setTimeout(function() { 449 if (full) 450 $.unblockUI(opts); 451 else 452 $(el).unblock(opts); 453 }, opts.timeout); 454 $(el).data('blockUI.timeout', to); 455 } 456 } 457 458 // remove the block 459 function remove(el, opts) { 460 var count; 461 var full = (el == window); 462 var $el = $(el); 463 var data = $el.data('blockUI.history'); 464 var to = $el.data('blockUI.timeout'); 465 if (to) { 466 clearTimeout(to); 467 $el.removeData('blockUI.timeout'); 468 } 469 opts = $.extend({}, $.blockUI.defaults, opts || {}); 470 bind(0, el, opts); // unbind events 471 472 if (opts.onUnblock === null) { 473 opts.onUnblock = $el.data('blockUI.onUnblock'); 474 $el.removeData('blockUI.onUnblock'); 475 } 476 477 var els; 478 if (full) // crazy selector to handle odd field errors in ie6/7 479 els = $('body').children().filter('.blockUI').add('body > .blockUI'); 480 else 481 els = $el.find('>.blockUI'); 482 483 // fix cursor issue 484 if ( opts.cursorReset ) { 485 if ( els.length > 1 ) 486 els[1].style.cursor = opts.cursorReset; 487 if ( els.length > 2 ) 488 els[2].style.cursor = opts.cursorReset; 489 } 490 491 if (full) 492 pageBlock = pageBlockEls = null; 493 494 if (opts.fadeOut) { 495 count = els.length; 496 els.stop().fadeOut(opts.fadeOut, function() { 497 if ( --count === 0) 498 reset(els,data,opts,el); 499 }); 500 } 501 else 502 reset(els, data, opts, el); 503 } 504 505 // move blocking element back into the DOM where it started 506 function reset(els,data,opts,el) { 507 var $el = $(el); 508 if ( $el.data('blockUI.isBlocked') ) 509 return; 510 511 els.each(function(i,o) { 512 // remove via DOM calls so we don't lose event handlers 513 if (this.parentNode) 514 this.parentNode.removeChild(this); 515 }); 516 517 if (data && data.el) { 518 data.el.style.display = data.display; 519 data.el.style.position = data.position; 520 data.el.style.cursor = 'default'; // #59 521 if (data.parent) 522 data.parent.appendChild(data.el); 523 $el.removeData('blockUI.history'); 524 } 525 526 if ($el.data('blockUI.static')) { 527 $el.css('position', 'static'); // #22 528 } 529 530 if (typeof opts.onUnblock == 'function') 531 opts.onUnblock(el,opts); 532 533 // fix issue in Safari 6 where block artifacts remain until reflow 534 var body = $(document.body), w = body.width(), cssW = body[0].style.width; 535 body.width(w-1).width(w); 536 body[0].style.width = cssW; 537 } 538 539 // bind/unbind the handler 540 function bind(b, el, opts) { 541 var full = el == window, $el = $(el); 542 543 // don't bother unbinding if there is nothing to unbind 544 if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked'))) 545 return; 546 547 $el.data('blockUI.isBlocked', b); 548 549 // don't bind events when overlay is not in use or if bindEvents is false 550 if (!full || !opts.bindEvents || (b && !opts.showOverlay)) 551 return; 552 553 // bind anchors and inputs for mouse and key events 554 var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove'; 555 if (b) 556 $(document).bind(events, opts, handler); 557 else 558 $(document).unbind(events, handler); 559 560 // former impl... 561 // var $e = $('a,:input'); 562 // b ? $e.bind(events, opts, handler) : $e.unbind(events, handler); 563 } 564 565 // event handler to suppress keyboard/mouse events when blocking 566 function handler(e) { 567 // allow tab navigation (conditionally) 568 if (e.type === 'keydown' && e.keyCode && e.keyCode == 9) { 569 if (pageBlock && e.data.constrainTabKey) { 570 var els = pageBlockEls; 571 var fwd = !e.shiftKey && e.target === els[els.length-1]; 572 var back = e.shiftKey && e.target === els[0]; 573 if (fwd || back) { 574 setTimeout(function(){focus(back);},10); 575 return false;
576 } 577 } 578 } 579 var opts = e.data; 580 var target = $(e.target); 581 if (target.hasClass('blockOverlay') && opts.onOverlayClick) 582 opts.onOverlayClick(e); 583 584 // allow events within the message content 585 if (target.parents('div.' + opts.blockMsgClass).length > 0) 586 return true; 587 588 // allow events for content that is not being blocked 589 return target.parents().children().filter('div.blockUI').length === 0; 590 } 591 592 function focus(back) { 593 if (!pageBlockEls) 594 return; 595 var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0]; 596 if (e) 597 e.focus(); 598 } 599 600 function center(el, x, y) { 601 var p = el.parentNode, s = el.style; 602 var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth'); 603 var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth'); 604 if (x) s.left = l > 0 ? (l+'px') : '0'; 605 if (y) s.top = t > 0 ? (t+'px') : '0'; 606 } 607 608 function sz(el, p) { 609 return parseInt($.css(el,p),10)||0; 610 } 611 612 } 613 614 615 /*global define:true */ 616 if (typeof define === 'function' && define.amd && define.amd.jQuery) { 617 define(['jquery'], setup); 618 } else { 619 setup(jQuery); 620 } 621 622})(); 623;/**************************************************************************** 624 * Global Variables & Configuration 625 ****************************************************************************/ 626// jQuery alias 627$ = jQuery; 628 629// Mapbox / Geolocation references 630var mapboxgl; 631var geoPosition; 632var map; 633var geocoder; 634var geocoder_element; 635var directionsDisplay; 636var directionsService; 637var distanceService; 638 639// DOM and UI references 640var divMap; 641var divPanel; 642var panelBase; 643var divClinic; 644var btnMyLoc; 645 646// Map settings 647var mapOptions; 648var boxOptions; 649var latlngbounds; 650var my_loc_icon; 651var can_cur_loc = false; 652var can_block = false; 653 654// Markers, popups, and data 655var markers = []; 656var infoBoxes = []; 657var pathWay = []; 658var selected_hospital_id = null; 659var matched_hospitals_to_focus = []; 660var currentlat = null; 661var currentlng = null; 662var newHspLatLngs = []; 663 664// Other app state 665let clnicNameDisplay = false; 666var got_directions; 667var patient_address; 668var patient_latlng; 669var location_timeout; 670var location_failed = false; 671var defaultHospitalOrder = []; 672 673const GEOCODER_BBOX = [-85.286368, 30.709341, -80.873826, 35.020965]; 674const INITIAL_MAP_CENTER = [-83.67915, 32.61902]; 675const INITIAL_MAP_ZOOM = 6; 676 677// "stores" is assumed to be globally defined or included elsewhere 678// Example: const stores = { "type": "FeatureCollection", "features": [...] }; 679// "clinic_details" also expected from global scope (admin_ajax, etc.) 680 681/**************************************************************************** 682 * 1. Cookie Utilities 683 ****************************************************************************/ 684function createCookie(name, value, days) { 685 var expires; 686 if (!days) { 687 days = 1; 688 } 689 if (days) { 690 var date = new Date(); 691 date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000); 692 expires = '; expires=' + date.toGMTString(); 693 } else { 694 expires = ''; 695 } 696 697 document.cookie = 698 encodeURIComponent(name) + 699 '=' + 700 encodeURIComponent(value) + 701 expires + 702 '; path=' + 703 window.location.pathname; 704} 705 706function readCookie(name) { 707 var nameEQ = encodeURIComponent(name) + '='; 708 var ca = document.cookie.split(';'); 709 for (var i = 0; i < ca.length; i++) { 710 var c = ca[i]; 711 while (c.charAt(0) === ' ') { 712 c = c.substring(1, c.length); 713 } 714 if (c.indexOf(nameEQ) === 0) { 715 return decodeURIComponent(c.substring(nameEQ.length, c.length)); 716 } 717 } 718 return null; 719} 720 721function eraseCookie(name) { 722 createCookie(name, '', -1); 723} 724 725/**************************************************************************** 726 * 2. Data Loading & Updating 727 ****************************************************************************/ 728async function loadMapData() { 729 try { 730 const response = await $.post(clinic_details.admin_ajax, { 731 action: 'fetch_clockwise_data', 732 }); 733 734 // Return the actual response data 735 return response; 736 } catch (error) { 737 console.error('Error fetching data:', error); 738 throw error; 739 } 740} 741 742function updateHospitalsData() { 743 loadMapData().then(function (data) { 744 // 'data' is the AJAX response 745 for (let i = 0; i < stores.features.length; i++) { 746 const hospital_id = stores.features[i].properties.api_id; 747 748 // Update Wait Times â handle "Closed" vs numeric/range values 749 const wait = data['current_wait'][hospital_id]; 750 const waitText = wait === 'Closed' || wait == null ? 'Closed' : `${wait} min`; 751 $('#list-hospital-' + hospital_id + ' .current_wait_placeholder').html(waitText); 752 753 // Update Today's Hours â only if present in the response 754 if (data['todays_hours'] && data['todays_hours'][hospital_id] != null) { 755 $('#list-hospital-' + hospital_id + ' .business-hours__text').html( 756 data['todays_hours'][hospital_id] 757 ); 758 } 759 760 // Update Queue 761 $('#marker-' + hospital_id + ' p.patient_queue').html(data['queue_length'][hospital_id]); 762 } 763 }); 764} 765 766/**************************************************************************** 767 * 3. Geolocation & Positioning 768 ****************************************************************************/ 769function findPosition() { 770 location_timeout = setTimeout(function () { 771 positionError(null); 772 }, 10000); 773 774 location_failed = false;
775 776 if (can_block) { 777 jQuery.blockUI({ 778 message: "<h5 class='opensans'><strong>Finding your location ...</strong></h5>", 779 onOverlayClick: jQuery.unblockUI, 780 }); 781 } else { 782 btnMyLoc.value = 'Checking Address...'; 783 } 784 785 geoPosition.getCurrentPosition(positionSuccess, positionError); 786 787 createCookie('search_location_address', JSON.stringify({ address: '', is_current: true })); 788} 789 790function positionSuccess(loc) { 791 if (!location_failed) { 792 clearTimeout(location_timeout); 793 794 if (can_block) { 795 jQuery.unblockUI({ 796 onUnblock: codePosition(loc), 797 }); 798 } else { 799 btnMyLoc.value = 'Use My Location'; 800 codePosition(loc); 801 } 802 } 803} 804 805function positionError(error) { 806 if (!location_failed) { 807 location_failed = true; 808 clearTimeout(location_timeout); 809 810 if (can_block) { 811 jQuery.unblockUI(); 812 } 813 814 var message; 815 if (error === null) { 816 message = 'Unable to retrieve user location.'; 817 } else { 818 switch (error.code) { 819 case error.PERMISSION_DENIED: 820 message = 'User denied the request for Geolocation.'; 821 break; 822 case error.POSITION_UNAVAILABLE: 823 message = 'Location information is unavailable.'; 824 break; 825 case error.TIMEOUT: 826 message = 'The request to get user location timed out.'; 827 break; 828 default: 829 message = 'Unable to retrieve user location.'; 830 } 831 } 832 833 alert(message); 834 } 835} 836 837function codePosition(loc) { 838 patient_latlng = new mapboxgl.LngLat(loc.coords.longitude, loc.coords.latitude); 839 calcRoutes(stores.features); 840 841 map.flyTo({ 842 center: [loc.coords.longitude, loc.coords.latitude], 843 zoom: 11, 844 }); 845 846 jQuery('#clear-address-btn').hide(); 847} 848 849function codeAddress() { 850 patient_address = document.getElementById('address').value; 851 852 if (patient_address) { 853 if (got_directions) { 854 got_directions = false; 855 reDrawMap(); 856 jQuery('#address').val(patient_address); 857 } 858 859 // Using older google.maps.Geocoder in code snippet 860 geocoder.geocode({ address: patient_address }, function (results, status) { 861 if (status == google.maps.GeocoderStatus.OK) { 862 patient_latlng = results[0].geometry.location; 863 864 // If you had a Google Maps marker, you'd set it like this: 865 my_loc_icon.setOptions({ 866 map: map, 867 position: patient_latlng, 868 title: 'My Location', 869 icon: '//www.google.com/mapfiles/ms/micons/green-dot.png', 870 }); 871 872 jQuery('#address-search-btn').val('Search Again'); 873 jQuery('#clear-address-btn').show(); 874 875 setTimeout(function () { 876 calcRoutes(); 877 }, 500); 878 } else { 879 alert('Unable to locate address'); 880 } 881 }); 882 } else { 883 alert('Please enter an address'); 884 } 885} 886 887/**************************************************************************** 888 * 4. Distance & Routes 889 ****************************************************************************/ 890function calcRoutes(hs_locations) { 891 pathWay = []; 892 latlngbounds = map.getBounds(); 893 route_times = []; // Possibly for route durations? 894 const searchAreaRadius = 80; 895 896 // Compute distances for all clinics 897 for (let l = 0; l < hs_locations.length; l++) { 898 getOneRoute(l); 899 } 900 901 // Check whether any clinic is inside the search radius 902 const insideSearchAreaRadius = pathWay.find((clinic) => clinic[1] <= searchAreaRadius); 903 904 if (!insideSearchAreaRadius) { 905 if (can_block) { 906 jQuery.blockUI({ 907 message: 908 "<h5 class='opensans'><strong>No locations</strong></h5>" + 909 "<h5 class='opensans'><strong>within " + 910 searchAreaRadius + 911 ' miles</strong></h5>', 912 onOverlayClick: jQuery.unblockUI, 913 }); 914 } 915 } else { 916 // Show the found clinics in the side list 917 $('#group-hospital-list').html(''); 918 $('#group-hospital-list').animate( 919 { scrollTop: 0 }, 920 { 921 duration: 1000, 922 easing: 'swing', 923 } 924 ); 925 pathWay.sort((a, b) => a[1] - b[1]); 926 927 const foundClinicIndex = pathWay.filter((clinic) => clinic[1] <= searchAreaRadius); 928 929 const foundClinics = foundClinicIndex.map((item) => stores.features[item[0]]); 930 matched_hospitals_to_focus = foundClinics.slice(0, 3); 931 932 // Optionally remove existing markers or re-add them 933 // if ($(".marker.mapboxgl-marker").length > 0) { 934 // $(".marker.mapboxgl-marker").remove(); 935 // } 936 // addMarkers(foundClinics); 937 938 pathWay.forEach((item) => { 939 if (item[1] <= searchAreaRadius) { 940 $('#group-hospital-list').append(createHospitalListItem(stores.features[item[0]], item[1])); 941 } 942 }); 943 updateHospitalsData(); 944 945 // Fly to user's position 946 map.flyTo({ 947 center: [patient_latlng.wrap().lng, patient_latlng.wrap().lat], 948 zoom: 11, 949 }); 950 951 // Marker for Searched Location 952 if ($('#marker-searched_location').length > 0) { 953 $('#marker-searched_location').remove(); 954 } 955 const el = document.createElement('div'); 956 el.id = `marker-searched_location`; 957 el.className = 'marker'; 958 959 el.innerHTML = `<svg height="41px" width="27px" viewBox="0 0 27 41" xmlns="http://www.w3.org/2000/svg"> 960 <g fill-rule="nonzero"> 961 <g fill="#008000"> 962 <path d="M27,13.5 C27,19.074644 20.250001,27.000002 14.75,34.500002 C14.016665,35.500004 12.983335,35.500004 12.25,34.500002 C6.7499993,27.000002 0,19.222562 0,13.5 C0,6.0441559 6.0441559,0 13.5,0 C20.955844,0 27,6.0441559 27,13.5 Z"/> 963 </g> 964 <g opacity="0.25" fill="#000000"> 965 <path d="M13.5,0 C6.0441559,0 0,6.0441559 0,13.5 C0,19.222562 6.7499993,27 12.25,34.5 C13,35.522727 14.016664,35.500004 14.75,34.5 C20.250001,27 27,19.074644 27,13.5 C27,6.0441559 20.955844,0 13.5,0 Z M13.5,1 C20.415404,1 26,6.584596 26,13.5 C26,15.898657 24.495584,19.181431 22.220703,22.738281 C19.945823,26.295132 16.705119,30.142167 13.943359,33.908203 C13.743445,34.180814 13.612715,34.322738 13.5,34.441406 C13.387285,34.322738 13.256555,34.180814 13.056641,33.908203 C10.284481,30.127985 7.4148684,26.314159 5.015625,22.773438 C2.6163816,19.232715 1,15.953538 1,13.5 C1,6.584596 6.584596,1 13.5,1 Z"/> 966 </g> 967 <g transform="translate(6.0, 7.0)" fill="#FFFFFF"/> 968 <g transform="translate(8.0, 8.0)"> 969 <circle fill="#FFFFFF" opacity="0.25" cx="5.5" cy="5.5" r="9.499996"/> 970 <circle fill="#FFFFFF" cx="5.5" cy="5.5" r="9.499996" id="waiting-container" /> 971 </g> 972 </g> 973</svg>`; 974 975 my_loc_icon = new mapboxgl.Marker(el, { 976 draggable: false, 977 anchor: 'center', 978 offset: [0, 0], 979 }) 980 .setLngLat([patient_latlng.wrap().lng, patient_latlng.wrap().lat]) 981 .addTo(map); 982 983 if (matched_hospitals_to_focus.length) { 984 var bounds_to_focus = new mapboxgl.LngLatBounds(); 985 986 for (var i = 0; i < matched_hospitals_to_focus.length; i++) { 987 bounds_to_focus.extend( 988 new mapboxgl.LngLat( 989 matched_hospitals_to_focus[i].geometry.coordinates[0], 990 matched_hospitals_to_focus[i].geometry.coordinates[1] 991 ) 992 ); 993 bounds_to_focus.extend(patient_latlng); 994 } 995 996 map.panTo(new mapboxgl.LngLat(patient_latlng.lng, patient_latlng.lat)); 997 998 if (window.innerWidth < 960) { 999 map.fitBounds(bounds_to_focus, { padding: 50 }); 1000 } else { 1001 map.fitBounds(bounds_to_focus, { padding: 125 }); 1002 } 1003 1004 jQuery('#map-panel').addClass('current-wait-container-shown'); 1005 } else { 1006 jQuery('#map-panel').removeClass('current-wait-container-shown'); 1007 } 1008 1009 // Finally fetch booking times 1010 getBookingTime(); 1011 } 1012} 1013 1014function getOneRoute(m) { 1015 var start = [patient_latlng.wrap().lng, patient_latlng.wrap().lat]; 1016 var end = [ 1017 stores.features[m].geometry.coordinates[0], 1018 stores.features[m].geometry.coordinates[1], 1019 ]; 1020 1021 var from = turf.point([patient_latlng.wrap().lng, patient_latlng.wrap().lat]); 1022 var to = turf.point([ 1023 stores.features[m].geometry.coordinates[0], 1024 stores.features[m].geometry.coordinates[1], 1025 ]); 1026 1027 var options = { units: 'miles' }; 1028 var distance = turf.distance(from, to, options); 1029 var rounded = Math.round(distance * 10) / 10; 1030 1031 pathWay.push([m, distance]); 1032} 1033 1034function latLngDist(ltln1, ltln2) { 1035 // Andrew Hedgersâ Haversine example 1036 var lat1 = deg2rad(ltln1.wrap().lat); 1037 var lon1 = deg2rad(ltln1.wrap().lng); 1038 var lat2 = deg2rad(ltln2.wrap().lat); 1039 var lon2 = deg2rad(ltln2.wrap().lng); 1040 var dlon = lon2 - lon1; 1041 var dlat = lat2 - lat1; 1042 1043 var a = 1044 Math.pow(Math.sin(dlat / 2), 2) + 1045 Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(dlon / 2), 2); 1046 var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 1047 return 3961 * c; // Earth radius in miles 1048} 1049 1050function getLatLngs(hs_locations) { 1051 for (var i = 0; i < hs_locations.length; i++) { 1052 newHspLatLngs[i] = new mapboxgl.LngLat( 1053 hs_locations[i].geometry.coordinates[0], 1054 hs_locations[i].geometry.coordinates[1] 1055 ); 1056 } 1057} 1058 1059// Initialize the newHspLatLngs array once 1060getLatLngs(stores.features); 1061 1062defaultHospitalOrder = stores.features.map(function (feature) { 1063 return feature.properties.api_id; 1064}); 1065 1066/**************************************************************************** 1067 * 5. Map Setup & Utility 1068 ****************************************************************************/ 1069function initialize(hs_locations) { 1070 document.getElementById('clear-address-btn').value = 'Clear Location'; 1071 1072 var addressElement = document.getElementById('address'); 1073 var searchButtonElement = document.getElementById('address-search-btn'); 1074 1075 addressElement.style.display = 'none'; 1076 searchButtonElement.style.display = 'none'; 1077 1078 clearRouteLayers(); 1079 1080 function clearRouteLayers() { 1081 if (typeof map.getLayer('route') !== 'undefined') { 1082 map.removeLayer('route'); 1083 } 1084 if (typeof map.getSource('route') !== 'undefined') { 1085 map.removeSource('route'); 1086 } 1087 if (typeof map.getLayer('step-marker') !== 'undefined') { 1088 map.removeLayer('step-marker'); 1089 } 1090 if (typeof map.getSource('step-marker') !== 'undefined') { 1091 map.removeSource('step-marker'); 1092 } 1093 1094 var container = document.getElementById('directionsPanel'); 1095 container.innerHTML = ''; 1096 container.style.display = 'none'; 1097 } 1098} 1099 1100function reDrawMap() { 1101 eraseCookie('search_location_address'); 1102 matched_hospitals_to_focus = []; 1103 currentlat = null; 1104 currentlng = null; 1105 jQuery('#map-panel').removeClass('current-wait-container-shown'); 1106 $('#group-hospital-list').html(''); 1107 $('#group-hospital-list').animate( 1108 { scrollTop: 0 }, 1109 { 1110 duration: 1000, 1111 easing: 'swing', 1112 } 1113 ); 1114 // Rebuild hospital list
1115 stores.features.forEach((clinic) => { 1116 $('#group-hospital-list').append(createHospitalListItem(clinic)); 1117 }); 1118 1119 updateHospitalsData(); 1120 1121 jQuery('#address').val(''); 1122 jQuery('#address-search-btn').val('Search Nearby'); 1123 jQuery('#clear-address-btn').hide(); 1124 1125 initialize(stores.features); 1126 1127 $('#marker-searched_location').remove(); 1128 map.flyTo({ 1129 center: INITIAL_MAP_CENTER, 1130 zoom: INITIAL_MAP_ZOOM, 1131 }); 1132 1133 // If you want to re-add all markers: 1134 // addMarkers(stores.features); 1135 1136 getBookingTime(); 1137} 1138 1139function startIt(hs_locations, map) { 1140 // Setup the MapboxGeocoder 1141 geocoder = new MapboxGeocoder({ 1142 accessToken: mapboxgl.accessToken, 1143 flyTo: false, 1144 placeholder: 'Enter Address or Zip Code', 1145 country: 'us', 1146 dragPan: 'false', 1147 bbox: GEOCODER_BBOX, 1148 }); 1149 1150 map.scrollZoom.disable(); 1151 map.addControl(new mapboxgl.NavigationControl()); 1152 1153 // Insert geocoder before the #address input 1154 geocoder_element = geocoder.onAdd(map); 1155 var addressElement = document.getElementById('address'); 1156 addressElement.parentNode.insertBefore(geocoder_element, addressElement.previousSibling); 1157 1158 // On geocoder result 1159 geocoder.on('result', function (event) { 1160 // Avoid re-processing if coords haven't changed 1161 if (event.result.center[0] == currentlng && event.result.center[1] == currentlat) { 1162 return false; 1163 } 1164 matched_hospitals_to_focus = []; 1165 pathWay = []; 1166 1167 patient_address = $('.mapboxgl-ctrl-geocoder--input').val(); 1168 patient_latlng = new mapboxgl.LngLat(event.result.center[0], event.result.center[1]); 1169 1170 currentlat = event.result.center[1]; 1171 currentlng = event.result.center[0]; 1172 1173 setTimeout(function () { 1174 calcRoutes(hs_locations); 1175 }, 500); 1176 1177 createCookie( 1178 'search_location_address', 1179 JSON.stringify({ address: patient_address, is_current: false }) 1180 ); 1181 1182 jQuery('#clear-address-btn').hide(); 1183 }); 1184 1185 // On geocoder clear 1186 geocoder.on('clear', function (event) { 1187 reDrawMap(); 1188 }); 1189} 1190 1191/**************************************************************************** 1192 * 6. Map Interactions: Fly, Focus, Display 1193 ****************************************************************************/ 1194function flyToStore(currentFeature) { 1195 map.flyTo({ 1196 center: currentFeature.geometry.coordinates, 1197 zoom: 11, 1198 }); 1199} 1200 1201function focusMap(api_id) { 1202 const clinicsArray = stores.features; 1203 const clinicElem = clinicsArray.find((clinic) => clinic.properties.api_id === String(api_id)); 1204 1205 if (api_id && clinicElem) { 1206 map.flyTo({ 1207 center: clinicElem.geometry.coordinates, 1208 zoom: 11, 1209 }); 1210 createPopUp(clinicElem); 1211 } 1212} 1213 1214function highlightClinicCard(api_id) { 1215 const $list = $('#group-hospital-list'); 1216 const $item = $('#list-hospital-' + api_id); 1217 1218 if (!$item.length) { 1219 return; 1220 } 1221 1222 $list.find('.hospital-list-item').removeClass('highlighted-clinic'); 1223 1224 $list.prepend($item); 1225 $item.addClass('highlighted-clinic'); 1226 $item.css('background-color', '#e9f5fc'); 1227 1228 selected_hospital_id = api_id; 1229 1230 $('.locations-list.frame').animate( 1231 { scrollTop: 0 }, 1232 { duration: 500, easing: 'swing' } 1233 ); 1234} 1235 1236function clearClinicHighlight() { 1237 if (!selected_hospital_id) { 1238 return; 1239 } 1240 1241 const $list = $('#group-hospital-list'); 1242 $list.find('.hospital-list-item').removeClass('highlighted-clinic'); 1243 1244 defaultHospitalOrder.forEach(function (api_id) { 1245 const $item = $('#list-hospital-' + api_id); 1246 if ($item.length) { 1247 $list.append($item); 1248 } 1249 }); 1250 1251 selected_hospital_id = null; 1252 1253 $('.locations-list.frame').animate( 1254 { scrollTop: 0 }, 1255 { duration: 500, easing: 'swing' } 1256 ); 1257 1258 map.flyTo({ 1259 center: INITIAL_MAP_CENTER, 1260 zoom: INITIAL_MAP_ZOOM, 1261 }); 1262} 1263 1264function displayWay(id) { 1265 var altText = 'Open directions in a new window'; 1266 var getDirectionsUrl = 1267 'https://www.google.com/maps/dir/Current+Location/' + 1268 encodeURIComponent($(`#clinic-direction_${id}`).text()) + 1269 '/@' + 1270 stores.features[0].geometry.coordinates[1] + 1271 ',' + 1272 stores.features[0].geometry.coordinates[0]; 1273 1274 window.open(getDirectionsUrl, '_blank', 'alt=' + altText); 1275 return; 1276} 1277 1278/**************************************************************************** 1279 * 7. Popups & List Rendering 1280 ****************************************************************************/ 1281function createPopUp(currentFeature, onClose) { 1282 const popUps = document.getElementsByClassName('mapboxgl-popup'); 1283 // Remove existing popup if any 1284 if (popUps[0]) { 1285 popUps[0].remove(); 1286 } 1287 1288 const popupInner = ` 1289 <div class="popup-inner"> 1290 <button class="mapboxgl-popup-close-button" type="button" aria-label="Close popup" aria-hidden="true">Ã</button> 1291 <h5 class="popup-heading">${currentFeature.properties.name}</h5> 1292 <h5 class="popup-address">${currentFeature.properties.address}</h5> 1293 <h5 class="popup-directions"> 1294 <a class="directions-link" data-no-turbolink="true" onclick="displayWaylink(${currentFeature.properties.api_id})" id="clinic-direction_${currentFeature.properties.api_id}"> 1295 <strong>Directions</strong> 1296 </a> 1297 </h5> 1298 <h5 class="popup-telephone"> 1299 <a href="tel:${currentFeature.properties.phone}">${currentFeature.properties.phone}</a> 1300 </h5> 1301 <div class="openbox"> 1302 1303 <a class="check-in-btn btn map-btn-primary" href="/get-clinic-book-page-by-api-id?id=${currentFeature.properties.api_id}" alt="Check into the ${currentFeature.properties.name} location"> 1304 Book a Visit 1305 </a> 1306 1307 <a href="${currentFeature.properties.clinic_page_link}" alt="Get more information about the ${currentFeature.properties.name} location" class="btn map-btn-secondary"> 1308 More Info 1309 </a> 1310 </div 1311 </div>`; 1312 1313 const popup = new mapboxgl.Popup({ closeOnClick: true, closeButton: true }) 1314 .setLngLat(currentFeature.geometry.coordinates) 1315 .setHTML(popupInner) 1316 .addTo(map); 1317 1318 if (typeof onClose === 'function') { 1319 popup.on('close', onClose); 1320 } 1321} 1322 1323function createHospitalListItem(clinicIteam, dist) { 1324 var hospitalItem = $('<div>', { 1325 class: 'span4 margin-group margin-top text-center hospital-list-item', 1326 id: `list-hospital-${clinicIteam.properties.api_id}`, 1327 }); 1328 1329 // (1) Title + Map Link 1330 var h3 = $('<h3>', { class: 'map-link' }); 1331 var mapLink = $('<a>', { 1332 class: 'map-tooltip', 1333 title: 'Select to open', 1334 'data-api_id': `${clinicIteam.properties.api_id}`, 1335 }).append( 1336 $('<img>', {
1337 src: '//maps.gstatic.com/mapfiles/api-3/images/spotlight-poi2.png', 1338 alt: 'map tooltip icon', 1339 }) 1340 ); 1341 mapLink.on('click', function () { 1342 const api_id = $(this).attr('data-api_id'); 1343 focusMap(api_id); 1344 }); 1345 var clinicLink = $('<a>', { 1346 class: `more-info-link ${clinicIteam.properties.name}`, 1347 href: `${clinicIteam.properties.clinic_page_link}`, 1348 text: `${clinicIteam.properties.name}`, 1349 }); 1350 h3.append(mapLink, clinicLink); 1351 1352 // (2) Reviews 1353 var reviewLink = $('<a>', { 1354 href: `${clinicIteam.properties.clinic_page_link}`, 1355 }); 1356 var reviewWrapper = $('<div>', { class: 'review-home-wrapper' }); 1357 var ratingWrapper = $('<div>', { class: 'home-rating-wrapper' }); 1358 var svg = 1359 '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" height="50" width="50" style="float: left; padding-right: 6px">' + 1360 ' <g fill="none" fill-rule="evenodd">' + 1361 ' <path d="M482.56 261.36c0-16.73-1.5-32.83-4.29-48.27H256v91.29h127.01c-5.47 29.5-22.1 54.49-47.09 71.23v59.21h76.27c44.63-41.09 70.37-101.59 70.37-173.46z" fill="#4285f4"></path>' + 1362 ' <path d="M256 492c63.72 0 117.14-21.13 156.19-57.18l-76.27-59.21c-21.13 14.16-48.17 22.53-79.92 22.53-61.47 0-113.49-41.51-132.05-97.3H45.1v61.15c38.83 77.13 118.64 130.01 210.9 130.01z" fill="#34a853"></path>' + 1363 ' <path d="M123.95 300.84c-4.72-14.16-7.4-29.29-7.4-44.84s2.68-30.68 7.4-44.84V150.01H45.1C29.12 181.87 20 217.92 20 256c0 38.08 9.12 74.13 25.1 105.99l78.85-61.15z" fill="#fbbc05"></path>' + 1364 ' <path d="M256 113.86c34.65 0 65.76 11.91 90.22 35.29l67.69-67.69C373.03 43.39 319.61 20 256 20c-92.25 0-172.07 52.89-210.9 130.01l78.85 61.15c18.56-55.78 70.59-97.3 132.05-97.3z" fill="#ea4335"></path>' + 1365 ' <path d="M20 20h472v472H20V20z"></path>' + 1366 ' </g>' + 1367 '</svg>'; 1368 1369 var ratingTitle = $('<div>', { 1370 class: 'google-rating-title', 1371 text: 'Avg. Google Rating', 1372 }); 1373 var avgReview = $('<div>', { 1374 id: 'avg-review', 1375 class: `${clinicIteam.properties.phone}`, 1376 }).append( 1377 $('<span>', { 1378 class: 'clinic-avg-rvw__loading', 1379 html: `<span class="map-data_loader"></span>`, 1380 }) 1381 ); 1382 1383 ratingWrapper.append(svg, ratingTitle, avgReview); 1384 reviewWrapper.append(ratingWrapper); 1385 reviewLink.append(reviewWrapper); 1386 h3.append(reviewLink); 1387 1388 // (3) Drive Time 1389 if (dist) { 1390 var h4DriveTime = $('<h4>', { class: 'drive-time' }).append( 1391 $('<span>', { 1392 class: 'drive-distance', 1393 text: `( ~${Math.round(dist * 10) / 10}mi away )`, 1394 }) 1395 ); 1396 } 1397 1398 // (4) Location / Directions 1399 var h4Location = $('<h4>', { style: 'text-transform: none;' }).append( 1400 $('<img>', { 1401 class: 'icon', 1402 src: '/wp-content/themes/crh/assets/icons/location.png', 1403 alt: 'location icon', 1404 }), 1405 $('<a>', { 1406 href: 'javascript:', 1407 onclick: `displayWay(${clinicIteam.properties.api_id})`, 1408 text: `${clinicIteam.properties.address}`, 1409 id: `clinic-direction_${clinicIteam.properties.api_id}`, 1410 }) 1411 ); 1412 var h4Directions = $('<h4>').append( 1413 $('<a>', { 1414 class: 'directions-link', 1415 'data-no-turbolink': 'true', 1416 onclick: `displayWay(${clinicIteam.properties.api_id})`, 1417 html: '<strong>Directions</strong>', 1418 }) 1419 ); 1420 1421 // (5) Phone 1422 var h4Phone = $('<h4>', { class: 'business' }).append( 1423 $('<img>', { 1424 class: 'icon', 1425 src: '/wp-content/themes/crh/assets/icons/phone.png', 1426 alt: 'phone icon', 1427 }), 1428 $('<a>', { 1429 href: `tel:${clinicIteam.properties.phone}`, 1430 text: `${clinicIteam.properties.phone}`, 1431 }) 1432 ); 1433 1434 // (6) Walk-In Wait 1435 var h4WaitTime = $('<div>', { 1436 class: 'current-wait-container', 1437 style: 'text-transform:none;', 1438 }).append( 1439 $('<img>', { 1440 class: 'icon', 1441 src: '/wp-content/themes/crh/assets/icons/walk-in-wait.png', 1442 alt: 'walk in wait icon', 1443 }), 1444 $('<h4>', { 1445 html: `Walk-In Wait: <strong class="current_wait_placeholder"><span class="map-data_loader"></span></strong>`, 1446 }) 1447 ); 1448 1449 // (7) Business Hours 1450 var h4Hours = $('<div>', { class: 'business' }).append( 1451 $('<h4>', { class: 'business-hours' }) 1452 .append( 1453 $('<img>', { 1454 class: 'icon', 1455 src: '/wp-content/themes/crh/assets/icons/hours.png', 1456 alt: 'hours icon', 1457 }) 1458 ) 1459 .append( 1460 $('<span>', { 1461 class: 'business-hours__text', 1462 html: `<span class="map-data_loader"></span>`, 1463 }) 1464 ) 1465 ); 1466 1467 // (8) More Info 1468 var h4MoreInfo = $('<h4>').append( 1469 $('<a>', { 1470 class: 'more-info-link', 1471 href: `${clinicIteam.properties.clinic_page_link}`, 1472 html: '<strong>More Info</strong>', 1473 }) 1474 ); 1475 1476 // (9) Booking & Times 1477 var infoBtns = $('<div>', { 1478 id: `info-btns-${clinicIteam.properties.api_id}`, 1479 }).append( 1480 $('<div>', { 1481 class: 'times-intro', 1482 }), 1483 $('<div>', { 1484 class: 'info-btns get-in-line-buttons', 1485 }) 1486 ); 1487 1488 var checkinBtn = $('<div>', { 1489 class: 'll-check-in-btn', 1490 }); 1491 1492 // Append all child elements
1493 return hospitalItem.append( 1494 h3, 1495 h4DriveTime ? h4DriveTime : '', 1496 h4Location, 1497 h4Directions, 1498 h4Phone, 1499 h4WaitTime, 1500 h4Hours, 1501 h4MoreInfo, 1502 infoBtns, 1503 checkinBtn 1504 ); 1505} 1506 1507/**************************************************************************** 1508 * 8. Markers 1509 ****************************************************************************/ 1510function addMarkers(clinics) { 1511 for (const marker of clinics) { 1512 const el = document.createElement('div'); 1513 el.id = `marker-${marker.properties.id}`; 1514 el.className = 'marker'; 1515 1516 el.innerHTML = ` 1517 <div class="marker-box" id="marker-${marker.properties.api_id}"> 1518 <div class="map-wait_icon"> 1519 <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="12" height="12" viewBox="0 0 256 256" xml:space="preserve"> 1520 <defs></defs> 1521 <g style="stroke: none; fill: none; opacity: 1;" transform="translate(1.4065934065934016 1.4065934065934016) scale(2.81 2.81)"> 1522 <path d="M 45 40.375 L 45 40.375 c -9.415 0 -17.118 -7.703 -17.118 -17.118 v -6.139 C 27.882 7.703 35.585 0 45 0 h 0 c 9.415 0 17.118 7.703 17.118 17.118 v 6.139 C 62.118 32.672 54.415 40.375 45 40.375 z" style="fill: rgb(39,69,115);"></path> 1523 <path d="M 54.639 42.727 C 51.743 44.226 48.47 45.09 45 45.09 s -6.743 -0.863 -9.639 -2.363 c -12.942 1.931 -22.952 13.162 -22.952 26.619 v 17.707 c 0 1.621 1.326 2.946 2.946 2.946 h 59.29 c 1.621 0 2.946 -1.326 2.946 -2.946 V 69.347 C 77.591 55.889 67.581 44.659 54.639 42.727 z" style="fill: rgb(39,69,115);"></path> 1524 </g> 1525 </svg> 1526 <p class="patient_queue"></p> 1527 </div> 1528 <svg height="41px" width="27px" viewBox="0 0 27 41" xmlns="http://www.w3.org/2000/svg"> 1529 <g fill-rule="nonzero"> 1530 <g fill="#274573"> 1531 <path d="M27,13.5 C27,19.074644 20.250001,27.000002 14.75,34.500002 C14.016665,35.500004 12.983335,35.500004 12.25,34.500002 C6.7499993,27.000002 0,19.222562 0,13.5 C0,6.0441559 6.0441559,0 13.5,0 C20.955844,0 27,6.0441559 27,13.5 Z"/> 1532 </g> 1533 <g opacity="0.25" fill="#000000"> 1534 <path d="M13.5,0 C6.0441559,0 0,6.0441559 0,13.5 C0,19.222562 6.7499993,27 12.25,34.5 C13,35.522727 14.016664,35.500004 14.75,34.5 C20.250001,27 27,19.074644 27,13.5 C27,6.0441559 20.955844,0 13.5,0 Z M13.5,1 C20.415404,1 26,6.584596 26,13.5 C26,15.898657 24.495584,19.181431 22.220703,22.738281 C19.945823,26.295132 16.705119,30.142167 13.943359,33.908203 C13.743445,34.180814 13.612715,34.322738 13.5,34.441406 C13.387285,34.322738 13.256555,34.180814 13.056641,33.908203 C10.284481,30.127985 7.4148684,26.314159 5.015625,22.773438 C2.6163816,19.232715 1,15.953538 1,13.5 C1,6.584596 6.584596,1 13.5,1 Z"/> 1535 </g> 1536 <g transform="translate(6.0, 7.0)" fill="#FFFFFF"/> 1537 <g transform="translate(8.0, 8.0)"> 1538 <circle fill="#FFFFFF" cx="5.5" cy="5.5" r="5.5" id="waiting-container" class="waiting-map__circle"/> 1539 </g> 1540 </g> 1541 </svg> 1542 </div> 1543 <div class="marker-clinic_name">${marker.properties.name}</div> 1544 `; 1545 1546 // Create a Mapbox Marker for each 1547 my_loc_icon = new mapboxgl.Marker(el, { 1548 draggable: false, 1549 anchor: 'center', 1550 offset: [0, 0], 1551 }) 1552 .setLngLat(marker.geometry.coordinates) 1553 .addTo(map); 1554 1555 // Click handler 1556 el.addEventListener('click', (e) => { 1557 flyToStore(marker); 1558 highlightClinicCard(marker.properties.api_id); 1559 createPopUp(marker, function () { 1560 clearClinicHighlight(); 1561 }); 1562 e.stopPropagation(); 1563 }); 1564 } 1565} 1566 1567/**************************************************************************** 1568 * 9. Booking & Times 1569 ****************************************************************************/ 1570 1571function submitMapBookingForm(clinicId, aptTime, apptDay, reason) { 1572 const form = document.createElement('form'); 1573 form.method = 'POST'; 1574 form.action = '/get-clinic-book-page-by-api-id'; 1575 form.style.display = 'none'; 1576 1577 const fields = { 1578 id: clinicId, 1579 apt_time: aptTime, 1580 apt_day: apptDay, 1581 options: reason, 1582 }; 1583
1584 Object.keys(fields).forEach(function (name) { 1585 const input = document.createElement('input'); 1586 input.type = 'hidden'; 1587 input.name = name; 1588 input.value = fields[name]; 1589 form.appendChild(input); 1590 }); 1591 1592 document.body.appendChild(form); 1593 form.submit(); 1594} 1595 1596 1597function getBookingTime() { 1598 // 1. Get the current local time 1599 const localNow = new Date(); 1600 1601 // 2. Convert to a string in the "America/New_York" time zone 1602 const nyNowString = localNow.toLocaleString('en-US', { 1603 timeZone: 'America/New_York', 1604 }); 1605 1606 // 3. Parse that string back into a Date object, so `today` = âright now in NYâ 1607 const today = new Date(nyNowString); 1608 1609 // Arrays for day and month names 1610 const daysOfWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; 1611 const months = [ 1612 'January', 1613 'February', 1614 'March', 1615 'April', 1616 'May', 1617 'June', 1618 'July', 1619 'August', 1620 'September', 1621 'October', 1622 'November', 1623 'December', 1624 ]; 1625 function formatSlotTime(encodedTime) { 1626 let slotTime = new Date(decodeURIComponent(encodedTime)); 1627 const options = { 1628 hour: '2-digit', 1629 minute: '2-digit', 1630 hour12: true, 1631 timeZone: 'America/New_York', 1632 }; 1633 return slotTime.toLocaleTimeString('en-US', options); 1634 } 1635 1636 // For each clinic 1637 for (let i = 0; i < stores.features.length; i++) { 1638 (function (clinic_api_id) { 1639 var clinic_api_id = stores.features[i].properties.api_id; 1640 var slots_url = 'https://api.clockwisemd.com/v1/hospitals/' + clinic_api_id + '/times'; 1641 1642 $.ajax({ 1643 url: slots_url, 1644 type: 'GET', 1645 headers: { 1646 'Content-Type': 'application/json', 1647 }, 1648 success: function (response) { 1649 var introButtonsHtml = ''; 1650 var dayParam = 'today'; 1651 const DEFAULT_APPT_REASON = 'New illness/infection'; 1652 1653 if (response[0].length > 0) { 1654 // Use today's date 1655 const todayDayName = daysOfWeek[today.getDay()]; 1656 const todayMonthName = months[today.getMonth()]; 1657 const todayDayOfMonth = today.getDate(); 1658 // If response[0] has times, we show "today"; otherwise "tomorrow" 1659 dayParam = 'today'; 1660 introButtonsHtml += `<p>Click a time to get in line <strong>today 1661 </strong></p> 1662 <div class="times-date"> 1663 ${todayDayName}, ${todayMonthName} ${todayDayOfMonth} 1664 </div>`; 1665 } else if (response[1].length > 0) { 1666 const tomorrow = new Date(today); 1667 1668 tomorrow.setDate(today.getDate() + 1); 1669 const tomorrowDayName = daysOfWeek[tomorrow.getDay()]; 1670 const tomorrowMonthName = months[tomorrow.getMonth()]; 1671 const tomorrowDayOfMonth = tomorrow.getDate(); 1672 // If response[0] has times, we show "today"; otherwise "tomorrow" 1673 dayParam = 'tomorrow'; 1674 introButtonsHtml += `<p>Click a time to get in line <strong>tomorrow 1675 </strong></p> 1676 <div class="times-date"> 1677 ${tomorrowDayName}, ${tomorrowMonthName} ${tomorrowDayOfMonth} 1678 </div>`; 1679 } 1680 1681 let slotBtns = []; 1682 if (response[0].length > 0) { 1683 slotBtns = response[0]; 1684 } else if (response[1].length > 0) { 1685 slotBtns = response[1]; 1686 } 1687 1688 let currentListItem = $('#list-hospital-' + clinic_api_id); 1689 let buttonsHtml = ''; 1690 1691 // Show first 2 time slots 1692 slotBtns.slice(0, 2).forEach((btn) => { 1693 const rawTime = btn[1]; 1694 const displayTime = formatSlotTime(rawTime); 1695 buttonsHtml += ` 1696 <div class="map-slot_btn get-map-slot" 1697 data-clinic-id="${clinic_api_id}" 1698 data-apt-time="${rawTime}" 1699 data-appt-day="${dayParam}" 1700 data-reason="${DEFAULT_APPT_REASON}"> 1701 ${displayTime} 1702 </div>`; 1703 }); 1704 1705 // If more than 2 time slots, create a dropdown 1706 if (slotBtns.length > 2) { 1707 buttonsHtml += `<span class="add-times-dropdown"> 1708 <div class="map-slot_btn">+ TIMES -</div> 1709 <ul class="add-times-dropdown-list">`; 1710
1711 slotBtns.slice(2, 5).forEach((btn) => { 1712 const rawTime = btn[1]; 1713 const displayTime = formatSlotTime(rawTime); 1714 buttonsHtml += ` 1715 <li> 1716 <div class="get-map-slot" 1717 data-clinic-id="${clinic_api_id}" 1718 data-apt-time="${rawTime}" 1719 data-appt-day="${dayParam}" 1720 data-reason="${DEFAULT_APPT_REASON}"> 1721 ${displayTime} 1722 </div> 1723 </li>`; 1724 }); 1725 1726 buttonsHtml += ` 1727 <li><a href="/get-clinic-book-page-by-api-id?id=${clinic_api_id}">More</a></li> 1728 </ul> 1729 </span>`; 1730 } 1731 1732 checkinBtnHTML = `<a class="check-in-button" href="/get-clinic-book-page-by-api-id?id=${clinic_api_id}"><button class="btn btn-primary">Book a Visit</button></a>`; 1733 1734 currentListItem.find('.times-intro').html(introButtonsHtml); 1735 currentListItem.find('.get-in-line-buttons').html(buttonsHtml); 1736 currentListItem.find('.ll-check-in-btn').html(checkinBtnHTML); 1737 }, 1738 error: function (error) { 1739 console.log('Error:', error); 1740 }, 1741 }); 1742 })(stores.features[i].properties.api_id); 1743 } 1744} 1745 1746/**************************************************************************** 1747 * 10. Document Ready: Main Entry Point 1748 ****************************************************************************/ 1749jQuery(document).ready(function ($) { 1750 // Check URL for location search queries 1751 var url = window.location.href; 1752 if ( 1753 !( 1754 url.indexOf('?location_search_query=') !== -1 || url.indexOf('&location_search_query=') !== -1 1755 ) && 1756 !( 1757 url.indexOf('?location_search_current=') !== -1 || 1758 url.indexOf('&location_search_current=') !== -1 1759 ) 1760 ) { 1761 var cookieValue = JSON.parse(readCookie('search_location_address')); 1762 if (cookieValue !== null) { 1763 if (typeof cookieValue.is_current !== 'undefined' && cookieValue.is_current === true) { 1764 function clickOnUseMyLocation() { 1765 if (typeof btnMyLoc !== 'undefined') { 1766 jQuery('#current-location-btn').click(); 1767 } else { 1768 // If you want auto-locate after a delay: 1769 // setTimeout(clickOnUseMyLocation, 300); 1770 } 1771 } 1772 // clickOnUseMyLocation(); 1773 } else if (typeof cookieValue.address !== 'undefined' && cookieValue.address !== '') { 1774 function clickOnSearchLocation() { 1775 if (typeof geocoder !== 'undefined') { 1776 geocoder.query(cookieValue.address); 1777 } else { 1778 setTimeout(() => { 1779 clickOnSearchLocation(); 1780 }, 300); 1781 } 1782 } 1783 clickOnSearchLocation(); 1784 } 1785 } else { 1786 function clickOnUseMyLocation() { 1787 if (typeof btnMyLoc !== 'undefined') { 1788 jQuery('#current-location-btn').click(); 1789 } else { 1790 // setTimeout(clickOnUseMyLocation, 300); 1791 } 1792 } 1793 clickOnUseMyLocation(); 1794 } 1795 } 1796 1797 // "Use My Location" button 1798 const btn = document.getElementById('current-location-btn'); 1799 btn.addEventListener('click', findPosition); 1800 1801 // Fetch Mapbox token from WP JSON 1802 async function fetchMapboxToken() { 1803 try { 1804 const response = await fetch('/wp-json/clinic_config/v1/details'); 1805 const data = await response.json(); 1806 if (data) { 1807 return data; // Return token if available 1808 } else { 1809 throw new Error('Mapbox token not found.'); 1810 } 1811 } catch (error) { 1812 console.error('Error fetching Mapbox token:', error); 1813 return null; 1814 } 1815 } 1816 1817 // Build the hospital list immediately 1818 stores.features.forEach((clinic) => { 1819 $('#group-hospital-list').append(createHospitalListItem(clinic)); 1820 }); 1821 updateHospitalsData(); 1822 1823 // Fetch token, then initialize map 1824 fetchMapboxToken().then(function (data) { 1825 mapboxgl.accessToken = data.mapToken; 1826 1827 map = new mapboxgl.Map({ 1828 container: 'map-canvas', 1829 style: 'mapbox://styles/mapbox/streets-v9', 1830 center: INITIAL_MAP_CENTER, 1831 zoom: INITIAL_MAP_ZOOM, 1832 }); 1833 1834 // Basic setup 1835 startIt(stores.features, map); 1836 initialize(stores.features); 1837 1838 // Assign each store a unique "id"
1839 stores.features.forEach((store, i) => { 1840 store.properties.id = i; 1841 }); 1842 1843 // Zoom event to dynamically resize/hide markers 1844 map.on('zoom', () => { 1845 const currentZoom = map.getZoom(); 1846 if (currentZoom >= 11) { 1847 $('.marker-clinic_name').show(); 1848 $('#map-canvas .marker .marker-box>svg').css({ 1849 width: '50px', 1850 height: '82px', 1851 }); 1852 $('#map-canvas .marker .marker-box .map-wait_icon').css({ 1853 display: 'flex', 1854 }); 1855 $('.waiting-map__circle').attr('r', '11.499996'); 1856 } else { 1857 $('.marker-clinic_name').hide(); 1858 $('#map-canvas .marker .marker-box>svg').css({ 1859 width: '15px', 1860 height: '23px', 1861 }); 1862 $('#map-canvas .marker .marker-box .map-wait_icon').hide().css({ 1863 display: 'none', 1864 }); 1865 $('.waiting-map__circle').attr('r', '5.5'); 1866 } 1867 }); 1868 1869 // Once map is loaded, add the markers 1870 map.on('load', () => { 1871 map.addSource('places', { 1872 type: 'geojson', 1873 data: stores, 1874 }); 1875 addMarkers(stores.features); 1876 }); 1877 1878 getBookingTime(); 1879 }); 1880}); 1881 1882// Initialize once the DOM is ready 1883jQuery(document).ready(firstLoad); 1884 1885function firstLoad() { 1886 jQuery('#address').keyup(function (e) { 1887 if (e.keyCode == 13) { 1888 // user hit Enter 1889 jQuery('#address-search-btn').click(); 1890 } 1891 }); 1892 1893 // Check for geolocation support 1894 if (geoPosition.init()) { 1895 can_cur_loc = true; 1896 btnMyLoc = document.getElementById('current-location-btn'); 1897 jQuery(btnMyLoc).show(); 1898 } 1899 1900 can_block = typeof jQuery.blockUI === 'function'; 1901} 1902 1903$(document).on('click', '.get-map-slot', function (e) { 1904 e.preventDefault(); 1905 submitMapBookingForm( 1906 $(this).data('clinic-id'), 1907 $(this).data('apt-time'), 1908 $(this).data('appt-day'), 1909 $(this).data('reason') 1910 ); 1911}); 1912 1913/**************************************************************************** 1914 * End of Script 1915 ****************************************************************************/ 1916;$ = jQuery; 1917$(document).ready(function () { 1918 $(document).on("click", ".faq-header", function () { 1919 $(this).siblings(".faq-content").slideToggle(); 1920 const altTxt = $(this).data("alt_text"); 1921 if ($(this).data("toggle") === "close") { 1922 $(this).data("toggle", "open"); 1923 $(this) 1924 .find(".faq-cntrl img") 1925 .attr( 1926 "src", 1927 "/wp-content/plugins/clinics-post-type/assets/img/faq-closed.svg", 1928 ) 1929 .attr("alt", `Close ${altTxt}`); 1930 } else { 1931 $(this).data("toggle", "close"); 1932 $(this) 1933 .find(".faq-cntrl img") 1934 .attr( 1935 "src", 1936 "/wp-content/plugins/clinics-post-type/assets/img/faq-opened.svg", 1937 ) 1938 .attr("alt", `Open ${altTxt}`); 1939 } 1940 }); 1941 1942 $("#today-btn").on("click", function () { 1943 $(this).addClass("active-day"); 1944 $("#tomorrow-btn").removeClass("active-day"); 1945 1946 $("#tomorrow-slots").hide(); 1947 $("#today-slots").show(); 1948 }); 1949 1950 $("#tomorrow-btn").on("click", function () { 1951 $(this).addClass("active-day"); 1952 $("#today-btn").removeClass("active-day"); 1953 1954 $("#today-slots").hide(); 1955 $("#tomorrow-slots").show(); 1956 }); 1957 1958 var $radioBtns = $('.radio-btn input[type="radio"]'); 1959 1960 $radioBtns.on("change", function () { 1961 $radioBtns.each(function () { 1962 var $label = $(this).parent(".radio-btn-lbl"); 1963 1964 if ($(this).prop("checked")) { 1965 $label.addClass("selected-type"); 1966 } else { 1967 $label.removeClass("selected-type"); 1968 } 1969 }); 1970 }); 1971 1972 // Share Links //////////////// 1973 1974 // Email Share Button Click Event 1975 $("#emailButton").on("click", function () { 1976 const subject = "Check out this link!"; 1977 const body = `Here is your clinic boking schedule: ${sharedLink}`; 1978 const sharedLink = $(".copy-link-text").text(); 1979 const mailtoLink = `mailto: ? subject = ${encodeURIComponent( 1980 subject, 1981 )} & body = ${encodeURIComponent(body)}`; 1982 window.location.href = mailtoLink; 1983 }); 1984 1985 // WhatsApp Share Button Click Event 1986 $("#whatsappButton").on("click", function () { 1987 const message = `Check out this link: ${sharedLink}`; 1988 const sharedLink = $(".copy-link-text").text(); 1989 const whatsappLink = `https://wa.me / ? text = ${encodeURIComponent( 1990 message, 1991 )}`; 1992 window.open(whatsappLink); 1993 }); 1994 1995 // SMS Share Button Click Event 1996 $("#smsButton").on("click", function () { 1997 const message = `Check out this link: ${sharedLink}`; 1998 const sharedLink = $(".copy-link-text").text(); 1999 const smsLink = `sms: ? body = ${encodeURIComponent(message)}`; 2000 window.location.href = smsLink; 2001 }); 2002 2003 // Closed Clinic Anchor 2004 2005 $(".closed_clinic_bh").on("click", function (e) { 2006 e.preventDefault(); 2007 2008 const $dailyBusinessHours = $("#daily_bh"); 2009 const $dailyBusinessHoursHeader = 2010 $dailyBusinessHours.children(".faq-header"); 2011 const $dailyBusinessHoursContent = 2012 $dailyBusinessHours.children(".faq-content"); 2013 2014 if (!$dailyBusinessHoursContent.is(":visible")) { 2015 $dailyBusinessHoursHeader.trigger("click"); 2016 } 2017 const headerHeight = $("header").outerHeight() || 0; 2018 $("html, body").animate( 2019 { 2020 scrollTop: $dailyBusinessHours.offset().top - headerHeight - 10, 2021 }, 2022 400, 2023 ); 2024 }); 2025 2026 // NB Clinic Anchor 2027 $(".nb_clinic_anchor").on("click", function (e) { 2028 e.preventDefault(); 2029 2030 const $nearbyClinic = $("#nearbyclinic"); 2031 const $nearbyClinicHeader = $nearbyClinic.find(".faq-header").first(); 2032 const $nearbyClinicContent = $nearbyClinic.find(".faq-content").first(); 2033 2034 if (!$nearbyClinicContent.is(":visible")) { 2035 $nearbyClinicHeader.trigger("click"); 2036 } 2037 2038 const headerHeight = $("header").outerHeight() || 0; 2039 $("html, body").animate( 2040 { scrollTop: $nearbyClinic.offset().top - headerHeight - 10 }, 2041 400, 2042 ); 2043 }); 2044 2045 // Copy Link Button Click Event 2046 $("#copyLinkButton").on("click", function () { 2047 const sharedLink = $(".copy-link-text").text(); 2048 copyToClipboard(sharedLink); 2049 alert("Link copied to clipboard!"); 2050 }); 2051 2052 // Adding Auto Slash on the date field 2053 const $jqDate = $("input#dob"); 2054 2055 // Bind keyup/keydown to the input 2056 $jqDate.bind("keyup", "keydown", function (e) { 2057 // To accomdate for backspacing, we detect which key was pressed - if backspace, do nothing: 2058 if (e.which !== 8) { 2059 if (e.keyCode == 8 || e.keyCode == 37 || e.keyCode == 39) { 2060 } else { 2061 var strDate = $jqDate.val(); 2062 strDate = strDate.replace(/[^0-9/]/g, "").replace(/\//g, ""); 2063 2064 str = 2065 strDate.substr(0, 2) + 2066 "/" + 2067 strDate.substr(2, 2) + 2068 "/" + 2069 strDate.substr(4, 4); 2070 2071 str = str.replace(/\/\/\//g, "/"); 2072 str = str.replace(/\/\//g, "/"); 2073 2074 if (str.substr(str.length - 1, 1) == "/") { 2075 str = str.substr(0, str.length - 1); 2076 } 2077 2078 $jqDate.val(str); 2079 } 2080 } 2081 }); 2082 2083 // Formatting Phone Number 2084 $("#patient-phone").on("focus input", function () { 2085 var phoneNumber = $(this).val(); 2086 2087 phoneNumber = $(this).val(); 2088 if (phoneNumber.length === 3 || phoneNumber.length === 7) { 2089 $(this).val(phoneNumber + "-"); 2090 } else if (phoneNumber.length > 12) { 2091 var formmatedPhoneNumber = phoneNumber.substring(0, 12); 2092 $(this).val(formmatedPhoneNumber); 2093 } 2094 }); 2095}); 2096 2097function copyToClipboard(text) { 2098 const input = $("<input>"); 2099 $("body").append(input); 2100 input.val(text).select(); 2101 document.execCommand("copy"); 2102 input.remove(); 2103} 2104 2105// Toggle button block on HERO 2106 2107function setActiveBlock(activeBlock, allBlocks, allButtons) { 2108 if (!activeBlock.classList.contains("active-query")) { 2109 allBlocks.forEach((block) => { 2110 block.classList.remove("active-query"); 2111 }); 2112 2113 allButtons.forEach((button) => { 2114 button.classList.add("btn-hidden"); 2115 }); 2116 2117 arrBtns.forEach((btn) => { 2118 btn.style.display = "inline-block"; 2119 }); 2120
2121 subTexts.forEach((text) => { 2122 text.style.display = "none"; 2123 }); 2124 2125 activeBlock.classList.add("active-query"); 2126 const activeBtn = activeBlock.querySelector(".query-btn"); 2127 activeBtn.classList.remove("btn-hidden"); 2128 } 2129} 2130 2131const allBlocks = document.querySelectorAll(".query-box"); 2132const allButtons = document.querySelectorAll(".query-btn"); 2133const arrBtns = document.querySelectorAll(".box-arr-icon"); 2134const subTexts = document.querySelectorAll(".care-content p"); 2135 2136allBlocks.forEach((block, index) => { 2137 const activeBlock = block; 2138 activeBlock.addEventListener("mouseover", function () { 2139 setActiveBlock(activeBlock, allBlocks, allButtons); 2140 activeBlock.querySelector(".care-content p").style.display = "block"; 2141 arrBtns[index].style.display = "none"; 2142 }); 2143}); 2144 2145const urgentCareBtnBlocks = document.querySelectorAll(".urgent-care-btn-block"); 2146const careCenterMap = document.querySelector("#care_center_block"); 2147 2148urgentCareBtnBlocks.forEach(function (block) { 2149 block.addEventListener("click", () => { 2150 careCenterMap.scrollIntoView({ behavior: "smooth" }); 2151 }); 2152}); 2153 2154// Toggle Switch 2155function handleToggle() { 2156 const toggleSwitches = document.querySelectorAll("#toggle"); 2157 const walkinBlocks = document.querySelectorAll("#walk-in-wait"); 2158 const queueLengthBlocks = document.querySelectorAll("#queue-length"); 2159 const newestSwitches = document.querySelectorAll(".newest-switch"); 2160 const oldestSwitches = document.querySelectorAll(".oldest-switch"); 2161 2162 toggleSwitches.forEach((toggleSwitch, i) => { 2163 if (toggleSwitch.checked) { 2164 toggleSwitch.checked = true; 2165 walkinBlocks[i].style.display = "none"; 2166 queueLengthBlocks[i].style.display = "block"; 2167 newestSwitches[i].classList.toggle("active-wait-info"); 2168 oldestSwitches[i].classList.toggle("active-wait-info"); 2169 } else { 2170 toggleSwitch.checked = false; 2171 walkinBlocks[i].style.display = "block"; 2172 queueLengthBlocks[i].style.display = "none"; 2173 newestSwitches[i].classList.toggle("active-wait-info"); 2174 oldestSwitches[i].classList.toggle("active-wait-info"); 2175 } 2176 }); 2177} 2178;jQuery(document).ready(function ($) { 2179 function getUrlParameter(name) { 2180 const urlParams = new URLSearchParams(window.location.search); 2181 2182 return urlParams.get(name); 2183 } 2184 2185 // Age calculation function 2186 2187 function calculateAgeInTimeZone(timestamp, timeZone) { 2188 var now = new Date(); 2189 2190 var birthdate = new Date(timestamp); 2191 2192 // Set the time zone for calculations 2193 2194 var nowInTimeZone = new Date( 2195 now.toLocaleString('en-US', { 2196 timeZone: timeZone, 2197 }) 2198 ); 2199 2200 var birthdateInTimeZone = new Date( 2201 birthdate.toLocaleString('en-US', { 2202 timeZone: timeZone, 2203 }) 2204 ); 2205 2206 var years = nowInTimeZone.getFullYear() - birthdateInTimeZone.getFullYear(); 2207 2208 var months = nowInTimeZone.getMonth() - birthdateInTimeZone.getMonth(); 2209 2210 var days = nowInTimeZone.getDate() - birthdateInTimeZone.getDate(); 2211 2212 // Adjust for negative months or days 2213 2214 if (months < 0 || (months === 0 && days < 0)) { 2215 years--; 2216 2217 months += 12; 2218 } 2219 2220 if (days < 0) { 2221 var lastMonthDays = new Date( 2222 nowInTimeZone.getFullYear(), 2223 2224 nowInTimeZone.getMonth(), 2225 2226 0 2227 ).getDate(); 2228 2229 days += lastMonthDays; 2230 2231 months--; 2232 } 2233 2234 return { 2235 years: years, 2236 2237 months: months, 2238 2239 days: days, 2240 }; 2241 } 2242 2243 // Selecting Appointment Time 2244 2245 $(document).on('click', '.get-apt-time', function () { 2246 const btnGroup = $(this).data('btn_group'); 2247 2248 const moreText = `More <img src="${bookingFormVars.pluginURL}/img/select_arrow.svg">`; 2249 2250 aptTimeVal = $(this).data('value'); 2251 2252 dayVal = $(this).data('day'); 2253 2254 $(`form[data-formType="${btnGroup}"] input[name="apt_day"]`).val(dayVal); 2255 2256 $(`form[data-formType="${btnGroup}"] input[name="apt_time"]`).val(aptTimeVal); 2257 2258 const aptText = $(this).find('span').text(); 2259 2260 if ($(`form#get_booking_page`).length > 0) { 2261 $(`form#get_booking_page`).submit(); 2262 } 2263 2264 const selectedArrImg = `<img src="${bookingFormVars.pluginURL}/img/selected_arrow_white.svg">`; 2265 2266 $(`form[data-formType=${btnGroup}] .get-apt-time`).each(function () { 2267 $(this).removeClass('active-slot'); 2268 }); 2269 2270 $(this).addClass('active-slot'); 2271 2272 if ($(this).closest('.expanded_slots').length > 0) { 2273 $(this) 2274 .closest('.more-slots') 2275 2276 .find('.more-slots_text') 2277 2278 .html(`${aptText} ${selectedArrImg}`); 2279 2280 $(this) 2281 .closest('.available-slots') 2282 2283 .find('li.more-slots') 2284 2285 .addClass('active-slot'); 2286 2287 $(this).closest('.more-slot-items').hide(); 2288 } else if ( 2289 $(this).closest('.expanded_slots').length === 0 && 2290 $('li.more-slots').hasClass('active-slot') 2291 ) { 2292 $(this) 2293 .closest('.available-slots') 2294 2295 .find('.more-slots_text') 2296 2297 .html(moreText); 2298 2299 $(this) 2300 .closest('.available-slots') 2301 2302 .find('li.more-slots') 2303 2304 .removeClass('active-slot'); 2305 } 2306 }); 2307 2308 $('.apt-btn__wrapper .single-clinic-btn').on('click', function () { 2309 if ($(this).attr('href') === '' && $('.get-apt-time').length > 0) { 2310 $('.get-apt-time')[0].click(); 2311 } 2312 }); 2313 2314 // Form Submission 2315 2316 $('#apt-booking-form').on('submit', function (e) { 2317 e.preventDefault(); 2318 2319 // Age Verification 2320 2321 const timestamp = new Date($('#dob').val()).getTime(); 2322
2323 const timeZone = 'America/New_York'; 2324 2325 const age = calculateAgeInTimeZone(timestamp, timeZone); 2326 2327 let errorsDefault = false; 2328 2329 // form Submission 2330 2331 if ( 2332 age.years < 2 || 2333 (age.years === 2 && age.months === 0 && age.days === 0 && errorsDefault == false) 2334 ) { 2335 $('#overlay, #consent-popup').show(); 2336 2337 $('#consent-popup .popup-content').html(`<h5>Please Call to Book Your Visit</h5> 2338 2339 <p>Providers don't typically see patients under two years of age. Please call to book an appointment.</p> 2340 2341 2342 2343 <div class="peach-icon-box"> 2344 2345 <img src="${bookingFormVars.pluginURL}/img/call.svg" style="width:14px;"> 2346 2347 <a href="tel:<?php echo $customClinic['phone'][0]; ?>" style="font-size:14px;font-family:'Inter', sans-serif;text-decoration:underline;"><?php echo $customClinic['phone'][0]; ?></a> 2348 2349 </div> 2350 2351 2352 2353 <p class="child-agree-btn peach-btn">I Understand</p> 2354 2355 2356 2357 `); 2358 2359 $('.child-agree-btn').on('click', function () { 2360 $('#overlay, #consent-popup').fadeOut(); 2361 }); 2362 } else if (age.years < 18 && errorsDefault == false) { 2363 $('#overlay, #consent-popup').show(); 2364 2365 $('#consent-popup .popup-content').html(`<h5>Minor Consent Required</h5> 2366 2367 <p>Since the patient is under the age of 18 you will need to print, fill, and bring with you to your visit the minor consent form found on the next page.</p> 2368 2369 <p class="minor-agree-btn peach-btn">I Understand</p> 2370 2371 `); 2372 2373 $('.minor-agree-btn').on('click', function () { 2374 $('#overlay, #consent-popup').fadeOut(); 2375 2376 submitTheForm(); 2377 }); 2378 } else { 2379 submitTheForm(); 2380 } 2381 2382 // Sending Data 2383 2384 function submitTheForm() { 2385 function scrollToError(fieldParent) { 2386 const stickyHeaderHeight = $('header').outerHeight() || 100; // fallback to 100px if header not found 2387 2388 $('html, body').animate( 2389 { 2390 scrollTop: fieldParent.offset().top - stickyHeaderHeight - 20, 2391 }, 2392 2393 800 2394 ); 2395 } 2396 2397 const dobVal = $('#dob').val(); 2398 2399 const dobParent = $('#dob').parent(); 2400 2401 if (!dobVal) { 2402 $('#dob').addClass('error'); 2403 2404 dobParent.find('.field-error-msg').html('Please fill out this field.'); 2405 2406 if (!errorsDefault) { 2407 errorsDefault = true; 2408 2409 scrollToError($('.slots-wrapper')); 2410 } 2411 } else if (dobVal.length !== 10) { 2412 $('#dob').addClass('error'); 2413 2414 dobParent 2415 2416 .find('.field-error-msg') 2417 2418 .html('Invalid date format. Date format Should be mm/dd/yyyy'); 2419 2420 if (!errorsDefault) { 2421 errorsDefault = true; 2422 2423 scrollToError(dobParent); 2424 } 2425 } 2426 2427 if (!isHartwellView && $('#apt_time').val() === '') { 2428 const aptParent = $('#apt_time').parent(); 2429 2430 $('#apt_time').addClass('error'); 2431 2432 $('#apt_missing_msg').html('Please select an appointment time.'); 2433 2434 $('#apt_missing_msg').show(); 2435 2436 if (!errorsDefault) { 2437 errorsDefault = true; 2438 2439 scrollToError(aptParent); 2440 } 2441 } 2442 2443 if (errorsDefault == false) { 2444 $('#bk-overlay').css('display', 'flex'); 2445 2446 const data = { 2447 hospital_id: $('#hospital_id').val(), 2448 2449 first_name: $('#first_name').val(), 2450 2451 last_name: $('#last_name').val(), 2452 2453 apt_time: isHartwellView ? $('#hartwell_time').val() : $('#apt_time').val(), 2454 2455 phone_number: $('#patient-phone').val(), 2456 2457 email: $('#email').val(), 2458 2459 dob: $('#dob').val(), 2460 2461 sex: $('#patient-sex').val(), 2462 2463 reason_id: $('#options').children(':selected').attr('id'), 2464 2465 reason_description: $('#options').val(), 2466 2467 type: 'online', 2468 2469 is_new_patient: $('input#new_patient_type').is(':checked'), 2470 2471 additional_patients: [], 2472 2473 custom_fields: { 2474 231450: window.location.href, 2475 }, 2476 2477 // custom_payload: {}, 2478 2479 rwg_token: getUrlParameter('rwg_token'), 2480 2481 session_id: getUrlParameter('session_id'), 2482 2483 // Data that won't be sent to the API server 2484 2485 current_wait_time: localStorage.getItem('wait_time_val'), 2486 2487 current_queue_length: $('input#booking_current_queue_length').val(), 2488 }; 2489 2490 $.ajax({ 2491 url: bookingFormVars.ajax_url, 2492 2493 type: 'POST', 2494 2495 data: { 2496 action: 'handle_booking_form', 2497 2498 payload: JSON.stringify(data), 2499 }, 2500 2501 success: function (response) { 2502 if (response.success) { 2503 $('#bk-overlay').hide(); 2504 2505 if (response.data && response.data.error) { 2506 let errorMsg = response.data.error; 2507 swal('Please update your information', errorMsg, 'error'); 2508 2509 return; 2510 } else if (response.data && response.data.id) { 2511 let url = new URL(window.location.href); 2512 2513 url.search = ''; 2514 url.searchParams.set('confirmed', 'true'); 2515 window.history.pushState({}, '', url); 2516 let queue_length = ''; 2517 2518 if (isHartwellView) { 2519 async function getQueueLength() { 2520 try { 2521 queue_length = await fetchWaitTime(); 2522 2523 afterBooking(response.data); 2524 } catch (error) { 2525 console.error('Error fetching data:', error); 2526 } 2527 } 2528 2529 async function fetchWaitTime() { 2530 return new Promise((resolve, reject) => { 2531 // Getting Queue Length with AJAX 2532 2533 $.ajax({ 2534 url: bookingFormVars.ajax_url, 2535 2536 type: 'POST', 2537 2538 data: { 2539 action: 'fetch_wait_time', 2540 }, 2541 2542 success: function (response) { 2543 if (response.error) { 2544 reject(response.error); 2545 } else { 2546 resolve(response.data.wait_time); 2547 } 2548 }, 2549 2550 error: function (xhr, status, error) { 2551 reject(error); 2552 }, 2553 }); 2554 }); 2555 } 2556 2557 getQueueLength(); 2558 } else { 2559 afterBooking(response.data); 2560 } 2561 } 2562 } else { 2563 console.log('Error:', response.message); 2564 2565 $('#result-container').html('<div class="error">' + response.message + '</div>'); 2566 } 2567 console.log(response); 2568 }, 2569 2570 error: function (xhr, status, error) { 2571 console.log('AJAX Error:', error); 2572 2573 $('#result-container').html('<div class="error">Request failed: ' + error + '</div>'); 2574 }, 2575 }); 2576 } 2577 } 2578 2579 function afterBooking(data) { 2580 swal( 2581 'Congratulations!', 2582 2583 'You have successfully reserved your spot in line.', 2584 2585 'success' 2586 ); 2587 2588 var baseUrl = bookingFormVars.base_url; 2589 2590 var current_wait_time = $('#booking_current_wait_time').val(); 2591 2592 var current_queue_length = $('#booking_current_queue_length').val(); 2593 2594 var nonce = bookingFormVars.apt_form_nonce; 2595 2596 const dataToSubmit = { 2597 clinic_id: data.hospital_id, 2598 2599 appointmentId: data.id, 2600 2601 confirmation_code: data.confirmation_code, 2602 2603 first_name: data.first_name, 2604 2605 last_name: data.last_name, 2606 2607 patient_phone: data.phone_number, 2608 2609 patient_email: data.email, 2610 2611 reason_type: data.reason_description, 2612 2613 apt_time: isHartwellView ? $('#hartwell_time').val() : $('#apt_time').val(), 2614 2615 current_wait_time: current_wait_time, 2616 2617 current_queue_length: current_queue_length, 2618 2619 _wpnonce: nonce, 2620 }; 2621 2622 const form = $('<form>', { 2623 method: 'POST', 2624 2625 action: `${baseUrl}/appointment-confirmation/`, 2626 }); 2627 2628 $.each(dataToSubmit, function (key, value) { 2629 form.append( 2630 $('<input>', { 2631 type: 'hidden', 2632 2633 name: key, 2634 2635 value: value, 2636 }) 2637 ); 2638 }); 2639 2640 let confirmationSubmitted = false;
2641 function submitConfirmationForm() { 2642 if (confirmationSubmitted) { 2643 return; 2644 } 2645 confirmationSubmitted = true; 2646 form.appendTo('body').submit(); 2647 } 2648 2649 // Trigger event on GTM Starts 2650 2651 /** 2652 * Calculate wait time in minutes 2653 */ 2654 function calculateWaitTimeDiff(nextAvailableTime) { 2655 const currentTime = new Date(); 2656 const nextAvailableDate = new Date(nextAvailableTime); 2657 const timeDifferenceMs = nextAvailableDate - currentTime; 2658 return Math.floor(timeDifferenceMs / (1000 * 60)); 2659 } 2660 /** 2661 * Build GA4 event data 2662 */ 2663 function buildEventData(clinicId, queueLength, waitTime, waitTimeDiff) { 2664 let waitTimeMinutes = null; 2665 let waitTimeStatus = null; 2666 let waitTimeDiffMinutes = null; 2667 let waitTimeDiffStatus = null; 2668 let queueLengthValue = null; 2669 let queueLengthStatus = null; 2670 2671 if (typeof waitTime === 'number' && Number.isFinite(waitTime)) { 2672 waitTimeMinutes = waitTime; 2673 } else if (typeof waitTime === 'string') { 2674 waitTimeStatus = waitTime; 2675 } 2676 if (typeof waitTimeDiff === 'number' && Number.isFinite(waitTimeDiff)) { 2677 waitTimeDiffMinutes = waitTimeDiff; 2678 } else if (typeof waitTimeDiff === 'string') { 2679 waitTimeDiffStatus = waitTimeDiff; 2680 } 2681 2682 if (typeof queueLength === 'number' && Number.isFinite(queueLength)) { 2683 queueLengthValue = queueLength; 2684 } else if (typeof queueLength === 'string') { 2685 queueLengthStatus = queueLength; 2686 } 2687 2688 const visitNow = new Date(); 2689 const eventTimeNyc = new Intl.DateTimeFormat('en-CA', { 2690 timeZone: 'America/New_York', 2691 year: 'numeric', 2692 month: '2-digit', 2693 day: '2-digit', 2694 hour: '2-digit', 2695 minute: '2-digit', 2696 second: '2-digit', 2697 hour12: false, 2698 }) 2699 .format(visitNow) 2700 .replace(', ', ' '); 2701 2702 const eventTimeUtcMs = Date.now(); 2703 const visitId = 2704 crypto?.randomUUID?.() || `${eventTimeUtcMs}-${Math.random().toString(16).slice(2)}`; 2705 2706 return { 2707 event: 'appointment_form_submitted', 2708 clinic_id: String(clinicId ?? ''), 2709 queue_length: queueLengthValue, 2710 queue_length_status: queueLengthStatus, 2711 appointment_id: data.id, 2712 wait_time_minutes: waitTimeMinutes, 2713 wait_time_status: waitTimeStatus, 2714 wait_time_diff: waitTimeDiffMinutes, 2715 wait_time_diff_status: waitTimeDiffStatus, 2716 event_time_nyc: eventTimeNyc, 2717 event_time_utc_ms: eventTimeUtcMs, 2718 }; 2719 } 2720 2721 function sendGA4Data(onComplete) { 2722 const waitTimeElement = document.getElementById('booking_current_wait_time'); 2723 const queueLengthElement = document.getElementById('booking_current_queue_length'); 2724 const clinicIdElement = document.getElementById('current_clinic_id'); 2725 2726 if (!clinicIdElement) { 2727 console.warn('Clinic ID element not found'); 2728 if (typeof onComplete === 'function') { 2729 onComplete(); 2730 } 2731 return; 2732 } 2733 2734 const clinicId = clinicIdElement.value; 2735 const firstTimeSlot = $('.available-slots li.get-apt-time').first().attr('data-value'); 2736 let waitTime; 2737 let waitTimeDiff; 2738 2739 if (firstTimeSlot) { 2740 const timeDifferenceMinutes = calculateWaitTimeDiff(firstTimeSlot); 2741 waitTimeDiff = timeDifferenceMinutes; 2742 } else { 2743 waitTimeDiff = 'No available slots'; 2744 } 2745 2746 if ( 2747 queueLengthElement && 2748 waitTimeElement && 2749 queueLengthElement.value !== 'Closed' && 2750 queueLengthElement.value !== '' && 2751 waitTimeElement.value !== '' 2752 ) { 2753 waitTime = Number(waitTimeElement.value); 2754 } else { 2755 waitTime = 2756 queueLengthElement && queueLengthElement.value === 'Closed' ? 'Closed' : 'Unknown'; 2757 } 2758 2759 const queueLength = 2760 queueLengthElement && 2761 queueLengthElement.value !== 'Closed' && 2762 queueLengthElement.value !== '' 2763 ? parseInt(queueLengthElement.value, 10) 2764 : queueLengthElement && queueLengthElement.value === 'Closed' 2765 ? 'Closed' 2766 : 'Unknown'; 2767 2768 const eventData = buildEventData(clinicId, queueLength, waitTime, waitTimeDiff); 2769 pushToDataLayer(eventData, onComplete); 2770 } 2771 2772 function pushToDataLayer(eventData, onComplete) { 2773 window.dataLayer = window.dataLayer || []; 2774 2775 if (typeof onComplete === 'function') { 2776 let callbackDone = false;
2777 const finish = function () { 2778 if (callbackDone) return; 2779 callbackDone = true; 2780 onComplete(); 2781 }; 2782 2783 window.dataLayer.push({ 2784 ...eventData, 2785 eventCallback: finish, 2786 eventTimeout: 1500, 2787 }); 2788 2789 // Fallback in case GTM/GA4 callback doesn't run. 2790 setTimeout(finish, 1600); 2791 return; 2792 } 2793 2794 window.dataLayer.push(eventData); 2795 } 2796 2797 // Trigger event on GTM Ends 2798 2799 sendGA4Data(submitConfirmationForm); 2800 } 2801 }); 2802 2803 // Click to to expand more slots 2804 2805 $(document).on('click', '.edit_schedule', function () { 2806 $(this).parent('.clinic-info').hide(); 2807 2808 $('#edit-slot-block').show(); 2809 2810 $('.get-apt-time').each(function () { 2811 if ($(this).data('value') === aptTimeVal) { 2812 $(this).addClass('active-slot'); 2813 } 2814 }); 2815 }); 2816}); 2817;(function () { 2818 "use strict"; 2819 2820 const STAR_PATH = 2821 "M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"; 2822 2823 function starSVG(type) { 2824 if (type === "half") { 2825 return `<svg class="cra-star cra-star--half" viewBox="0 0 20 20" aria-hidden="true"> 2826 <defs><linearGradient id="cra-hg"><stop offset="50%" stop-color="#F59E0B"/><stop offset="50%" stop-color="#D1D5DB"/></linearGradient></defs> 2827 <path fill="url(#cra-hg)" d="${STAR_PATH}"/> 2828 </svg>`; 2829 } 2830 2831 const fill = type === "full" ? "#F59E0B" : "#D1D5DB"; 2832 2833 return `<svg class="cra-star cra-star--${type}" viewBox="0 0 20 20" aria-hidden="true"><path fill="${fill}" d="${STAR_PATH}"/></svg>`; 2834 } 2835 2836 function buildStarRow(avg) { 2837 const full = Math.floor(avg); 2838 const half = avg - full >= 0.5 ? 1 : 0; 2839 const empty = 5 - full - half; 2840 let html = ""; 2841 2842 for (let i = 0; i < full; i++) { 2843 html += starSVG("full"); 2844 } 2845 2846 if (half) { 2847 html += starSVG("half"); 2848 } 2849 2850 for (let j = 0; j < empty; j++) { 2851 html += starSVG("empty"); 2852 } 2853 2854 return html; 2855 } 2856 2857 function queryAll(selector, root) { 2858 try { 2859 return Array.prototype.slice.call( 2860 (root || document).querySelectorAll(selector), 2861 ); 2862 } catch (e) { 2863 return []; 2864 } 2865 } 2866 2867 function matchElToClinic(el) { 2868 const ratings = window.CLINICS_RR_MAP_RATINGS || {}; 2869 const cls = typeof el.className === "string" ? el.className : ""; 2870 const elId = el.id || ""; 2871 const digitsKeys = Object.keys(ratings); 2872 2873 for (let i = 0; i < digitsKeys.length; i++) { 2874 const dk = digitsKeys[i]; 2875 const info = ratings[dk]; 2876 const phoneKeys = info.keys ? info.keys.slice() : [dk]; 2877 2878 if (phoneKeys.indexOf(dk) === -1) { 2879 phoneKeys.push(dk); 2880 } 2881 2882 for (let k = 0; k < phoneKeys.length; k++) { 2883 const pk = phoneKeys[k]; 2884 2885 if (!pk) { 2886 continue; 2887 } 2888 2889 if (cls.indexOf(pk) !== -1 || elId.indexOf(pk) !== -1) { 2890 return info; 2891 } 2892 } 2893 } 2894 return null; 2895 } 2896 2897 function renderRating(el, info) { 2898 if (!el) { 2899 return; 2900 } 2901 2902 queryAll( 2903 ".clinic-avg-rvw__loading, .map-data_loader, .avg-review-rating, .cra-map-rating", 2904 el, 2905 ).forEach(function (s) { 2906 if (s.parentNode) { 2907 s.parentNode.removeChild(s); 2908 } 2909 }); 2910 2911 el.innerHTML = `<div class="cra-map-rating"> 2912 <span class="cra-map-rating__avg">${info.avg.toFixed(1)}</span> 2913 <span class="cra-map-rating__stars">${buildStarRow(info.avg)}</span> 2914 <span class="cra-map-rating__count">(${info.total})</span> 2915 </div>`; 2916 } 2917 2918 function tryInjectFromNode(node) { 2919 if (typeof window.CLINICS_RR_MAP_RATINGS === "undefined") { 2920 return false; 2921 } 2922 2923 if (!node || node.nodeType !== 1) { 2924 return false; 2925 } 2926 2927 let el = node; 2928 for (let depth = 0; depth < 8; depth++) { 2929 if (!el) { 2930 break; 2931 } 2932 2933 const info = matchElToClinic(el); 2934 2935 if (info) { 2936 renderRating(el, info); 2937 return true; 2938 } 2939 el = el.parentElement; 2940 } 2941 2942 return false;
2943 } 2944 2945 function scanAndInjectAll() { 2946 if (typeof window.CLINICS_RR_MAP_RATINGS === "undefined") { 2947 return; 2948 } 2949 2950 const ratings = window.CLINICS_RR_MAP_RATINGS; 2951 2952 queryAll(".clinic-avg-rvw__loading, .map-data_loader").forEach(function (el) { 2953 const matched = tryInjectFromNode(el); 2954 2955 // fallback message for clinics with no review data 2956 if (!matched) { 2957 const wrapper = el.closest(".review-home-wrapper"); 2958 if (wrapper) { 2959 wrapper.style.display = "none"; 2960 } 2961 } 2962 }); 2963 2964 Object.keys(ratings).forEach(function (dk) { 2965 const info = ratings[dk]; 2966 const phoneKeys = info.keys ? info.keys.slice() : [dk]; 2967 2968 if (phoneKeys.indexOf(dk) === -1) { 2969 phoneKeys.push(dk); 2970 } 2971 2972 phoneKeys.forEach(function (pk) { 2973 if (!pk) { 2974 return; 2975 } 2976 2977 queryAll(`[class*="${pk}"]`).forEach(function (el) { 2978 renderRating(el, info); 2979 }); 2980 }); 2981 }); 2982 } 2983 2984 function startMapObserver() { 2985 if (typeof window.CLINICS_RR_MAP_RATINGS === "undefined") { 2986 return; 2987 } 2988 2989 if (!window.MutationObserver) { 2990 return; 2991 } 2992 2993 const observer = new MutationObserver(function (mutations) { 2994 mutations.forEach(function (mut) { 2995 mut.addedNodes.forEach(function (node) { 2996 if (node.nodeType !== 1) { 2997 return; 2998 } 2999 3000 const cls = typeof node.className === "string" ? node.className : ""; 3001 const nid = node.id || ""; 3002 3003 if ( 3004 cls.indexOf("clinic-avg-rvw__loading") !== -1 || 3005 cls.indexOf("map-data_loader") !== -1 || 3006 nid === "avg-review" 3007 ) { 3008 const matched = tryInjectFromNode(node); 3009 3010 if (!matched) { 3011 const wrapper = node.closest(".review-home-wrapper"); 3012 if (wrapper) { 3013 wrapper.style.display = "none"; 3014 } 3015 } 3016 return; 3017 } 3018 3019 if (node.querySelectorAll) { 3020 const inner = node.querySelectorAll( 3021 '.clinic-avg-rvw__loading, .map-data_loader, [id="avg-review"]', 3022 ); 3023 if (inner.length) { 3024 Array.prototype.forEach.call(inner, function (innerNode) { 3025 const matched = tryInjectFromNode(innerNode); 3026 3027 if (!matched) { 3028 const wrapper = innerNode.closest(".review-home-wrapper"); 3029 if (wrapper) { 3030 wrapper.style.display = "none"; 3031 } 3032 } 3033 }); 3034 } 3035 } 3036 3037 if (matchElToClinic(node)) { 3038 tryInjectFromNode(node); 3039 } 3040 }); 3041 }); 3042 }); 3043 3044 observer.observe(document.body || document.documentElement, { 3045 childList: true, 3046 subtree: true, 3047 }); 3048 } 3049 3050 document.addEventListener("click", function (e) { 3051 const btn = e.target.closest ? e.target.closest(".cra-read-more") : null; 3052 3053 if (!btn) { 3054 return; 3055 } 3056 3057 const p = btn.closest("p"); 3058 const open = btn.getAttribute("aria-expanded") === "true"; 3059 const s = p ? p.querySelector(".cra-text-short") : null; 3060 const f = p ? p.querySelector(".cra-text-full") : null; 3061 3062 if (s) { 3063 s.hidden = !open; 3064 } 3065 3066 if (f) { 3067 f.hidden = open; 3068 } 3069 3070 btn.setAttribute("aria-expanded", String(!open)); 3071 btn.textContent = open ? "Read more" : "Read less"; 3072 }); 3073 3074 function fetchPageData(cfg, onSuccess, onError) { 3075 const body = new URLSearchParams(); 3076 body.append("action", cfg.action); 3077 body.append("nonce", cfg.nonce); 3078 3079 fetch(cfg.ajaxUrl, { 3080 method: "POST", 3081 credentials: "same-origin", 3082 headers: { 3083 "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", 3084 }, 3085 body: body.toString(), 3086 }) 3087 .then(function (res) { 3088 return res.json(); 3089 }) 3090 .then(function (json) { 3091 if (json && json.success && json.data) { 3092 onSuccess(json.data); 3093 } else { 3094 onError(new Error("CLINICS_RR: AJAX response error")); 3095 } 3096 }) 3097 .catch(onError); 3098 } 3099 3100 function boot() { 3101 const ajaxCfg = window.CLINICS_RR_AJAX_MODE; 3102 3103 if (!ajaxCfg) { 3104 startMapObserver(); 3105 scanAndInjectAll(); 3106 return; 3107 } 3108 3109 fetchPageData( 3110 ajaxCfg, 3111 function (data) { 3112 window.CLINICS_RR_MAP_RATINGS = data.mapRatings || {}; 3113 3114 startMapObserver(); 3115 scanAndInjectAll(); 3116 3117 const ids = ajaxCfg.carouselIds || []; 3118 const carouselReviews = 3119 data.carousel && data.carousel.length ? data.carousel : []; 3120 3121 if (ids.length) { 3122 window.CLINICS_RR_CAROUSEL = ids.map(function (id) { 3123 return { carouselId: id, reviews: carouselReviews }; 3124 }); 3125 } 3126 3127 window.dispatchEvent(new CustomEvent("clinics_rr_data_ready")); 3128 }, 3129 function () { 3130 queryAll(".clinic-avg-rvw__loading, .map-data_loader").forEach( 3131 function (el) { 3132 const wrapper = el.closest(".review-home-wrapper"); 3133 if (wrapper) { 3134 wrapper.style.display = "none"; 3135 } 3136 else { 3137 el.style.display = "none"; 3138 } 3139 }, 3140 ); 3141 window.dispatchEvent(new CustomEvent("clinics_rr_data_ready")); 3142 }, 3143 ); 3144 } 3145 3146 if (document.readyState === "loading") { 3147 document.addEventListener("DOMContentLoaded", boot); 3148 } else {
vendor: 19,127 bytes, lines 3149-3267
3149 boot(); 3150 } 3151})(); 3152;/*! jQuery UI - v1.13.3 - 2024-04-26 3153* https://jqueryui.com 3154* Includes: widget.js, position.js, data.js, disable-selection.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js, focusable.js, form-reset-mixin.js, jquery-patch.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/draggable.js, widgets/droppable.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/resizable.js, widgets/selectable.js, widgets/selectmenu.js, widgets/slider.js, widgets/sortable.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js 3155* Copyright jQuery Foundation and other contributors; Licensed MIT */ 3156!function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)}(function(x){"use strict";var t,e,i,n,W,C,o,s,r,l,a,h,u;function E(t,e,i){return[parseFloat(t[0])*(a.test(t[0])?e/100:1),parseFloat(t[1])*(a.test(t[1])?i/100:1)]}function L(t,e){return parseInt(x.css(t,e),10)||0}function N(t){return null!=t&&t===t.window}x.ui=x.ui||{},x.ui.version="1.13.3", 3157/*! 3158 * jQuery UI :data 1.13.3 3159 * https://jqueryui.com 3160 * 3161 * Copyright OpenJS Foundation and other contributors 3162 * Released under the MIT license. 3163 * https://jquery.org/license 3164 */ 3165x.extend(x.expr.pseudos,{data:x.expr.createPseudo?x.expr.createPseudo(function(e){return function(t){return!!x.data(t,e)}}):function(t,e,i){return!!x.data(t,i[3])}}), 3166/*! 3167 * jQuery UI Disable Selection 1.13.3 3168 * https://jqueryui.com 3169 * 3170 * Copyright OpenJS Foundation and other contributors 3171 * Released under the MIT license. 3172 * https://jquery.org/license 3173 */ 3174x.fn.extend({disableSelection:(t="onselectstart"in document.createElement("div")?"selectstart":"mousedown",function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}),enableSelection:function(){return this.off(".ui-disableSelection")}}), 3175/*! 3176 * jQuery UI Focusable 1.13.3 3177 * https://jqueryui.com 3178 * 3179 * Copyright OpenJS Foundation and other contributors 3180 * Released under the MIT license. 3181 * https://jquery.org/license 3182 */ 3183x.ui.focusable=function(t,e){var i,n,o,s=t.nodeName.toLowerCase();return"area"===s?(o=(i=t.parentNode).name,!(!t.href||!o||"map"!==i.nodeName.toLowerCase())&&0<(i=x("img[usemap='#"+o+"']")).length&&i.is(":visible")):(/^(input|select|textarea|button|object)$/.test(s)?(n=!t.disabled)&&(o=x(t).closest("fieldset")[0])&&(n=!o.disabled):n="a"===s&&t.href||e,n&&x(t).is(":visible")&&function(t){var e=t.css("visibility");for(;"inherit"===e;)t=t.parent(),e=t.css("visibility");return"visible"===e}(x(t)))},x.extend(x.expr.pseudos,{focusable:function(t){return x.ui.focusable(t,null!=x.attr(t,"tabindex"))}}),x.fn._form=function(){return"string"==typeof this[0].form?this.closest("form"):x(this[0].form)}, 3184/*! 3185 * jQuery UI Form Reset Mixin 1.13.3 3186 * https://jqueryui.com 3187 * 3188 * Copyright OpenJS Foundation and other contributors 3189 * Released under the MIT license. 3190 * https://jquery.org/license 3191 */ 3192x.ui.formResetMixin={_formResetHandler:function(){var e=x(this);setTimeout(function(){var t=e.data("ui-form-reset-instances");x.each(t,function(){this.refresh()})})},_bindFormResetHandler:function(){var t;this.form=this.element._form(),this.form.length&&((t=this.form.data("ui-form-reset-instances")||[]).length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t))},_unbindFormResetHandler:function(){var t;this.form.length&&((t=this.form.data("ui-form-reset-instances")).splice(x.inArray(this,t),1),t.length?this.form.data("ui-form-reset-instances",t):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset"))}},x.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()), 3193/*! 3194 * jQuery UI Support for jQuery core 1.8.x and newer 1.13.3 3195 * https://jqueryui.com 3196 * 3197 * Copyright OpenJS Foundation and other contributors 3198 * Released under the MIT license. 3199 * https://jquery.org/license 3200 * 3201 */ 3202x.expr.pseudos||(x.expr.pseudos=x.expr[":"]),x.uniqueSort||(x.uniqueSort=x.unique),x.escapeSelector||(e=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g,i=function(t,e){return e?"\0"===t?"�":t.slice(0,-1)+"\\"+t.charCodeAt(t.length-1).toString(16)+" ":"\\"+t},x.escapeSelector=function(t){return(t+"").replace(e,i)}),x.fn.even&&x.fn.odd||x.fn.extend({even:function(){return this.filter(function(t){return t%2==0})},odd:function(){return this.filter(function(t){return t%2==1})}}), 3203/*! 3204 * jQuery UI Keycode 1.13.3 3205 * https://jqueryui.com 3206 * 3207 * Copyright OpenJS Foundation and other contributors 3208 * Released under the MIT license. 3209 * https://jquery.org/license 3210 */ 3211x.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}, 3212/*! 3213 * jQuery UI Labels 1.13.3 3214 * https://jqueryui.com 3215 * 3216 * Copyright OpenJS Foundation and other contributors 3217 * Released under the MIT license. 3218 * https://jquery.org/license 3219 */ 3220x.fn.labels=function(){var t,e,i;return this.length?this[0].labels&&this[0].labels.length?this.pushStack(this[0].labels):(e=this.eq(0).parents("label"),(t=this.attr("id"))&&(i=(i=this.eq(0).parents().last()).add((i.length?i:this).siblings()),t="label[for='"+x.escapeSelector(t)+"']",e=e.add(i.find(t).addBack(t))),this.pushStack(e)):this.pushStack([])},x.ui.plugin={add:function(t,e,i){var n,o=x.ui[t].prototype;for(n in i)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([e,i[n]])},call:function(t,e,i,n){var o,s=t.plugins[e];if(s&&(n||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(o=0;o<s.length;o++)t.options[s[o][0]]&&s[o][1].apply(t.element,i)}}, 3221/*! 3222 * jQuery UI Position 1.13.3 3223 * https://jqueryui.com 3224 * 3225 * Copyright OpenJS Foundation and other contributors 3226 * Released under the MIT license. 3227 * https://jquery.org/license 3228 * 3229 * https://api.jqueryui.com/position/ 3230 */ 3231W=Math.max,C=Math.abs,o=/left|center|right/,s=/top|center|bottom/,r=/[\+\-]\d+(\.[\d]+)?%?/,l=/^\w+/,a=/%$/,h=x.fn.position,x.position={scrollbarWidth:function(){var t,e,i;return void 0!==n?n:(i=(e=x("<div style='display:block;position:absolute;width:200px;height:200px;overflow:hidden;'><div style='height:300px;width:auto;'></div></div>")).children()[0],x("body").append(e),t=i.offsetWidth,e.css("overflow","scroll"),t===(i=i.offsetWidth)&&(i=e[0].clientWidth),e.remove(),n=t-i)},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),e="scroll"===e||"auto"===e&&t.width<t.element[0].scrollWidth;return{width:"scroll"===i||"auto"===i&&t.height<t.element[0].scrollHeight?x.position.scrollbarWidth():0,height:e?x.position.scrollbarWidth():0}},getWithinInfo:function(t){var e=x(t||window),i=N(e[0]),n=!!e[0]&&9===e[0].nodeType;return{element:e,isWindow:i,isDocument:n,offset:!i&&!n?x(t).offset():{left:0,top:0},scrollLeft:e.scrollLeft(),scrollTop:e.scrollTop(),width:e.outerWidth(),height:e.outerHeight()}}},x.fn.position=function(f){var c,d,p,g,m,v,y,w,b,_,t,e;return f&&f.of?(v="string"==typeof(f=x.extend({},f)).of?x(document).find(f.of):x(f.of),y=x.position.getWithinInfo(f.within),w=x.position.getScrollInfo(y),b=(f.collision||"flip").split(" "),_={},e=9===(e=(t=v)[0]).nodeType?{width:t.width(),height:t.height(),offset:{top:0,left:0}}:N(e)?{width:t.width(),height:t.height(),offset:{top:t.scrollTop(),left:t.scrollLeft()}}:e.preventDefault?{width:0,height:0,offset:{top:e.pageY,left:e.pageX}}:{width:t.outerWidth(),height:t.outerHeight(),offset:t.offset()},v[0].preventDefault&&(f.at="left top"),d=e.width,p=e.height,m=x.extend({},g=e.offset),x.each(["my","at"],function(){var t,e,i=(f[this]||"").split(" ");(i=1===i.length?o.test(i[0])?i.concat(["center"]):s.test(i[0])?["center"].concat(i):["center","center"]:i)[0]=o.test(i[0])?i[0]:"center",i[1]=s.test(i[1])?i[1]:"center",t=r.exec(i[0]),e=r.exec(i[1]),_[this]=[t?t[0]:0,e?e[0]:0],f[this]=[l.exec(i[0])[0],l.exec(i[1])[0]]}),1===b.length&&(b[1]=b[0]),"right"===f.at[0]?m.left+=d:"center"===f.at[0]&&(m.left+=d/2),"bottom"===f.at[1]?m.top+=p:"center"===f.at[1]&&(m.top+=p/2),c=E(_.at,d,p),m.left+=c[0],m.top+=c[1],this.each(function(){var i,t,r=x(this),l=r.outerWidth(),a=r.outerHeight(),e=L(this,"marginLeft"),n=L(this,"marginTop"),o=l+e+L(this,"marginRight")+w.width,s=a+n+L(this,"marginBottom")+w.height,h=x.extend({},m),u=E(_.my,r.outerWidth(),r.outerHeight());"right"===f.my[0]?h.left-=l:"center"===f.my[0]&&(h.left-=l/2),"bottom"===f.my[1]?h.top-=a:"center"===f.my[1]&&(h.top-=a/2),h.left+=u[0],h.top+=u[1],i={marginLeft:e,marginTop:n},x.each(["left","top"],function(t,e){x.ui.position[b[t]]&&x.ui.position[b[t]][e](h,{targetWidth:d,targetHeight:p,elemWidth:l,elemHeight:a,collisionPosition:i,collisionWidth:o,collisionHeight:s,offset:[c[0]+u[0],c[1]+u[1]],my:f.my,at:f.at,within:y,elem:r})}),f.using&&(t=function(t){var e=g.left-h.left,i=e+d-l,n=g.top-h.top,o=n+p-a,s={target:{element:v,left:g.left,top:g.top,width:d,height:p},element:{element:r,left:h.left,top:h.top,width:l,height:a},horizontal:i<0?"left":0<e?"right":"center",vertical:o<0?"top":0<n?"bottom":"middle"};d<l&&C(e+i)<d&&(s.horizontal="center"),p<a&&C(n+o)<p&&(s.vertical="middle"),W(C(e),C(i))>W(C(n),C(o))?s.important="horizontal":s.important="vertical",f.using.call(this,t,s)}),r.offset(x.extend(h,{using:t}))})):h.apply(this,arguments)},x.ui.position={fit:{left:function(t,e){var i,n=e.within,o=n.isWindow?n.scrollLeft:n.offset.left,n=n.width,s=t.left-e.collisionPosition.marginLeft,r=o-s,l=s+e.collisionWidth-n-o;n<e.collisionWidth?0<r&&l<=0?(i=t.left+r+e.collisionWidth-n-o,t.left+=r-i):t.left=!(0<l&&r<=0)&&l<r?o+n-e.collisionWidth:o:0<r?t.left+=r:0<l?t.left-=l:t.left=W(t.left-s,t.left)},top:function(t,e){var i,n=e.within,n=n.isWindow?n.scrollTop:n.offset.top,o=e.within.height,s=t.top-e.collisionPosition.marginTop,r=n-s,l=s+e.collisionHeight-o-n;o<e.collisionHeight?0<r&&l<=0?(i=t.top+r+e.collisionHeight-o-n,t.top+=r-i):t.top=!(0<l&&r<=0)&&l<r?n+o-e.collisionHeight:n:0<r?t.top+=r:0<l?t.top-=l:t.top=W(t.top-s,t.top)}},flip:{left:function(t,e){var i=e.within,n=i.offset.left+i.scrollLeft,o=i.width,i=i.isWindow?i.scrollLeft:i.offset.left,s=t.left-e.collisionPosition.marginLeft,r=s-i,s=s+e.collisionWidth-o-i,l="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,a="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,h=-2*e.offset[0];r<0?((o=t.left+l+a+h+e.collisionWidth-o-n)<0||o<C(r))&&(t.left+=l+a+h):0<s&&(0<(n=t.left-e.collisionPosition.marginLeft+l+a+h-i)||C(n)<s)&&(t.left+=l+a+h)},top:function(t,e){var i=e.within,n=i.offset.top+i.scrollTop,o=i.height,i=i.isWindow?i.scrollTop:i.offset.top,s=t.top-e.collisionPosition.marginTop,r=s-i,s=s+e.collisionHeight-o-i,l="top"===e.my[1]?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,a="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,h=-2*e.offset[1];r<0?((o=t.top+l+a+h+e.collisionHeight-o-n)<0||o<C(r))&&(t.top+=l+a+h):0<s&&(0<(n=t.top-e.collisionPosition.marginTop+l+a+h-i)||C(n)<s)&&(t.top+=l+a+h)}},flipfit:{left:function(){x.ui.position.flip.left.apply(this,arguments),x.ui.position.fit.left.apply(this,arguments)},top:function(){x.ui.position.flip.top.apply(this,arguments),x.ui.position.fit.top.apply(this,arguments)}}},x.ui.safeActiveElement=function(e){var i;try{i=e.activeElement}catch(t){i=e.body}return i=(i=i||e.body).nodeName?i:e.body},x.ui.safeBlur=function(t){t&&"body"!==t.nodeName.toLowerCase()&&x(t).trigger("blur")}, 3232/*! 3233 * jQuery UI Scroll Parent 1.13.3 3234 * https://jqueryui.com 3235 * 3236 * Copyright OpenJS Foundation and other contributors 3237 * Released under the MIT license. 3238 * https://jquery.org/license 3239 */ 3240x.fn.scrollParent=function(t){var e=this.css("position"),i="absolute"===e,n=t?/(auto|scroll|hidden)/:/(auto|scroll)/,t=this.parents().filter(function(){var t=x(this);return(!i||"static"!==t.css("position"))&&n.test(t.css("overflow")+t.css("overflow-y")+t.css("overflow-x"))}).eq(0);return"fixed"!==e&&t.length?t:x(this[0].ownerDocument||document)}, 3241/*! 3242 * jQuery UI Tabbable 1.13.3 3243 * https://jqueryui.com 3244 * 3245 * Copyright OpenJS Foundation and other contributors 3246 * Released under the MIT license. 3247 * https://jquery.org/license 3248 */ 3249x.extend(x.expr.pseudos,{tabbable:function(t){var e=x.attr(t,"tabindex"),i=null!=e;return(!i||0<=e)&&x.ui.focusable(t,i)}}), 3250/*! 3251 * jQuery UI Unique ID 1.13.3 3252 * https://jqueryui.com 3253 * 3254 * Copyright OpenJS Foundation and other contributors 3255 * Released under the MIT license. 3256 * https://jquery.org/license 3257 */ 3258x.fn.extend({uniqueId:(u=0,function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++u)})}),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&x(this).removeAttr("id")})}}); 3259/*! 3260 * jQuery UI Widget 1.13.3 3261 * https://jqueryui.com 3262 * 3263 * Copyright OpenJS Foundation and other contributors 3264 * Released under the MIT license. 3265 * https://jquery.org/license 3266 */ 3267var f,c=0,d=Array.prototype.hasOwnProperty,p=Array.prototype.slice;x.cleanData=(f=x.cleanData,function(t){for(var e,i,n=0;null!=(i=t[n]);n++)(e=x._data(i,"events"))&&e.remove&&x(i).triggerHandler("remove");f(t)}),x.widget=function(t,i,e){var n,o,s,r={},l=t.split(".")[0],a=l+"-"+(t=t.split(".")[1]);return e||(e=i,i=x.Widget),Array.isArray(e)&&(e=x.extend.apply(null,[{}].concat(e))),x.expr.pseudos[a.toLowerCase()]=function(t){return!!x.data(t,a)},x[l]=x[l]||{},n=x[l][t],o=x[l][t]=function(t,e){if(!this||!this._createWidget)return new o(t,e);arguments.length&&this._createWidget(t,e)},x.extend(o,n,{version:e.version,_proto:x.extend({},e),_childConstructors:[]}),(s=new i).options=x.widget.extend({},s.options),x.each(e,function(e,n){function o(){return i.prototype[e].apply(this,arguments)}function s(t){return i.prototype[e].apply(this,t)}r[e]="function"!=typeof n?n:function(){var t,e=this._super,i=this._superApply;return this._super=o,this._superApply=s,t=n.apply(this,arguments),this._super=e,this._superApply=i,t}}),o.prototype=x.widget.extend(s,{widgetEventPrefix:n&&s.widgetEventPrefix||t},r,{constructor:o,namespace:l,widgetName:t,widgetFullName:a}),n?(x.each(n._childConstructors,function(t,e){var i=e.prototype;x.widget(i.namespace+"."+i.widgetName,o,e._proto)}),delete n._childConstructors):i._childConstructors.push(o),x.widget.bridge(t,o),o},x.widget.extend=function(t){for(var e,i,n=p.call(arguments,1),o=0,s=n.length;o<s;o++)for(e in n[o])i=n[o][e],d.call(n[o],e)&&void 0!==i&&(x.isPlainObject(i)?t[e]=x.isPlainObject(t[e])?x.widget.extend({},t[e],i):x.widget.extend({},i):t[e]=i);return t},x.widget.bridge=function(s,e){var r=e.prototype.widgetFullName||s;x.fn[s]=function(i){var t="string"==typeof i,n=p.call(arguments,1),o=this;return t?this.length||"instance"!==i?this.each(function(){var t,e=x.data(this,r);return"instance"===i?(o=e,!1):e?"function"!=typeof e[i]||"_"===i.charAt(0)?x.error("no such method '"+i+"' for "+s+" widget instance"):(t=e[i].apply(e,n))!==e&&void 0!==t?(o=t&&t.jquery?o.pushStack(t.get()):t,!1):void 0:x.error("cannot call methods on "+s+" prior to initialization; attempted to call method '"+i+"'")}):o=void 0:(n.length&&(i=x.widget.extend.apply(null,[i].concat(n))),this.each(function(){var t=x.data(this,r);t?(t.option(i||{}),t._init&&t._init()):x.data(this,r,new e(i,this))})),o}},x.Widget=function(){},x.Widget._childConstructors=[],x.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=x(e||this.defaultElement||this)[0],this.element=x(e),this.uuid=c++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=x(),this.hoverable=x(),this.focusable=x(),this.classesElementLookup={},e!==this&&(x.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=x(e.style?e.ownerDocument:e.document||e),this.window=x(this.document[0].defaultView||this.document[0].parentWindow)),this.options=x.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:x.noop,_create:x.noop,_init:x.noop,destroy:function(){var i=this;this._destroy(),x.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:x.noop,widget:function(){return this.element},option:function(t,e){var i,n,o,s=t;if(0===arguments.length)return x.widget.extend({},this.options);if("string"==typeof t)if(s={},t=(i=t.split(".")).shift(),i.length){for(n=s[t]=x.widget.extend({},this.options[t]),o=0;o<i.length-1;o++)n[i[o]]=n[i[o]]||{},n=n[i[o]];if(t=i.pop(),1===arguments.length)return void 0===n[t]?null:n[t];n[t]=e}else{if(1===arguments.length)return void 0===this.options[t]?null:this.options[t];s[t]=e}return this._setOptions(s),this},_setOptions:function(t){for(var e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(t){var e,i,n;for(e in t)n=this.classesElementLookup[e],t[e]!==this.options.classes[e]&&n&&n.length&&(i=x(n.get()),this._removeClass(n,e),i.addClass(this._classes({element:i,keys:e,classes:t,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(o){var s=[],r=this;function t(t,e){for(var i,n=0;n<t.length;n++)i=r.classesElementLookup[t[n]]||x(),i=o.add?(function(){var i=[];o.element.each(function(t,e){x.map(r.classesElementLookup,function(t){return t}).some(function(t){return t.is(e)})||i.push(e)}),r._on(x(i),{remove:"_untrackClassesElement"})}(),x(x.uniqueSort(i.get().concat(o.element.get())))):x(i.not(o.element).get()),r.classesElementLookup[t[n]]=i,s.push(t[n]),e&&o.classes[t[n]]&&s.push(o.classes[t[n]])}return(o=x.extend({element:this.element,classes:this.options.classes||{}},o)).keys&&t(o.keys.match(/\S+/g)||[],!0),o.extra&&t(o.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(i){var n=this;x.each(n.classesElementLookup,function(t,e){-1!==x.inArray(i.target,e)&&(n.classesElementLookup[t]=x(e.not(i.target).get()))}),this._off(x(i.target))},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)}
3267,_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,n){var o="string"==typeof t||null===t,e={extra:o?e:i,keys:o?t:e,element:o?this.element:t,add:n="boolean"==typeof n?n:i};return e.element.toggleClass(this._classes(e),n),this},_on:function(o,s,t){var r,l=this;"boolean"!=typeof o&&(t=s,s=o,o=!1),t?(s=r=x(s),this.bindings=this.bindings.add(s)):(t=s,s=this.element,r=this.widget()),x.each(t,function(t,e){function i(){if(o||!0!==l.options.disabled&&!x(this).hasClass("ui-state-disabled"))return("string"==typeof e?l[e]:e).apply(l,arguments)}"string"!=typeof e&&(i.guid=e.guid=e.guid||i.guid||x.guid++);var t=t.match(/^([\w:-]*)\s*(.*)$/),n=t[1]+l.eventNamespace,t=t[2];t?r.on(n,t,i):s.on(n,i)})},_off:function(t,e){e=(e||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.off(e),this.bindings=x(this.bindings.not(t).get()),this.focusable=x(this.focusable.not(t).get()),this.hoverable=x(this.hoverable.not(t).get())},_delay:function(t,e){var i=this;return setTimeout(function(){return("string"==typeof t?i[t]:t).apply(i,arguments)},e||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){this._addClass(x(t.currentTarget),null,"ui-state-hover")},mouseleave:function(t){this._removeClass(x(t.currentTarget),null,"ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){this._addClass(x(t.currentTarget),null,"ui-state-focus")},focusout:function(t){this._removeClass(x(t.currentTarget),null,"ui-state-focus")}})},_trigger:function(t,e,i){var n,o,s=this.options[t];if(i=i||{},(e=x.Event(e)).type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),e.target=this.element[0],o=e.originalEvent)for(n in o)n in e||(e[n]=o[n]);return this.element.trigger(e,i),!("function"==typeof s&&!1===s.apply(this.element[0],[e].concat(i))||e.isDefaultPrevented())}},x.each({show:"fadeIn",hide:"fadeOut"},function(s,r){x.Widget.prototype["_"+s]=function(e,t,i){var n,o=(t="string"==typeof t?{effect:t}:t)?!0!==t&&"number"!=typeof t&&t.effect||r:s;"number"==typeof(t=t||{})?t={duration:t}:!0===t&&(t={}),n=!x.isEmptyObject(t),t.complete=i,t.delay&&e.delay(t.delay),n&&x.effects&&x.effects.effect[o]?e[s](t):o!==s&&e[o]?e[o](t.duration,t.easing,i):e.queue(function(t){x(this)[s](),i&&i.call(e[0]),t()})}})}); 3268;/*! This file is auto-generated */ 3269!function(e){"use strict";"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof module&&module.exports?module.exports=e(require("jquery")):jQuery&&!jQuery.fn.hoverIntent&&e(jQuery)}(function(f){"use strict";function u(e){return"function"==typeof e}var i,r,v={interval:100,sensitivity:6,timeout:0},s=0,a=function(e){i=e.pageX,r=e.pageY},p=function(e,t,n,o){if(Math.sqrt((n.pX-i)*(n.pX-i)+(n.pY-r)*(n.pY-r))<o.sensitivity)return t.off(n.event,a),delete n.timeoutId,n.isActive=!0,e.pageX=i,e.pageY=r,delete n.pX,delete n.pY,o.over.apply(t[0],[e]);n.pX=i,n.pY=r,n.timeoutId=setTimeout(function(){p(e,t,n,o)},o.interval)};f.fn.hoverIntent=function(e,t,n){function o(e){var u=f.extend({},e),r=f(this),v=((t=r.data("hoverIntent"))||r.data("hoverIntent",t
3269={}),t[i]),t=(v||(t[i]=v={id:i}),v.timeoutId&&(v.timeoutId=clearTimeout(v.timeoutId)),v.event="mousemove.hoverIntent.hoverIntent"+i);"mouseenter"===e.type?v.isActive||(v.pX=u.pageX,v.pY=u.pageY,r.off(t,a).on(t,a),v.timeoutId=setTimeout(function(){p(u,r,v,d)},d.interval)):v.isActive&&(r.off(t,a),v.timeoutId=setTimeout(function(){var e,t,n,o,i;e=u,t=r,n=v,o=d.out,(i=t.data("hoverIntent"))&&delete i[n.id],o.apply(t[0],[e])},d.timeout))}var i=s++,d=f.extend({},v);f.isPlainObject(e)?(d=f.extend(d,e),u(d.out)||(d.out=d.over)):d=u(t)?f.extend(d,{over:e,out:t,selector:n}):f.extend(d,{over:e,out:e,selector:t});return this.on({"mouseenter.hoverIntent":o,"mouseleave.hoverIntent":o},d.selector)}}); 3270;/*! Max Mega Menu jQuery Plugin */(function(n){"use strict";let K=0;n.maxmegamenu=function(E,P){const e=this,i=n(E),m=i.parent(),b=i.siblings(".mega-menu-toggle"),w=i.attr("id"),k=".megamenu-"+(w+"-"+ ++K),_=n(["li.mega-menu-megamenu.mega-menu-item-has-children","li.mega-menu-flyout.mega-menu-item-has-children","li.mega-menu-tabbed > ul.mega-sub-menu > li.mega-menu-item-has-children","li.mega-menu-flyout li.mega-menu-item-has-children"].join(","),i),T=n("li.mega-menu-megamenu li.mega-menu-item-has-children.mega-collapse-children > a.mega-menu-link",i),S="a.mega-menu-link, button.mega-menu-link, .mega-search span[role=button]",V="Tab",z="Escape",R="Enter",B=" ",F="ArrowLeft",L="ArrowUp",W="ArrowRight",A="ArrowDown",N={event:i.attr("data-event"),effect:i.attr("data-effect"),effect_speed:parseInt(i.attr("data-effect-speed")),effect_mobile:i.attr("data-effect-mobile"),effect_speed_mobile:parseInt(i.attr("data-effect-speed-mobile")),panel_width:i.attr("data-panel-width"),panel_inner_width:i.attr("data-panel-inner-width"),mobile_force_width:i.attr("data-mobile-force-width"),mobile_overlay:i.attr("data-mobile-overlay"),mobile_state:i.attr("data-mobile-state"),mobile_direction:i.attr("data-mobile-direction"),second_click:i.attr("data-second-click"),vertical_behaviour:i.attr("data-vertical-behaviour"),document_click:i.attr("data-document-click"),breakpoint:i.attr("data-breakpoint"),unbind_events:i.attr("data-unbind"),hover_intent_timeout:i.attr("data-hover-intent-timeout")??300,hover_intent_interval:i.attr("data-hover-intent-interval")??100};e.settings={};let y;e.addAnimatingClass=function(t){if(e.settings.effect==="disabled")return;n(".mega-animating",m).removeClass("mega-animating");const l=e.settings.effect_speed+parseInt(e.settings.hover_intent_timeout,10);t.addClass("mega-animating"),setTimeout(function(){t.removeClass("mega-animating")},l)},e.hideAllPanels=function(){n(".mega-toggle-on > a.mega-menu-link",i).each(function(){e.hidePanel(n(this),!1)})},e.expandMobileSubMenus=function(){if(e.settings.mobile_direction==="vertical"&&(n(".mega-menu-item-has-children.mega-expand-on-mobile > a.mega-menu-link",i).each(function(){e.showPanel(n(this),!0)}),e.settings.mobile_state==="expand_all"&&n(".mega-menu-item-has-children:not(.mega-toggle-on) > a.mega-menu-link",i).each(function(){e.showPanel(n(this),!0)}),e.settings.mobile_state==="expand_active")){const t=["li.mega-current-menu-ancestor.mega-menu-item-has-children > a.mega-menu-link","li.mega-current-menu-item.mega-menu-item-has-children > a.mega-menu-link","li.mega-current-menu-parent.mega-menu-item-has-children > a.mega-menu-link","li.mega-current_page_ancestor.mega-menu-item-has-children > a.mega-menu-link","li.mega-current_page_item.mega-menu-item-has-children > a.mega-menu-link"];i.find(t.join(", ")).each(function(){e.showPanel(n(this),!0)})}},e.hideSiblingPanels=function(t,l){t.parent().parent().find(".mega-toggle-on").children("a.mega-menu-link").each(function(){e.hidePanel(n(this),l)})},e.isDesktopView=function(){return Math.max(document.documentElement.clientWidth||0,window.innerWidth||0)>e.settings.breakpoint},e.isMobileView=function(){return!e.isDesktopView()},e.isHorizontalMobileSubmenuMode=function(){return e.isMobileView()&&e.isMobileOffCanvas()&&e.settings.mobile_direction==="horizontal"};const M=function(t){return t.find("> li.mega-mobile-back:visible > button.mega-mobile-back-link").first()},I=function(){return n("li.mega-toggle-on:not(.mega-collapse-children) > ul.mega-sub-menu",i).last()};e.getFocusableItemsInSubmenu=function(t){return t.find(S).not(".mega-mobile-back-link").filter(function(){return n(this).is(":visible")&&window.getComputedStyle(this).visibility!=="hidden"})},e.focusFirstItemInOpenedSubmenu=function(t){if(!e.isHorizontalMobileSubmenuMode()||!m.hasClass("mega-keyboard-navigation"))return;const l=t.children("ul.mega-sub-menu");if(!l.length)return;const a=l.find(S).not(".mega-mobile-back-link").filter(":visible").first();a.length?a.trigger("focus"):M(l).trigger("focus")},e.deferFocusFirstItemInOpenedSubmenu=function(t){const l=Math.min(120,parseInt(e.settings.effect_speed_mobile,10)||0);setTimeout(function(){e.focusFirstItemInOpenedSubmenu(t),setTimeout(function(){t.find("ul.mega-sub-menu").has(document.activeElement).length!==0||e.focusFirstItemInOpenedSubmenu(t)},40)},l)};const O=function(t){return typeof t=="number"||typeof t=="string"&&t.trim()!==""&&!isNaN(t)?n("li.mega-menu-item-"+t,i).find("a.mega-menu-link").first():t.is("li.mega-menu-item")?t.f
3270ind("a.mega-menu-link").first():t};e.showPanel=function(t,l){t=O(t);const a=t.parent(),d=e.isDesktopView(),v=!d;if(a.triggerHandler("before_open_panel"),a.find("[aria-expanded]").first().attr("aria-expanded","true"),n(".mega-animating",m).removeClass("mega-animating"),!(v&&a.hasClass("mega-hide-sub-menu-on-mobile"))){if(d&&(i.hasClass("mega-menu-horizontal")||i.hasClass("mega-menu-vertical"))&&!a.hasClass("mega-collapse-children")&&e.hideSiblingPanels(t,!0),(v&&m.hasClass("mega-keyboard-navigation")||e.settings.vertical_behaviour==="accordion")&&e.hideSiblingPanels(t,!1),e.calculateDynamicSubmenuWidths(t),e.shouldUseSlideAnimation(t,l)){const p=v?e.settings.effect_speed_mobile:e.settings.effect_speed;t.siblings(".mega-sub-menu").css("display","none").animate({height:"show",paddingTop:"show",paddingBottom:"show",minHeight:"show"},p,function(){n(this).css("display","")})}a.addClass("mega-toggle-on").triggerHandler("open_panel"),e.deferFocusFirstItemInOpenedSubmenu(a)}},e.shouldUseSlideAnimation=function(t,l){if(l===!0)return!1;if(t.parent().hasClass("mega-collapse-children"))return!0;const a=e.isDesktopView();if(a&&e.settings.effect==="slide")return!0;if(!a){if(e.settings.effect_mobile==="slide")return!0;if(e.isMobileOffCanvas())return e.settings.mobile_direction!=="horizontal"}return!1},e.hidePanel=function(t,l){t=O(t);const a=t.parent(),d=t.siblings(".mega-sub-menu"),v=e.isMobileView();if(a.triggerHandler("before_close_panel"),a.find("[aria-expanded]").first().attr("aria-expanded","false"),e.shouldUseSlideAnimation(t)){const p=v?e.settings.effect_speed_mobile:e.settings.effect_speed;d.animate({height:"hide",paddingTop:"hide",paddingBottom:"hide",minHeight:"hide"},p,function(){d.css("display",""),a.removeClass("mega-toggle-on").triggerHandler("close_panel")});return}l&&d.css("display","none").delay(e.settings.effect_speed).queue(function(){n(this).css("display","").dequeue()}),d.find(".widget_media_video video").each(function(){this.player&&this.player.pause()}),a.removeClass("mega-toggle-on").triggerHandler("close_panel"),e.addAnimatingClass(a)};const x=function(t){return t==="$menu"?i:t==="$wrap"?m:n(t)};e.calculateDynamicSubmenuWidths=function(t){const l=t.parent(),a=t.siblings(".mega-sub-menu"),d=e.isDesktopView(),v=l.hasClass("mega-menu-megamenu")&&l.parent().hasClass("max-mega-menu");if(v&&e.settings.panel_width)if(d){const p=i.offset();if(e.settings.panel_width==="100vw"){const h=n("body").offset();a.css({left:h.left-p.left+"px"})}else{const h=x(e.settings.panel_width);h.length>0&&a.css({width:h.outerWidth(),left:h.offset().left-p.left+"px"})}}else a.css({width:"",left:""});if(v&&e.settings.panel_inner_width){const p=x(e.settings.panel_inner_width);if(p.length>0){const h=parseInt(p.width(),10);a.css({paddingLeft:"",paddingRight:""});const C=parseInt(a.innerWidth(),10);d&&h>0&&h<C&&a.css({paddingLeft:(C-h)/2+"px",paddingRight:(C-h)/2+"px"})}}};const H=function(){e.calculateDynamicSubmenuWidths(n("> li.mega-menu-megamenu > a.mega-menu-link",i))};e.bindClickEvents=function(){e.unbindClickEvents(!0);let t=!1;n(document).on({["touchmove"+k]:function(){t=!0},["touchstart"+k]:function(){t=!1}}),n(document).on("click"+k+" touchend"+k,function(a){!t&&e.settings.document_click==="collapse"&&!n(a.target).closest(".mega-menu-wrap").length&&(e.hideAllPanels(),e.hideMobileMenu()),t=!1}),T.off("click.megamenu touchend.megamenu");const l=n("> a.mega-menu-link",_).add(T);l.on("touchend.megamenu",function(a){e.settings.event==="hover_intent"&&e.unbindHoverIntentEvents(),e.settings.event==="hover"&&e.unbindHoverEvents()}),l.on("click.megamenu",function(a){if(!n(a.target).hasClass("mega-indicator")){if(e.isDesktopView()&&n(this).parent().hasClass("mega-toggle-on")&&n(this).closest("ul.mega-sub-menu").parent().hasClass("mega-menu-tabbed")){if(e.settings.second_click==="go")return;a.preventDefault();return}t||e.isMobileView()&&n(this).parent().hasClass("mega-hide-sub-menu-on-mobile")||((e.settings.second_click==="go"||n(this).parent().hasClass("mega-click-click-go"))&&n(this).attr("href")!==void 0?n(this).parent().hasClass("mega-toggle-on")||(a.preventDefault(),e.showPanel(n(this))):(a.preventDefault(),n(this).parent().hasClass("mega-toggle-on")?e.hidePanel(n(this),!1):e.showPanel(n(this))))}}),e.settings.second_click==="disabled"&&l.off("click.megamenu"),n(".mega-close-after-click:not(.mega-menu-item-has-children) > a.mega-menu-link",i).on("click.megamenu",function(){e.hideAllPanels(),e.hideMobileMenu()}),n("button.mega-close",m).on("click.megamenu",function(a){e.hideMobileMenu()})},e.bindHoverEvents=function(){_.on({"mouseenter.megamenu":function(){e.unbindClickEvents(),n(this).hasClass("mega-toggle-on")||e.showPanel(n(this).children("a.mega-menu-link"))},"mouseleave.megamenu":function(){n(this).hasClass("mega-toggle-on")&&!n(this).hasClass("mega-disable-collapse")&&!n(this).parent().parent().hasClass("mega-menu-tabbed")&&e.hidePanel(n(this).children("a.mega-menu-link"),!1)}})},e.bindHoverIntentEvents=function(){_.hoverIntent({over:function(){e.unbindClickEvents(),n(this).hasClass("mega-toggle-on")||e.showPanel(n(this).children("a.mega-menu-link"))},out:function(){n(this).hasClass("mega-toggle-on")&&!n(this).hasClass("mega-disable-collapse")&&!n(this).parent().parent().hasClass("mega-menu-tabbed")&&e.hidePanel(n(this).children("a.mega-menu-link"),!1)},timeout:e.settings.hover_intent_timeout,interval:e.settings.hover_intent_interval})},e.isMobileOffCanvas=function(){return e.settings.effect_mobile==="slide_left"||e.settings.effect_mobile==="slide_right"},e.shouldGoToNextTopLevelItem=function(t){return(t===W&&e.isDesktopView()||t===A&&e.isMobileView())&&i.hasClass("mega-menu-horizontal")},e.shouldGoToPreviousTopLevelItem=function(t){return(t===F&&e.isDesktopView()||t===L&&e.isMobileView())&&i.hasClass("mega-menu-horizontal")},e.bindKeyboardEvents=function(){const t=i.find("a.mega-menu-link").first(),l=m.find("button.mega-close").first(),a=S.split(", ").map(s=>"> "+s).join(", "),d=function(s){!s||!s.length||(s.parent().hasClass("mega-toggle-on")&&!s.closest("ul.mega-sub-menu").parent().hasClass("mega-menu-tabbed")?e.hidePanel(s):e.showPanel(s))},v=function(){const s=i[0].contains(document.activeElement)?n(document.activeElement):n(),o=n("> a.mega-menu-link",s.closest(".mega-toggle-on"));return o.length?(e.hidePanel(o),o.trigger("focus"),!0):!1},p=function(s,o,g,f){if(o.is(l)&&f){if(s.shiftKey){if(g){const u=e.getFocusableItemsInSubmenu(I()).last();u.length&&(s.preventDefault(),u.trigger("focus"))}}else{s.preventDefault();const u=g?M(I()):n();(u.length?u:t).trigger("focus")}return}if(f&&s.shiftKey&&o.is(t)){s.preventDefault(),l.trigger("focus");return}if(g){const u=I();if(u.length&&!u.has(o).length){if(s.preventDefault(),s.shiftKey)l.trigger("focus");else{const c=M(u);(c.length?c:e.getFocusableItemsInSubmenu(u).first()).trigger("focus")}return}const r=o.parentsUntil(i,"ul.mega-sub-menu").filter(function(){const c=n(this).parent();return c.hasClass("mega-toggle-on")&&!c.hasClass("mega-collapse-children")}).first();if(r.length)if(s.shiftKey)if(o.hasClass("mega-mobile-back-link"))s.preventDefault(),l.trigger("focus");else{const c=e.getFocusableItemsInSubmenu(r),D=M(r);c.length&&D.length&&o.is(c.first())&&(s.preventDefault(),D.trigger("focus"))}else{const c=e.getFocusableItemsInSubmenu(r);
3270c.length&&o.is(c.last())&&(s.preventDefault(),l.trigger("focus"))}}},h=function(s){s.preventDefault(),b.hasClass("mega-menu-open")?e.hideMobileMenu():(e.showMobileMenu(),y=setTimeout(function(){i.find("a.mega-menu-link").first().trigger("focus")},e.settings.effect_speed_mobile))},C=function(s,o){o.is("a.mega-menu-link")?(s.preventDefault(),o.parent().is(_)&&d(o)):o.is(".mega-indicator")&&(s.preventDefault(),d(o.parent()))},U=function(){const s=n(".mega-toggle-on",i).length!==0;s&&v()||e.isMobileView()&&!s&&e.hideMobileMenu()},j=function(s,o){if(o.is(".mega-indicator")){d(o.parent());return}if(o.parent().is(_)){if(e.isMobileView()&&o.parent().is(".mega-hide-sub-menu-on-mobile"))return;if(!o.is("[href]")){d(o);return}if(o.parent().hasClass("mega-toggle-on")&&!o.closest("ul.mega-sub-menu").parent().hasClass("mega-menu-tabbed"))return;s.preventDefault(),e.showPanel(o)}},q=function(s,o){s.preventDefault();const g=I();if(g.length){const f=M(g),u=e.getFocusableItemsInSubmenu(g),r=[];f.length&&r.push(f[0]),u.each(function(){r.push(this)}),l.length&&r.push(l[0]);const c=r.indexOf(document.activeElement),D=c<0?o?0:r.length-1:(c+(o?1:-1)+r.length)%r.length;n(r[D]).trigger("focus")}else{const f=i.children("li.mega-menu-item:visible").find(a),u=f.index(document.activeElement);if(u>=0){const r=(u+(o?1:-1)+f.length)%f.length;f.eq(r).trigger("focus")}}},G=function(s,o){s.preventDefault();const g=i.children("li.mega-menu-item:visible").find(a),f=n(document.activeElement).closest(i.children("li.mega-menu-item")).find(a).first(),u=g.index(f),r=o?u+1:u-1;u>=0&&r>=0&&(e.hideAllPanels(),g.eq(r).trigger("focus"))};m.on("keyup.megamenu",".max-mega-menu, .mega-menu-toggle",function(s){if(s.key!==V)return;m.addClass("mega-keyboard-navigation"),e.bindClickEvents();const o=n(s.target);e.isDesktopView()&&o.is(".mega-menu-link")&&o.parent().parent().hasClass("max-mega-menu")&&e.hideAllPanels()}),m.on("keydown.megamenu","a.mega-menu-link, button.mega-menu-link, button.mega-mobile-back-link, .mega-indicator, .mega-menu-toggle-block, .mega-menu-toggle-animated-block button, button.mega-close",function(s){if(!m.hasClass("mega-keyboard-navigation"))return;const o=s.key,g=n(s.target),f=e.isHorizontalMobileSubmenuMode(),u=e.isMobileView()&&e.isMobileOffCanvas();switch(o){case V:p(s,g,f,u);break;case B:g.is(".mega-menu-toggle-block button, .mega-menu-toggle-animated-block button")?h(s):C(s,g);break;case R:g.is(".mega-menu-toggle-block button, .mega-menu-toggle-animated-block button")?h(s):j(s,g);break;case z:U();break;case L:case A:f&&q(s,o===A);break;case F:case W:const r=e.shouldGoToNextTopLevelItem(o),c=e.shouldGoToPreviousTopLevelItem(o);(r||c)&&G(s,r);break}}),m.on("focusout.megamenu",function(s){m.hasClass("mega-keyboard-navigation")&&setTimeout(function(){m[0].contains(document.activeElement)||(m.removeClass("mega-keyboard-navigation"),e.hideAllPanels(),e.hideMobileMenu())},10)})},e.unbindAllEvents=function(){n(document).off(k),n("ul.mega-sub-menu, li.mega-menu-item, li.mega-menu-row, li.mega-menu-column, a.mega-menu-link, .mega-indicator",i).off()},e.unbindClickEvents=function(t){!t&&m.hasClass("mega-keyboard-navigation")||(n(document).off(k),n("> a.mega-menu-link",_).not(T).off("click.megamenu touchend.megamenu"))},e.unbindHoverEvents=function(){_.off("mouseenter.megamenu mouseleave.megamenu")},e.unbindHoverIntentEvents=function(){_.off("mouseenter mouseleave").removeProp("hoverIntent_t").removeProp("hoverIntent_s")},e.unbindKeyboardEvents=function(){m.off("keyup.megamenu keydown.megamenu focusout.megamenu")},e.unbindMegaMenuEvents=function(){e.settings.event==="hover_intent"&&e.unbindHoverIntentEvents(),e.settings.event==="hover"&&e.unbindHoverEvents(),e.unbindClickEvents(),e.unbindKeyboardEvents()},e.bindMegaMenuEvents=function(){e.unbindMegaMenuEvents();const t=e.isDesktopView();t&&e.settings.event==="hover_intent"&&e.bindHoverIntentEvents(),t&&e.settings.event==="hover"&&e.bindHoverEvents(),e.bindClickEvents(),e.bindKeyboardEvents()},e.checkWidth=function(){e.isMobileView()&&i.data("view")==="desktop"&&e.switchToMobile(),e.isDesktopView()&&i.data("view")==="mobile"&&e.switchToDesktop(),H()},e.reverseRightAlignedItems=function(){!n("body").hasClass("rtl")&&i.hasClass("mega-menu-horizontal")&&i.css("display")!=="flex"&&i.append(i.children("li.mega-item-align-right").get().reverse())},e.addClearClassesToMobileItems=function(){n(".mega-menu-row",i).each(function(){n("> .mega-sub-menu > .mega-menu-column:not(.mega-hide-on-mobile)",n(this)).filter(":even").addClass("mega-menu-clear")}
3270)},e.initDesktop=function(){i.data("view","desktop"),e.bindMegaMenuEvents(),e.initIndicators(),i.trigger("mmm:switchToDesktop")},e.initMobile=function(){e.switchToMobile()},e.switchToDesktop=function(){i.data("view","desktop"),e.bindMegaMenuEvents(),e.reverseRightAlignedItems(),e.hideAllPanels(),e.hideMobileMenu(!0),i.removeAttr("role"),i.removeAttr("aria-modal"),i.removeAttr("aria-hidden"),i.trigger("mmm:switchToDesktop")},e.switchToMobile=function(){i.data("view","mobile"),e.isMobileOffCanvas()&&b.is(":visible")&&(i.attr("role","dialog"),i.attr("aria-modal","true"),i.attr("aria-hidden","true")),e.bindMegaMenuEvents(),e.initIndicators(),e.reverseRightAlignedItems(),e.addClearClassesToMobileItems(),e.hideAllPanels(),e.expandMobileSubMenus(),i.trigger("mmm:switchToMobile")},e.initToggleBar=function(){b.on("click",function(t){n(t.target).closest(".mega-menu-toggle-block, button.mega-toggle-animated, .mega-menu-toggle-custom-block",this).length?(t.preventDefault(),n(this).hasClass("mega-menu-open")?e.hideMobileMenu():e.showMobileMenu()):t.target===this&&e.isMobileOffCanvas()&&e.hideMobileMenu()})},e.initIndicators=function(){i.off("click.megamenu",".mega-indicator"),i.on("click.megamenu",".mega-indicator",function(t){t.preventDefault(),t.stopPropagation(),n(this).closest(".mega-menu-item").hasClass("mega-toggle-on")?(!n(this).closest("ul.mega-sub-menu").parent().hasClass("mega-menu-tabbed")||e.isMobileView())&&e.hidePanel(n(this).parent(),!1):e.showPanel(n(this).parent(),!1)})},e.hideMobileMenu=function(t=!1){if(!b.is(":visible")&&!t)return;i.attr("aria-hidden","true"),clearTimeout(y),y=setTimeout(function(){n("body").removeClass(w+"-mobile-open"),n("html").removeClass(w+"-off-canvas-open")},e.settings.effect_speed_mobile),m.hasClass("mega-keyboard-navigation")&&n(".mega-menu-toggle-block button, button.mega-toggle-animated",b).first().trigger("focus"),n(".mega-toggle-label, .mega-toggle-animated",b).attr("aria-expanded","false");const l=function(){i.css({width:"",left:"",display:""}),b.removeClass("mega-menu-open")};e.settings.effect_mobile==="slide"&&!t?i.animate({height:"hide"},e.settings.effect_speed_mobile,l):l(),i.triggerHandler("mmm:hideMobileMenu")},e.showMobileMenu=function(){b.is(":visible")&&(clearTimeout(y),n("body").addClass(w+"-mobile-open"),e.expandMobileSubMenus(),e.isMobileOffCanvas()&&n("html").addClass(w+"-off-canvas-open"),e.settings.effect_mobile==="slide"&&i.animate({height:"show"},e.settings.effect_speed_mobile,function(){n(this).css("display","")}),n(".mega-toggle-label, .mega-toggle-animated",b).attr("aria-expanded","true"),b.addClass("mega-menu-open"),e.toggleBarForceWidth(),i.attr("aria-hidden","false"),i.triggerHandler("mmm:showMobileMenu"))},e.toggleBarForceWidth=function(){const t=n(e.settings.mobile_force_width);if(t.length&&(e.settings.effect_mobile==="slide"||e.settings.effect_mobile==="disabled")){const l=b.offset(),a=t.offset();i.css({width:t.outerWidth(),left:a.left-l.left+"px"})}},e.doConsoleChecks=function(){e.settings.mobile_force_width!=="false"&&!n(e.settings.mobile_force_width).length&&(e.settings.effect_mobile==="slide"||e.settings.effect_mobile==="disabled")&&console.warn("Max Mega Menu #"+m.attr("id")+": Mobile Force Width element ("+e.settings.mobile_force_width+") not found");const t=/^((\d+(\.\d+)?(px|%|em|rem|vw|vh|ch|ex|cm|mm|in|pt|pc))|auto)$/i;e.settings.panel_width!==void 0&&!t.test(e.settings.panel_width)&&!x(e.settings.panel_width).length&&console.warn("Max Mega Menu #"+m.attr("id")+": Panel Width (Outer) element ("+e.settings.panel_width+") not found"),e.settings.panel_inner_width!==void 0&&!t.test(e.settings.panel_inner_width)&&!x(e.settings.panel_inner_width).length&&console.warn("Max Mega Menu #"+m.attr("id")+": Panel Width (Inner) element ("+e.settings.panel_inner_width+") not found")},e.init=function(){i.triggerHandler("before_mega_menu_init"),e.settings=n.extend({},N,P),window.console&&e.doConsoleChecks(),i.removeClass("mega-no-js"),e.initToggleBar(),e.settings.unbind_events==="true"&&e.unbindAllEvents(),document.readyState==="complete"?H():n(window).on("load",H),e.isDesktopView()?e.initDesktop():e.initMobile(),n(window).on("resize",function(){e.checkWidth()}),i.triggerHandler("after_mega_menu_init")}
3270,e.init()},n.fn.maxmegamenu=function(E){return this.each(function(){if(n(this).data("maxmegamenu")===void 0){const P=new n.maxmegamenu(this,E);n(this).data("maxmegamenu",P)}})},n(function(){n(".max-mega-menu").maxmegamenu()})})(jQuery); 3271;(function () { 3272 "use strict"; 3273 3274 const STAR_PATH = 3275 "M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"; 3276 3277 function esc(str) { 3278 return String(str) 3279 .replace(/&/g, "&") 3280 .replace(/</g, "<") 3281 .replace(/>/g, ">") 3282 .replace(/"/g, """) 3283 .replace(/'/g, "'"); 3284 } 3285 3286 function starSVG(full) { 3287 const cls = full ? "cra-star--full" : "cra-star--empty"; 3288 const fill = full ? "#506FBE" : "#D1D5DB"; 3289 3290 return `<svg class="cra-star ${cls}" viewBox="0 0 20 20" aria-hidden="true"><path fill="${fill}" d="${STAR_PATH}"/></svg>`; 3291 } 3292 3293 function timeAgo(iso) { 3294 if (!iso) { 3295 return ""; 3296 } 3297 var diff = Math.floor((Date.now() - new Date(iso).getTime()) / 1000); 3298 if (diff < 60) { 3299 return "just now"; 3300 } 3301 if (diff < 3600) { 3302 var mins = Math.floor(diff / 60); 3303 return mins + " minute" + (mins !== 1 ? "s" : "") + " ago"; 3304 } 3305 if (diff < 86400) { 3306 var hrs = Math.floor(diff / 3600); 3307 return hrs + " hour" + (hrs !== 1 ? "s" : "") + " ago"; 3308 } 3309 if (diff < 2592000) { 3310 var days = Math.floor(diff / 86400); 3311 return days + " day" + (days !== 1 ? "s" : "") + " ago"; 3312 } 3313 if (diff < 31536000) { 3314 var months = Math.floor(diff / 2592000); 3315 if (months < 1) { 3316 var daysFallback = Math.floor(diff / 86400); 3317 return daysFallback + " day" + (daysFallback !== 1 ? "s" : "") + " ago"; 3318 } 3319 return months + " month" + (months !== 1 ? "s" : "") + " ago"; 3320 } 3321 3322 var years = Math.floor(diff / 31536000); 3323 return years + " year" + (years !== 1 ? "s" : "") + " ago"; 3324 } 3325 3326 function buildStarRow(rating) { 3327 let html = ""; 3328 3329 for (let i = 1; i <= 5; i++) { 3330 html += starSVG(i <= rating); 3331 } 3332 3333 return html; 3334 } 3335 3336 function fadeIn(el, duration) { 3337 el.style.opacity = "0"; 3338 el.style.transition = `opacity ${duration || 400}ms ease`; 3339 el.removeAttribute("hidden"); 3340 3341 void el.offsetHeight; 3342 el.style.opacity = "1"; 3343 } 3344 3345 function fadeOut(el, duration, cb) { 3346 el.style.opacity = "1"; 3347 el.style.transition = `opacity ${duration || 300}ms ease`; 3348 el.style.opacity = "0"; 3349 3350 setTimeout(function () { 3351 el.style.display = "none"; 3352 if (cb) { 3353 cb(); 3354 } 3355 }, duration || 300); 3356 } 3357 3358 function buildSlide(r) { 3359 const rating = Math.max(1, Math.min(5, parseInt(r.review_rating, 10) || 5)); 3360 const text = r.review_text || ""; 3361 const fullName = (r.author_name || "Patient").trim(); 3362 const nameParts = fullName.split(/\s+/); 3363 const name = 3364 nameParts.length > 1 3365 ? nameParts[0] + " " + nameParts[nameParts.length - 1].charAt(0) + "." 3366 : nameParts[0]; 3367 const clinic = r.clinic_name || ""; 3368 const maxLen = 320; 3369 const isLong = text.length > maxLen; 3370 const reviewTime = timeAgo(r.review_date); 3371 3372 const textBlock = isLong 3373 ? `<p class="cra-tc-card__text"> 3374 <span class="cra-tc-short"> 3375 ${esc(text.substring(0, maxLen))}… 3376 </span> 3377 <span class="cra-tc-full" hidden>${esc(text)}</span> 3378 <button class="cra-tc-readmore" type="button" aria-expanded="false"> 3379 Read more 3380 </button> 3381 </p>` 3382 : `<p class="cra-tc-card__text">${esc(text)}</p>`; 3383 3384 return `<div class="cra-tc-slide" role="listitem"> 3385 <div class="cra-tc-card__body">${textBlock}</div> 3386 <div class="cra-tc-card__footer"> 3387 <div class="cra-tc-card__stars" aria-label="${rating} out of 5 stars"> 3388 ${buildStarRow(rating)}</div> 3389 <p class="cra-tc-card__clinic">${esc(clinic)}</p> 3390 <p class="cra-tc-card__review-time">${esc(reviewTime)}</p> 3391 <p class="cra-tc-card__author-name">${esc(name)}</p> 3392 </div> 3393 </div>`; 3394 } 3395 3396 function createCarouselEngine(sectionEl, trackEl, total, autoplayDelay) {
3397 let currentIndex = 0; 3398 let isAnimating = false; 3399 const FADE_DURATION = 400; 3400 const AUTOPLAY_DELAY = (autoplayDelay > 0) ? autoplayDelay : 0; 3401 let autoplayTimer = null; 3402 let userPaused = false; 3403 3404 function startAutoplay() { 3405 if (!AUTOPLAY_DELAY || total <= 1) return; 3406 stopAutoplay(); 3407 3408 autoplayTimer = setInterval(function () { 3409 if (!userPaused) next(); 3410 }, AUTOPLAY_DELAY); 3411 } 3412 3413 function stopAutoplay() { 3414 if (autoplayTimer) { 3415 clearInterval(autoplayTimer); 3416 autoplayTimer = null; 3417 } 3418 } 3419 3420 const slides = Array.prototype.slice.call( 3421 trackEl.querySelectorAll(".cra-tc-slide"), 3422 ); 3423 3424 function initFadeLayout() { 3425 trackEl.style.position = "relative"; 3426 trackEl.style.display = "block"; 3427 trackEl.style.transform = "none"; 3428 trackEl.style.transition = "none"; 3429 trackEl.style.width = "100%"; 3430 3431 slides.forEach(function (slide, i) { 3432 slide.style.position = "absolute"; 3433 slide.style.top = "0"; 3434 slide.style.left = "0"; 3435 slide.style.width = "100%"; 3436 slide.style.boxSizing = "border-box"; 3437 slide.style.opacity = i === 0 ? "1" : "0"; 3438 slide.style.transition = `opacity ${FADE_DURATION}ms ease`; 3439 slide.style.pointerEvents = i === 0 ? "auto" : "none"; 3440 slide.setAttribute("aria-hidden", i === 0 ? "false" : "true"); 3441 }); 3442 3443 matchTrackHeight(); 3444 } 3445 3446 function matchTrackHeight() { 3447 const active = slides[currentIndex]; 3448 if (!active) { 3449 return; 3450 } 3451 3452 const heights = slides.map(function (s) { 3453 const prev = s.style.visibility; 3454 s.style.visibility = "hidden"; 3455 s.style.opacity = "1"; 3456 const h = s.offsetHeight; 3457 s.style.visibility = prev || ""; 3458 s.style.opacity = slides.indexOf(s) === currentIndex ? "1" : "0"; 3459 return h; 3460 }); 3461 3462 const maxH = Math.max.apply(null, heights); 3463 trackEl.style.height = `${maxH}px`; 3464 } 3465 3466 function goTo(idx) { 3467 if (isAnimating) { 3468 return; 3469 } 3470 if (total <= 1) { 3471 return; 3472 } 3473 3474 if (idx >= total) { 3475 idx = 0; 3476 } else if (idx < 0) { 3477 idx = total - 1; 3478 } 3479 3480 if (idx === currentIndex) { 3481 return; 3482 } 3483 3484 isAnimating = true; 3485 3486 const outSlide = slides[currentIndex]; 3487 const inSlide = slides[idx]; 3488 3489 outSlide.style.transition = `opacity ${FADE_DURATION}ms ease`; 3490 outSlide.style.opacity = "0"; 3491 outSlide.style.pointerEvents = "none"; 3492 outSlide.setAttribute("aria-hidden", "true"); 3493 3494 inSlide.style.transition = `opacity ${FADE_DURATION}ms ease`; 3495 inSlide.style.opacity = "1"; 3496 inSlide.style.pointerEvents = "auto"; 3497 inSlide.setAttribute("aria-hidden", "false"); 3498 3499 currentIndex = idx; 3500 3501 setTimeout(function () { 3502 isAnimating = false; 3503 matchTrackHeight(); 3504 }, FADE_DURATION + 20); 3505 } 3506 3507 function next() { 3508 goTo(currentIndex + 1); 3509 } 3510 function prev() { 3511 goTo(currentIndex - 1); 3512 } 3513 3514 function wireArrows() { 3515 const wrap = trackEl.closest 3516 ? trackEl.closest(".cra-testimonial-carousel-wrap") 3517 : sectionEl; 3518 const container = wrap || sectionEl; 3519 3520 const prevBtn = container.querySelector(".cra-tc-arrow--prev"); 3521 const nextBtn = container.querySelector(".cra-tc-arrow--next"); 3522 3523 if (prevBtn) { 3524 prevBtn.removeAttribute("disabled"); 3525 3526 prevBtn.addEventListener("click", function () { 3527 prev(); 3528 userPaused = false; 3529 startAutoplay(); 3530 }); 3531 } 3532 3533 if (nextBtn) { 3534 nextBtn.removeAttribute("disabled"); 3535 nextBtn.addEventListener("click", function () { 3536 next(); 3537 userPaused = false; 3538 startAutoplay(); 3539 }); 3540 } 3541 } 3542 3543 let touchStartX = 0; 3544 let touchDeltaX = 0; 3545 3546 trackEl.parentNode.addEventListener( 3547 "touchstart", 3548 function (e) { 3549 touchStartX = e.changedTouches[0].screenX; 3550 touchDeltaX = 0; 3551 }, 3552 { passive: true }, 3553 ); 3554 3555 trackEl.parentNode.addEventListener( 3556 "touchmove", 3557 function (e) { 3558 touchDeltaX = e.changedTouches[0].screenX - touchStartX; 3559 }, 3560 { passive: true }, 3561 ); 3562 3563 trackEl.parentNode.addEventListener("touchend", function () {
3564 if (touchDeltaX < -40) { 3565 next(); 3566 } else if (touchDeltaX > 40) { 3567 prev(); 3568 } 3569 userPaused = false; 3570 startAutoplay(); 3571 }); 3572 3573 // Pause on hover resume on mouse leave 3574 sectionEl.addEventListener("mouseenter", function () { 3575 userPaused = true; 3576 }); 3577 3578 sectionEl.addEventListener("mouseleave", function () { 3579 userPaused = false; 3580 }); 3581 3582 sectionEl.setAttribute("tabindex", "0"); 3583 sectionEl.addEventListener("keydown", function (e) { 3584 if (e.key === "ArrowLeft") { 3585 prev(); 3586 userPaused = false; 3587 startAutoplay(); 3588 } 3589 if (e.key === "ArrowRight") { 3590 next(); 3591 userPaused = false; 3592 startAutoplay(); 3593 } 3594 }); 3595 3596 let resizeTimer; 3597 window.addEventListener("resize", function () { 3598 clearTimeout(resizeTimer); 3599 resizeTimer = setTimeout(function () { 3600 matchTrackHeight(); 3601 }, 120); 3602 }); 3603 3604 initFadeLayout(); 3605 wireArrows(); 3606 startAutoplay(); 3607 3608 return { goTo, next, prev, startAutoplay, stopAutoplay }; 3609 } 3610 3611 function initCarousel(carouselId, reviews) { 3612 const loader = document.getElementById(`${carouselId}-loader`); 3613 const wrap = document.getElementById(`${carouselId}-wrap`); 3614 const track = document.getElementById(carouselId); 3615 const section = wrap ? wrap.closest(".cra-testimonial-section") : null; 3616 3617 if (!track) { 3618 if (loader) { 3619 loader.style.display = "none"; 3620 } 3621 return; 3622 } 3623 3624 if (track.querySelectorAll(".cra-tc-slide").length === 0) { 3625 if (!reviews || reviews.length === 0) { 3626 if (loader) { 3627 loader.style.display = "none"; 3628 } 3629 if (wrap) { 3630 wrap.innerHTML = 3631 '<p class="cra-tc-empty">No patient reviews are available right now.</p>'; 3632 wrap.removeAttribute("hidden"); 3633 } 3634 return; 3635 } 3636 let html = ""; 3637 3638 for (let i = 0; i < reviews.length; i++) { 3639 html += buildSlide(reviews[i]); 3640 } 3641 track.innerHTML = html; 3642 } 3643 3644 const total = track.querySelectorAll(".cra-tc-slide").length; 3645 3646 if (loader) { 3647 fadeOut(loader, 280, function () { 3648 if (wrap) { 3649 fadeIn(wrap, 380); 3650 requestAnimationFrame(function () { 3651 createCarouselEngine(section || wrap, track, total, (window.CLINICS_RR_AJAX_MODE && window.CLINICS_RR_AJAX_MODE.autoplayDelay) || 0); 3652 }); 3653 } 3654 }); 3655 } else if (wrap) { 3656 fadeIn(wrap, 380); 3657 requestAnimationFrame(function () { 3658 createCarouselEngine(section || wrap, track, total, (window.CLINICS_RR_AJAX_MODE && window.CLINICS_RR_AJAX_MODE.autoplayDelay) || 0); 3659 }); 3660 } 3661 } 3662 3663 document.addEventListener("click", function (e) { 3664 const btn = e.target; 3665 if (!btn || !btn.classList.contains("cra-tc-readmore")) { 3666 return; 3667 } 3668 3669 const p = btn.closest ? btn.closest("p") : btn.parentNode; 3670 const isOpen = btn.getAttribute("aria-expanded") === "true"; 3671 const sEl = p ? p.querySelector(".cra-tc-short") : null; 3672 const fEl = p ? p.querySelector(".cra-tc-full") : null; 3673 3674 if (sEl) { 3675 sEl.hidden = !isOpen; 3676 } 3677 if (fEl) { 3678 fEl.hidden = isOpen; 3679 } 3680 btn.setAttribute("aria-expanded", String(!isOpen)); 3681 btn.textContent = isOpen ? "Read more" : "Read less"; 3682 }); 3683 3684 function runConfigs(configs) { 3685 configs.forEach(function (cfg) { 3686 if (cfg && cfg.carouselId) { 3687 initCarousel(cfg.carouselId, cfg.reviews || []); 3688 } 3689 }); 3690 } 3691 3692 function boot() { 3693 if (!window.CLINICS_RR_AJAX_MODE) { 3694 const cfg = window.CLINICS_RR_CAROUSEL; 3695 3696 if (!cfg) { 3697 document.querySelectorAll(".cra-tc-loader").forEach(function (el) { 3698 el.style.display = "none"; 3699 }); 3700 document 3701 .querySelectorAll(".cra-testimonial-carousel-wrap") 3702 .forEach(function (el) { 3703 el.removeAttribute("hidden"); 3704 }); 3705 return; 3706 } 3707 runConfigs(Array.isArray(cfg) ? cfg : [cfg]); 3708 return; 3709 } 3710 3711 if (window.CLINICS_RR_CAROUSEL) { 3712 const cfg = window.CLINICS_RR_CAROUSEL; 3713 runConfigs(Array.isArray(cfg) ? cfg : [cfg]); 3714 return; 3715 } 3716 3717 window.addEventListener("clinics_rr_data_ready", function onDataReady() { 3718 window.removeEventListener("clinics_rr_data_ready", onDataReady); 3719 const cfg = window.CLINICS_RR_CAROUSEL; 3720 3721 if (!cfg) { 3722 document.querySelectorAll(".cra-tc-loader").forEach(function (el) { 3723 el.style.display = "none"; 3724 }); 3725 document 3726 .querySelectorAll(".cra-testimonial-carousel-wrap") 3727 .forEach(function (el) { 3728 el.removeAttribute("hidden"); 3729 }); 3730 return; 3731 } 3732 runConfigs(Array.isArray(cfg) ? cfg : [cfg]); 3733 }); 3734 } 3735 3736 function waitForConfig(attempts) { 3737 if (window.CLINICS_RR_AJAX_MODE || window.CLINICS_RR_CAROUSEL) { 3738 boot(); 3739 return; 3740 } 3741 if (attempts > 0) { 3742 setTimeout(function () { 3743 waitForConfig(attempts - 1); 3744 }, 50); 3745 } else { 3746 boot(); 3747 } 3748 } 3749 3750 if (document.readyState === "loading") { 3751 document.addEventListener("DOMContentLoaded", function () { 3752 waitForConfig(10); 3753 }); 3754 } else { 3755 waitForConfig(10); 3756 } 3757})(); 3758;/*! This file is auto-generated */ 3759(()=>{var t={507:(t,e,r)=>{"use strict";r.d(e,{A:()=>A});var n=function(t){return"string"!=typeof t||""===t?(console.error("The namespace must be a non-empty string."),!1):!!/^[a-zA-Z][a-zA-Z0-9_.\-\/]*$/.test(t)||(console.error("The namespace can only contain numbers, letters, dashes, periods, underscores and slashes."),!1)};var i=function(t){return"string"!=typeof t||""===t?(console.error("The hook name must be a non-empty string."),!1):/^__/.test(t)?(console.error("The hook name cannot begin with `__`."),!1):!!/^[a-zA-Z][a-zA-Z0-9_.-]*$/.test(t)||(console.error("The hook name can only contain numbers, letters, dashes, periods and underscores."),!1)};var o=function(t,e){return function(r,o,s,c=10){const l=t[e];if(!i(r))return;if(!n(o))return;if("function"!=typeof s)return void console.error("The hook callback must be a function.");
3759if("number"!=typeof c)return void console.error("If specified, the hook priority must be a number.");const a={callback:s,priority:c,namespace:o};if(l[r]){const t=l[r].handlers;let e;for(e=t.length;e>0&&!(c>=t[e-1].priority);e--);e===t.length?t[e]=a:t.splice(e,0,a),l.__current.forEach((t=>{t.name===r&&t.currentIndex>=e&&t.currentIndex++}))}else l[r]={handlers:[a],runs:0};"hookAdded"!==r&&t.doAction("hookAdded",r,o,s,c)}};var s=function(t,e,r=!1){return function(o,s){const c=t[e];if(!i(o))return;if(!r&&!n(s))return;if(!c[o])return 0;let l=0;if(r)l=c[o].handlers.length,c[o]={runs:c[o].runs,handlers:[]};else{const t=c[o].handlers;for(let e=t.length-1;e>=0;e--)t[e].namespace===s&&(t.splice(e,1),l++,c.__current.forEach((t=>{t.name===o&&t.currentIndex>=e&&t.currentIndex--})))}return"hookRemoved"!==o&&t.doAction("hookRemoved",o,s),l}};var c=function(t,e){return function(r,n){const i=t[e];return void 0!==n?r in i&&i[r].handlers.some((t=>t.namespace===n)):r in i}};var l=function(t,e,r,n){return function(i,...o){const s=t[e];s[i]||(s[i]={handlers:[],runs:0}),s[i].runs++;const c=s[i].handlers;if(!c||!c.length)return r?o[0]:void 0;const l={name:i,currentIndex:0};return(n?async function(){try{s.__current.add(l);let t=r?o[0]:void 0;for(;l.currentIndex<c.length;){const e=c[l.currentIndex];t=await e.callback.apply(null,o),r&&(o[0]=t),l.currentIndex++}return r?t:void 0}finally{s.__current.delete(l)}}:function(){try{s.__current.add(l);let t=r?o[0]:void 0;for(;l.currentIndex<c.length;){t=c[l.currentIndex].callback.apply(null,o),r&&(o[0]=t),l.currentIndex++}return r?t:void 0}finally{s.__current.delete(l)}})()}};var a=function(t,e){return function(){const r=t[e],n=Array.from(r.__current);return n.at(-1)?.name??null}};var d=function(t,e){return function(r){const n=t[e];return void 0===r?n.__current.size>0:Array.from(n.__current).some((t=>t.name===r))}};var u=function(t,e){return function(r){const n=t[e];if(i(r))return n[r]&&n[r].runs?n[r].runs:0}};class h{actions;filters;addAction;addFilter;removeAction;removeFilter;hasAction;hasFilter;removeAllActions;removeAllFilters;doAction;doActionAsync;applyFilters;applyFiltersAsync;currentAction;currentFilter;doingAction;doingFilter;didAction;didFilter;constructor(){this.actions=Object.create(null),this.actions.__current=new Set,this.filters=Object.create(null),this.filters.__current=new Set,this.addAction=o(this,"actions"),this.addFilter=o(this,"filters"),this.removeAction=s(this,"actions"),this.removeFilter=s(this,"filters"),this.hasAction=c(this,"actions"),this.hasFilter=c(this,"filters"),this.removeAllActions=s(this,"actions",!0),this.removeAllFilters=s(this,"filters",!0),this.doAction=l(this,"actions",!1,!1),this.doActionAsync=l(this,"actions",!1,!0),this.applyFilters=l(this,"filters",!0,!1),this.applyFiltersAsync=l(this,"filters",!0,!0),this.currentAction=a(this,"actions"),this.currentFilter=a(this,"filters"),this.doingAction=d(this,"actions"),this.doingFilter=d(this,"filters"),this.didAction=u(this,"actions"),this.didFilter=u(this,"filters")}}var A=function(){return new h}},8770:()=>{}},e={};function r(n){var i=e[n];if(void 0!==i)return i.exports;var o=e[n]={exports:{}};return t[n](o,o.exports,r),o.exports}r.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return r.d(e,{a:e}),e},r.d=(t,e)=>{for(var n in e)r.o(e,n)&&!r.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},r.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var n={};(()=>{"use strict";r.r(n),r.d(n,{actions:()=>x,addAction:()=>s,addFilter:()=>c,applyFilters:()=>m,applyFiltersAsync:()=>v,createHooks:()=>t.A,currentAction:()=>y,currentFilter:()=>F,defaultHooks:()=>o,didAction:()=>b,didFilter:()=>k,doAction:()=>f,doActionAsync:()=>p,doingAction:()=>_,doingFilter:()=>g,filters:()=>w,hasAction:()=>d,hasFilter:()=>u,removeAction:()=>l,removeAllActions:()=>h,removeAllFilters:()=>A,removeFilter:()=>a});var t=r(507),e=r(8770),i={};for(const t in e)["default","actions","addAction","addFilter","applyFilters","applyFiltersAsync","createHooks","currentAction","currentFilter","defaultHooks","didAction","didFilter","doAction","doActionAsync","doingAction","doingFilter","filters","hasAction","hasFilter","removeAction","removeAllActions","removeAllFilters","removeFilter"].indexOf(t)<0&&(i[t]=()=>e[t]);r.d(n,i);const o=(0,t.A)(),{addAction:s,addFilter:c,removeAction:l,removeFilter:a,hasAction:d,hasFilter:u,removeAllActions:h,removeAllFilters:A,doAction:f,doActionAsync:p,applyFilters:m,applyFiltersAsync:v,currentAction:y,currentFilter:F,doingAction:_,doingFilter:g,didAction:b,didFilter:k,actions:x,filters:w}=o})(),(window.wp=window.wp||{}).hooks=n})(); 3760;/*! This file is auto-generated */ 3761(()=>{"use strict";var t={d:(n,e)=>{for(var r in e)t.o(e,r)&&!t.o(n,r)&&Object.defineProperty(n,r,{enumerable:!0,get:e[r]})},o:(t,n)=>Object.prototype.hasOwnProperty.call(t,n),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}
3761),Object.defineProperty(t,"__esModule",{value:!0})}},n={};t.r(n),t.d(n,{__:()=>F,_n:()=>L,_nx:()=>D,_x:()=>w,createI18n:()=>h,defaultI18n:()=>b,getLocaleData:()=>g,hasTranslation:()=>O,isRTL:()=>P,resetLocaleData:()=>x,setLocaleData:()=>v,sprintf:()=>l,subscribe:()=>m});var e,r,a,i,o=/%(((\d+)\$)|(\(([$_a-zA-Z][$_a-zA-Z0-9]*)\)))?[ +0#-]*\d*(\.(\d+|\*))?(ll|[lhqL])?([cduxXefgsp%])/g;function l(t,...n){return function(t,...n){var e=0;return Array.isArray(n[0])&&(n=n[0]),t.replace(o,(function(){var t,r,a,i,o;return t=arguments[3],r=arguments[5],"%"===(i=arguments[9])?"%":("*"===(a=arguments[7])&&(a=n[e],e++),void 0===r?(void 0===t&&(t=e+1),e++,o=n[t-1]):n[0]&&"object"==typeof n[0]&&n[0].hasOwnProperty(r)&&(o=n[0][r]),"f"===i?o=parseFloat(o)||0:"d"===i&&(o=parseInt(o)||0),void 0!==a&&("f"===i?o=o.toFixed(a):"s"===i&&(o=o.substr(0,a))),null!=o?o:"")}))}(t,...n)}e={"(":9,"!":8,"*":7,"/":7,"%":7,"+":6,"-":6,"<":5,"<=":5,">":5,">=":5,"==":4,"!=":4,"&&":3,"||":2,"?":1,"?:":1},r=["(","?"],a={")":["("],":":["?","?:"]},i=/<=|>=|==|!=|&&|\|\||\?:|\(|!|\*|\/|%|\+|-|<|>|\?|\)|:/;var s={"!":function(t){return!t},"*":function(t,n){return t*n},"/":function(t,n){return t/n},"%":function(t,n){return t%n},"+":function(t,n){return t+n},"-":function(t,n){return t-n},"<":function(t,n){return t<n},"<=":function(t,n){return t<=n},">":function(t,n){return t>n},">=":function(t,n){return t>=n},"==":function(t,n){return t===n},"!=":function(t,n){return t!==n},"&&":function(t,n){return t&&n},"||":function(t,n){return t||n},"?:":function(t,n,e){if(t)throw n;return e}};function u(t){var n=function(t){for(var n,o,l,s,u=[],d=[];n=t.match(i);){for(o=n[0],(l=t.substr(0,n.index).trim())&&u.push(l);s=d.pop();){if(a[o]){if(a[o][0]===s){o=a[o][1]||o;break}}else if(r.indexOf(s)>=0||e[s]<e[o]){d.push(s);break}u.push(s)}a[o]||d.push(o),t=t.substr(n.index+o.length)}return(t=t.trim())&&u.push(t),u.concat(d.reverse())}(t);return function(t){return function(t,n){var e,r,a,i,o,l,u=[];for(e=0;e<t.length;e++){if(o=t[e],i=s[o]){for(r=i.length,a=Array(r);r--;)a[r]=u.pop();try{l=i.apply(null,a)}catch(t){return t}}else l=n.hasOwnProperty(o)?n[o]:+o;u.push(l)}return u[0]}(n,t)}}var d={contextDelimiter:"�",onMissingKey:null};function c(t,n){var e;for(e in this.data=t,this.pluralForms={},this.options={},d)this.options[e]=void 0!==n&&e in n?n[e]:d[e]}c.prototype.getPluralForm=function(t,n){var e,r,a,i=this.pluralForms[t];return i||("function"!=typeof(a=(e=this.data[t][""])["Plural-Forms"]||e["plural-forms"]||e.plural_forms)&&(r=function(t){var n,e,r;for(n=t.split(";"),e=0;e<n.length;e++)if(0===(r=n[e].trim()).indexOf("plural="))return r.substr(7)}(e["Plural-Forms"]||e["plural-forms"]||e.plural_forms),a=function(t){var n=u(t);return function(t){return+n({n:t})}}(r)),i=this.pluralForms[t]=a),i(n)},c.prototype.dcnpgettext=function(t,n,e,r,a){var i,o,l;return i=void 0===a?0:this.getPluralForm(t,a),o=e,n&&(o=n+this.options.contextDelimiter+e),(l=this.data[t][o])&&l[i]?l[i]:(this.options.onMissingKey&&this.options.onMissingKey(e,t),0===i?e:r)};const p={plural_forms:t=>1===t?0:1},f=/^i18n\.(n?gettext|has_translation)(_|$)/,h=(t,n,e)=>{const r=new c({}),a=new Set,i=()=>{a.forEach((t=>t()))},o=(t,n="default")=>{r.data[n]={...r.data[n],...t},r.data[n][""]={...p,...r.data[n]?.[""]},delete r.pluralForms[n]},l=(t,n)=>{o(t,n),i()},s=(t="default",n,e,a,i)=>(r.data[t]||o(void 0,t),r.dcnpgettext(t,n,e,a,i)),u=t=>t||"default",d=(t,n,r)=>{let a=s(r,n,t);return e?(a=e.applyFilters("i18n.gettext_with_context",a,t,n,r),e.applyFilters("i18n.gettext_with_context_"+u(r),a,t,n,r)):a};if(t&&l(t,n),e){const t=t=>{f.test(t)&&i()};e.addAction("hookAdded","core/i18n",t),e.addAction("hookRemoved","core/i18n",t)}return{getLocaleData:(t="default")=>r.data[t],setLocaleData:l,addLocaleData:(t,n="default")=>{r.data[n]={...r.data[n],...t,"":{...p,...r.data[n]?.[""],...t?.[""]}},delete r.pluralForms[n],i()},resetLocaleData:(t,n)=>{r.data={},r.pluralForms={},l(t,n)},subscribe:t=>(a.add(t),()=>a.delete(t)),__:(t,n)=>{let r=s(n,void 0,t);return e?(r=e.applyFilters("i18n.gettext",r,t,n),e.applyFilters("i18n.gettext_"+u(n),r,t,n
3761)):r},_x:d,_n:(t,n,r,a)=>{let i=s(a,void 0,t,n,r);return e?(i=e.applyFilters("i18n.ngettext",i,t,n,r,a),e.applyFilters("i18n.ngettext_"+u(a),i,t,n,r,a)):i},_nx:(t,n,r,a,i)=>{let o=s(i,a,t,n,r);return e?(o=e.applyFilters("i18n.ngettext_with_context",o,t,n,r,a,i),e.applyFilters("i18n.ngettext_with_context_"+u(i),o,t,n,r,a,i)):o},isRTL:()=>"rtl"===d("ltr","text direction"),hasTranslation:(t,n,a)=>{const i=n?n+"�"+t:t;let o=!!r.data?.[a??"default"]?.[i];return e&&(o=e.applyFilters("i18n.has_translation",o,t,n,a),o=e.applyFilters("i18n.has_translation_"+u(a),o,t,n,a)),o}}},_=window.wp.hooks,y=h(void 0,void 0,_.defaultHooks);var b=y;const g=y.getLocaleData.bind(y),v=y.setLocaleData.bind(y),x=y.resetLocaleData.bind(y),m=y.subscribe.bind(y),F=y.__.bind(y),w=y._x.bind(y),L=y._n.bind(y),D=y._nx.bind(y),P=y.isRTL.bind(y),O=y.hasTranslation.bind(y);(window.wp=window.wp||{}).i18n=n})(); 3762;
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.